3828 Commits
Author SHA1 Message Date
karafruit 7bab5b0434 Merge commit '3cb1e' 2026-05-04 00:41:59 -05:00
karafruit 3cb1e9d77b Fix issue with make_custom_pool 2026-05-03 17:37:40 -05:00
karafruit bdf22ac3d5 Merge commit 'ca221b9324485b09e16bc268c131dcd86d883ab6' into beta_2 2026-05-03 00:00:34 -05:00
karafruit f421bba9f3 Fix issue with make_custom_pool 2026-04-14 10:20:53 -05:00
codemann8 ca221b9324 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-03-15 17:08:37 -05:00
codemann8 a663ab892d Version bump 0.7.0.3 2026-03-15 17:08:18 -05:00
codemann8 a3adb12422 Various baserom fixes
- Fix buffer sword slash when dashing into water
- Fixed bug with MSU-1 GT2 track not falling back to GT track
- Fix for Kiki unfollowing after certain entrance transition conditions
2026-03-15 17:01:50 -05:00
codemann8 3ce66a4952 Changed big bomb shop vendor text to be follower agnostic 2026-03-15 16:46:07 -05:00
codemann8 0dbae8e21e Fixed bug/oversight with vanilla_fill and prize_shuffle 2026-03-15 16:32:54 -05:00
Esme 3547aef480 Account for failure to determine locale. 2026-03-15 10:44:28 -05:00
codemann8 c9ebb80f3f Merge pull request #30 from Catobat/GridImprovements
Grid Layout Shuffle Customizer and improvements
2026-03-15 10:42:53 -05:00
theclearmouse b45ebdc2ab add crosskeys winners 2026-03-15 10:31:31 -05:00
codemann8 45f5f3955b Merged in DR v1.5.6 2026-03-14 08:53:07 -05:00
aerinon 4da73127a2 fix: reworked spawn refills for standard + enemy drop 2026-03-12 15:52:09 -06:00
aerinon a4d7d63235 fix: disable pikit drops due to vanilla steal failure bug 2026-03-11 15:32:11 -06:00
aerinon b2b775e243 feat: item_pool_adjust added to customizer 2026-03-11 15:32:11 -06:00
aerinon af9b61ad7d fix: beemizer + pottery + multiworld generation issue 2026-03-11 10:08:54 -06:00
codemann8 9a6d5b2112 Merged in DR v1.5.5 2026-03-03 08:23:47 -06:00
Catobat 54e4176311 Consider distance between starting locations when picking a grid layout 2026-02-22 23:11:47 +01:00
Catobat 6a59f58230 Consider number of separate overworld areas when picking a grid layout 2026-02-22 23:11:06 +01:00
Catobat b8884e9010 Add and update presets for Grid Layout Shuffle 2026-02-22 23:11:06 +01:00
aerinon f04ede1e21 doc: fix broken links 2026-02-11 12:22:44 -07:00
aerinon 0e432106d5 fix: handle universal keys issue 2026-02-11 10:49:33 -07:00
aerinon 40260c4fd4 fix: logic issue in PoD Arena (too stringent requirements) 2026-02-11 10:20:39 -07:00
Catobat 78c389e2d5 Add Grid Layout Shuffle Customizer options for custom arrangements, restricted positions and split large screens 2026-02-08 21:57:46 +01:00
Catobat f5d547cc5e Handle trimming and wrapping for large pieces 2026-02-07 12:29:32 +01:00
Catobat 086d1bbc85 Place pieces with only one possible position first 2026-02-05 20:22:42 +01:00
Catobat 0133bd1da7 Implement piece merging 2026-02-05 20:22:42 +01:00
karafruit b1a71ef9b1 Merge in OW Shuffle 0.7.0.2 (#3)
Reviewed-on: #3
2026-02-03 23:47:48 +00:00
karafruit 699d395b3d Update texts 2026-02-03 17:46:18 -06:00
aerinon 27acabadef doc: update known issues 2026-02-03 13:22:02 -07:00
aerinon d3f8e5fd58 fix: key counts when door shuffle is off 2026-02-03 13:17:42 -07:00
Catobat 87ba33852f Refactor how large screen quadrants are stored in grids 2026-02-01 14:15:19 +01:00
karafruit 6859f5cd24 Update prize positions on world map 2026-01-31 13:02:07 -06:00
karafruit 8a7cc02282 Merge remote-tracking branch 'codemann/OverworldShuffle' into codemann_OverworldShuffle 2026-01-31 08:57:53 -06:00
codemann8 ac17d0ead8 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-30 12:41:38 -06:00
codemann8 ad8dff3b2d Version bump 0.7.0.2 2026-01-30 12:41:26 -06:00
codemann8 f1aef298ef Minor efficiency 2026-01-30 12:35:42 -06:00
aerinon e27fb51dc9 deploy: github action site deploy 2026-01-30 10:09:22 -07:00
aerinon bf92fe91c2 doc: new documentation helps
fix: issue with blank shop items
2026-01-30 10:05:29 -07:00
karafruit 950df6b1d0 Remove empty bottle from fairy refill pool 2026-01-29 22:36:25 -06:00
codemann8 2a24048e87 Fix buffered sword issue when transitioning to water with sword out 2026-01-29 21:26:32 -06:00
codemann8 afe888a87a Fix Link sprite using vanilla coords on map check in Special OW 2026-01-29 20:53:24 -06:00
karafruit dab247807f Update baserom 2026-01-29 15:53:14 -06:00
codemann8 09254850d3 Fixed error with bombbag + non-shopsanity 2026-01-28 20:03:56 -06:00
codemann8 31f634396a Fixed issue with map checks showing opposite world icons in Inverted 2026-01-28 19:49:20 -06:00
codemann8 daa54e8aad Fixed palette issue with map checks when Link stands in grass/water 2026-01-28 18:40:51 -06:00
codemann8 b16777ede7 Added new PlasmaKappa tribute TF text 2026-01-28 18:13:58 -06:00
karafruit fb96d04e56 Update baserom 2026-01-27 22:12:20 -06:00
karafruit 54981b5c51 Update baserom to fix OW Map palette issue 2026-01-27 00:26:09 -06:00
aerinon eda03d8657 chore: version bump 2026-01-26 15:10:51 -07:00
aerinon 31682fb8a2 doc: update release note 2026-01-26 14:58:17 -07:00
theclearmouse fabad625d2 add main tournament 2025 winner 2026-01-26 14:56:07 -07:00
karafruit f43fb18bad Remove some more dead files 2026-01-25 22:29:38 -06:00
karafruit ff4f546ec9 Add collections-extended as a proper dependency 2026-01-25 22:27:22 -06:00
karafruit 6a58773dad Pull in OR 0.7.0.1 (#2)
Reviewed-on: #2
2026-01-26 04:19:24 +00:00
karafruit 51b581aa8c Yet more spacing fixes 2026-01-25 22:14:57 -06:00
karafruit 6949545ef8 More spacing fixes 2026-01-25 22:08:34 -06:00
karafruit 0366198d44 Fix spacings 2026-01-25 22:05:16 -06:00
karafruit 2be02890bd Merge remote-tracking branch 'codemann/OverworldShuffle' into codemann_OverworldShuffle 2026-01-25 21:39:53 -06:00
karafruit 61d7940183 Fix punctuation on Ganon sign 2026-01-25 20:17:57 -06:00
karafruit f539e24ddb GK Version 1.0.0 (#1)
Establish GK as its own fork with versioning, starting with v1.0.0
- bosshunt mode
- dungeon maps are useful
- ensure there's always a bee for sale in shop shuffle

Reviewed-on: #1
Co-authored-by: Kara Alexandra <ardnaxelarak@gmail.com>
Co-committed-by: Kara Alexandra <ardnaxelarak@gmail.com>
2026-01-25 21:29:44 +00:00
karafruit 78dd5c65fc isort 2026-01-25 13:59:45 -06:00
codemann8 83254f4c78 Moved Flute Shuffle 2026-01-25 00:06:19 -06:00
karafruit ec81a900ef Remove unnecessary references to data/base2current.json 2026-01-24 13:50:11 -06:00
codemann8 86c9f7cfb6 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-19 15:24:35 -06:00
codemann8 d576e9ee39 Version bump 0.7.0.1 2026-01-19 15:24:24 -06:00
codemann8 00ba5d89fb Fixes issue not able to screen transition if bumped by enemy in water 2026-01-19 15:21:13 -06:00
codemann8 e01c779f3d Fix buggy sprites in post-aga Zoras Domain 2026-01-17 17:40:16 -06:00
codemann8 61ea641b38 Fixed L/R map swap while in special world 2026-01-17 13:59:28 -06:00
codemann8 1d89564efc Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-17 11:44:53 -06:00
codemann8 81a6fd387b no change 2026-01-17 11:44:40 -06:00
codemann8 dc1211256c Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-17 11:10:53 -06:00
codemann8 32d1c2610d Fixed un-flags for new OWR options 2026-01-17 11:09:14 -06:00
codemann8 3185864007 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-17 02:22:58 -06:00
codemann8 56549abfbe Version bump 0.7.0.0 2026-01-17 02:22:23 -06:00
codemann8 3744b4406b label change 2026-01-17 02:19:18 -06:00
codemann8 cb4e8e0242 Merge branch 'OverworldShuffleDev' into pr/27 2026-01-17 01:17:03 -06:00
codemann8 adaeccf23e Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-17 01:07:33 -06:00
codemann8 a2a291b0e1 Version bump 0.6.1.11 2026-01-17 01:06:55 -06:00
codemann8 bb7c482d1d Fixed issue with Old Man follower infinite pit fall 2026-01-17 00:52:31 -06:00
codemann8 ebebfe3ec0 Allowing some enemies on water since enemies can move on water 2026-01-16 23:24:06 -06:00
codemann8 5a28f42454 Fixed issue with ow sprite data pushing the uw sprite pointer table down to overlap the pot pointer table 2026-01-16 21:26:26 -06:00
karafruit ea8498f402 Add --tries arg 2026-01-16 18:35:59 -06:00
karafruit f52a6c02c6 Update baserom (lamp fix) 2026-01-16 18:30:21 -06:00
aerinon a2b23110c4 fix: started using the map_hud_mode flag (somewhat against my better judgement, there's some crufty asm lying about) 2026-01-16 15:46:37 -07:00
codemann8 a84b125bbd missing DR version number change 2026-01-16 15:36:58 -06:00
codemann8 ffbff6d08d Fixing key totals marking MapCountDisplay flag 2026-01-16 15:30:34 -06:00
codemann8 769a8e626b Fixing key totals marking MapCountDisplay flag 2026-01-16 14:30:35 -06:00
aerinon 3fab26f423 fix: prevent locked location from being moved by rupee balancing 2026-01-15 15:16:02 -07:00
karafruit 5b6187d6ab Invert bitfield for pseudoflute 2026-01-15 04:05:51 -06:00
Catobat 56e4a8c59b Add Customizer options for wrapping in Grid Layout Shuffle 2026-01-12 22:20:26 +01:00
Catobat 4b7c453219 Add ow_fog setting 2026-01-12 21:53:52 +01:00
Catobat 6afdd79741 Adjust map locations for flute spots and prizes to layout 2026-01-11 22:34:20 +01:00
Catobat d0e9fa73fa Implement Grid Layout Shuffle 2026-01-11 22:34:20 +01:00
codemann8 515bc0cb0b Bandaid fix to money balancing 2026-01-11 13:45:06 -06:00
codemann8 ceb189b048 dungeon_counters default behavior is handled elsewhere 2026-01-11 03:40:15 -06:00
codemann8 5f53da73be Fixed key total autotracking after prior default key total HUD change 2026-01-11 02:39:53 -06:00
codemann8 44415b3ca5 Fixed boss icons not showing on dungeon map check 2026-01-11 02:00:00 -06:00
codemann8 006d25c102 Fixed bonk drops duplicate counting and potentially writing bad values 2026-01-11 00:43:55 -06:00
codemann8 7b483780db Fixed bonk drops duplicate counting and potentially writing bad values 2026-01-11 00:07:20 -06:00
Catobat 080f3b1cca Add ow_layout and ow_parallel settings 2026-01-10 12:18:41 +01:00
codemann8 bd40ddf2e6 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-08 19:50:35 -06:00
codemann8 452981ffe2 Version bump 0.6.1.10 2026-01-08 19:50:12 -06:00
codemann8 40f8507fcb Fix psuedoboots ability to open Kings Tomb 2026-01-08 19:49:04 -06:00
codemann8 43c34f4494 Fixed Invulnerable goals, no longer expects a target value 2026-01-08 16:43:49 -06:00
codemann8 594bca2a1c Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-08 16:23:08 -06:00
codemann8 de343ce650 Version bump 0.6.1.9 2026-01-08 16:22:47 -06:00
codemann8 24d8da3810 Disallow money balancing to apply to locked and event items 2026-01-08 16:19:43 -06:00
codemann8 7b25261f67 Fix psuedoboots ability to open Kings Tomb 2026-01-08 16:17:45 -06:00
codemann8 aac7ff1791 Improved and fixed map check coord accuracy 2026-01-08 12:59:57 -06:00
aerinon 8480353028 fix: specific fix for vanilla entrance shuffle with no doors to properly process dungeon in the correct order for key logic 2026-01-07 10:59:36 -07:00
codemann8 7d757f3e28 Reordered ow_prize_table data based on screen ID 2026-01-06 12:49:28 -06:00
codemann8 3c386a0c0d Fix follower shuffle placement errors 2026-01-05 16:38:25 -06:00
codemann8 89b255c031 Fixed follower placement failures 2026-01-02 18:12:23 -06:00
codemann8 84cd129ead Merge branch 'OverworldShuffleDev' into OverworldShuffle 2026-01-01 12:14:16 -06:00
codemann8 9d6335efd7 Version bump 0.6.1.8 2026-01-01 12:13:56 -06:00
codemann8 b3d629bc54 Fixed issue with follower logic assuming vanilla placement 2026-01-01 11:57:16 -06:00
codemann8 2f002fa921 Using main item fill to place followers 2026-01-01 11:26:59 -06:00
codemann8 b5ba21a039 Fixed error with HC Courtyard Tree Pull rule 2026-01-01 09:59:18 -06:00
karafruit 7bec1f899c Add pyproject.toml 2025-12-22 14:57:40 -06:00
codemann8 cb21e1e4e9 Fixed issue where OW sprite list data collides with following UW sprite pointer table 2025-12-22 08:31:38 -06:00
karafruit 37823134db Fix enemizer 2025-12-19 11:09:52 -06:00
karafruit 3f76c7ac66 Fix intro text 2025-12-14 20:11:16 -06:00
karafruit 7b5c6e52a5 Pseudoflute 2025-12-14 10:00:06 -06:00
karafruit f8414e2f67 Merge branch 'OverworldShuffle' into GwaaKiwi 2025-12-14 10:00:01 -06:00
codemann8 cf0fb152a0 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-12-09 18:02:39 -06:00
codemann8 faa00efe61 Version bump 0.6.1.7 2025-12-09 18:01:48 -06:00
codemann8 e003c25dc0 Merged in DR v1.5.2 2025-12-09 18:00:56 -06:00
aerinon bb2228d70a fix: keys 2025-12-09 11:20:34 -07:00
codemann8 f74bac43c2 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-12-09 09:27:24 -06:00
codemann8 b983b52252 Version bump 0.6.1.6 2025-12-09 09:27:13 -06:00
codemann8 d40334f790 Fixed key counts being off 2025-12-09 09:25:55 -06:00
aerinon cfa448947d chore: bump version 2025-12-09 08:09:52 -07:00
aerinon 6a0aa190a9 fix: issue with keys counts not updating correctly 2025-12-08 16:37:04 -07:00
codemann8 382a22dd2f Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-12-07 00:02:03 -06:00
codemann8 159e7e3785 Version bump 0.6.1.5 2025-12-07 00:01:53 -06:00
codemann8 6cdcc800e0 Fixed error with non-prize shuffle 2025-12-07 00:00:14 -06:00
codemann8 6bb7921a01 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-12-05 03:04:45 -06:00
codemann8 72f370de4a Version bump 0.6.1.4 2025-12-05 03:04:32 -06:00
codemann8 bd94cfa43f Minor GUI fixes for triforce gfx 2025-12-05 02:54:57 -06:00
codemann8 e3e65f0540 Some fixes for DR v1.5.0 2025-12-04 19:51:51 -06:00
codemann8 0c7f88b588 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2025-12-03 12:09:19 -06:00
codemann8 f9a11484a9 Merged in DR v1.5.0 2025-12-03 12:09:18 -06:00
codemann8 0bf6f5f0da Merged in DR v1.5.0 2025-12-03 10:53:30 -06:00
codemann8 e48a4faf7c Merged in DR v1.5.0 2025-12-03 10:40:54 -06:00
aerinon 8b40c13d1c fix: crash 2025-12-02 11:10:56 -07:00
aerinon 3f0c3ed810 fix: perf optimization
fix: playthrough calc and drop rules
refactor: using compass_mode for map info
2025-12-02 09:46:09 -07:00
codemann8 0364367306 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-11-22 10:20:14 -06:00
codemann8 2a1eeb25db oops 2025-11-22 10:19:54 -06:00
codemann8 40beb8dbdc Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-11-22 09:23:40 -06:00
codemann8 e13451df1e Version bump 0.6.1.3 2025-11-22 09:23:18 -06:00
Catobat 4e78cc882a Make placement of dungeon items faster 2025-11-22 09:08:59 -06:00
codemann8 a8ac33c093 Fix for post-mirror follower sprite gfx 2025-11-22 07:31:51 -06:00
codemann8 1bb803016e Remove unneeded world region setting 2025-11-21 11:40:42 -06:00
Catobat 483e7f49ad Fix issues with dynamic flute and mirror exits 2025-11-21 11:02:12 +01:00
Catobat c305995fad Skip unneeded rules in copy_world_premature 2025-11-20 18:43:53 +01:00
aerinon 0c50e08cdc feat: rom fixups, update docs 2025-11-20 10:12:56 -07:00
codemann8 fb99d33007 Added new post-gen option to change TF Piece GFX 2025-11-19 09:54:31 -06:00
codemann8 2b7a9e3bf8 Added new gfx for 10/11 keys rather than A/B keys 2025-11-18 23:57:27 -06:00
codemann8 3e9070f30d Added missing entries to OWR vanilla preset 2025-11-18 05:47:14 -06:00
aerinon f4021afac0 feat: free_lamp_cone as experimental feature 2025-11-14 14:37:46 -07:00
aerinon 5ce9a3e297 refactor: remove old asm code 2025-11-14 13:43:32 -07:00
aerinon f6d774b13f fix: potential fix for GT basement 2025-11-14 13:24:08 -07:00
aerinon 923ba14d61 feat: force_enemy feature
feat: rom-side enemy "spies"
2025-11-14 09:05:12 -07:00
codemann8 b62316d3f3 Merged in DR v1.4.11 2025-11-13 19:28:23 -06:00
codemann8 ef87884fb3 Fix to allow VRAM corruption in boss fights 2025-11-13 19:17:01 -06:00
aerinon 9847b71a02 fix: blind vram fight fix 2025-11-13 08:57:15 -07:00
aerinon 58daf424f3 fix: enemy bans
doc: version information
2025-11-11 16:38:49 -07:00
aerinon b64b7d9d6d fix: ban swamola enemies 2025-11-11 15:33:32 -07:00
aerinon 96e48b2892 fix: pot drops at sprite limit
fix: music silence DR
fix: kondongo AI in vanilla rooms
2025-11-11 15:32:00 -07:00
codemann8 7e293301bb Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-11-08 11:18:52 -06:00
codemann8 f66ec985a9 Version bump 0.6.1.2 2025-11-08 11:18:34 -06:00
codemann8 411f0bc7bc Re-fixed purple chest follower dupe 2025-11-08 11:12:27 -06:00
aerinon d7af3a4a7d Merge pull request #170 from theclearmouse/patch-3
update tournament winners in telepathy tiles
2025-11-08 10:45:12 -06:00
codemann8 ace8f3144e Adding missing rule for Hyrule Castle Tree Pull 2025-11-08 10:38:10 -06:00
codemann8 600865b659 Some fixes for Custom Goals
- Changed spoiler meta output to include goaltext
- Fixed GT Cutscene crash
- Allow multiple %d to resolve in goaltext
2025-11-08 10:37:16 -06:00
codemann8 2ff0aa7b67 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2025-11-08 10:34:29 -06:00
codemann8 7016e5afbf Yaml errors no longer fail silently 2025-11-08 10:34:26 -06:00
codemann8 7cfa8f4b4d Yaml errors no longer fail silently 2025-11-08 02:36:28 -06:00
codemann8 a3dd82f467 Initial custom header implementation 2025-11-07 22:08:18 -06:00
codemann8 2771040cb3 Added custom gfx for Ped and Murahdahla 2025-11-07 22:06:07 -06:00
aerinon dea2f170ff Merge pull request #167 from KrisDavie/glitched_fixes_250316
More glitched fixes
2025-11-04 08:19:38 -07:00
aerinon 20806e1ecf Merge pull request #169 from theclearmouse/patch-2
Update Text.py to change Ladder -> Stepladder
2025-11-04 08:17:51 -07:00
aerinon 442abfd156 Merge pull request #170 from theclearmouse/patch-3
update tournament winners in telepathy tiles
2025-11-04 08:17:23 -07:00
theclearmouse 8b75aeb78f fix typo 2025-11-03 11:35:10 -05:00
theclearmouse 61dd76e7ea typo 2025-11-03 10:56:55 -05:00
theclearmouse e00c0ee88d update tournament winners in telepathy tiles 2025-11-03 10:55:14 -05:00
codemann8 3f77398657 Documentation fix 2025-10-31 15:49:13 -05:00
codemann8 89402efa07 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-10-31 01:24:46 -05:00
codemann8 bf7f307982 Version bump 0.6.1.1 2025-10-31 01:24:22 -05:00
codemann8 8cfeecdb60 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2025-10-31 01:16:43 -05:00
codemann8 6edfbda0bf Custom Goal framework fixes 2025-10-31 01:13:45 -05:00
codemann8 c5ea8e4703 Custom Goal framework fixes 2025-10-31 01:01:28 -05:00
codemann8 0b8618c5b5 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-10-29 15:42:21 -05:00
codemann8 a5ce59c7e8 Version bump 0.6.1.0 2025-10-29 15:41:56 -05:00
codemann8 605bacf490 Implemented Custom Goal Framework 2025-10-29 15:17:24 -05:00
codemann8 fd28ef77d2 Fixed issue with Locksmith despawning after purple chest turn-in when a follower is stored 2025-10-29 15:01:56 -05:00
hiimcody1 cf488fda36 Initial custom header implementation 2025-10-29 14:31:49 -05:00
codemann8 6cb05f18ca Changed vital/useful hints to logic hints 2025-10-29 14:07:21 -05:00
codemann8 fdbe9cf9fd Implemented Custom Goal Framework 2025-10-29 05:23:59 -05:00
codemann8 ba444f4bbc Remove duplicated hint possibility between location and item hinting 2025-10-27 23:23:10 -05:00
codemann8 048487fce0 Moved random settings resolutions into helper function 2025-10-19 23:35:17 -05:00
codemann8 917d126023 Fixed Ganon silvers hint for free-standing items 2025-10-18 02:27:43 -05:00
codemann8 8a68965872 New fix for pot drops when at sprite limit 2025-10-15 18:31:15 -05:00
codemann8 237ed4bdfd Fixed pogdor (frogdor at PoD entrance) with Kiki following while exiting at PoD 2025-09-21 13:56:41 -05:00
codemann8 cce6abc468 Fixed issue with Duck overwriting GT cutscene gfx 2025-09-21 13:39:07 -05:00
codemann8 4a82b2ad50 Remove unused argument from MultiServer call 2025-09-21 13:37:07 -05:00
codemann8 277fdff0e1 Added new Snitch Lady text when Links House is placed there 2025-09-08 12:55:57 -05:00
codemann8 20a75687de Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-09-07 11:00:35 -05:00
codemann8 b8a40cf6c1 Version bump 0.6.0.8 2025-09-07 10:59:34 -05:00
codemann8 76dd0414ae Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2025-09-07 10:54:39 -05:00
codemann8 52ed4cf7de Re-fixed old man spawn on pyramid issue 2025-09-07 10:52:23 -05:00
codemann8 a5f14530cd Allow Zelda escape to use TT Maiden Cell as checkpoint 2025-09-07 10:51:39 -05:00
karafruit 94fe0475b9 Update baserom 2025-09-05 20:47:50 -05:00
karafruit c97260a337 Add random Ganon vulnerability item. 2025-09-03 19:58:38 -05:00
codemann8 5fc3924b8a Allow Zelda escape to use TT Maiden Cell as checkpoint 2025-09-03 02:55:29 -05:00
codemann8 808daf224d Fixed EG2 spawn starts to connect logic exits more consistently 2025-09-03 02:54:58 -05:00
codemann8 95ec5c7983 Fixed error with placing Old Man cave in ER 2025-09-03 02:54:58 -05:00
codemann8 cb11ddb1c6 Fixed follower plando error 2025-09-03 02:41:26 -05:00
karafruit 74a676ac17 Merge remote-tracking branch 'origin/OverworldShuffle' into GwaaKiwi 2025-09-01 11:03:25 -05:00
codemann8 b45db6f2ad Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-08-25 15:23:06 -05:00
codemann8 d70ca29d62 Version bump 0.6.0.7 2025-08-25 15:22:50 -05:00
codemann8 062afa75b5 Fix for GT cutscene GFX 2025-08-25 15:21:23 -05:00
codemann8 23b606f36f Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-08-25 12:35:20 -05:00
codemann8 18a8f98ff6 Version bump 0.6.0.6 2025-08-25 12:34:49 -05:00
codemann8 b80bed0853 Fix issue with Mystery subweights not correctly evaluating boolean settings 2025-08-25 12:31:11 -05:00
codemann8 802a75c2a3 Small doc fix 2025-08-25 11:21:58 -05:00
codemann8 c3d6c96e79 Added customizer ability to change GT cutscene gfx 2025-08-25 11:21:44 -05:00
codemann8 8372a8a9bf Changing hard-coded value to labeled value 2025-08-19 10:21:26 -05:00
codemann8 0d3feb33d1 Various ROM fixes
- New chicken gfx
- Fixed music silence in DR when straight stairs lead into pre-Aga room
- Other various music fixes
2025-08-19 10:19:30 -05:00
karafruit dc3ec0238d Damage Table shuffle 2025-07-22 12:44:57 -05:00
karafruit a886b4ee10 Merge remote-tracking branch 'origin/OverworldShuffle' into GwaaKiwi 2025-07-22 11:38:24 -05:00
codemann8 7c7fc192d5 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-07-18 10:50:05 -05:00
codemann8 e4d7d40127 Version bump 0.6.0.5 2025-07-18 10:49:46 -05:00
codemann8 dd5f0618fd Fixed map key totals on map pickup in non-DR 2025-07-18 10:46:39 -05:00
codemann8 f9a37c3c2e Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-07-18 01:26:18 -05:00
codemann8 76f429ac59 Version bump 0.6.0.4 2025-07-18 01:25:45 -05:00
codemann8 8e34dfa627 Fix incorrect sphere count in CLI output 2025-07-18 01:19:55 -05:00
codemann8 7e42fa2927 Restore Kodongo AI when in vanilla rooms 2025-07-13 00:27:52 -05:00
codemann8 30da5e8c22 Allow Old Man to exit from his destination entrance 2025-07-11 05:01:00 -05:00
codemann8 e66214cac3 Fix crash when Old Man exits out of his House entrance 2025-07-11 04:55:17 -05:00
codemann8 2d6b80e74f Fix HUD to show prize, key count, and compass count if seen by player 2025-07-10 23:00:29 -05:00
karafruit 77796daca3 Merge branch 'OriginOverworldShuffle' into GwaaKiwi 2025-07-01 14:11:59 -05:00
codemann8 8c9a5d7ebb Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-06-16 14:55:18 -05:00
codemann8 28fd328a53 Version bump 0.6.0.3 2025-06-16 14:55:01 -05:00
codemann8 fc0c5df943 Fixed issue with Quake scaring Kiki 2025-06-13 23:39:58 -05:00
codemann8 73ffa41751 Some basrom fixes
- Fix issue with no music in LH after S+Q from Kakariko
- Boots missing from menu upon collection until S+Q
- Kiki runs away if Link spawned from Sanc
- Locksmith sprite despawns after purple chest item get
2025-06-12 11:00:14 -05:00
codemann8 a1e6509765 Reset MSU Resume on S+Q 2025-06-05 20:53:37 -05:00
codemann8 69ff38521e Restoring water floor in Arrghus' room in boss shuffle 2025-06-05 19:53:01 -05:00
theclearmouse 9719958119 revert 2025-06-02 23:55:23 -04:00
theclearmouse e63f686308 Update Text.py
updated ladder to stepladder because ladder is no more
2025-06-02 23:52:43 -04:00
karafruit c186f8068b Update baserom 2025-05-18 02:56:26 -05:00
karafruit 7868a76a93 Fix gloom heart icons 2025-05-18 02:32:24 -05:00
karafruit 53be043af4 Damage Challenge modes: OHKO and Gloom 2025-05-18 01:00:09 -05:00
codemann8 42e560f72c Merged in DR v1.4.10 2025-05-16 23:51:04 -05:00
codemann8 be4a440f6c Revert "Possibly fix false positive error message for python package requirements"
This reverts commit 63f39c5c05.
2025-05-16 23:43:41 -05:00
codemann8 4cd1443634 Possible fix for prizes not getting placed in major locations 2025-05-16 23:42:47 -05:00
codemann8 870d157e58 Fixed issue with mirroring with a dropped purple chest 2025-05-16 22:27:36 -05:00
codemann8 42bafa1c99 Locksmith follower now behaves closer to vanilla 2025-05-16 22:22:37 -05:00
aerinon bb1bbdaee7 fix: notes clarity 2025-05-13 15:02:42 -06:00
aerinon 3243b0a9ee fix: faeries on overworld disallowed 2025-05-13 14:59:53 -06:00
aerinon ab98b346e0 fix: price in shops bug 2025-05-13 14:52:37 -06:00
aerinon 91d6d4ec8a fix: Restrict murderdactyl logic to ohko 2025-05-13 14:49:38 -06:00
aerinon 1b904605c1 fix: Helmacopter fix 2025-05-13 14:28:55 -06:00
karafruit 04270990cb Merge remote-tracking branch 'origin/OverworldShuffle' into GwaaKiwi 2025-05-04 15:24:08 -05:00
codemann8 d36f996b00 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-05-04 09:33:56 -05:00
codemann8 73ee8a9942 Version bump 0.6.0.2 2025-05-04 09:33:32 -05:00
codemann8 fc172dd593 Fixed issue with item pool placing items on Zelda Drop Off 2025-05-04 09:31:36 -05:00
codemann8 40bff27e6b Various bug fixes for Follower Shuffle post-launch
- Fix issue with infinite purple chest item get
- Fix issue with Kiki running away on iframe ledge hops
- Fix issue with bad follower gfx on screens with followers
- Fix issue with Zelda appearing in conditional follower locations
2025-05-04 09:27:29 -05:00
codemann8 d082ebf293 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-05-01 08:12:58 -05:00
codemann8 20c9bb0f56 h 2025-05-01 08:12:40 -05:00
codemann8 a1eee9f074 Version bump 0.6.0.1 2025-05-01 08:12:24 -05:00
codemann8 8309b1cf9c Error when follower shuffle not enabled 2025-05-01 08:11:00 -05:00
codemann8 242b7d0bed Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-05-01 04:33:03 -05:00
codemann8 dee0a25f42 oopsie 2025-05-01 04:31:47 -05:00
codemann8 e7c1037359 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-04-30 13:48:27 -05:00
codemann8 3f930c095c Version bump 0.6.0.0 2025-04-30 13:47:49 -05:00
codemann8 1c0641c57e Merged in DR v1.4.9 2025-04-30 07:07:57 -05:00
codemann8 3a59fa3e03 Fixed incorrect bunny music issue 2025-04-30 06:49:42 -05:00
codemann8 fcaaab30a4 Initial Follower Shuffle Implementation 2025-04-30 06:45:16 -05:00
aerinon 4657aaf0b6 fix: some customizer generation issues 2025-04-28 14:16:31 -06:00
aerinon f3b774ad7f fix: attempt at fixing moth conveyor room timing 2025-04-28 12:34:19 -06:00
KrisDavie d6b7f5161d More glitched fixes 2025-04-22 09:53:26 +02:00
aerinon 2c1ecd70ff fix: various Enemizer fixes 2025-04-18 12:51:00 -06:00
codemann8 fe0cfe8b3a fix: various Enemizer fixes
Fixed enemizer sprite gfx for soldier enemies falling down pits
Remove unnecessary sprite sheet subgroup for somaria platforms
Freeing up unnecessary sprite sheet subgroups for old man screens
Fix paradox cave and kakariko shop gfx in enemizer
Fix swamp drain gfx in enemizer
Fix bat crash sprite gfx in enemizer
Remove unused subgroups and consolidate purple chest/frog sprite sheets
Remove invalid OW IDs from sprite sheets
2025-04-17 14:44:38 -06:00
codemann8 267552bfee Improved Retro button in GUI 2025-04-16 01:24:59 -05:00
codemann8 63f39c5c05 Possibly fix false positive error message for python package requirements 2025-04-16 01:19:51 -05:00
codemann8 bce49b9e76 Minor documentation and error fixes 2025-04-16 01:18:58 -05:00
codemann8 65f84a1c55 Added documentation for little-known start_inventory items 2025-04-16 01:01:27 -05:00
codemann8 813caa894e Fixed enemizer sprite gfx for soldier enemies falling down pits 2025-04-05 08:12:30 -05:00
codemann8 d423193aa6 Remove unnecessary sprite sheet subgroup for somaria platforms 2025-04-05 08:10:32 -05:00
codemann8 5c5e5e5428 Freeing up unnecessary sprite sheet subgroups for old man screens 2025-04-05 08:07:49 -05:00
codemann8 f365267201 Fix paradox cave and kakariko shop gfx in enemizer 2025-04-05 08:03:23 -05:00
codemann8 9d0404af39 Fix swamp drain gfx in enemizer 2025-04-05 08:02:30 -05:00
codemann8 b6ea505843 Fix bat crash sprite gfx in enemizer 2025-04-05 08:00:40 -05:00
codemann8 4b02a2d5a2 Remove unused subgroups and consolidate purple chest/frog sprite sheets 2025-04-05 08:00:09 -05:00
codemann8 fad9c06b05 Remove invalid OW IDs from sprite sheets 2025-04-05 07:34:56 -05:00
codemann8 58baa412f5 Fix extra junk added to pool for some prize shuffles 2025-03-27 02:28:03 -05:00
aerinon 966bd8d05e fix: prevent big key door modification while door shuffle is vanilla 2025-03-21 11:07:09 -06:00
Kris Davie 7cba411e45 More glitched fixes 2025-03-21 10:57:08 -06:00
karafruit 9b77bb4ac3 Update baserom 2025-03-17 19:02:57 -05:00
karafruit 3c8b08329b fix lamp rules for multis 2025-03-17 17:01:20 -05:00
karafruit ca4829db87 Update baserom 2025-03-14 07:54:39 -05:00
karafruit 7f41ba88d9 Keep static sprites better in mimic-mode 2025-03-11 18:09:59 -05:00
codemann8 acc802dfdf Fixed errors with starting equipment containing bottles 2025-03-11 09:07:57 -05:00
codemann8 7efc23b867 Fixed error with prizes in starting inventory 2025-03-11 09:07:11 -05:00
karafruit 9ad70fb3d7 Add sanctuary goal 2025-03-10 08:37:55 -05:00
karafruit 4a8ab9e02f Baserom update 2025-03-09 17:12:20 -05:00
karafruit 979a710d5c Crystal book setting 2025-03-09 16:50:55 -05:00
karafruit ef642e6c1f Mimic mode 2025-03-09 15:37:44 -05:00
karafruit 8436b32b29 Fix require_lamp mode 2025-03-08 18:22:49 -06:00
karafruit 4c498a723b Add dark_room settings 2025-03-08 18:18:06 -06:00
karafruit 82815d256d Allow using _ for space in starting items 2025-03-06 20:47:23 -06:00
codemann8 5d7e9b8c0b Merge pull request #23 from KrisDavie/OverworldShuffleDev
Fix cavestate dungeon items in non-keysanity
2025-03-06 11:38:47 -06:00
KrisDavie 2af5aad078 Fix cavestate dungeon items in non-keysanity 2025-03-06 17:58:29 +01:00
karafruit 283ece4020 Remove extracting link sprite 2025-03-02 13:10:25 -06:00
karafruit 62eb78e1ce Add json spoiler option 2025-03-02 00:19:57 -06:00
karafruit 0d50f90c55 Double speed mimic mode 2025-03-01 23:53:02 -06:00
karafruit 77fd889121 Change direction of green mimics 2025-03-01 14:14:43 -06:00
karafruit b9a11e75bb Add all-mimics mode 2025-03-01 13:09:40 -06:00
codemann8 8c580afa1f Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-02-18 22:02:23 -06:00
codemann8 1ae183b519 Version bump 0.5.1.5 2025-02-18 22:01:52 -06:00
codemann8 609bbef49a Various baserom fixes
- Fixed overworld map check VRAM crash
- Fixed cavestate dark room hidden items
2025-02-18 21:54:24 -06:00
codemann8 8e511ff5c8 Removing dungeon items from hint pool for nearby shuffle 2025-02-18 21:47:22 -06:00
codemann8 3f6b932410 Fixed common error with shopsanity 2025-02-18 16:56:44 -06:00
codemann8 489694ad8a Fixed issue where empty cave lists were being added to candidates list in ER 2025-02-18 16:54:47 -06:00
codemann8 939b4622f6 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-01-20 22:46:30 -06:00
codemann8 89f72234a2 Version bump 0.5.1.4 2025-01-20 22:46:07 -06:00
theclearmouse 265578dca5 display mirror scroll icon on start screen if enabled 2025-01-19 22:41:55 -05:00
codemann8 ca68455f6f Merge branch 'DoorDevUnstable' into OverworldShuffleDev 2025-01-19 02:00:38 -06:00
codemann8 94d870e2a4 Fixed incorrect ganon silvers hint 2025-01-19 01:30:53 -06:00
aerinon d5385ea8af feat: money balance arg now applies to prices
fix: capacity upgrades now respect price customization
2025-01-17 15:33:23 -07:00
aerinon 8555b13c55 fix: added missing doors 2025-01-17 15:04:13 -07:00
codemann8 37d7697915 Added some missing attributes to copy_world 2025-01-16 00:44:17 -06:00
codemann8 51dd233ac7 Merged in DR v1.4.8 2025-01-16 00:34:36 -06:00
codemann8 663dda9eb9 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2025-01-15 22:35:30 -06:00
codemann8 9bca4988b3 Merged in DR v1.4.8 2025-01-15 22:32:29 -06:00
codemann8 c02ad77726 Merged in DR v1.4.8 2025-01-15 22:26:04 -06:00
aerinon c7a57d63fa feat: customizer options for prices in shops and money balance tuning 2025-01-15 14:34:46 -07:00
aerinon 9f55e90b7e refactor: TR Dark Ride model 2025-01-15 10:37:02 -07:00
aerinon 996462d623 fix: enemy drops in TR Dark Ride need to require Somaria 2025-01-15 08:51:41 -07:00
Kris Davie 5664526e0c Restore native dungeon item behavior for glitched modes. baserom handles dungeon IDs 2025-01-15 08:31:38 -07:00
Kris Davie 6268a7e503 Fixed issue with 2 extra SP keys in pool for HMG (codemann) 2025-01-15 08:31:38 -07:00
Kris Davie 7da70470fa Extra logic changes and early exits @codemann8 2025-01-15 08:31:38 -07:00
Kris Davie ecbd30389e Make sure we can actually reach clips 2025-01-15 08:31:38 -07:00
codemann8 b2511d1cee Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-01-11 17:10:23 -06:00
codemann8 c63e8bd0d2 Version bump 0.5.1.3 2025-01-11 17:10:07 -06:00
codemann8 9bc5a6b256 Fixed some multiworld issues 2025-01-11 17:07:55 -06:00
codemann8 2a0c171d29 Renaming keyword for Nearby dungeon item shuffle from 'district' to 'nearby' 2025-01-11 17:05:53 -06:00
aerinon 07ed662309 fix: key logic bug with recent fix 2025-01-08 12:06:52 -07:00
aerinon f83b6d03da fix: remove some restrictions from gui's custom item pool 2025-01-08 11:54:29 -07:00
aerinon 1bb7345a01 fix: bonk fairy used as mandatory connector in standard
fix: hmg multi-player issue
2025-01-08 09:47:44 -07:00
aerinon fe520626e9 fix: rain state + activated flute 2025-01-08 09:19:38 -07:00
aerinon 9a8529100e doc: doc fix 2025-01-08 08:00:00 -07:00
codemann8 3a9b1601af Documentation typo 2025-01-07 15:56:57 -07:00
aerinon ed5627d5bc feat: mirror scroll forced on in DR modes, fix settings code bit for it 2025-01-07 15:56:33 -07:00
Telethar c3f6317e84 Change to |= 2025-01-07 15:12:24 -07:00
Telethar d558e14065 Add Mirror Scroll as an option instead of baking it into door shuffle. 2025-01-07 15:12:24 -07:00
aerinon f5a8b563d9 fix: key logic issue with decoupled doors 2025-01-07 14:45:02 -07:00
codemann8 3782e56498 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-01-05 08:03:16 -06:00
codemann8 c59bc7590e Version bump 0.5.1.2 2025-01-05 08:02:55 -06:00
codemann8 7b4801d409 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2025-01-05 07:48:33 -06:00
codemann8 3d9b2a5271 Version bump 0.5.1.2 2025-01-05 07:48:04 -06:00
codemann8 41080e73bd Fixed issue with 2 extra SP keys in pool for HMG 2025-01-05 07:32:04 -06:00
codemann8 d8899f3e6f Fixed issue with Free Terrain not requiring Pearl on DW water transitions 2025-01-05 05:41:04 -06:00
codemann8 107eef9c6a Fixed issue with MapCountDisplay flags not getting set when entering a dungeon and maps aren't wild 2025-01-05 05:34:21 -06:00
codemann8 c2a637e0b5 Added flipper and mire clip rules to hera clip, also some efficiency fixes 2025-01-05 04:45:04 -06:00
codemann8 329dd0876f Merge branch 'pr/22' into OverworldShuffleDev 2025-01-05 03:44:21 -06:00
codemann8 ea5ad39a07 Renaming keyword for Nearby dungeon item shuffle from 'district' to 'nearby' 2025-01-05 03:42:52 -06:00
codemann8 ee45257862 Minor issue with plandoing SW dropdowns in Follow Linked Drops 2025-01-05 03:26:55 -06:00
codemann8 84fc0dc10a Fixed issue with In-dungeon Prize shuffle placing multiple prizes within the same dungeon 2025-01-05 03:25:07 -06:00
Kris Davie 5fbcedbb24 Make sure we can actually reach clips 2025-01-05 09:30:32 +01:00
codemann8 8ce8b93c8b Fixed some inconsistencies with OWG starting boots considerations 2025-01-03 04:31:51 -06:00
codemann8 9eba1d4c40 Fixed issue with prize shuffle where HMG uses cross dungeon paths to show prize on map 2025-01-02 22:58:07 -06:00
codemann8 d479789274 Fixed issue with OWG+ placing old man outside DM 2025-01-02 22:53:34 -06:00
codemann8 8ebbff3e7d Allow flute in rain state for glitched modes with starting preactivated flute 2025-01-02 05:17:26 -06:00
codemann8 b7437fa9fd Restoring some native dungeon item behavior for glitched modes
Also fixes issues with HC BK (item collection in other dungeons, acting like a small key on BnC)
2025-01-02 03:41:42 -06:00
codemann8 373a4ee53e Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-12-27 00:51:15 -06:00
codemann8 8a9df7a8ef Version bump 0.5.1.1 2024-12-27 00:50:56 -06:00
codemann8 246ce7e75c Backwards compatibility for new dungeon item shuffle structure in customizer 2024-12-27 00:31:14 -06:00
codemann8 4854255990 Documentation typo 2024-12-25 23:37:38 -06:00
codemann8 a6303f1963 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-12-25 23:11:08 -06:00
codemann8 e28eae08c1 Version bump 0.5.1.0 2024-12-25 23:10:40 -06:00
codemann8 12f65f0e05 Baserom update to allow textbox suppression for "this dungeon" items 2024-12-25 22:59:23 -06:00
codemann8 1247716e92 Implemented District/Nearby Dungeon Item Shuffle 2024-12-24 12:09:16 -06:00
codemann8 e3e227f3d5 Baserom update to allow textbox suppression for "this dungeon" items 2024-12-24 11:39:27 -06:00
codemann8 3d1190375e Merged in DR v1.4.7.2 2024-12-24 11:38:15 -06:00
aerinon 897f248c25 doc: update notes 2024-12-23 15:00:58 -07:00
KrisDavie e5f38b2d01 Separate OWG and HMG connection code
Split making HMG entrances and connecting them
Correctly link IP lobby (not portal)
2024-12-23 10:18:36 -07:00
aerinon d2f4271a87 fix: make shuffleganon per player 2024-12-23 10:16:58 -07:00
codemann8 507fbeece9 Fix minor issue with shuffle_ganon option missing player check 2024-12-21 18:57:28 -06:00
codemann8 f1c681bb1f Fix issue with smith getting deleted on s+q due to bomb walls 2024-12-21 18:49:03 -06:00
aerinon fe2a01b384 fix: bump version 2024-12-20 09:57:44 -07:00
aerinon 46e52682e5 fix: backwards compatibility with old beemizer settings 2024-12-20 09:49:41 -07:00
aerinon 804e693803 fix: problem with enemizer bush enemies 2024-12-19 16:30:40 -07:00
aerinon 17e48e4e18 fix: prevent crash from bush spawning mimics hopefully 2024-12-19 15:18:09 -07:00
aerinon 96f646b1ab fix: prevent enemizer crash with walking zora
fix: various enemy bans
2024-12-19 15:00:34 -07:00
aerinon 01f3f6ad50 fix: dark sanc at tavern north
fix: gt exit point for all players
2024-12-17 16:17:55 -07:00
aerinon 4f1f61bc68 fix: simple shuffle blacksmith 2024-12-17 16:12:49 -07:00
aerinon 338e949213 feat: update docs and version 2024-12-17 15:38:59 -07:00
Cody fb6727c527 Fix NoneType object error when BK in starting inventory
ZenArcane has a mode that starts you with all the big keys, maps, compasses, and enough universal small keys to open all doors. The item pool is updated to remove them, but generation fails due to NoneType item variables.

This changes how current_amount is determined to prevent a NoneType variable access and allows for generation to continue.

I haven't noticed any adverse side-effects to this, so I decided to PR this upstream.
2024-12-17 15:17:23 -07:00
KrisDavie 8ec25d8476 Trim down unnecessary parts of loop 2024-12-17 15:08:35 -07:00
KrisDavie 252a99f0d2 Revamp HMG logic 2024-12-17 15:08:35 -07:00
KrisDavie 1c33f793e0 SP Bosstest for MP 2024-12-17 15:08:35 -07:00
KrisDavie 76834a477a Don't ever check playthough when all seeds are no logic 2024-12-17 15:08:35 -07:00
KrisDavie 8aba0f66fc Tests update 2024-12-17 15:08:35 -07:00
KrisDavie 81a8b3a0f5 HMG PoD Region fix + reformatting
* Create a region in HMG when PoD entrance isn't pre-opened that limits access to the overworld unless already available
* Change rule generations to loop
* Check for bomb and dash clips properly
2024-12-17 15:08:35 -07:00
KrisDavie 5dc51d4a2c Actually check if we can leave IP bomb drop 2024-12-17 15:08:35 -07:00
KrisDavie 514dfcc0c8 Fix world copy in HMG/NL 2024-12-17 15:08:35 -07:00
codemann8 ffd31f0224 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-12-17 07:52:40 -06:00
codemann8 3d002c26f3 Version bump 0.5.0.6 2024-12-17 07:51:39 -06:00
codemann8 051fb075a3 Added Thieves Maiden to followers that have pathing logic 2024-12-17 07:40:11 -06:00
codemann8 a5d572a41c Prevent duplicate entrance entries 2024-12-17 06:26:07 -06:00
codemann8 60c1334c27 Minor fix in ER to remove assumption there is only one way into a cave 2024-12-17 06:24:20 -06:00
codemann8 c38cb4d874 Some corrections and improvements to pathing logic 2024-12-17 05:32:07 -06:00
codemann8 a5bfd41aca Added Thieves Maiden to followers that have pathing logic 2024-12-17 05:27:46 -06:00
codemann8 db8fbb448d Fixed Insanity ER to exit correctly out of GT entrance 2024-12-16 09:23:07 -06:00
codemann8 1075bd821c Fixed issue with Good Bee Cave getting chosen as a Take Any Cave 2024-12-16 08:20:07 -06:00
codemann8 e7de84ab6d Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2024-12-16 03:05:07 -06:00
codemann8 50d746f6c9 Merged glitched mode fixes from Muffins PR/21 2024-12-16 03:05:04 -06:00
codemann8 9cc36732ca Merged glitched mode fixed from Muffins PR/21 2024-12-16 03:04:19 -06:00
KrisDavie af1892c7d5 Revamp HMG logic 2024-12-16 00:06:54 +01:00
codemann8 023bbede0a Skip playthrough calc when all seeds are NL 2024-12-15 14:50:10 -06:00
codemann8 0ead417d99 Fix world copy in HMG/NL 2024-12-14 16:47:57 -06:00
codemann8 22c9359459 Minor district error 2024-12-14 16:20:42 -06:00
codemann8 7e952c0b9e Base ROM update - Improved psuedobots / music fixes 2024-12-14 16:17:52 -06:00
codemann8 385165f7c7 Fixed issue with HMG/NL 2024-12-13 00:52:27 -06:00
codemann8 459eca9b4a Fixed issue with District ER not including SW as a connector 2024-12-12 18:26:31 -06:00
KrisDavie 8b73fee1f2 SP Bosstest for MP 2024-12-12 20:56:59 +01:00
KrisDavie 0d5872ef74 Don't ever check playthough when all seeds are no logic 2024-12-12 20:44:26 +01:00
codemann8 d95e5cf4d2 Fixed issue with plandoing prizes 2024-12-10 22:25:40 -06:00
codemann8 9d69745c37 Minor casing adjustment 2024-12-08 01:30:57 -06:00
codemann8 15898a4c70 Fixed some OWR compatibility with HMG DM Super Jump 2024-12-08 01:19:59 -06:00
aerinon 718ef718f4 fix: broken compare 2024-12-02 10:43:07 -07:00
codemann8 7cecb64ac6 Fixed Blue Potion in shop for Inverted 2024-11-15 17:37:35 -06:00
aerinon a2075ec992 fix: inconsistent treatment of beemizer 2024-11-12 14:10:28 -07:00
aerinon 82a04dabd7 fix: standard+enemizer rules 2024-11-12 14:07:43 -07:00
aerinon 7de6671477 fix: accessibility bug 2024-11-11 08:19:31 -07:00
codemann8 f52d4d5058 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-10-30 10:24:38 -05:00
codemann8 e5f3722f4e Version bump 0.5.0.5 2024-10-30 10:24:23 -05:00
codemann8 353b2fa1fd Fixed issue with vanilla HCBK acting like a small key 2024-10-30 10:22:18 -05:00
codemann8 0721682cd6 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-10-20 04:14:48 -05:00
codemann8 8cfdaf7d3c Version bump 0.5.0.4 2024-10-20 04:14:30 -05:00
codemann8 4e6f4255d9 Fixed "this" dungeon items for glitched modes 2024-10-20 04:07:39 -05:00
codemann8 413d5cc5fd Merged in DR v1.4.6 2024-10-15 19:11:10 -05:00
KrisDavie 7575c3de8a Tests update 2024-10-12 16:43:09 +02:00
KrisDavie dc21885e1b HMG PoD Region fix + reformatting
* Create a region in HMG when PoD entrance isn't pre-opened that limits access to the overworld unless already available
* Change rule generations to loop
* Check for bomb and dash clips properly
2024-10-12 16:42:14 +02:00
KrisDavie b0ca154a92 Actually check if we can leave IP bomb drop 2024-10-12 16:38:27 +02:00
KrisDavie 831ce9ec6a Fix world copy in HMG/NL 2024-10-12 16:37:22 +02:00
aerinon b93a287b36 feat: spoiler/playthrough support in meta section of customizer 2024-10-10 15:16:24 -06:00
aerinon 5225ce996f Merge pull request #161 from KrisDavie/glitch_fixes
Glitch mode fixes
2024-10-10 13:07:53 -06:00
aerinon e12c4f693b fix: report enemizer problems 2024-10-10 13:00:04 -06:00
aerinon d66632a021 fix: make murahdahla accessible as a bunny 2024-10-10 11:03:14 -06:00
aerinon cb66e0248b fix: minor text fix 2024-10-10 09:13:57 -06:00
aerinon c00d8ab80a fix: lean/lite shuffling fairy caves when enemy drop not enabled 2024-10-10 09:11:16 -06:00
aerinon 585940f768 fix: sanc & quit fix 2024-10-10 08:16:33 -06:00
codemann8 b52d292b1b Fixed regression issue with items not drawing in dark rooms 2024-09-18 12:07:50 -05:00
KrisDavie eaa21eda3b Update glitched tournament winners 2024-09-08 22:21:47 +02:00
KrisDavie 4f2efab8de Fix UW connector names + formatting 2024-09-08 19:49:14 +02:00
codemann8 b1f5f0bc0b Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-09-03 10:05:44 -05:00
codemann8 928a7a8944 Version bump 0.5.0.3 2024-09-03 10:05:29 -05:00
codemann8 7a6455a58b Fixed crash on pedestal 2024-09-03 10:02:54 -05:00
codemann8 effc436293 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-08-29 06:14:30 -05:00
codemann8 b91cdc1001 no change 2024-08-29 06:14:17 -05:00
codemann8 b94cffb94a Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-08-29 05:40:54 -05:00
codemann8 0cfdc0e3ae Fix GitHub Actions 2024-08-29 05:40:40 -05:00
codemann8 6628b59fdf Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-08-29 05:07:30 -05:00
codemann8 fbdc8f0668 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2024-08-29 05:07:03 -05:00
codemann8 0c101f1750 Fix GitHub Actions 2024-08-29 05:06:01 -05:00
codemann8 42138732d3 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-08-29 05:03:13 -05:00
codemann8 afbbac98af Fix GitHub Actions 2024-08-29 05:02:53 -05:00
codemann8 28d3fcd1a4 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-08-29 04:37:18 -05:00
codemann8 7e9178c250 Removed tests for GA build 2024-08-29 04:36:52 -05:00
codemann8 f82d1756ae Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-08-29 03:16:17 -05:00
codemann8 dbcfad24c5 Version bump 0.5.0.2 2024-08-29 03:15:36 -05:00
codemann8 eb877b60e4 Base ROM fixes
- Some music fixes for Mixed OWR
- Attempt to fix silent music after S+Q from Kakariko
- No follower deletion on crystal cutscene if prize shuffle
- Show shadows on hidden enemies in enemy drop shuffle
- Fix black palette issue for custom item gfx
- Fix enemy drops being drawn off center in Hera Cage
- Fix red crystal gfx in dark rooms
- Fix small magic gfx for standing items
- Fix screen scroll issue in Zora's Domain when failing water entry
- Fix weird palette issue in Potion Shop
- Fix issue with Potion Shop prices drawing on top of Link
2024-08-29 01:42:10 -05:00
codemann8 d5661c4f3b Skip Pre-Aga music change if DR enabled 2024-08-25 08:29:40 -05:00
codemann8 ae9f804bd1 Fix Tavern North spawn softlocks 2024-08-21 06:09:34 -05:00
codemann8 a3be8d6d33 Mystery spoiler fixes 2024-08-21 04:54:36 -05:00
codemann8 89e91a85fd Merged in DR v1.4.5 2024-08-21 03:57:12 -05:00
codemann8 fe303876b4 Regression error for Prize Shuffle 2024-08-21 03:52:50 -05:00
codemann8 b81012a0f3 Fixed menu gfx issue with A items in DR menu, hera basement key fix 2024-08-16 21:48:30 -05:00
codemann8 47214bc40a Fixed issue with prize shuffle where HMG uses cross dungeon paths to show prize on map 2024-08-16 19:59:18 -05:00
codemann8 67c87426fb Some fixed errors with Prize Shuffle 2024-08-16 18:23:44 -05:00
KrisDavie 5d5aec0325 Fix SP smalls in HMG and remove bat screen wrap from logic 2024-08-12 08:31:13 +02:00
aerinon e681968aa2 feat: 300 Rupees marked as priority
fix: PreferredLocationGroup works with priority items and pre-activated flute
2024-07-15 13:02:06 -06:00
aerinon a37d783ad8 fix: generation issue with dungeonsfull 2024-07-05 09:46:21 -06:00
aerinon 2109733364 fix: standardized enemy logic for mire 2
fix: applied new enemy logic for gt mimics 1 & 2
2024-07-02 09:51:50 -06:00
aerinon defd237480 fix: credits crash 2024-07-01 16:00:35 -06:00
aerinon 27e792d6c4 fix: baserom issue 2024-06-21 14:12:31 -06:00
aerinon 44ef13c0f6 change: update baserom 2024-06-21 10:35:52 -06:00
aerinon 05f4ef8c3c fix: various enemy bans 2024-06-21 09:50:58 -06:00
Cody Bailey 9ecd88341f Make item hint text less ambiguous
Update Items.py
Fix some typos, update hookshot text
2024-06-20 16:46:34 -06:00
aerinon 1a8231af3b feat: minor stats compilation utility 2024-06-20 16:20:44 -06:00
aerinon e6b0239d24 fix: customizer bug when placing small keys
fix: hera basement cage fix - again
2024-06-17 17:16:22 -06:00
aerinon 9a34024d90 feat: various indicators for fake boots and mirror scroll added 2024-06-14 17:06:35 -06:00
aerinon fe28c17637 fix: various enemy bans 2024-06-14 16:21:40 -06:00
aerinon 336a9379b6 change: renamed "default" key logic algorithm to "dangerous" 2024-06-07 15:48:43 -06:00
aerinon 9898b5bcb6 doc: version bump and note 2024-06-07 15:08:30 -06:00
aerinon 119c863f06 fix: insanity gen failure 2024-06-07 14:05:51 -06:00
aerinon 6d129edc3c fix: inverted ER issues 2024-06-07 12:25:07 -06:00
aerinon 5740a03c25 fix: testsuite with new spoiler setting 2024-06-07 10:55:04 -06:00
aerinon 7fe544861f fix: ensure crystals reachable wasn't properly accounting for lobbies with switches 2024-06-07 07:35:59 -06:00
aerinon 0d536a593b change: python cmd not version specific 2024-06-07 07:35:11 -06:00
aerinon 4315b99908 fix: Swapped and Simple ER generation errors 2024-06-06 15:00:39 -06:00
codemann8 3b287466b3 Fixed issue with Prize Shuffle not adding prize locations to district locations 2024-06-05 04:19:39 -05:00
codemann8 151e118048 Rename release-complete.yml to release-complete.yml-old 2024-05-31 01:13:46 -05:00
codemann8 32083e66b1 Rename release-complete.yml to release-complete.yml-old 2024-05-31 01:13:08 -05:00
codemann8 27dd530dbe GH Actions nonsense 2024-05-31 01:12:33 -05:00
codemann8 ee122059a3 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-05-30 23:26:27 -05:00
codemann8 8951faa39e Version bump 0.5.0.1 2024-05-30 23:25:59 -05:00
codemann8 0d09d757ed Replacing discord attachment reference with actual references that don't expire 2024-05-30 23:18:34 -05:00
codemann8 95caa96fbd Fix for flute shuffle cancel with X icon 2024-05-30 23:00:16 -05:00
codemann8 bcac25fd7d Fixed issue with Big Bomb Shop ending up at Pyramid Fairy entrance 2024-05-30 22:58:37 -05:00
codemann8 6b84306b9f Various updates and fixes to Prize Shuffle
- Includes colorblind support
- Fixed HP heart refill interrupting boss cutscenes
- Improved some QoL on map checks
- Added new map GFX for flute spot cancel X
2024-05-30 22:57:16 -05:00
codemann8 68ee8262ea Change GH Action Release to grab CHANGELOG 2024-05-30 22:54:45 -05:00
aerinon 97178787a9 build: ci changes 2024-05-30 14:47:52 -06:00
aerinon 8240118d7e build: ci changes 2024-05-30 14:25:04 -06:00
Minnie A. Trethewey (Mike) ca40f87daa CI Changes 2024-05-30 14:19:54 -06:00
aerinon 54858500e5 fix: suppress warning for missing items if they are in start inventory 2024-05-30 14:02:52 -06:00
aerinon 3ba1472635 fix: typo causing ER generation failure 2024-05-30 13:12:25 -06:00
aerinon 3554177a61 feat: RandomWeapon for starting items
feat: Start with "Big Magic" or "Small Magic" for starting magic meter
2024-05-30 13:02:22 -06:00
codemann8 9ea1cb47c7 Adding a few nonsense duplicate tests for OWR Test Suite 2024-05-30 04:03:13 -05:00
codemann8 9726c0eeb6 Some minor Prize Shuffle fixes 2024-05-30 01:05:23 -05:00
codemann8 620adb93fd Adding prize shuffle options to example yaml docs 2024-05-29 19:45:26 -05:00
codemann8 351081c522 Fix error when generating with Forbidden Boss Items option 2024-05-29 19:43:40 -05:00
codemann8 4b8bbe6c4f Fix issue with dungeon counts not correct in Prize Shuffle 2024-05-29 19:36:33 -05:00
codemann8 42fc1a086c ROM fixes for Prize Shuffle
- Added color blind support for Prize Shuffle
- Changed LW dungeon icons to letters
- Added crystal numbers to crystals in Prize Shuffle
- Fixed HP refill bug interrupting boss cutscene
2024-05-29 19:24:39 -05:00
aerinon 28872c8d27 feat: skull woods er options 2024-05-28 14:52:24 -06:00
codemann8 a3c5974906 Changelog update 2024-05-25 03:50:03 -05:00
codemann8 2b24d254a2 Doc change 2024-05-25 03:32:57 -05:00
codemann8 db39f7795b Version bump 2024-05-25 03:31:24 -05:00
codemann8 a7971d950a Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-05-25 03:19:35 -05:00
codemann8 db45e98e86 Version bump 0.5.0.0 2024-05-25 03:19:06 -05:00
codemann8 747f5fae98 Some further fixes to Prize Shuffle 2024-05-25 03:14:07 -05:00
codemann8 39dc0abb53 Banning bunny traversal thru DM Return Cave and Paradox Cave Top 2024-05-24 15:26:12 -05:00
codemann8 e15ac6b9a4 Fixed moved door_addresses 2024-05-24 09:41:54 -05:00
codemann8 be904a8f3b Merged in DR v1.4.1.12 2024-05-23 21:49:24 -05:00
codemann8 e7819de9c8 Further config of GH Actions for OWR 2024-05-23 20:17:07 -05:00
codemann8andMinnie A. Trethewey b55c3700c0 Owr actions update (#19)
* Go for Broke

* Let it fire

* Add PipLine

* Create the dir if it doesn't exist

* Install Setuptools

* Track Test Action's files

* Fix Calling Job

* Track Build Action files

* Install Distutils, rename filenames

* Fix Fail conditions

* Make Build scripts smarter

* Add file

* Concat DLLs lists

* Try to fail if Error DLLs

* Try to make the fail smarter

* Moar verbosity

* Print the stuff first

* Print outputs objects

* See if this skips failure

* Use py instead

* Print error list

* Don't ValueError

* Try checking a different way

* Try something else

* Bleh, spell filename correctly

* Update excluded_dlls.json

* Ugh, gotta compare old to new somehow

* Compare to old list

* Condense build script

* Moar verbosity

* Update the global version

* Update Excluded DLLs list

* Actually use the bad DLLs list

* Make a version number

* Fix version number building

* Fix version number building again

* Fix Diagnostics

* Try REST API stuff

* Try REST API again

* Moar REST

* await

* Get SHA

* Try it all together

* Del test workflow

* Add Perms

* Use a Token

* Try this Token

* Try different Token

* Try different Token

* Create App Version earlier

* See this error again

* Don't fail if App Version not made yet

* Use New Secret

* Print whole response

* Documentation for Tagger

* Update CI Instructions

* Update CI

* List References

* Find latest tag

Fix App Version getter

* Fix commas

* Check returned data

* Update Build Script

* Fix substring

* Fix Git tag

* Fix tag again

* Visual indicators

* Use encoding

* Remove an indicator

* Update CI

* Update Project Name

* PyInstaller Spec Template file

* Update Build Script

* Fix Tagger

* Update CI

* Download AppVersion during build

* Test job can fail

* Upload Logs instead of printing them

* Change from Reusable Workflow to Action

* Change ref to token

* Compare to string

* Use PAT

* Use String literal

* Remove Reusable Workflow

* Update CI Scripts

* Go for Broke

* Let it fire

* Add PipLine

* Create the dir if it doesn't exist

* Install Setuptools

* Track Test Action's files

* Fix Calling Job

* Track Build Action files

* Install Distutils, rename filenames

* Fix Fail conditions

* Make Build scripts smarter

* Add file

* Concat DLLs lists

* Try to fail if Error DLLs

* Try to make the fail smarter

* Moar verbosity

* Print the stuff first

* Print outputs objects

* See if this skips failure

* Use py instead

* Print error list

* Don't ValueError

* Try checking a different way

* Try something else

* Bleh, spell filename correctly

* Update excluded_dlls.json

* Ugh, gotta compare old to new somehow

* Compare to old list

* Condense build script

* Moar verbosity

* Update the global version

* Update Excluded DLLs list

* Actually use the bad DLLs list

* Make a version number

* Fix version number building

* Fix version number building again

* Fix Diagnostics

* Try REST API stuff

* Try REST API again

* Moar REST

* await

* Get SHA

* Try it all together

* Del test workflow

* Add Perms

* Use a Token

* Try this Token

* Try different Token

* Try different Token

* Create App Version earlier

* See this error again

* Don't fail if App Version not made yet

* Use New Secret

* Print whole response

* Documentation for Tagger

* Update CI Instructions

* Update CI

* List References

* Find latest tag

Fix App Version getter

* Fix commas

* Check returned data

* Update Build Script

* Fix substring

* Fix Git tag

* Fix tag again

* Visual indicators

* Use encoding

* Remove an indicator

* Update CI

* Update Project Name

* PyInstaller Spec Template file

* Update Build Script

* Fix Tagger

* Update CI

* Download AppVersion during build

* Test job can fail

* Upload Logs instead of printing them

* Change from Reusable Workflow to Action

* Change ref to token

* Compare to string

* Use PAT

* Use String literal

* Remove Reusable Workflow

* Update CI Scripts

---------

Co-authored-by: Minnie A. Trethewey (Mike) <minnietrethewey@gmail.com>
2024-05-23 19:29:39 -05:00
codemann8 9eb5293a3c Merge pull request #18 from Catobat/UndefinedChanceFix
Fix edge cases with undefined_chance
2024-05-23 18:54:15 -05:00
codemann8 fa0cf87fdc SFX Instrument ban 2024-05-23 18:51:56 -05:00
codemann8 edd4e8034d Some cleanup 2024-05-23 18:50:35 -05:00
codemann8 143de53c29 Add print_template_yaml to Mystery 2024-05-23 18:48:33 -05:00
codemann8 75187ec608 Minor TF text adjustments 2024-05-23 18:46:11 -05:00
codemann8 103e098a2e Initial Prize Shuffle Implementation
commit c89c5d3798e2a777011e90d565d74af792330d9f
commit 4159f2e7097fca648828a60d8f6878211d0ded9e
commit a80e3a4301d69146ccfffe0f2f375adac381e165
commit d8ac588cb904152831f514d8276be4e39a43dcd0
commit 68eb75e3391631355b4f56f1dcb7e9dadadf1fdf
commit ba241b47964eadfb40ad323f87b1117598dd91a6
commit aed2821c7165822f5fd5cc1ff3f58f2af095d915
commit bd1c5d8d35ae3cae5f27f236346fff057b7b8cd7
commit f034e31cc585a1648657fc2c4850ebc0c1d8bf78

Author: codemann8 <codemann8@gmail.com>
2024-05-23 18:40:50 -05:00
aerinon a5023a18a6 change: default port for MultiClient snes connection is now 23074 2024-05-23 09:58:52 -06:00
Catobat 90817a14fd Make Doors adjust to Santuary in the Dark World 2024-05-21 18:09:31 +02:00
aerinon 18b33f6822 fix: typo 2024-05-21 08:26:16 -06:00
Catobat 8f7ebc46b2 Fix edge cases with undefined_chance 2024-05-20 18:20:05 +02:00
aerinon 7bb3760ec6 build: disable mac b/c issues #2 2024-05-14 14:23:09 -06:00
aerinon 34b14ae157 build: disable mac b/c issues 2024-05-14 14:19:41 -06:00
aerinon 2694efeb9f fix: issues with major_only and too mnay major items
chore: reformatted spoiler, moved crystal reqs to requirements
2024-05-14 14:08:33 -06:00
aerinon a15a12d240 fix: couple of enemy bans 2024-05-14 10:03:54 -06:00
aerinon 56add15970 fix: all cross-dungeon modes should add the mc_rule 2024-05-14 08:36:43 -06:00
codemann8 8b295a74ad Some random Mixed OWR fixes 2024-05-11 14:39:05 -05:00
codemann8 1f66aa87fe Customizer option to always allow flipping Sanctuary 2024-05-11 14:08:55 -05:00
aerinon 8e1f2911cd feat: PreferredLocationGroup support updated 2024-05-11 07:28:07 -06:00
aerinon 1f85bc5a8d fix: typo 2024-05-11 06:30:56 -06:00
aerinon cabde21a2c fix: starting inventory flute + flute_mode active 2024-05-11 06:10:30 -06:00
codemann8 3f60eb79e5 Merge pull request #17 from Catobat/mixed-sanctuary-2
Add Customizer option to always allow flipping Sanctuary
2024-05-10 21:27:12 -05:00
Catobat 71ab2b96fd Fix oversight with some modes 2024-05-11 03:10:17 +02:00
Catobat d792560c9a Customizer option to always allow flipping Sanctuary 2024-05-11 02:16:59 +02:00
aerinon ae35096f16 fix: hera basement + small key for this dungeon 2024-05-09 14:35:50 -06:00
aerinon f80e8bbfd5 fix: hc big key drop on basic doors 2024-05-08 15:13:38 -06:00
codemann8 9056a32e8d Added new logical boss defeated items for AD 2024-05-06 20:52:38 -05:00
aerinon f1a996c2f8 change: enable CI on unstable branch 2024-05-06 16:55:48 -06:00
aerinon b3692c861d fix: remove wallmasters from consideration from rooms with spiral staircases 2024-05-06 16:55:48 -06:00
aerinon bb5236d5d4 feat: promote new entrance shuffle algorithm out of experimental 2024-05-06 16:55:48 -06:00
aerinon 26c2aa9fc5 change: shuffle back of tavern now default 2024-05-06 16:55:47 -06:00
aerinon 3f08cc2a7d fix: minor traversal error, was hiding other potential issues 2024-05-06 15:57:21 -06:00
codemann8 509b5ce641 Fixed missing Ganon crystal rule for Trinity 2024-05-03 17:19:38 -05:00
codemann8 757f156838 Fixed TF Cutscene issue 2024-04-30 15:37:39 -05:00
codemann8 dab9d75dc1 Merged in DR v1.4.1.11 2024-04-25 15:06:59 -05:00
aerinon 89645bb4b5 feat(entrances): lite/lean support enemy shuffle caves 2024-04-23 14:18:55 -06:00
aerinon 292d49faed fix(enemizer): enenmy bans 2024-04-23 11:02:41 -06:00
aerinon fcc464ef23 fix(enemizer): messed up gfx on hyrule castle rain state 2024-04-22 11:49:03 -06:00
aerinon 20e60c8a1d feat(spoiler): introducing custom spoiler levels 2024-04-22 08:35:17 -06:00
aerinon 8461503c85 fix(customizer): Fixed an issue with customizing prize packs 2024-04-22 08:33:59 -06:00
codemann8 fbb2e39caa Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-04-21 09:38:06 -05:00
codemann8 27c82a18db Version bump 0.4.0.2 2024-04-21 09:37:49 -05:00
codemann8 56c2f8abf7 ROM Fixes
Potential fix for bonk items duping OW items
Fixed Inverted GT map issue
2024-04-21 09:34:02 -05:00
codemann8 aacde594e9 Fix issue with GUI message showing wrong seed number when yaml specifies a different seed 2024-04-21 09:32:59 -05:00
codemann8 67e2910ad4 Fixed issue with outputpath getting changed incorrectly 2024-04-21 05:24:26 -05:00
codemann8 8caee1e202 Allowing seed number to save onto exported yaml if provided by user 2024-04-21 05:23:22 -05:00
aerinon 0faeeeb45f fix(enemizer): bonk fairies and standard tutorial guard fixed 2024-04-19 14:29:26 -06:00
codemann8 795f31bd68 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-04-18 10:07:26 -05:00
codemann8 f377cc1bda Version bump 0.4.0.1 2024-04-18 10:06:49 -05:00
codemann8 4a304b272c Merged in DR v1.4.1.10 2024-04-18 09:56:12 -05:00
codemann8 08050bdcdf Minor TF Room Text Correction 2024-04-18 09:21:59 -05:00
codemann8 04baad9a5f Base ROM GFX Fixes and more 2024-04-18 09:17:17 -05:00
aerinon 22a9f76c77 fix(enemizer): various enemy bans 2024-04-15 12:39:33 -06:00
S 2cf2383c16 allow BPS to be encoded into the jsonout 2024-04-15 12:25:14 -06:00
aerinon ebd86e80d7 fix(logic): exception for vanilla mire key door layout, crystal switches can be reached with two keys, just can't tell which one was chosen 2024-04-12 17:32:35 -06:00
aerinon d8199742db chore(rom): code cleanup
fix(rom): chest turns for MW items
2024-04-12 16:24:11 -06:00
aerinon ce0c86bcf3 fix: terrorpins in hellway can clip out 2024-03-28 13:29:24 -06:00
aerinon 2f0e27b8e2 fix: dungeon indicator changes from rom 2024-03-28 13:15:58 -06:00
aerinon 9235c19d34 Merge branch 'DoorDev' into DoorDevUnstable 2024-03-28 10:04:40 -06:00
aerinon b55727f0bf chore: updated tournament winners 2024-03-28 09:51:29 -06:00
codemann8 48930721a5 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-03-25 22:06:59 -05:00
codemann8 f3dc2b881e Version bump 0.4.0.0 2024-03-25 22:06:36 -05:00
codemann8 46565126fd Various GFX updates to base ROM 2024-03-25 21:52:46 -05:00
codemann8 9a7ea165e6 Added to SFX shuffle ban list 2024-03-25 21:50:26 -05:00
codemann8 3ff5e3f685 Changed bottle vendor to give key for fish prize in Universal keys 2024-03-24 18:58:10 -05:00
codemann8 6d02d3da7a Fix SP key placement/removal issue in HMG 2024-03-22 06:35:10 -05:00
codemann8 da749e4a11 Fix generation issues in HMG 2024-03-22 05:24:10 -05:00
codemann8 4dd334f66e Fix SP key placement/removal issue in HMG 2024-03-22 05:19:10 -05:00
codemann8 9eedbff0e5 Fixed issue with GFX not transferring to VRAM in some cases 2024-03-21 05:39:17 -05:00
codemann8 21e4ef684f Merged in DR v1.4.1.8 2024-03-20 18:09:08 -05:00
codemann8 f671c5ed52 Minor TF room text alignment 2024-03-20 18:05:40 -05:00
codemann8 db45906ba6 Use new bombbag item gfx if bombbag mode 2024-03-20 18:04:45 -05:00
codemann8 67e4515bb7 Fix corruption issue caused by bad collection rate address 2024-03-20 18:04:17 -05:00
codemann8 967bd79900 Various GFX fixes and merge stability updates 2024-03-20 17:49:06 -05:00
codemann8 c2280b439e Adding documentation regarding Swapped and District ER modes 2024-03-17 05:17:57 -05:00
codemann8 856deda2a9 Updated Image Links in README 2024-03-17 04:30:57 -05:00
KrisDavie 6c1f673086 fix: Make pendants consistent between in-game, spoiler and memory 2024-03-17 10:26:25 +01:00
codemann8 778dee4193 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2024-03-17 04:14:11 -05:00
codemann8 dd75273b83 Fixed Pyramid Exit inaccessible issue in District ER 2024-03-17 04:13:55 -05:00
codemann8 929bcb3de4 Banned quiet heart beep SFX in shuffle 2024-03-16 01:43:57 -05:00
codemann8 4423a33fee Merged in DR v1.4.1.7 2024-03-16 01:34:39 -05:00
aerinon a99183f936 fix(enemizer): enemy ban 2024-03-14 13:02:49 -06:00
aerinon 4629285e7e fix(dropshuffle): minor drops do not increase counter if in the wrong dungeon 2024-03-14 12:54:19 -06:00
aerinon d5d55b8017 fix(enemizer): any trinexx outside of TR should disable ice breath now 2024-03-11 17:03:40 -06:00
aerinon e737a138cf feat: new tiles for dungeon indicators
build: test for lynel logic
2024-03-11 16:58:12 -06:00
aerinon da80fd45e4 fix(owg+hmg): eg allowed to be armed 2024-03-11 16:49:43 -06:00
codemann8 7bc303efb8 Merged in DR v1.4.1.7 2024-03-02 15:38:07 -06:00
codemann8 46b8dff43a Adding Doors Async League yamls 2024-03-01 14:11:28 -06:00
codemann8 feb6bd475f Implemented New Item GFX System 2024-03-01 14:10:55 -06:00
aerinon 6d0debd987 fix(enemizer): remove mimic exception 2024-03-01 10:06:15 -07:00
aerinon 49b190c489 fix: more enemy bans
fix: custom item pool aborts if player is missing
2024-02-26 16:02:35 -07:00
codemann8 21a1706657 Merged in DR v1.4.1.6 2024-02-23 11:48:04 -06:00
aerinon ad611f9dda fix(gui): problem with customitemarray being empty 2024-02-21 12:27:32 -07:00
aerinon a7e0b85226 fix(rom): baserom update 2024-02-07 15:25:06 -07:00
aerinon 21c3618c01 fix(enemizer): random tutorial guards in south kak 2024-02-07 13:12:49 -07:00
aerinon d03d21425b fix(ow map): red/blue pendant colors 2024-02-07 12:49:50 -07:00
aerinon 646fc95143 fix(enemizer): more enemy bans 2024-02-07 11:51:22 -07:00
Christopher Heuer dd942865e5 Update main & glitched tourney winners 2024-02-01 11:41:03 -07:00
aerinon c139a971c4 fix (enemizer): enemy bans 2024-01-31 11:54:50 -07:00
aerinon d70c9c87f5 fix (hmg): remove the two placed swamp palace keys from the pool 2024-01-31 11:31:59 -07:00
aerinon 4281457139 fix: eliminate writing a stray byte when the sprite array is empty 2024-01-31 11:26:10 -07:00
codemann8 f6ca920364 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-01-31 07:20:18 -06:00
codemann8 538996b750 Temp fix for Smith not deleting on S+Q issue 2024-01-31 07:19:57 -06:00
codemann8 dc953a7d19 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-01-29 14:21:04 -06:00
codemann8 744c2ef527 Fix for HMG SP keys in pool 2024-01-29 14:20:50 -06:00
aerinon ef778b7125 fix: logic for dynamic doors 2024-01-29 10:06:27 -07:00
codemann8 d2a1bc3c75 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-01-26 23:34:56 -06:00
codemann8 6ec9bec547 Version bump 0.3.4.2 2024-01-26 23:34:33 -06:00
codemann8 691ad1ff93 Fixed issue with Inverted Swapped ER placing swap for Vanilla GT 2024-01-26 23:29:03 -06:00
codemann8 f3afba7ee6 Fixed issue with Lite ER and Vanilla GT 2024-01-26 23:27:06 -06:00
codemann8 d8f33d6b8b Fixed error with canceling out of Select Destination 2024-01-26 22:39:00 -06:00
codemann8 893947f89b Added new SFX instrument shuffle option 2024-01-26 22:36:30 -06:00
aerinon a6e96720a3 fix: castle warp gate
fix: potential swamola issue fix
2024-01-26 13:48:34 -07:00
aerinon ba6f9e0493 feat: Documentation update 2024-01-25 11:02:50 -07:00
aerinon 3ee3d88a06 Merge branch 'DoorDevVolatile' into DoorDevUnstable 2024-01-22 11:05:48 -07:00
codemann8 f7705c3ec9 Fixed issue with AT/GT in Inverted Swapped ER 2024-01-18 09:20:49 -06:00
codemann8 87e4e95cd3 Changing spawn prompt to show Bomb Shop for Inverted 2.0 2024-01-18 09:18:53 -06:00
codemann8 121726b095 Small adjustment to hints in Swapped and Lite/Lean ER 2024-01-18 09:13:48 -06:00
aerinon c8386122b7 fix: restore correct enemizer flags 2024-01-17 16:24:40 -07:00
aerinon 8d841b0252 feat: rom performance
chore: bump version and release notes
2024-01-17 09:12:01 -07:00
aerinon be8a3a6fa7 fix: ban problematic roller 2024-01-16 16:13:38 -07:00
aerinon 87f072e070 fix: possible generation issue for old man cave in swapped ER 2024-01-16 16:08:17 -07:00
aerinon da80cb9d03 fix: cap fairy in different item pools should use the bee trap id 2024-01-16 16:07:52 -07:00
codemann8 041c7fae5d Fix for Old Man Cave running out of choices in Swapped ER 2024-01-14 09:08:21 -06:00
codemann8 1555219053 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-01-10 06:09:28 -06:00
codemann8 2b461f2dfb Version bump 0.3.4.1 2024-01-10 06:09:11 -06:00
codemann8 2bec50b26b Implemented District ER 2024-01-10 05:57:39 -06:00
codemann8 17532160ee Allowing Insanity ER to decouple Standard entrances 2024-01-10 05:45:27 -06:00
codemann8 64a27993aa Changing Big Bomb Shop start to be independent of ER modes 2024-01-09 20:32:12 -06:00
codemann8 2b0e40438d Merged in DR v1.2.0.23 2024-01-09 08:32:19 -06:00
codemann8 9ad5cebddf Fixed some typos and incorrect references 2024-01-09 07:15:19 -06:00
codemann8 dc8ba4b197 Fix for generation issue with GT bottom in boss shuffle 2024-01-09 07:04:14 -06:00
codemann8 431cb2cdf4 Fix for vanilla partial key logic 2024-01-09 07:02:18 -06:00
aerinon cacef076bb fix: vanilla key logic doesn't apply with universal keys 2024-01-08 13:30:11 -07:00
aerinon c5789891c0 fix: reorder boss assignment, since GT bottom is more restricted now 2024-01-08 13:22:56 -07:00
aerinon 971a5c3963 fix: no need for menu map check if ER is vanilla 2024-01-08 13:21:35 -07:00
codemann8 38a2c693e6 Fixed issue with customized OW tile flips 2024-01-07 08:34:09 -06:00
codemann8 20d1398e4d Only apply bunny pocket rule if glitched logic 2024-01-05 20:47:41 -06:00
aerinon a77d3faf78 fix: moon pearl paths respect blocked doors 2024-01-05 20:26:27 -06:00
aerinon dab1b7a379 feat: More strict requirment for some bosses on ice 2024-01-05 20:23:33 -06:00
aerinon 5ebebb2dae fix: moon pearl paths respect blocked doors 2024-01-05 17:15:48 -07:00
aerinon d612709a76 chore: bump version 2024-01-05 15:29:44 -07:00
aerinon d2095b4293 fix: merge issue 2024-01-05 12:58:35 -07:00
aerinon ec65999a26 fix: missing import 2024-01-05 12:58:35 -07:00
aerinon ce4179abb9 feat: updated maze race/hobo clips
refactor: bunny pocket assumes a connector/dungeon_revive entrance is available, for now
fix: mirrorless_moat_rule no longer allows flippers in swamp
fix: problems from merge
2024-01-05 12:58:35 -07:00
codemann8 4246439c61 Fixed issue with flipper rules not getting pearl rules added 2024-01-05 12:58:35 -07:00
codemann8 0b7b82d027 Split overworld model up by screen 2024-01-05 12:58:35 -07:00
aerinon 2c3e47d2f6 feat: enemizer damage rework 2024-01-05 12:11:56 -07:00
codemann8 db6e9dfb02 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2024-01-05 13:09:20 -06:00
codemann8 e246684f37 Version bump 0.3.4.0 2024-01-05 13:09:03 -06:00
aerinon b5795e4bf2 Merge branch 'KrisDavie-hmg_logic' into DoorDevVolatile 2024-01-05 09:47:57 -06:00
aerinon 62162b6fbc fix: maiden deleted instead of replaced with ped tex
fix: thief damage to player is not randomized
2024-01-04 14:54:30 -07:00
aerinon 0222b09aab feat: Restore Lanmo/Trinexx as possible lobbies 2024-01-04 13:00:12 -07:00
aerinon 744fcd5255 feat: More strict requirment for some bosses on ice 2024-01-04 12:56:34 -07:00
aerinon 4201d5d067 feat: Laser bridge logic accounts for item functionality for Byrna 2024-01-04 11:57:52 -07:00
aerinon 2b505df429 fix: typo 2024-01-04 11:50:09 -07:00
Cody Bailey 7c5a5f39fe Add aga_randomness to exposed settings 2024-01-04 01:56:35 -06:00
aerinon 37fd1ab5ef fix: Aga1 defeatable in rain state for glitched mode
fix: Terrorpin AI code excised
2024-01-03 11:58:17 -07:00
aerinon 6edc295951 fix: vanilla key logic adjustment (dropshuffle must be none for reduction) 2024-01-03 03:22:25 -06:00
aerinon 108b67cbcf fix: fix up some vanilla key logic
fix: fix tile pattern
2024-01-03 03:20:04 -06:00
aerinon 1590c351a4 fix: vanilla key logic adjustment (dropshuffle must be none for reduction) 2024-01-02 18:14:31 -07:00
aerinon 3f5eafb74f fix: muradahla typo
fix: remove warp in inverted after aga1 defeated
fix: shopsanity repeatable item bug
2024-01-02 18:01:54 -07:00
aerinon 3d6432af95 fix: enemy ban 2024-01-02 17:26:17 -07:00
aerinon 846423fc38 fix: fix up some vanilla key logic
fix: fix tile pattern
2024-01-02 17:09:08 -07:00
codemann8 c521980982 Added sparkles to Bonk Drop locations 2023-12-31 03:17:43 -06:00
codemann8 24d1eefb8c Adding back in missing logger 2023-12-30 16:48:38 -06:00
aerinon 6357e4d979 build: bump version 2023-12-29 11:16:31 -07:00
aerinon d44ac89faf fix(generation): reduce memory usage for bunny walk calculations
fix(key logic): make partial the default
2023-12-29 11:15:30 -07:00
codemann8 359d2b132e fix(generation): reduce memory usage for bunny walk calculations 2023-12-29 04:14:44 -06:00
codemann8 e1a86221ea Fixed logic with Laser Bridge with Byrna Item Functionality 2023-12-29 03:54:50 -06:00
codemann8 785188904d Added missing OW Terrain exits 2023-12-29 03:52:57 -06:00
codemann8 eb0276926d Fixed duplicate exit issue in copy_world 2023-12-29 03:51:49 -06:00
aerinon 121091c5a3 fix(generation): reduce memory usage for bunny walk calculations
fix(key logic): make partial the default
2023-12-29 00:41:25 -06:00
codemann8 ba904f3f63 Fixed duplicate exit issue in copy_world 2023-12-29 00:32:38 -06:00
aerinon 337ace1fa3 fix(generation): reduce memory usage for bunny walk calculations
fix(key logic): make partial the default
2023-12-28 17:22:36 -07:00
aerinon 81e5aff923 feat(logic): Hybrid major glitches - HMG
fix(enemizer): enemy bans
2023-12-28 10:51:16 -07:00
codemann8 92f7d4da92 Added new option to export pre-seed customizer template yaml 2023-12-27 20:40:32 -06:00
aerinon 6ed937971d fix(vanilla_fill): make uncle weapon non-random, make medallions vanilla
fix(enemizer): enemy bans
2023-12-27 15:56:25 -06:00
aerinon 7def7081b9 fix: ganonhunt playthrough 2023-12-27 15:52:29 -06:00
aerinon 8f3b3dc760 feat: MW progresssion balancing tweaked to be percentage based instead of raw count. Tries to keep each player's locations in each sphere within 80% of the player with the most locations available. (Measured with percentage instead of raw count.) Old algo tried to keep everyone within 20 locations of each other. Difficult if one player has a lot more locations than another.
fix: Potential fix for early Trinexx start
2023-12-27 15:49:12 -06:00
aerinon bd7ce54dd3 fix: minor fix for take_anys
fix: money balancing - initialization in a good case
2023-12-27 15:45:01 -06:00
aerinon 2d467efded fix: don't bother blocking rain doors in no logic 2023-12-27 15:43:22 -06:00
aerinon 29504b7d53 fix: accept shufflebosses and shuffleenemies 2023-12-27 15:36:43 -06:00
codemann8 95fc30a8bd Implement Beat Agahnim 1 already in starting inventory 2023-12-27 15:27:49 -06:00
codemann8 99f7443819 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2023-12-27 15:23:07 -06:00
aerinon a0e80e0c26 Merge branch 'KrisDavie-hmg_logic' into DoorDevVolatile 2023-12-27 13:00:44 -07:00
codemann8 55caf24011 Changed Print Template Yaml from checkbox to button 2023-12-23 17:27:01 -06:00
codemann8 18fde2a3f3 Changed Print Template Yaml from checkbox to button 2023-12-23 04:23:34 -06:00
codemann8 d8319ca727 Renamed a couple buttons 2023-12-23 04:18:35 -06:00
codemann8 bd5232bf24 Fixed missing OWR brand labels 2023-12-23 03:42:52 -06:00
KrisDavie 36c8b5aaa6 Code cleanup and more tests 2023-12-22 22:48:43 +01:00
KrisDavie 81ace17889 More tests fixes 2023-12-22 22:48:43 +01:00
KrisDavie 22c4dcdfd3 More test updates + disable bunny check skip 2023-12-22 22:48:43 +01:00
KrisDavie 9fb7cf9f71 Refactor UW Glitches 2023-12-22 22:48:43 +01:00
KrisDavie 80c8c189a8 Minor HMG changes 2023-12-22 22:48:43 +01:00
KrisDavie fce43eb289 HMG tests 2023-12-22 22:48:43 +01:00
KrisDavie 6d79e48ab0 Don't explore dungeons with a single exit for bunny logic 2023-12-22 22:48:43 +01:00
KrisDavie e1a2e1bb5f Only return lobbies rather than dungeon regions 2023-12-22 22:48:43 +01:00
KrisDavie a4a523ce4c Small cleanup 2023-12-22 22:48:43 +01:00
KrisDavie 6510968401 Support bunny pocket for SW back and voo hammer house 2023-12-22 22:48:42 +01:00
KrisDavie 6a41dff98b Raise error on doors + hmg 2023-12-22 22:48:42 +01:00
KrisDavie 7f5fb16453 Refactor hmg key logic 2023-12-22 22:48:42 +01:00
KrisDavie 15558250da Change Maze race to collect location rather than reach region
- Brother West is not reachable from the clip
2023-12-22 22:48:42 +01:00
KrisDavie e1f2369f13 Refactor OWG rules to use lists rather than generators 2023-12-22 22:48:42 +01:00
KrisDavie 9870217698 Undo test 2023-12-22 22:48:42 +01:00
KrisDavie 0f28cd97d8 Logic fixes 2023-12-22 22:48:42 +01:00
KrisDavie 4de3544e0d Syntax fixes 2023-12-22 22:48:42 +01:00
KrisDavie 228f18fed4 Logic updates
- Add Thieves -> Desert clip (+ as connector)
 - Spec rock bomb clip (+ as connector)
 - Paradox teleport for chests in crystal area and from front
 - Require bombs or Somaria to get out of IP clip
 - Add dash clip checks
2023-12-22 22:48:42 +01:00
KrisDavie 2b826077fc Undo test doors check 2023-12-22 22:48:42 +01:00
KrisDavie 9352067d69 Fix swamp smalls in pottery to get out of swamp 2023-12-22 22:48:42 +01:00
KrisDavie 95703fe2b5 Fix flippers logic preventing locks on drain 2023-12-22 22:48:42 +01:00
KrisDavie 0ff25d7fd9 Give access to correct IP door for lobby clip 2023-12-22 22:48:42 +01:00
KrisDavie dad1ee8336 Implement basic HMG logic
* Ice Palace Lobby Clip
* Kikiskip to Pod
* Mire -> Hera -> Swamp
  - Mire small door to rupee room is removed
  - Hera and Swamp keys are placed without logic
  - Swamp locked by vanilla rules or having all mire smalls
* Above as connectors in ER
2023-12-22 22:48:42 +01:00
aerinon c4ebbe5421 fix(vanilla_fill): make uncle weapon non-random, make medallions vanilla
fix(enemizer): enemy bans
2023-12-22 14:41:05 -07:00
aerinon 4b888b3c48 feat: swapped ER 2023-12-19 16:31:29 -07:00
aerinon 78713a633e fix: different door types with TR in door shuffle modes 2023-12-18 16:05:57 -07:00
aerinon 7619eb480d fix: small issue with lite (TR) using all must exits 2023-12-18 16:05:23 -07:00
aerinon 44d33ea629 fix: ganonhunt playthrough 2023-12-18 14:10:30 -07:00
aerinon 126e055cec fix: accept shufflebosses and shuffleenemies 2023-12-18 14:10:14 -07:00
codemann8 80eac44ac0 Fixed issue with Insanity ER and Pyramid Crack exit 2023-12-15 11:35:27 -06:00
codemann8 be18412cdd Some fixes to Song Instrument shuffle data 2023-12-15 00:48:43 -06:00
codemann8 0e0df12677 Added new option to export pre-seed customizer template yaml 2023-12-14 15:12:48 -06:00
aerinon 0bd1f90bca feat: MW progresssion balancing tweaked to be percentage based instead of raw count. Tries to keep each player's locations in each sphere within 80% of the player with the most locations available. (Measured with percentage instead of raw count.) Old algo tried to keep everyone within 20 locations of each other. Difficult if one player has a lot more locations than another.
fix: Potential fix for early Trinexx start
2023-12-14 10:13:22 -07:00
aerinon c4ec28da76 fix: minor fix for take_anys
fix: money balancing - initialization in a good case
2023-12-13 13:59:34 -07:00
codemann8 159dbcd8db Replacing Save Settings on Exit with Settings on Load 2023-12-13 14:02:43 -06:00
aerinon af03a8a243 fix: don't bother blocking rain doors in no logic 2023-12-13 11:45:59 -07:00
aerinon ffac17f330 fix: mimics are forbidden except in previous kill rooms 2023-12-13 11:42:35 -07:00
aerinon d117bc4fda fix: several enemy bans 2023-12-13 11:23:08 -07:00
codemann8 9820f79b0b Fixed minor incorrect Entrance data 2023-12-12 23:29:12 -06:00
codemann8 1d0045624b Remove song instruments output file 2023-12-12 23:28:34 -06:00
aerinon 792ba081a6 fix: customizer errors 2023-12-11 15:15:26 -07:00
codemann8 f954907af8 Implement Beat Agahnim 1 already in starting inventory 2023-12-09 16:22:25 -06:00
codemann8 5983629d6b Fixed issue with Starting Inventory not printing to Spoiler 2023-12-07 13:24:47 -06:00
codemann8 de6c1790e5 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2023-12-07 13:06:51 -06:00
codemann8 a6f244cd01 Implement Return Old Man already in starting inventory 2023-12-07 13:06:49 -06:00
codemann8 e955fc02d8 Implement Return Old Man already in starting inventory 2023-12-07 13:04:24 -06:00
codemann8 2225b493c2 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-12-02 15:45:16 -06:00
codemann8 bcd311980b aenum import hotfix 2023-12-02 15:45:02 -06:00
codemann8 2cef69f192 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-12-02 06:48:47 -06:00
codemann8 257eabb6c6 Version bump 0.3.3.2 2023-12-02 06:30:12 -06:00
codemann8 a1b570da62 Added song instrument shuffle 2023-12-02 05:46:33 -06:00
codemann8 d9e515429a Undo bunny walking change due to infinite loop 2023-12-02 05:29:11 -06:00
aerinon 93211567c2 fix: customizer errors
fix: poor enemy placement
fix: insanity rng
2023-11-27 16:41:58 -07:00
aerinon f2a40b0941 fix: typo 2023-11-27 10:27:04 -07:00
codemann8 98dc38e3ac Some minor OWR corrections 2023-11-24 16:43:42 -06:00
codemann8 b65c55e1b5 Fix some issues with Smith return 2023-11-24 16:38:21 -06:00
aerinon 871a15393c fix: couple more enemy bans for hera big 2023-11-22 15:44:35 -07:00
aerinon 5c58782d0c fix: multiworld lamp gfx again 2023-11-22 15:37:46 -07:00
aerinon e094d07905 fix: ban enemies around hera big chest 2023-11-21 09:46:43 -07:00
aerinon 070f489be8 fix: fix spectacle rock cave enemy drops 2023-11-20 16:53:24 -07:00
aerinon 3e5d4abfd3 fix: don't shuffle bonk fairies
fix: fix mimic cave enemy drops
2023-11-20 16:46:42 -07:00
codemann8 f2b07a7f8f Added missing saved user settings in Adjust tab 2023-11-20 11:38:41 -07:00
Cody Bailey a2c4be4c4c Add aga_randomness to exposed settings 2023-11-19 17:37:30 -05:00
codemann8 3328ab2718 Added missing saved user settings in Adjust tab 2023-11-19 14:07:47 -06:00
codemann8 83831265dd Merged in DR v1.2.0.22 2023-11-18 17:49:41 -06:00
aerinon 156f223829 build: forgot to include lower case 2023-11-15 16:47:17 -07:00
aerinon 94d05df72b fix(logic): Backwards to Lanmo 2 with Trinexx requires the cape 2023-11-15 16:38:19 -07:00
aerinon c0a06e7986 build: fix rom build 2023-11-15 15:54:54 -07:00
aerinon c27c5455a4 fix: YA Hera Boss music
fix: Various enemizer enemy bans
2023-11-15 15:48:13 -07:00
aerinon 3f0fcd45ff fix: Flute doesn't work in rain state (even if pre-activated) except for glitched modes
fix(msu): GTBK Music in DR
2023-11-15 15:03:30 -07:00
aerinon 876e6e09d7 fix(ER): Links house on Dm won't allow a cave to be used twice anymore 2023-11-15 15:01:58 -07:00
aerinon ae3215ff9a fix(key logic): typo
fix(bunny logic): multiple paths considered
2023-11-15 15:01:21 -07:00
aerinon a50170c54f fix: Flute doesn't work in rain state (even if pre-activated) except for glitched modes
fix(msu): GTBK Music in DR
2023-11-15 14:33:11 -07:00
aerinon 215c80eb4a fix(algorithm): District algorithm fails if unable to comply with restriction 2023-11-15 13:36:09 -07:00
aerinon 7030ff01be fix(ER): Links house on Dm won't allow a cave to be used twice anymore 2023-11-15 13:25:13 -07:00
aerinon 71eadd051c fix(key logic): typo
fix(bunny logic): multiple paths considered
2023-11-14 14:42:25 -07:00
aerinon 14c0448fe7 fix(key logic): typo
fix(bunny logic): multiple paths considered
2023-11-13 15:43:27 -07:00
aerinon f4a702951c fix(key logic): typo 2023-11-11 20:00:31 -07:00
codemann8 ca7e4de35c Marking OW screens as visited 2023-11-08 23:10:34 -06:00
codemann8 b8d38afca4 Various MSU corrections/fixes
- GT2 track now plays if DR and GTBK is collected
2023-11-05 08:46:58 -06:00
aerinon 13f9fe8f92 Enemy bans see release notes 2023-11-02 16:24:38 -06:00
aerinon 66ede5cda2 Fix for sprite limit on Lanmo 2
Fix for enemies at GT Falling Tile Square
2023-10-31 15:35:45 -06:00
codemann8 42c51d2815 Fix Hera music to play correct dungeon track following a floor change 2023-10-24 07:38:45 -05:00
codemann8 2d004fbe63 Allow user to change and save output directory within the Gui 2023-10-24 05:29:52 -05:00
codemann8 c04040cb3e Fix for Hera boss music fadeout when falling 2023-10-22 16:24:11 -05:00
aerinon da938722ca Merge pull request #150 from pwendelboe/DoorDevVolatile
Update ItemList.py
2023-10-16 16:19:14 -06:00
aerinon 07e06add11 Fix for bonk torches counting issue
Hera basement issue fixed by banning wallmasters
Known Statue+Pull Switch interactions banned
Making sprite spammers count for more on tile to increase chance of pots being available to pick up.
More enemy bans
2023-10-11 12:26:54 -06:00
codemann8 8b5c5ce254 ROM Fixes
- Fix standing item dupe respawns
- Fix Hera boss room falling fade out
2023-10-10 02:08:36 -05:00
Paul Wendelboe c849f8202c Update ItemList.py
Fix iteration on item instead of name when using a custom pool in some cases.
2023-10-09 00:39:54 +00:00
aerinon b50cf16fbf Merge branch 'DoorDevUnstable' into DoorDevVolatile 2023-10-06 12:57:37 -06:00
aerinon fd99620ac9 Standard: generation error fixed 2023-10-06 12:56:29 -06:00
aerinon 1434911727 Freeze fairy abyss/beam dash enemies
Fix original key drops on split supertiles (pokey 1)
Fix mystery/customizer boolean issue
Enemy bans
2023-10-06 10:47:22 -06:00
codemann8 697ea6e849 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-10-05 01:06:14 -05:00
codemann8 a1f2ee8d91 Version bump 0.3.3.1 2023-10-05 01:05:16 -05:00
codemann8 346d91fe37 More OWR yamls and some adjustments to existing ones 2023-10-05 00:43:12 -05:00
codemann8 1843cc90ec Some fixes to OWR district shuffle yamls 2023-10-02 21:52:34 -05:00
aerinon 7d371b9952 Async doors league settings 2023-10-02 12:49:02 -06:00
aerinon 047f539f8d More bans 2023-10-02 09:40:53 -06:00
codemann8 9d6e2c770d New solution for mirror portal disabling in Crossed OWR
Map check correctly displays mirror portal sprite
2023-10-01 06:13:36 -05:00
codemann8 929d24c818 Merged in DR v.1.2.0.21 2023-09-29 15:11:06 -05:00
aerinon 6c529cc7de Some more trap door exceptions (can be opened by trigger and should be bunny impassible) 2023-09-29 13:06:10 -06:00
aerinon 267e3214a7 Merge branch 'DoorDevUnstable' into DoorDevVolatile
# Conflicts:
#	CLI.py
#	Main.py
#	RELEASENOTES.md
#	Rom.py
#	Rules.py
#	data/base2current.bps
#	source/classes/CustomSettings.py
#	source/tools/MysteryUtils.py
2023-09-29 11:44:23 -06:00
aerinon 7a16ea4fe1 Rule fix for zelda to throne room
Minor fix to standard generation and spoilers
2023-09-29 09:33:33 -06:00
codemann8 fd749553a9 New solution for mirror portal disabling in Crossed OWR 2023-09-28 22:05:31 -05:00
aerinon 329367e04a Account for vanilla BK doors in Stitcher 2023-09-28 10:43:10 -06:00
aerinon dc96c53a95 Fix for Ganonhunt and various algorithms 2023-09-28 10:43:03 -06:00
aerinon e722a1129f Rule fix for zelda to throne room 2023-09-28 10:31:36 -06:00
aerinon dd9cdee37f Fix location of new doors 2023-09-27 09:10:55 -06:00
aerinon f4c465f5c3 Baserom update (colletion rate counter for mystery)
Minor issue with customizer/mystery yamls and booleans
2023-09-26 13:40:22 -06:00
codemann8 27ed92cfcb Restructured forced crossed/noncrossed to share code 2023-09-26 13:03:18 -05:00
aerinon 915e7dc416 Ability to enemize fairies
Fix for blue square in caves
Lower limit for sprites on tiles that support it, to help with pot lifting
Swamp waterway enemies fixed to not drop
2023-09-26 08:59:31 -06:00
codemann8 3d86199002 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2023-09-25 19:22:49 -05:00
codemann8 d8b4419b04 Converting flute data to owid-based rather than by owslot 2023-09-25 19:22:46 -05:00
codemann8 32c55cc0a5 Converting flute data to owid-based rather than by owslot 2023-09-25 19:19:03 -05:00
codemann8 9c04140134 Remove some commented out code 2023-09-24 01:21:13 -05:00
codemann8 4f5779143d Restructured forced crossed/noncrossed to share code 2023-09-24 01:19:56 -05:00
codemann8 2b3c635680 Fixed issue with limit_crossed affecting other modes outside Unrestricted Crossed OWR 2023-09-24 01:17:55 -05:00
aerinon 06ae4f25e1 Several rom fixes, multiworld keys/lamp, pendant count, collection rate
Fix for castle barrier gfx in rain state
Chainchomp placement in Spiral Cave generation issue
A bunch of new bans, Mimics, Stal, Bumper issues mostly. A few others.
2023-09-20 13:11:44 -06:00
aerinon 26c26acd6e Fix item duping and disappearing
Fix mutliworld crash
Fix assured sword + start inventory
New bans on enemy placement
2023-09-14 08:51:29 -06:00
aerinon b37bcc987a Merge pull request #149 from tcprescott/patch-2
Update sprite author char_map
2023-09-14 08:35:24 -06:00
Thomas Prescott 3088960c89 Update sprite author char_map 2023-09-14 09:32:18 -05:00
aerinon 2e5b9758c2 Unkillable thieves for now
Turn off enemy drop indicator for modes that don't need it
2023-09-12 10:13:15 -06:00
aerinon 9e6bcf8a99 Various enemizer adjustments and fixes
Fix for retro location counting
Baserom update
2023-09-12 08:40:24 -06:00
codemann8 1cc9b993f2 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-09-10 17:11:51 -05:00
codemann8 a9b5dffcfa Version bump 0.3.3.0 2023-09-10 17:11:26 -05:00
codemann8 3a06049bc4 Adding many OWR customizer mode yamls 2023-09-10 15:40:40 -05:00
codemann8 1024126835 Moving Display Collection Rate option away from post-gen options 2023-09-10 14:51:43 -05:00
codemann8 9bb29d32d8 Changing TakeAny sword to count towards item collection 2023-09-10 14:44:46 -05:00
codemann8 268bc1b278 Adding many OWR customizer mode yamls 2023-09-10 14:43:15 -05:00
codemann8 9adba09c54 Adding additional info to error message during OWR Layout placement 2023-09-09 16:31:27 -05:00
codemann8 78abcb4196 Implemented remaining Crossed OWR Customizer support 2023-09-09 16:28:09 -05:00
codemann8 e19622b566 Fixed and reorganized OWR sections on spoilers 2023-09-08 08:48:15 -05:00
codemann8 a3d7abf71a Small bugfix for OWR Customizer stuff 2023-09-07 11:31:24 -05:00
codemann8 c0985dacdc Adding Customizer support for grouping tiles together in Mixed OWR 2023-09-07 11:30:32 -05:00
codemann8 535945477b Fixed some broken randomization 2023-09-06 17:46:29 -05:00
codemann8 4cb28a1155 Force tile group merges if Customizer edge connections force it 2023-09-06 17:36:09 -05:00
codemann8 d709ab7a19 Fixed some broken randomization 2023-09-06 17:19:56 -05:00
codemann8 72e41e20dc Implemented Customizer OWR Edge Groups 2023-09-06 13:58:19 -05:00
codemann8 99753c0039 Minor fixed to OWR algorithm 2023-09-06 12:39:57 -05:00
codemann8 bcb224ade8 Some code simplification 2023-09-05 13:38:29 -05:00
codemann8 508a68e5e5 Merging Limited and Chaos Crossed OWR options into Unrestricted 2023-09-05 03:01:49 -05:00
codemann8 b0c9f943ef Adding Customizer documentation for OWR modes 2023-09-05 02:00:19 -05:00
codemann8 290fe9f3bd Minor logical code restructure
Mostly just indentation but GitHub textdiff sucks
2023-09-05 00:44:02 -05:00
codemann8 927588a3d8 Adding Customizer support for Crossed OWR
Also made Layout OWR compatible with Mixed OWR with asterisk notation
2023-09-05 00:30:53 -05:00
codemann8 c1f98dfb51 Customizer: Force Tile Flip for connected whirlpools 2023-09-05 00:14:05 -05:00
codemann8 7f0e2d8b65 Removing yamls not meant to be commited 2023-09-04 23:05:22 -05:00
codemann8 712188251d Restructuring parallel_links in OWR 2023-09-04 19:32:34 -05:00
aerinon 8d31b0080f Fixed shops not counting items
Baserom update
2023-09-01 14:14:57 -06:00
aerinon 9ce8daf4e8 Let dungeons exceed 256 items 2023-08-30 16:17:36 -06:00
aerinon fa155a78f8 Baserom patch
Attempt to repair bee trap and other items
Some other minor fixes
2023-08-30 15:26:46 -06:00
codemann8 179e605253 Added Customizer support for OWR Layout and Whirlpool Shuffle 2023-08-27 08:19:02 -05:00
codemann8 59d446aac2 Adding consideration when flute is removed entirely from item pool 2023-08-25 14:15:33 -05:00
codemann8 b68438bc35 Added Customizer support for OWR Layout and Whirlpool Shuffle 2023-08-25 14:14:03 -05:00
codemann8 2f2764adb4 Fixed error with Mixed OWR + Flute Shuffle 2023-08-25 13:20:24 -05:00
codemann8 63d33e4817 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2023-08-25 13:15:01 -05:00
codemann8 3cc166bd28 Fixed error with Mixed OWR + Flute Shuffle 2023-08-25 13:14:18 -05:00
codemann8 e8193463b4 Fixed error with Mixed OWR + Flute Shuffle 2023-08-25 11:19:43 -05:00
codemann8 26727fbfca Added Customizer support for OWR Layout and Whirlpool Shuffle 2023-08-25 11:18:21 -05:00
aerinon 42bf2f3534 Bunch of fixes for the baserom changes 2023-08-24 16:18:49 -06:00
codemann8 196279b65f Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-08-19 19:43:44 -05:00
codemann8 eb1888334e Version bump 0.3.2.2 2023-08-19 19:43:11 -05:00
codemann8 911dd4d702 Sorting flute spots by OW Slot 2023-08-19 19:24:16 -05:00
codemann8 b0d8ea074c Fixed issue with Major Item + TF goals 2023-08-19 13:27:38 -05:00
codemann8 256b59b4b8 Temporarily fix issue with Customizer+Grouped OWR 2023-08-19 13:20:27 -05:00
codemann8 8b077cb379 Adding Customizer support for flute shuffle 2023-08-19 12:55:55 -05:00
codemann8 bbd3187cb1 Converting flute data to owid-based rather than by owslot 2023-08-18 05:24:26 -05:00
aerinon 2a5ceaacd8 Several small fixes
Added special bitmask table for cross dungeon drops and indicator
2023-08-17 13:54:14 -06:00
aerinon cf2e001447 Fix for TFH 2023-08-17 13:42:45 -06:00
codemann8 4151e16893 Fix some bugs in OWR layout validation 2023-08-17 12:19:53 -05:00
codemann8 24372c3868 Converting flute data to owid-based rather than by owslot 2023-08-17 11:50:06 -05:00
codemann8 7bc9a43ef4 Fixed false negative reachability error in playthru calc 2023-08-17 07:33:17 -05:00
codemann8 6ef8abd2ed Changing hints in Swapped ER to not hint entrance locations 2023-08-17 07:31:42 -05:00
codemann8 70e1e7a28b Fixed Swapped ER so that remaining cave placements in mandatory exits cannot choose vanilla 2023-08-17 07:05:38 -05:00
codemann8 ed9585eef6 Fixed Swapped ER to prevent Old Man from being unretunable 2023-08-17 07:04:06 -05:00
aerinon 1985139cb5 Fixing generation errors
Update rom for multiworld/vanilla sewers problems
2023-08-09 15:33:11 -06:00
aerinon f906633c2b Fix for older key drops (multidata still uses the old address calculation) 2023-08-09 13:30:14 -06:00
aerinon 57da9efcb1 Mimic work 2023-08-09 12:06:20 -06:00
codemann8 5042c32ba9 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-08-07 18:01:03 -05:00
codemann8 541dbbd9e5 Merge branch 'DoorDevUnstable' into OverworldShuffleDev 2023-08-07 17:59:22 -05:00
aerinon a4d5dec8ad Fixed an error
Small performance increase
2023-08-07 16:49:34 -06:00
codemann8 de2e55a526 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-08-07 16:06:46 -05:00
codemann8 fd3bdc6b71 Version bump 0.3.2.1 2023-08-07 16:04:58 -05:00
codemann8 06e3dc80d6 Merged in DR v1.2.0.20 2023-08-07 15:30:50 -05:00
aerinon 4dce2762f1 CI Update ubuntu 2023-08-07 13:24:36 -06:00
aerinon 329950eadc CI Update ubuntu 2023-08-07 13:19:03 -06:00
aerinon bc5c6da2ac Fix for hera boss music (the last?) 2023-08-07 12:19:35 -06:00
aerinon a3fcd5ee24 Merge branch 'Catobat-StairLoops' into DoorDevUnstable 2023-08-07 12:15:48 -06:00
aerinon 44acc4e290 Merge branch 'StairLoops' of github.com:Catobat/ALttPDoorRandomizer into Catobat-StairLoops 2023-08-07 12:15:13 -06:00
aerinon db70a16dea Fixed minor issue with dungeon counter interfering with timer (rom re-build) 2023-08-07 10:49:55 -06:00
aerinon e6072cb8dc Fixed minor issue with dungeon counter interfering with timer (merge from Stable) 2023-08-07 10:48:23 -06:00
aerinon 9e26c9c42c Fixed minor issue with dungeon counter interfering with timer 2023-08-07 10:44:55 -06:00
aerinon e6597a7ab9 Fixed inverted problem with experimental (logically assumed link's house was in the light world)
Fixed hint typo
2023-08-07 09:36:50 -06:00
aerinon 90f1629f0e Merge branch 'DoorDevUnstable' into DoorDevVolatile
# Conflicts:
#	Main.py
#	MultiClient.py
#	Rom.py
#	data/base2current.bps
#	resources/app/gui/lang/en.json
#	resources/app/gui/randomize/item/widgets.json
#	source/gui/bottom.py
#	source/gui/widgets.py
2023-08-04 11:33:31 -06:00
aerinon 5d3c401f1f Remove hovers in waterway from drop pool 2023-08-04 10:48:59 -06:00
aerinon f442cff061 Logic added for openable trap doors 2023-08-03 15:06:54 -06:00
codemann8 1566813f81 Changing yaml output to show hex numbers as hex and not as decimal 2023-08-02 15:01:37 -05:00
codemann8 c0c3204fd5 Notes field 2023-08-02 09:45:41 -06:00
Catobat f2b8c840a2 Fix potential bug with re-linking decoupled doors 2023-08-02 17:02:15 +02:00
aerinon 9497ef36ad Paired needs a bunch of generation work apparently. Disabling it. Minor generation improvements. 2023-08-02 08:05:54 -06:00
Catobat 7197a23b45 Add setting for self-looping doors 2023-08-02 02:23:19 +02:00
Catobat 1817cf3824 Fix byte 12 in settings code 2023-08-01 22:00:58 +02:00
aerinon 0ee88618a7 Paired dungeon shuffle 2023-08-01 11:31:59 -06:00
codemann8 35f3abc1c1 Creating user notes field to be supplied by the seed roller 2023-07-29 05:10:47 -05:00
codemann8 982032e156 Supporting old keyshuffle keywords 2023-07-29 05:04:46 -05:00
codemann8 d79c8c1fd1 Merged in DR v1.2.0.19 2023-07-29 05:03:37 -05:00
aerinon 1592fac792 Typo 2023-07-28 12:32:28 -06:00
aerinon 75fc1f7cc3 Fixed customizer example
Fixed /missing command in multiworld for non-pottery lottery settings
2023-07-28 12:29:47 -06:00
aerinon b7b9e5aea7 Merge branch 'Catobat-TriforceMinMax' into DoorDevUnstable 2023-07-27 13:47:29 -06:00
aerinon 2e07d03000 Merge branch 'TriforceMinMax' of github.com:Catobat/ALttPDoorRandomizer into Catobat-TriforceMinMax 2023-07-27 13:46:42 -06:00
aerinon 8d17d95640 Fixed a generation bug
Add ganonhunt to pyramid open
2023-07-27 13:45:44 -06:00
Catobat bf9ad536fe Implement triforce_max_difference 2023-07-26 15:27:47 +02:00
Catobat 66bd8960a1 Support Triforce Piece settings in Customizer YAML 2023-07-26 15:03:45 +02:00
Catobat ea70d7cb5a Move Triforce Pieces Min and Max handling to Main 2023-07-26 02:40:40 +02:00
codemann8 551638e00c Merged in DR v1.2.0.18 2023-07-19 16:12:09 -05:00
codemann8 6d03c5c532 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev
Adding console output when generation fails to reach required items
2023-07-19 14:14:01 -05:00
codemann8 2c6af4e44c More Swapped ER fixes 2023-07-19 14:09:01 -05:00
aerinon b6275d0688 Typo 2023-07-19 12:57:07 -06:00
aerinon 213d3d3aa0 Fixed an issue where certain vanilla door types would not allow other types to be placed.
Customizer: fixed an issue where last ditch placements would move customized items. Those are now locked and the generation will fail instead if no alternatives are found.
2023-07-19 12:31:50 -06:00
codemann8 a987e58fc9 Adding Flute Activation only if an activated flute cannot be found elsewhere 2023-07-17 02:13:16 -05:00
codemann8 263dcf76f9 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-07-16 13:17:48 -05:00
codemann8 fce629b95f Version bump 0.3.2.0 2023-07-16 13:17:20 -05:00
codemann8 d4f33f50eb More code for Swapped ER implementation 2023-07-16 12:59:43 -05:00
codemann8 138bd2b41f Minor formatting 2023-07-16 01:12:12 -05:00
codemann8 4f5d268401 Adding new Swapped ER mode option 2023-07-16 01:07:17 -05:00
codemann8 4f1bad2510 Adding missing code that allows Sanc spawn to be placed in DW in Lean ER 2023-07-16 00:51:16 -05:00
codemann8 84ecf22142 Disabling "LH on mountain" connector
Due to bug found/fixed in previous commit, it was found this was effectively disabled anyways for many months, seemingly without issue
2023-07-16 00:26:12 -05:00
codemann8 c2ec7c7491 Fixed a bad merge causing LH on mountain to not place a connector 2023-07-13 23:26:57 -05:00
codemann8 119e289512 Fixed issue with non crossworld ER modes not clearing out entrances from previous attempts 2023-07-13 16:53:15 -05:00
codemann8 e0bf8227fb Fixed issue with flipper rules not getting pearl rules added 2023-07-12 20:05:47 -05:00
aerinon 1b81151941 Customizer: Fixed issue with Assured sword and start inventory 2023-07-12 09:50:53 -06:00
aerinon d135405ed3 Customizer: Exception raised for placements of items that are not in pool 2023-07-12 09:16:00 -06:00
codemann8 ccbbe93d63 Changing retro so bottle vendor fish prize gives a key instead of arrows
Fixed issue where all other narrow OW items drew 4 pixels to the left
2023-07-11 13:05:20 -05:00
aerinon 5d2ceaf75c Updated baserom for crystal custscene and hera music fix
Updated a couple of error messages and when they are displayed
Updated Ganonhunt goal text to be more consistent across randomizers
2023-07-10 13:56:05 -06:00
aerinon 0c640bf9dd Fix for pyrmaid hole logic 2023-07-10 10:35:18 -06:00
codemann8 27baf8d715 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-07-07 04:15:25 -05:00
codemann8 5ca2522386 Version bump 0.3.1.2 2023-07-07 04:15:05 -05:00
codemann8 f3fd86e10e Add seed number to spoiler metadata 2023-07-07 04:02:59 -05:00
codemann8 63c9b986f3 Removing Bat Cave Screen Wrap from logic per v31 logic 2023-07-07 03:42:23 -05:00
codemann8 d30642c0c7 Including OW Tile Flips in Printed Customizer File 2023-07-07 03:41:33 -05:00
codemann8 581597234c Changing retro so bottle vendor fish prize gives a key instead of arrows 2023-07-07 01:33:39 -05:00
codemann8 2bd6f6ec71 Fixed issue with Mixed OWR where Ice Cave/Shopping Mall water transitions were not flipping 2023-07-04 16:59:24 -05:00
codemann8 67eedf465d Fixed issue with Kakariko music playing when killing Aggro Guards in enemizer 2023-07-03 15:55:35 -05:00
codemann8 32d13a904b Merge pull request #12 from hiimcody1/patch-1 2023-06-29 20:27:49 -05:00
codemann8 cad2d632d3 Fixed issue with Aga Door preventing TF Cutscene 2023-06-29 19:33:36 -05:00
aerinon 627168e771 First pass on multiworld for enemy drops. Fixed a few graphical enemizer issues. 2023-06-26 10:29:37 -06:00
codemann8 3dbcab1357 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-06-16 20:40:55 -05:00
codemann8 0314958201 Fixed issue where items spawning off screen might not redraw 2023-06-16 20:40:34 -05:00
codemann8 b89c617f0a Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-06-16 20:27:52 -05:00
codemann8 7512d73e99 Version bump 0.3.1.1 2023-06-16 20:27:28 -05:00
codemann8 8362886cc1 Merged in DR v1.2.0.17 2023-06-16 12:14:16 -05:00
aerinon 8afdbaca25 Update release notes 2023-06-16 09:22:08 -06:00
aerinon 002e46e56e Merge branch 'hiimcody1-DoorDevUnstable' into DoorDevUnstable 2023-06-16 09:18:31 -06:00
aerinon 0d4ff815d3 Merge branch 'DoorDevUnstable' of github.com:hiimcody1/ALttPDoorRandomizer into hiimcody1-DoorDevUnstable 2023-06-16 09:17:46 -06:00
aerinon 5da0836d9f Fixed logic with mirror in west dark world 2023-06-16 09:15:06 -06:00
codemann8 1cbee3f190 Minor logic and terrain GFX changes to Spiral/Mimic Ledge in Inverted
- Also updated GFX routine to handle and correct GFX issues when exceeding the max number of GFX
2023-06-15 12:42:33 -05:00
Cody Bailey 8955e8b26f Fix JSON metadata 2023-06-14 15:31:49 -04:00
codemann8 a842939e92 Various region/rule reorganization to match DR 2023-06-13 18:36:16 -05:00
aerinon 0ab54def8b Removed backup locations for Dungeon Only and Major Only algorithms. If item cannot be placed in the appropriate location, the seed will fail to generate instead. 2023-06-08 10:25:05 -06:00
codemann8 496c4fb369 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-06-03 16:23:41 -05:00
codemann8 f19b19ea00 Updated documentation for Good Bee addition to Bonk Drops 2023-06-03 16:23:04 -05:00
aerinon 503be6aa91 Enemizer refinement 2023-05-19 08:53:01 -06:00
codemann8 68852a127b Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-05-13 02:23:43 -05:00
codemann8 d16d0bedf5 Version bump 0.3.1.0 2023-05-13 02:23:15 -05:00
codemann8 2a008dfc3e Added a TF Cutscene when getting the TF item
- Also fixed an issue with vanilla enemy key drops displaying incorrectly
2023-05-13 02:16:36 -05:00
codemann8 d606a84c35 ROM Updates
- Fix Bonk count capping at 99 in credits
- Fix Hera boss music still plays after boss defeated
- Fixed Murahdahla in Rainstate
2023-05-12 21:31:24 -05:00
codemann8 a039a4fb71 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-05-09 21:54:17 -05:00
codemann8 2dd0a64a4b Version bump 0.3.0.8 2023-05-09 21:53:29 -05:00
codemann8 66cec505de Only apply powder patch if flag is set 2023-05-09 21:49:11 -05:00
codemann8 b0497ffe7e More GFX updates
- Apples and Chickens now have GFX
- Fixed issue with Menu not allowing DPad input with standing item on screen
- Fixed issue with keys not drawing properly during tablet animation
2023-05-09 21:36:38 -05:00
codemann8 5bce245de4 Added better GFX for fairy and good bee 2023-05-08 07:49:38 -05:00
codemann8 393cbdd0ab Apples/BeeTraps/Fairies now spawn automatically under pots 2023-05-08 05:03:53 -05:00
codemann8 5d7d2514ff Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-05-07 20:29:36 -05:00
codemann8 e1092b7def Version bump 0.3.0.7 2023-05-07 20:29:16 -05:00
codemann8 73fc85df3b Big ROM changes
- New Item GFX code
- Fixed Bonk Dupe issue
- Fixed Bonk Despawn issue
2023-05-07 20:19:18 -05:00
codemann8 608e01c906 Fix pottery to retain gfx during map check 2023-04-16 04:37:50 -05:00
codemann8 ee9fc3c6b1 Animate standing rupees for enemy drops 2023-04-15 05:18:40 -05:00
aerinon d5e69b28f2 Fix for Non-ER Inverted Experimental (Aga and GT weren't logically swapped)
Fix for customizer setting crystals to 0 for either GT/Ganon
2023-04-14 15:23:38 -06:00
codemann8 6d2e95e6ef Merged in DR v1.2.0.16 2023-04-14 16:00:21 -05:00
aerinon ea8bd117fc Fix for partial key logic for vanilla mire
Fix for Kholdstare shell collision
2023-04-14 14:17:57 -06:00
codemann8 5223b8fe35 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-04-13 19:21:24 -05:00
codemann8 1359514dea Fixed default connections in Inverted to correctly swap AT/GT 2023-04-13 19:21:11 -05:00
codemann8 6f5a4a12e8 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-04-13 18:50:56 -05:00
codemann8 f5181adf36 Version bump 0.3.0.6 2023-04-13 18:50:35 -05:00
aerinon 072bbfac1f Version bump and release note 2023-04-13 16:20:54 -06:00
aerinon 2abfc6ea80 Swap E/W on Mire Torches/Mire Attic Hint 2023-04-13 16:19:18 -06:00
codemann8 e1fe3e1639 Changed bonk drops to not set flag if sprite is off screen 2023-04-13 15:01:23 -05:00
codemann8 c2538d44cb Minor GUI indentation 2023-04-13 14:03:30 -05:00
aerinon 907639b984 any_enemy_logic option added 2023-04-10 09:07:01 -06:00
codemann8 2e750c471f Fixed issue with bonk drops causing other duplicate spawns 2023-04-09 11:08:26 -05:00
aerinon 4af9419461 GUI cleanup
Fix Chest Game prize display
2023-04-07 16:01:08 -06:00
codemann8 b0eefd36b0 Merge branch 'DoorDevUnstable' into OverworldShuffleDev 2023-04-07 16:03:10 -05:00
aerinon 546f5ca10c Fix for gui 2023-04-07 15:00:14 -06:00
codemann8 2da8dc72cc Better fix for Hera music silence
This reverts commit c2b3d8ce6c, reversing
changes made to 1bf95fe2d7.
2023-04-07 15:48:56 -05:00
codemann8 8e7a4fcd8e Merged in DR v1.2.0.15 2023-04-07 13:22:53 -05:00
codemann8 793f3b30b0 Merged in DR v1.2.0.14 (2nd) 2023-04-07 12:04:12 -05:00
codemann8 c2b3d8ce6c Fix for Hera music silence 2023-04-07 11:49:39 -05:00
aerinon 8ffefdca9a Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable 2023-04-07 10:28:07 -06:00
aerinon 5d86ed4055 start of any enemy logic option 2023-04-06 16:57:15 -06:00
aerinon ef63511bd8 Update notes 2023-04-06 11:25:32 -06:00
aerinon 85afd0c09e Add collection_rate to customizer 2023-04-06 11:23:54 -06:00
aerinon 10eac87922 Logic fix: hookshot needed for pots in GT conveyor cross 2023-04-06 11:23:04 -06:00
aerinon 3c18dc6e3a Re-vamp multiple settings as buttons.
Minor logic clean up.
2023-04-06 11:22:12 -06:00
aerinon ddfbece2bd Clean up enemizer cli argument and gui code 2023-04-05 16:38:17 -06:00
aerinon 187478eb24 Merge branch 'DoorDevUnstable' into Sandbox
# Conflicts:
#	Gui.py
#	Main.py
#	Rom.py
#	Rules.py
#	data/base2current.bps
#	resources/app/gui/lang/en.json
#	resources/app/gui/randomize/dungeon/widgets.json
2023-04-05 16:26:26 -06:00
aerinon abb11558d8 Correct version bump 2023-04-05 15:58:16 -06:00
aerinon 17f9efb230 Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable
# Conflicts:
#	RELEASENOTES.md
2023-04-05 15:56:17 -06:00
aerinon 50f92e7aee Release notes and minor cleanup 2023-04-05 15:55:30 -06:00
codemann8 1bf95fe2d7 Symmetrical GTCutscene Crystals 2023-04-05 08:31:39 -05:00
codemann8 f13880eee9 Major GUI reorganization 2023-04-04 17:11:43 -06:00
aerinon 09550cd546 Minor fix 2023-04-04 16:53:45 -06:00
aerinon 3e65deda14 Minor fixes 2023-04-03 16:37:29 -06:00
codemann8 7296735c50 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-04-03 08:33:55 -05:00
codemann8 46ed496669 Version bump 0.3.0.5 2023-04-03 08:33:28 -05:00
codemann8 9406f408df Fix for HC dark rooms not getting correct lamp logic in partitioned DR 2023-04-03 08:25:14 -05:00
codemann8 9cef1ff32e Temporary fix for avoiding VRAM issues in non-layout OWR modes 2023-04-03 08:21:34 -05:00
codemann8 bbf254d6f6 Adding missing region to Tile Regions list 2023-04-02 09:03:17 -05:00
codemann8 2ed1edbc20 Fixed issue with some Cliff Drop connections in Mixed + OWG 2023-04-02 08:28:29 -05:00
codemann8 7f38b31d55 Fixed Old Man Death causing fake world in glitched 2023-04-02 07:42:27 -05:00
codemann8 034598c85e Added logic for mirror offset to Pyramid Area 2023-04-02 06:49:20 -05:00
codemann8 b66b2b24b7 Fixed dungeon revival fake world behavior in glitched 2023-04-02 06:47:11 -05:00
codemann8 09ea7dd9a9 Fixed various Flute logic issues and improved logic efficiency 2023-04-01 09:11:13 -05:00
codemann8 1005c7f844 Reorganized spoiler log based on UI reorg 2023-04-01 08:16:27 -05:00
codemann8 3eeeda363b Fixed various Flute logic issues and improved logic efficiency 2023-04-01 07:59:13 -05:00
aerinon 41a0751009 Merge branch 'WorldModelRefactor' into DoorDevUnstable 2023-03-31 16:07:31 -06:00
aerinon a4f3afdf5d Reduce retro keys slightly 2023-03-31 16:00:15 -06:00
aerinon d9c18407e4 Fix starting flute logic 2023-03-31 09:29:01 -06:00
codemann8 d216cb337b Adding missing bunny rule for Water D Leave 2023-03-30 22:52:44 -05:00
aerinon 6f18c4c4a5 Fix lamp logic in partitioned 2023-03-30 16:42:56 -06:00
aerinon a0b781521f Big enemizer updates
Fix sheets
Health + damage rando
Logical kill rooms
2023-03-30 16:12:46 -06:00
codemann8 f1f75ec760 Major GUI reorganization 2023-03-29 10:19:36 -05:00
codemann8 28e5b7503d Improved can_reach_smith search 2023-03-27 21:28:46 -05:00
aerinon 4a1efb141a Add collection_rate to customizer 2023-03-24 09:12:46 -06:00
aerinon b513bbef1b Logic fix: hookshot needed for pots in GT Conveyor Cross 2023-03-23 15:33:29 -06:00
codemann8 c3266a904a Disallow some LH placements in DM in Lite/Lean ER 2023-03-22 18:38:26 -05:00
codemann8 89ccf10da0 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-03-22 17:49:43 -05:00
codemann8 4cbd45c17b Version bump 0.3.0.4 2023-03-22 17:49:32 -05:00
codemann8 f4f0ff1018 Merge branch 'DoorDevUnstable' into OverworldShuffleDev 2023-03-22 16:15:38 -05:00
codemann8 37750c55cf Remove Polar from Crossed if Mixed not enabled 2023-03-22 16:09:01 -05:00
codemann8 2de64ef565 Set up code structure for future OW palette changes and return to safer changes 2023-03-22 16:07:39 -05:00
codemann8 f14657ad74 Minor text tweak 2023-03-22 16:00:58 -05:00
codemann8 7212284ba0 Fixed disconnected Dark Chapel Exit with Inverted + Vanilla ER 2023-03-22 16:00:37 -05:00
aerinon c9c510ae21 Minor fixes for customized vanilla doors 2023-03-22 14:58:07 -06:00
codemann8 b549860fb8 Fixed issue with no Woods mosiac on exit in vanilla OW 2023-03-19 12:21:43 -05:00
codemann8 504f2e6a3a Fixed issue with MW Player ID on Bonk Locations 2023-03-19 11:01:22 -05:00
codemann8 d3cdb2fffc Correcting OW screen palette on transition 2023-03-18 05:47:49 -05:00
codemann8 61846c0f81 Load correct Link/Bunny palette on transition 2023-03-16 22:28:36 -05:00
codemann8 7b939a9166 Fix ... issue in credits 2023-03-15 21:20:03 -05:00
codemann8 a14ca50a71 Adjusting Bonk Sprite landing position and water ripple 2023-03-15 05:44:18 -05:00
codemann8 6166151b33 Burning OWR Version to ROM 2023-03-14 17:50:55 -05:00
codemann8 57b39993b9 Merged in DR v1.2.0.13 2023-03-14 17:48:42 -05:00
aerinon 636819ffc0 Versioning update 2023-03-14 16:05:28 -06:00
codemann8 e55d23915c Improved Standard+Inverted preset yaml 2023-03-14 06:21:42 -05:00
codemann8 2338b3e4e7 Fixed item duping issue on OW 2023-03-14 06:20:26 -05:00
codemann8 5ce983513f Fixed incorrect edge coord data for Desert Pass WS 2023-03-13 21:57:11 -05:00
aerinon b2b3d789ca Some rom fixes: - standing item data now cleared on dungeon exit
Escape assist won't fill arrows resulting in free quiver in retro bow mode
2023-03-13 20:42:55 -06:00
aerinon 02c7a5279c Fix some paired doors 2023-03-13 20:40:45 -06:00
aerinon f4524d8a87 Fix Snitch Lady (West) location on map 2023-03-13 16:28:11 -06:00
aerinon b44caa76a7 Customize certain potions refills. 2023-03-13 14:26:25 -06:00
aerinon d85a63ece1 Damage table start 2023-03-13 11:11:59 -06:00
codemann8 3c9c9e7b1e Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-03-12 21:57:56 -05:00
codemann8 b3da38fb31 Version bump 0.3.0.3 2023-03-12 21:57:21 -05:00
codemann8 4c887ca044 Fixed issue with forced HP on Good Bee Bonk Location 2023-03-12 21:46:10 -05:00
codemann8 142f158c27 Reversing chicken fix for Bonk Drops 2023-03-12 20:06:40 -05:00
codemann8 a158cb6b75 Fixed some bad assert syntax 2023-03-12 19:38:30 -05:00
codemann8 d140679c13 Reversing water collision fix and replacing with a sprite targeted fix for Bonk Drops 2023-03-12 19:29:51 -05:00
codemann8 30deb1d5bc Fix for Bonk Locations in Multiworld 2023-03-12 19:25:35 -05:00
codemann8 ae9bf31984 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-03-12 03:33:45 -05:00
codemann8 6811ab29b2 Adding bonk drops to Customizer settings 2023-03-12 03:33:18 -05:00
codemann8 574196f75f Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-03-10 23:57:10 -06:00
codemann8 6283a880de Version bump 0.3.0.2 2023-03-10 23:56:40 -06:00
codemann8 76da44f658 Adding more OWR examples to customizer example yaml 2023-03-10 23:48:04 -06:00
codemann8 6110104db9 Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2023-03-10 21:06:20 -06:00
codemann8 4108370849 Adding Lean/Lite ER support for new Good Bee Cave location 2023-03-10 21:06:16 -06:00
aerinon 9d9071a984 Unstable rom updates 2023-03-10 14:19:09 -07:00
aerinon 4aae603462 Merge branch 'DoorDevUnstable' into Sandbox
# Conflicts:
#	ItemList.py
#	Items.py
#	Main.py
#	Rom.py
#	data/base2current.bps
2023-03-10 13:43:38 -07:00
codemann8 ab5670c64f Adding Lean/Lite ER support for new Good Bee Cave location 2023-03-09 22:23:32 -06:00
codemann8 93eea0b40f Added Cold Fairy Statue to bonkable locations 2023-03-09 20:35:39 -06:00
aerinon affd7568cb Minor adjustments to world model refactor 2023-03-09 16:48:14 -07:00
aerinon 1a1c60f84a Merge branch 'SynthesisOWRMerge' of github.com:codemann8/ALttPDoorRandomizer into codemann8-SynthesisOWRMerge
# Conflicts:
#	Rules.py
#	source/overworld/EntranceShuffle2.py
2023-03-09 11:29:03 -07:00
aerinon c48c89f65b Merge branch 'DoorDev' into DoorDevUnstable
# Conflicts:
#	Main.py
#	RELEASENOTES.md
2023-03-09 11:16:24 -07:00
aerinon 1bb4d5f03b Version bump and note 2023-03-09 11:14:13 -07:00
aerinon bd25c6be26 Merge pull request #141 from tcprescott/DoorDev_MultiworldService
MultiServer: Add option to MultiServer to disable client forfeits
2023-03-09 11:12:37 -07:00
codemann8 252f9ba1a7 Remove 5 Arrow items from bonk drop locations 2023-03-08 20:41:16 -06:00
codemann8 d549a2c323 Adding OWR modes to Customizer settings 2023-03-08 16:19:29 -06:00
codemann8 b6da5e51fd Merged in DR v1.2.0.12 2023-03-08 16:16:04 -06:00
aerinon 44afe50bf4 Version bump 2023-03-08 08:26:50 -07:00
aerinon 4563f96fd5 Fix for mirror portal in inverted
Yet another fix for blocked doors in Standard ER, minor alteration for the swamp entrance fix to work when blocked as well.
2023-03-08 08:25:46 -07:00
codemann8 e6a1476244 Merged in DR v1.2.0.11 2023-03-07 18:58:08 -06:00
Thomas Prescott 35e7784445 clarify forfeit disabled 2023-03-06 23:21:24 -06:00
aerinon 14ced2435c Update for enemizer bits 2023-03-06 16:29:58 -07:00
aerinon 87ab4a8c8a Update baserom and release notes 2023-03-06 16:10:07 -07:00
codemann8 da71e9ba12 Placing Sanc Drop in DW if HC in DW and non-crossworld 2023-03-06 15:16:23 -06:00
codemann8 fd20ec7769 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-03-05 19:31:46 -06:00
codemann8 0748947502 Version bump 0.3.0.1 2023-03-05 19:31:15 -06:00
codemann8 cc84c4e9b4 Adding OWR Tile Flip to Customizer 2023-03-05 19:24:17 -06:00
codemann8 2f61dceb0e Placing Sanc Drop in DW if HC in DW and non-crossworld 2023-03-04 13:44:23 -06:00
Thomas Prescott 060092a53e add ability to disable forfeits 2023-03-03 21:55:02 -06:00
aerinon a5da504b90 Fix for district shuffle's placeholder issue 2023-03-03 16:53:50 -07:00
aerinon 9aab5a2c95 Beemizer fix for shopsanity, pottery, etc. 2023-03-03 16:53:23 -07:00
aerinon c3dd6bac79 Murderdactyl ohko rule 2023-03-03 16:52:29 -07:00
codemann8 d1b4d9e044 Merged in DR v1.2.0.10 2023-03-02 19:07:04 -06:00
aerinon 00b06c53d6 Rom updates and version update 2023-03-01 16:28:47 -07:00
aerinon a75b36e2eb ER2 Minor issues 2023-03-01 16:23:03 -07:00
aerinon 1dc3b13449 Change info message to debug for cleaner output
Possible generation error
2023-02-27 14:42:52 -07:00
aerinon 3047826808 Fix AllowAccidentalGlitches flag 2023-02-27 14:41:43 -07:00
codemann8 c883c6e8c7 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2023-02-26 14:04:41 -06:00
codemann8 bb3b51f1d6 Version bump 0.3.0.0 2023-02-26 14:04:21 -06:00
codemann8 70978e8efd Merge branch 'OverworldShuffleDev' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffleDev 2023-02-26 13:46:38 -06:00
codemann8 90c6854919 Initial OWR/ER2 merge 2023-02-26 13:44:30 -06:00
codemann8 129459f871 Initial OWR/ER2 merge 2023-02-26 13:40:36 -06:00
codemann8 e8b4d23595 Fixed Placeholder NoneType error 2023-02-26 13:13:13 -06:00
codemann8 a6f5c3a1e6 Adding missing Mystery options in example 2023-02-26 13:11:30 -06:00
codemann8 12cd83a92c Reducing verbosity in DR generation 2023-02-25 23:08:10 -06:00
codemann8 a8d30c3686 Remove some glitch fixes from glitched modes 2023-02-25 21:39:13 -06:00
codemann8 9867424e60 Disable flute in rain state 2023-02-25 21:38:22 -06:00
codemann8 c284b90f74 Fixed issue where S&Q points getting set before Mixed OWR 2023-02-25 20:18:01 -06:00
aerinon 6c0da515b4 Fix dungeon_only + pottery modes 2023-02-24 17:00:25 -07:00
aerinon 7397d779ad Changing colorizing pots defaults 2023-02-24 16:20:29 -07:00
aerinon d23d2d8323 Better support for customized start_inverntory with dungeon items (can be mixed with item pool) 2023-02-24 15:45:37 -07:00
codemann8 4caee1cbec Merged in DR v1.2.0.9 2023-02-24 16:14:00 -06:00
aerinon 409f7d50d5 Rom changes (see that commmit message or release notes)
Customizer improvements:
- Better logic around customized lobbies
- Better logic around customized door types
Fix to key doors that was causing extra key doors
Generation improvement around crystal switches
Fix bug in dungeon_only that wasn't using pot key locations (known issue still exists in pottery modes)
Fixes an issue when keys are found in own dungeon for another player when using the bizhawk plugin
2023-02-24 14:25:04 -07:00
codemann8 121c9424c1 Moving OneWayLedge list to OWR code 2023-02-22 18:56:53 -06:00
codemann8 2c10c3b6eb Minor incorrect region error 2023-02-22 17:37:48 -06:00
codemann8 4ea0eda0b9 Initializing districts after OWR so ER can use them 2023-02-22 17:37:27 -06:00
codemann8 7e6488656c Minor assert addition 2023-02-18 21:33:30 -06:00
codemann8 4d62a2c7c4 Suppressing console output for unconnected exits 2023-02-18 21:22:31 -06:00
codemann8 16dc743d2d Removed unused glitched exits 2023-02-18 20:31:04 -06:00
codemann8 ab5f348f77 Merged in DR v1.2.0.8 2023-02-18 19:33:15 -06:00
codemann8 f493709cfe Merged in DR v1.2.0.7 2023-02-18 18:50:21 -06:00
aerinon 9a71e56546 Trap door refinement with "optional" value versus "vanilla"
Slight balance of chaos mode
Warping Pool trap no longer shuffled
2023-02-17 16:55:35 -07:00
aerinon d7c15ae22c Strict and Partial key logic implementations with new test suite utility 2023-02-17 10:07:43 -07:00
aerinon 2b8b9156d9 Minor randomization consistency 2023-02-17 10:03:37 -07:00
aerinon 77c4babca1 Potential fix for vanilla door + ER key logic 2023-02-16 15:40:13 -07:00
aerinon f0101c9854 Trap door mode initial work 2023-02-16 11:49:29 -07:00
Cody cdf3d5b776 Update BaseClasses.py
Fix --jsonout
2023-02-15 20:22:47 -05:00
aerinon 0e82dd73b7 Merge branch 'DoorDev' into DoorDevUnstable
# Conflicts:
#	Doors.py
#	Main.py
#	RELEASENOTES.md
2023-02-15 14:27:26 -07:00
aerinon 5f8be831ec Version bump and release notes 2023-02-15 14:25:00 -07:00
aerinon afac655de2 Fixed door position typo 2023-02-15 14:22:31 -07:00
aerinon fe0e0805ad Fix for Desert Tiles 1 2023-02-15 14:20:15 -07:00
aerinon 45c762ce40 Merge branch 'tcprescott-patch-2' into DoorDev 2023-02-15 14:18:38 -07:00
aerinon 67bd5e870c Fix for decoupled door in standard 2023-02-15 14:13:10 -07:00
aerinon b19232db69 Fix for Desert Tiles 1 2023-02-15 08:41:08 -07:00
aerinon a304fd31ac Standard keysanity distribution and generation fixes
Includes new S&Q safety
2023-02-14 15:58:52 -07:00
aerinon 142b82a261 BK door fix 2023-02-10 13:47:58 -07:00
Thomas Prescott 9bf7315904 Remove a bad triforce text
It was brought up on the ALTTPR Discord that this Triforce text can feel really bad to see at the end of a long race.  I think it's best we give it a permanent vacation.
2023-02-09 13:08:36 -06:00
aerinon fb13785abc Minor standard generation fix
Minor ER + Partitioned fix
2023-02-06 13:46:25 -07:00
codemann8 d68d821e06 Fixed Bomb Shop to not exit at Spec Rock Ledges in Inverted 2023-02-03 15:18:15 -06:00
aerinon 7c75053cc1 Fix for vanilla mire key logic 2023-01-30 15:32:26 -07:00
codemann8 4714e411b8 Fix issue with placing Dark Chapel in proper world 2023-01-30 16:28:56 -06:00
aerinon ec557cd953 Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable 2023-01-28 11:51:53 -07:00
aerinon c88d70bd84 Fix for starting with plain Ocarina (Inactived version) 2023-01-28 11:51:42 -07:00
aerinon d16bca670a Merge pull request #138 from KrisDavie/patch-1
Enable `settingsfile` for multiworld generation
2023-01-28 10:34:52 -07:00
aerinon 9546d87584 Merge pull request #137 from hiimcody1/DoorDevUnstable
Add Race Yes/No to spoiler output
2023-01-28 10:34:00 -07:00
aerinon 04a9bcc68b Fix for free light cone in escape.
No longer missing when entering from DW.
No longer disappears after using fire rod to light torch.
2023-01-27 15:21:22 -07:00
Kris Davie f67cf929f7 Enable settingsfile for multiworld generation 2023-01-22 11:13:40 +01:00
Cody Bailey 5cde789b43 Potential fix for duped HC/AT Maps/Compasses 2023-01-19 20:02:49 -05:00
Cody b3aba607f8 Merge branch 'aerinon:DoorDevUnstable' into DoorDevUnstable 2023-01-19 20:01:29 -05:00
codemann8 3ae853fa23 New non-recursive ER Must-Exit fill algorithm 2023-01-19 08:24:08 -06:00
codemann8 96806f2b5e Merged DR v1.2.0.5 2023-01-19 08:18:22 -06:00
aerinon 4547a0a43b Logic fix for sanc mirror route
Minor updates to customizer
Minor update to new ER (seed duplication issue)
2023-01-18 08:02:32 -07:00
codemann8 34d833b716 Added Lite/Lean support for Fixed Take-Any caves 2023-01-16 07:14:57 -06:00
codemann8 a3edbaf8b9 New non-recursive ER Must-Exit fill algorithm 2023-01-16 07:13:44 -06:00
Cody Bailey fb66ca5607 Add Race Yes/No to spoiler output 2023-01-14 18:27:43 -05:00
codemann8 904ff5ec85 Merged in DR v1.2.0.4 2023-01-13 04:08:10 -06:00
aerinon 22dfeeecca Starting inventory updates
Logic fix for skull woods star tile logic
Standard logic improvement
2023-01-12 15:32:49 -07:00
aerinon 4a58ec1d2c Merge pull request #136 from tcprescott/patch-1
remove hard requirement of tkinter when using CLI
2023-01-09 08:19:44 -07:00
codemann8 e335de8e92 Fixing problems when connecting entrances from outside ER 2023-01-08 03:39:25 -06:00
codemann8 72ba1f1f0d Minor OWG generation error issue 2023-01-08 03:34:38 -06:00
codemann8 87dd31633a Corrected some one-way ledges in definition 2023-01-08 03:32:23 -06:00
codemann8 52a94d5574 Moving S&Q exits to OWR mandatory connections 2023-01-07 21:07:14 -06:00
codemann8 ce5f58ec3c Added Lite/Lean support for Fixed Take-Any caves 2023-01-07 16:59:40 -06:00
Thomas Prescott beb7f8074b remove hard requirement of tkinter when using CLI 2023-01-07 14:58:24 -06:00
codemann8 c98300e2ff Merged in DR v1.2.0.3 2023-01-06 21:37:28 -06:00
aerinon 4d1b5f58c0 Minor naming convention fixed 2023-01-06 16:57:52 -07:00
aerinon 839baee9a4 Minor fix for preset 2023-01-06 15:11:38 -07:00
aerinon 9ca3d179f9 Fix for randomization replication issue 2023-01-06 15:01:24 -07:00
aerinon 8839926a97 Race flag on GUI
Async Doors League presets
Take into account starting inventory with default item pool
2023-01-06 13:56:18 -07:00
aerinon 46903470b5 Fix typo for door "Sewers Key Rat E" 2023-01-03 16:14:42 -07:00
aerinon c2da20207b Fix for experimental inverted + vanilla ER 2023-01-03 16:10:32 -07:00
codemann8 285038c871 Moving S&Q exits to OWR mandatory connections 2023-01-02 07:48:02 -06:00
codemann8 b725774d96 Adding new mirror connections 2022-12-30 06:48:06 -06:00
codemann8 118adabeb1 Changing mirror exits to be dynamically created 2022-12-30 06:17:54 -06:00
codemann8 c6d0df5f4f Modeling Fairy Ascension Mirror Spot more correctly 2022-12-29 23:46:15 -06:00
codemann8 ce93770887 Moved DW regions to follow LW regions 2022-12-29 23:06:32 -06:00
codemann8 4c53ef1f7b Correcting and adding some Inverted Mirror Offset glitches in OWG logic 2022-12-29 22:53:45 -06:00
aerinon 106397b13c Fixed door position typo 2022-12-29 19:39:13 -07:00
codemann8 7fc3929280 Fixed follower logic to use new dynamic mirror connections 2022-12-29 18:44:07 -06:00
codemann8 5fd88fcc78 Minor OWG generation error issue 2022-12-29 18:43:20 -06:00
codemann8 cba3ced501 Added Mirror Offset Glitch exits for Uncle/HC Ledge in Inverted 2022-12-29 04:31:12 -06:00
codemann8 6351ea634b Fixed follower logic to use new dynamic mirror connections 2022-12-27 06:33:25 -06:00
codemann8 3cb90d8221 Combining dynamic exits into one call 2022-12-26 13:09:23 -06:00
codemann8 ca28a9654f Renaming Bombos Tablet Ledge Mirror Spot to match new naming convention 2022-12-26 06:21:45 -06:00
codemann8 32bbb431b4 Small formatting change for settings code 2022-12-26 05:23:36 -06:00
codemann8 a4a2993f99 Fixed flute exits to work correctly in Inverted 2022-12-26 05:22:36 -06:00
codemann8 f6744f93b4 Modeled 'Mirror To Fairy Ascension' correctly 2022-12-26 05:21:59 -06:00
codemann8 196de5a08e Changing mirror exits to be dynamically created 2022-12-26 05:09:27 -06:00
codemann8 245b4744bb Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffleDev 2022-12-22 04:27:59 -06:00
codemann8 0324017c2d Merge remote-tracking branch 'upstream/DoorDevUnstable' into SynthesisOWRMerge 2022-12-22 03:47:30 -06:00
aerinon 8f9f9e03c1 Fixed an issue with certain trap doors
DR Hint reference started
2022-12-21 16:57:25 -07:00
codemann8 6240061a65 Final fixes and reorganization to Inverted Region merging 2022-12-16 18:26:05 -06:00
codemann8 55a91f8d17 Merged in DRUnstable v1.2.0.1 2022-12-16 18:18:07 -06:00
codemann8 a4120e0cb5 Merged in DR v1.2.0.1 2022-12-16 18:14:27 -06:00
aerinon ccb35fd1b1 Small key door limit per dungeon
RainPrevention fix
2022-12-16 15:56:53 -07:00
aerinon 99f92f3d79 Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable 2022-12-16 14:25:42 -07:00
codemann8 616b27ff80 Allowing Stumpy as bunny accessible 2022-12-16 14:42:34 -06:00
aerinon cd8bc9bd57 Merge pull request #134 from arborelia/elial/fix-standard-start
Fix standard + partitioned door shuffle
2022-12-16 08:19:45 -07:00
Elia Robyn Lake 8d12f15d6f Fix standard + partitioned door shuffle
Also includes a fix to the case where it would try to generate a
negative number of bomb doors or dash doors.
2022-12-16 02:33:11 -05:00
codemann8 2d26954422 Final fixes and reorganization to Inverted Region merging 2022-12-15 17:26:02 -06:00
codemann8 86c8fd37e7 Reorganized and renamed regions, rules, and lists 2022-12-14 05:36:36 -06:00
codemann8 f8bba4176b Reorganized and renamed regions, rules, and lists 2022-12-14 04:12:17 -06:00
codemann8 8e08f336d0 Merging Regions and Rulesets 2022-12-13 01:40:44 -06:00
aerinon f0ad711e78 Fix inverted Lean/Lite ER 2022-12-09 16:44:26 -07:00
aerinon 9ab741d481 Documentation updates 2022-12-09 16:04:12 -07:00
codemann8 5ac01f4f35 Merged Inverted/Open ER code and data 2022-12-07 22:16:55 -06:00
codemann8 52edfcdddb Merged Inverted/Open ER code and data 2022-12-07 22:05:48 -06:00
aerinon c42f3c3202 Various typos and fixes 2022-12-07 16:06:31 -07:00
aerinon e67ff4d5dc Completionist fixes 2022-12-07 15:57:51 -07:00
codemann8 bd53400fec Replaced all references of Inverted-variant regions/exits 2022-12-06 22:21:35 -06:00
codemann8 d0ddd49a79 Minor change for code consistency 2022-12-06 02:41:04 -06:00
codemann8 f55bda9534 Only hint Dark Chapel if not Inverted and not Lite/Lean 2022-12-04 01:43:31 -06:00
codemann8 c861cb5b3d Removing the possibility for double AT/GT hints 2022-12-04 01:42:44 -06:00
codemann8 e5afe70bcb Merged DR v1.2.0.0 2022-12-03 01:52:22 -06:00
aerinon 9bf0391e60 Cleanup and generation fix 2022-12-01 16:23:11 -07:00
aerinon 89f467f995 District generation fix 2022-12-01 16:22:15 -07:00
aerinon becba348b9 New goals and rom update 2022-12-01 14:10:10 -07:00
aerinon 1c91eef29a Another known issue 2022-12-01 11:47:54 -07:00
aerinon 8af70ce1ef Version bump 2022-12-01 10:04:13 -07:00
aerinon 249fae39a0 Fix for certain Standard key layouts
Valid key door logic fix
2022-12-01 08:30:27 -07:00
codemann8 b881e431f9 Fixed incorrect bonk drop hint 2022-11-30 10:23:36 -06:00
aerinon f977c06b5e Merge branch 'DoorDev' into Synthesis
# Conflicts:
#	Main.py
#	RELEASENOTES.md
2022-11-29 13:26:32 -07:00
aerinon 6934aedfd8 Logic bug for GT Refill room not requiring boots 2022-11-29 13:22:27 -07:00
aerinon 56ee20c4d2 Fix for incorrect keylock situation
Fix for spoiler playthrough (makes things pretty slow though)
2022-11-29 13:18:34 -07:00
codemann8 af34a76490 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-11-29 02:18:11 -06:00
codemann8 8635994a6c Fixed OWG logic to apply logic in correct world 2022-11-29 02:17:52 -06:00
codemann8 d013b06bd6 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-11-28 16:27:32 -06:00
codemann8 ba95ae3903 Version bump 0.2.11.4 2022-11-28 16:27:16 -06:00
codemann8 acbe38fbec Added improvements to installation steps for simplicity 2022-11-28 16:27:02 -06:00
codemann8 b9bbd5fcd6 Added improvements to installation steps for simplicity 2022-11-28 16:10:58 -06:00
aerinon 1134eb23e7 Added support for various avianart modes
Uncle boots hints
Some key logic re-working unsure if safe
2022-11-28 15:05:39 -07:00
codemann8 81def0dee8 Fixed indentation issues in Readme 2022-11-28 16:00:17 -06:00
codemann8 a646fcd25a Fixed OWG logic to apply logic in correct world 2022-11-28 15:22:42 -06:00
codemann8 d572db1233 Remodeled Pyramid Crack/Fairy to allow OWG entry 2022-11-28 14:38:21 -06:00
codemann8 5316885d46 Fixed OWG logic to apply logic in correct world 2022-11-28 14:37:04 -06:00
codemann8 16862b4afd Fixed OWG logic to apply logic in correct world 2022-11-28 14:35:17 -06:00
codemann8 3ffe137f57 Modeled South Portal Area correctly for OWG prep 2022-11-28 14:24:32 -06:00
codemann8 217fcc14da Modeled South Portal Area correctly for OWG prep 2022-11-27 14:11:29 -06:00
codemann8 771795f521 Removal of unused deprecated light cone logic 2022-11-23 16:29:05 -06:00
codemann8 2c96f31bc8 Removal of unused deprecated light cone logic 2022-11-21 15:22:05 -06:00
codemann8 21b7d6fd8a Created pseudoitem for TR entry 2022-11-21 12:56:00 -06:00
codemann8 5effa39b40 Giving chickens a base price for shops 2022-11-21 11:18:31 -06:00
codemann8 a136f1dd8e Created pseudoitem for TR entry 2022-11-21 11:15:29 -06:00
codemann8 09f81d8b69 Removal of indirect connections 2022-11-21 11:10:10 -06:00
codemann8 4986821e92 Created pseudoitem for TR entry 2022-11-21 11:09:12 -06:00
aerinon 742d7db650 Merge pull request #133 from jdlyga/DoorDev
Updated Github actions yml to fix Node.js 12 deprecation
2022-11-21 09:43:41 -07:00
codemann8 e0a7fdc4f0 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-11-19 17:03:44 -06:00
codemann8 c886f529ee Version bump 0.2.11.3 2022-11-19 17:03:24 -06:00
codemann8 7e7b29ac27 Fixed copy_world_premature error in multiworld 2022-11-19 16:55:48 -06:00
codemann8 58c1a0f4d1 Corrected formatting in Changelog 2022-11-18 01:04:58 -06:00
codemann8 e221046b96 Corrected formatting in Changelog 2022-11-18 01:04:28 -06:00
codemann8 d390047258 Removing most entrance hints for Lite/Lean ER 2022-11-13 16:29:20 -06:00
codemann8 ab409baec1 Fix incorrect references to world.shuffle_ganon 2022-11-13 16:28:23 -06:00
codemann8 ff6bbbf1fc Including Links House entrance if LH is included in ER shuffle 2022-11-13 16:17:18 -06:00
codemann8 5c8a5b3e45 Including GT entrance if Ganon is included in ER shuffle 2022-11-13 16:03:39 -06:00
Joe Lyga 10677b4bf1 Updated Github actions yml to fix Node.js 12 deprecation
Several actions have been updated to avoid the Node.js 12 deprecation:
  actions/checkout
  actions/setup-python
  mad9000/actions-find-and-replace-string
  actions/upload-artifact
  actions/download-artifact
2022-11-13 16:49:58 -05:00
aerinon fa75d2b4e9 Possible fix for standing items weirdness
Generation fix for Bumper Cave
Chaos door type fix
Minor fix for universal keys
Relaase notes update
2022-11-10 14:14:54 -07:00
codemann8 590875b356 Remove the sprite spawn delay when bonking prizes 2022-11-08 18:53:07 -06:00
codemann8 8ae32fd76e Add Old Man to bunny accessible locations 2022-11-07 18:35:08 -06:00
codemann8 0a96b518ae Consolidating Old Man pathing in spoiler log 2022-11-07 18:08:36 -06:00
codemann8 af6468961e Added Old Man escorting to pathing logic
Removing mirror portal re-entry
2022-11-07 16:55:26 -06:00
codemann8 026bb642c6 Added Old Man escorting to pathing logic 2022-11-07 16:43:45 -06:00
codemann8 56e26875fa Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-11-07 11:00:12 -06:00
codemann8 4872f78b94 Version bump 0.2.11.2 2022-11-07 10:59:56 -06:00
codemann8 371fe9f24f Adding pre-aga Farmable locations to optional location list 2022-11-05 22:18:11 -05:00
codemann8 1756d22b5d Fixed Bonk Drop Locations in Districts 2022-11-05 21:57:15 -05:00
codemann8 757fee8220 Fixing spoiler log suppression for OW locations 2022-11-05 21:56:40 -05:00
codemann8 47b92997df Adding missing OWG exits to classification list 2022-11-05 18:27:44 -05:00
codemann8 f762d982a2 Mixed Districts Initial Implementation 2022-11-05 18:26:52 -05:00
codemann8 50c40cedd5 Splitting up Stone Bridge region in prep for Mixed Districts 2022-11-04 11:14:08 -05:00
codemann8 61e44adb15 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-11-03 19:36:38 -05:00
codemann8 6fc4b04635 Yet another copy_world_premature fix 2022-11-03 19:36:08 -05:00
codemann8 f24e017402 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-11-03 13:47:55 -05:00
codemann8 a901234d98 Version bump 0.2.11.1 2022-11-03 13:47:32 -05:00
codemann8 254df9703b Improved copy_world_premature 2022-11-03 13:24:19 -05:00
codemann8 df897c53ff Bandaid fix for universal key error 2022-11-03 12:35:06 -05:00
codemann8 2e72a306e7 Updated Readme 2022-11-01 20:39:45 -05:00
codemann8 46786ca489 Renamed Tile Swap to Tile Flip 2022-11-01 20:16:01 -05:00
codemann8 35d9b48cad "Should" be a better copied world
Prior to this, it was as close to DR as could be, but I'm pretty sure this is more correct
2022-11-01 17:06:11 -05:00
codemann8 06216d977b Potential key lock logic fix 2022-11-01 16:14:01 -05:00
codemann8 29a1e1fc12 Revert "Aerinon's keylogic fix for Vanilla Mire case"
This reverts commit 7b25e1931f.
2022-11-01 16:09:24 -05:00
aerinon 34d77653d3 More robust sweep_for_events (supports events that later become unreachable)
Minor fix for AllowSmall key logic
2022-11-01 16:08:56 -05:00
aerinon cb4cf65c9c More robust sweep_for_events (supports events that later become unreachable)
Minor fix for AllowSmall key logic
2022-11-01 15:05:28 -06:00
codemann8 9d46aaec58 Adding pre-aga Farmable locations to optional location list 2022-11-01 15:42:10 -05:00
codemann8 45065134cd Improved OWEdges in copy_world 2022-11-01 15:41:39 -05:00
codemann8 7b25e1931f Aerinon's keylogic fix for Vanilla Mire case 2022-11-01 15:30:23 -05:00
codemann8 dadf88bcda Fixed sweep_for_events to better detect new locations 2022-11-01 15:26:11 -05:00
codemann8 3e17b61428 Improvement to copy_world 2022-11-01 12:36:00 -05:00
codemann8 734740a0a7 Improvement to copy_world_premature 2022-11-01 11:45:43 -05:00
codemann8 e4d760a00c Improvement to copy_world_premature 2022-10-31 16:13:52 -05:00
codemann8 4639db8b2a Marking light/dark regions after OWR 2022-10-31 16:11:56 -05:00
codemann8 246006d394 Merged light/dark world marking 2022-10-31 14:10:03 -05:00
codemann8 8919729262 Merged light/dark world marking 2022-10-31 13:43:18 -05:00
codemann8 e83d0fa8e4 Bumper cave fix 2022-10-30 16:04:53 -05:00
codemann8 d532a579e8 Changed copy_world_limited to premature and made it only for one player 2022-10-30 15:52:40 -05:00
codemann8 14ca81af6b Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-10-29 15:50:51 -05:00
codemann8 6d434918e1 Updated Readme 2022-10-29 15:50:35 -05:00
codemann8 9d7ef44380 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-10-29 11:35:43 -05:00
codemann8 5c14a3f245 Version bump 0.2.11.0 2022-10-29 11:35:18 -05:00
codemann8 4885ce3e4c Updated Readme 2022-10-29 11:34:02 -05:00
codemann8 ae1a775248 Reordering Crossed options to have Grouped as first option 2022-10-29 11:30:10 -05:00
aerinon 5d294f91f0 Bumper cave fix 2022-10-29 07:04:41 -05:00
codemann8 417609eb8d Increasing allowance on infinite loop detection 2022-10-28 13:51:10 -05:00
aerinon 9fafa8981e Big Key Door fix for when big key double sided is off
Fix for basic issues - key total doesn't change
Potential key lock logic fix
2022-10-28 12:47:43 -06:00
codemann8 bba486f526 Changing Lite ER to place Old Man House in any world per Inverted 2.0 changes 2022-10-28 13:19:49 -05:00
codemann8 5b7530c12e Fixed Lite ER 2022-10-28 13:16:48 -05:00
codemann8 19176cea72 Making crossworld ER modes fill DW inaccessible entrances first rather than combined 2022-10-28 12:06:53 -05:00
codemann8 c6eb0d80e7 Fixed ER bug causing inaccessible entrances to not get resolved 2022-10-28 12:04:14 -05:00
aerinon e2392ef237 Merge branch 'Customizer' into Synthesis 2022-10-28 08:56:15 -06:00
aerinon 82965ac734 Big Key fix for dungeons with only big chests
Door pairing issues
Minor gui error
2022-10-28 08:56:06 -06:00
aerinon bd619ff2ef Bumper cave fixes for ES2 2022-10-27 15:48:04 -06:00
aerinon 1167f2b1ba Bumper cave fix for new entrance shuffle 2022-10-27 15:23:58 -06:00
aerinon 0783f97b57 Merge branch 'DoorDev' into Synthesis
# Conflicts:
#	Main.py
#	README.md
#	RELEASENOTES.md
2022-10-27 15:22:44 -06:00
aerinon 4ab0a40c45 Bumper cave fix
Pottery coloring updated
2022-10-27 13:56:37 -06:00
aerinon 4f2fed48d7 Big key door fix
Some generation fixes (need to look at pre-validate some more)
Bumped up escape assist values in non-basic shuffles
2022-10-26 16:46:32 -06:00
codemann8 311b002b95 Fixed fake world handling for IB transitions 2022-10-26 07:54:33 -05:00
aerinon 57c479e1c2 Overworld enemizer work 2022-10-25 09:14:19 -06:00
codemann8 8517d70eba Moving OWG connection creation to after Mixed OWR but before Crossed/Layout OWR 2022-10-24 20:22:20 -05:00
codemann8 1912504c93 Moving OWG connection creation to after Mixed OWR but before Crossed/Layout OWR 2022-10-24 20:17:44 -05:00
codemann8 9b2d13bcd0 Fixed Rupee/Bomb logic in playthru 2022-10-24 19:36:48 -05:00
codemann8 20e99a27c5 Fixed Rupee/Bomb logic in playthru 2022-10-24 19:34:35 -05:00
codemann8 cf43762799 Fixed Murahduhla freeze issue 2022-10-24 17:57:10 -05:00
codemann8 53c6f2e647 Removing old Inverted 1.0 assumptions 2022-10-24 17:49:58 -05:00
codemann8 7546251911 Added Mixed OWG Logic 2022-10-24 17:48:25 -05:00
codemann8 f28fc45a46 Added Mixed OWG Logic 2022-10-24 16:55:44 -05:00
codemann8 2c2ed5d5af Adding missing shuffles for Simple Dungeon ER shuffle 2022-10-22 09:23:39 -05:00
codemann8 111ce66962 Fixed glitched fake world and OOB behavior 2022-10-22 09:22:26 -05:00
codemann8 d8fc0ff752 Minor simplification 2022-10-20 10:31:24 -05:00
codemann8 6e3b4a6b2d Cato fixes for Free Terrain transitions 2022-10-20 10:29:59 -05:00
codemann8 dd6d8e508f Replaced bomb/rupee logic with pseudo locations/items 2022-10-11 07:12:52 -05:00
codemann8 fca4d0424e Merge pull request #11 from Catobat/Terrain 2022-10-08 19:04:49 -05:00
Catobat 0c53fc8519 Add Free Terrain mode and terrain rules 2022-10-09 01:23:47 +02:00
aerinon 1529ec9473 First pass on boss randomization 2022-10-06 14:17:12 -06:00
codemann8 af8349fbc3 Fixed issue with OWG access to Dark Central Cliff portal 2022-10-05 22:39:54 -05:00
codemann8 bb2e7d198d Moved Cave 45 Ledge Drop connection to ow_connections 2022-10-05 03:56:33 -05:00
codemann8 1ef53e4317 Moved Inverted Ice Portal to its correct logical region 2022-10-05 02:54:49 -05:00
codemann8 680a9f14fe Fixed bunny logic bug with rupee/bomb logic 2022-10-04 21:32:23 -05:00
aerinon a5fc4dd7a6 Rules changes
Implement Big Magic/Chicken/Fairy spawn items
2022-10-03 16:12:05 -06:00
aerinon b71c7aa2b4 Underworld dropshuffle 2022-09-30 15:38:35 -06:00
aerinon 3c0f6ca0e6 UW Enemizer work
Refinements for data table support
2022-09-27 14:40:43 -06:00
aerinon 037a9479d8 UW Enemizer Work 2022-09-26 14:07:41 -06:00
codemann8 be1e17d9ba Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-09-19 01:19:45 -05:00
codemann8 1fd1f9ca5c Fixed issue with generating multiworlds 2022-09-19 01:19:22 -05:00
codemann8 0c8f71a87b Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-09-18 17:55:37 -05:00
codemann8 635fd10a8c Version bump 0.2.10.1 2022-09-18 17:55:17 -05:00
aerinon 5b4bcc02d4 Finished region mapping 2022-09-16 15:49:16 -06:00
aerinon a9806ec40f Minor doc update 2022-09-16 13:31:26 -06:00
aerinon 5137826837 Fix github build? 2022-09-16 13:00:15 -06:00
aerinon 303600f198 Merge branch 'DoorDevUnstable' into DoorDev
# Conflicts:
#	Main.py
#	RELEASENOTES.md
#	Rules.py
2022-09-16 12:08:57 -06:00
aerinon 4f5a41d040 Change customizer item pool to warn of missing items 2022-09-16 10:41:18 -06:00
aerinon 4e7632c16a Changes for enemy regions 2022-09-16 10:38:36 -06:00
aerinon fd17c2576d Enemy drops work 2022-09-16 10:20:54 -06:00
aerinon 30833152f6 Minor decoupled adjustment 2022-09-13 15:54:06 -06:00
codemann8 f393bad008 Added Menu Speed to example mystery yaml 2022-09-09 20:40:37 -05:00
aerinon db43ce8d15 Fix keyshuffle 2022-09-08 16:24:48 -06:00
aerinon 9caea3fc85 Merge branch 'DoorDevUnstable' into Synthesis
# Conflicts:
#	CLI.py
#	Main.py
#	Rom.py
#	data/base2current.bps
2022-09-08 13:47:38 -06:00
codemann8 7adb75cfb9 Added Unique Boss Shuffle to mystery example yaml 2022-09-08 13:50:38 -05:00
codemann8 98c345f7a1 Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffleDev 2022-09-07 22:44:54 -05:00
codemann8 c7610188ef Merged DR v1.0.1.3 2022-09-07 22:44:11 -05:00
aerinon 3227ffee14 Missed a change 2022-09-07 21:30:57 -06:00
aerinon 1e4b857dab Update default setting to vanilla 2022-09-07 16:55:46 -06:00
aerinon 4ce85a9f2d Couple minor issues - let a door not be dead in higher intensity, slightly better reporting 2022-09-07 16:54:02 -06:00
aerinon c298b392d0 Fix for rain prevented doors fouling up key doors 2022-09-07 16:53:52 -06:00
aerinon e2b9735600 Rain prevention fix for keydoors (plus test case)
Couple fixes for standard throne
2022-09-07 16:50:44 -06:00
aerinon 5850edfbe6 Couple minor issues - let a door not be dead in higher intensity, slightly better reporting 2022-09-07 16:49:47 -06:00
codemann8 37fc55cd2a Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-09-05 13:41:06 -05:00
codemann8 f74a64d0b8 Avoid bunny rules in limited copy world 2022-09-05 12:46:56 -05:00
codemann8 9a62841557 More descriptive error for failed dungeon prize placement 2022-09-05 12:46:03 -05:00
codemann8 3b0310e487 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-09-04 22:23:58 -05:00
codemann8 0030e1bf1d Version bump 0.2.10.0 2022-09-04 22:23:35 -05:00
codemann8 a9ed28c59a Overhauled how map checks display dungeon prizes 2022-09-04 14:09:54 -05:00
codemann8 a34f177e13 Merge pull request #10 from Catobat/TileSwapFix 2022-09-02 16:10:44 -05:00
Catobat d6ae8b9fab Counting is hard 2022-09-02 22:51:59 +02:00
Catobat 2bd89bc367 Fix for Digging Game screens in Grouped 2022-09-02 22:47:05 +02:00
Catobat 43130d0578 Fix tile swap parity check in Keep Similar 2022-09-02 22:41:25 +02:00
aerinon 4a4598a9b5 Merge branch 'DoorDevUnstable' into Synthesis 2022-09-02 13:12:36 -06:00
aerinon 9cca25bdc4 Modified key fix for Unstable 2022-09-02 13:11:03 -06:00
aerinon c10a791ed6 Important key fix for logic placment 2022-09-02 13:10:20 -06:00
aerinon 4e418f4218 Important key fix for logic placment 2022-09-02 13:10:03 -06:00
aerinon 87834986d4 Retro break up of various options 2022-09-02 13:09:39 -06:00
aerinon af4f8e5b4b Flute mode
And some odd fixes
2022-09-01 13:59:26 -06:00
aerinon 3975c6c65d Merge branch 'DoorDevUnstable' into Synthesis
# Conflicts:
#	TestSuite.py
2022-09-01 11:38:02 -06:00
codemann8 03bae603e7 Merged DR v1.0.1.2 2022-09-01 03:40:03 -05:00
aerinon 2c78170579 Pyinstaller 5.0+ build fix 2022-08-31 16:16:20 -06:00
aerinon 258d66fb5c Minor standard fix, fix for test suite, made one error less annoying 2022-08-31 14:10:02 -06:00
aerinon 4aff460b22 Fix for crossed doors with ambrosia
Fix for ER + OWG in crossed doors
Fix for Small Key shuffle
2022-08-30 13:51:12 -06:00
codemann8 b873e80034 Merged DR v1.0.1.2 2022-08-29 19:38:06 -05:00
aerinon 45395e9b15 Legacy pot shuffle fix 2022-08-26 16:08:18 -06:00
aerinon ae0efad830 More inverted pot fixes 2022-08-26 15:48:07 -06:00
aerinon 3e6f2bb79b Fixed issue with small key shuffle when big keys aren't 2022-08-26 15:20:53 -06:00
aerinon 55364c071a Fixed issue with inverted and certain pottery settings. 2022-08-26 14:42:06 -06:00
codemann8 453532520a Merged DR v1.0.1.2 2022-08-25 16:18:24 -05:00
aerinon 16d7ce5e76 Minor issue with new Mire Falling Bridge and a miss in dungeon gen for dungeon pools. 2022-08-25 08:59:44 -06:00
codemann8 a24a2e4254 Changed Castle Gate to only require mirror when screen not swapped 2022-08-25 00:30:32 -05:00
codemann8 01de92d10f Chickens now spawn on same layer as Link 2022-08-25 00:27:38 -05:00
aerinon 7e5542f3a2 Merge branch 'DoorDevUnstable' into Synthesis
# Conflicts:
#	Mystery.py
2022-08-24 16:27:18 -06:00
aerinon 0dfdbfd39e Removed "good bee" from Mothula logic
Fixed an issue with Mystery generation and windows file path
2022-08-24 15:00:48 -06:00
aerinon 7be5cc1a6b Merge branch 'Customizer' into Synthesis
# Conflicts:
#	Main.py
#	RELEASENOTES.md
#	Rom.py
#	data/base2current.bps
2022-08-24 14:29:10 -06:00
aerinon 152c383233 Merge branch 'DoorDevUnstable' into Customizer
# Conflicts:
#	Bosses.py
#	ItemList.py
#	Main.py
#	Mystery.py
#	RELEASENOTES.md
#	Rom.py
#	data/base2current.bps
2022-08-24 13:38:59 -06:00
aerinon 6b369b68b7 Update lite/lean with pottery options. Houses and caves with pots are shuffled in the ER pool if the pottery setting turns that on. 2022-08-24 13:29:14 -06:00
aerinon 5d419210af Fix a bank conflict with OWR
Release notes and version bump
2022-08-24 13:18:01 -06:00
aerinon 0d9d6f2ceb Copy world needs to copy location type 2022-08-24 13:10:57 -06:00
aerinon 262b36cac6 Custom yaml properly record interior doors that are key doors 2022-08-24 13:10:32 -06:00
aerinon 32305a2202 Copy world needs to copy location type 2022-08-24 12:53:04 -06:00
codemann8 56072e6094 Creating a separate copy_world_limited for OWR/ER purposes 2022-08-23 18:39:05 -05:00
codemann8 34c9972c74 Suppressing Inaccessible Regions debug output 2022-08-23 18:20:23 -05:00
codemann8 a7e9d6d43f Creating a separate copy_world_limited for OWR/ER purposes 2022-08-23 18:19:17 -05:00
aerinon 9c612b6c00 Minor edit to when pyramid hole auto pre-opens 2022-08-23 16:43:27 -06:00
aerinon 0d5ea19ecd Fix for small key fill 2022-08-23 15:52:59 -06:00
codemann8 270d10b698 Possible fix for SK placement errors 2022-08-23 16:52:43 -05:00
aerinon 5b8b0cb7f8 Mire Falling Bridge logic refinement for possible trap door movement 2022-08-23 15:27:22 -06:00
aerinon 3e7dfaf856 Fix Key Rat region 2022-08-23 15:06:36 -06:00
codemann8 c9823f28af Moving Aerinon's room mod somewhere else 2022-08-22 23:01:38 -05:00
codemann8 21b951433e Undoing absolutely no change whatsoever so help me God 2022-08-22 22:04:29 -05:00
codemann8 76c1fef4b6 Absolutely no change whatsoever so help me God 2022-08-22 22:01:48 -05:00
codemann8 3c7d3ed36f Merged DR v1.0.1.1 2022-08-18 20:59:29 -05:00
codemann8 f2d7cdca1b Changed Standard+Inverted to include Sanc screen in fixed Std screens 2022-08-17 14:38:19 -05:00
codemann8 6455cad361 Fixed Mystery to detect Windows Paths over URLs 2022-08-17 14:09:02 -05:00
aerinon a5354f1f30 Spoiler bug 2022-08-12 13:50:04 -06:00
codemann8 e5cff2e773 Fixed so Lean ER + Inverted Dark Chapel start is guaranteed to be in DW 2022-08-12 01:54:20 -05:00
codemann8 3aa97ee8bc Fixed early rupee money balancing to make item free if <20 rupees available 2022-08-12 01:53:13 -05:00
aerinon c3dcd56992 Some fixes sent by Catobat 2022-08-11 16:37:15 -06:00
aerinon 07b03f78d6 Rom update 2022-08-11 16:07:11 -06:00
aerinon 21456b5c90 Merge branch 'Customizer' into Synthesis
# Conflicts:
#	BaseClasses.py
#	Rom.py
#	data/base2current.bps
2022-08-11 16:06:50 -06:00
aerinon 1168273e43 Merge branch 'DoorDevUnstable' into Synthesis
# Conflicts:
#	Bosses.py
#	Main.py
#	Rom.py
#	data/base2current.bps
2022-08-11 15:43:33 -06:00
aerinon 5dd9403afd Correct rom for tavern work 2022-08-11 15:38:15 -06:00
aerinon b2ae92a451 Merge branch 'Tavern' of github.com:Catobat/ALttPDoorRandomizer into Catobat-Tavern
# Conflicts:
#	BaseClasses.py
#	Rom.py
#	data/base2current.bps
Note: rom is not correct
2022-08-11 15:37:19 -06:00
aerinon 2ed0a80609 Fix for pot items to not reload with the supertile
Key distribution change
Unique boss shuffle make gt bosses also unique
Removed text color in hints due to bug
2022-08-11 15:25:09 -06:00
aerinon 32714b4c6a Fix for colorized pots in "dark desert hint" aka mire storyteller 2022-08-05 16:48:34 -06:00
aerinon e167811d34 Merge branch 'DoorDevUnstable' into Synthesis
# Conflicts:
#	Main.py
#	Mystery.py
#	RELEASENOTES.md
#	Rom.py
#	data/base2current.bps
2022-08-05 14:06:01 -06:00
aerinon 09fbdc46ca Finish bomb/dash doors
Lots of minor fixes
Fixed a few existing bugs
2022-08-05 14:01:19 -06:00
codemann8 85fe7d1d04 Fixed bomb/rupee farming to not include caves if cave pots are shuffled 2022-08-03 17:52:22 -05:00
codemann8 74912e3bed Fixed issue with flute shuffle placing spots not in pool 2022-08-02 10:56:09 -05:00
codemann8 bc4b16d910 Creating a separate copy_world_limited for OWR/ER purposes 2022-08-02 10:34:15 -05:00
codemann8 e847b21360 Creating a separate copy_world_limited for OWR/ER purposes 2022-08-02 00:14:08 -05:00
codemann8 64c65f680f Creating a separate copy_world_limited for OWR/ER purposes 2022-08-01 23:48:54 -05:00
codemann8 ddba1cd813 Creating a separate copy_world_limited for OWR/ER purposes 2022-08-01 20:54:29 -05:00
codemann8 8a5a092522 Adding attribute to world object to indicate whether world is a copy 2022-08-01 19:42:54 -05:00
codemann8 7fecbee3bb Removed 'allowed' Crossed OWR option 2022-08-01 15:51:33 -05:00
codemann8 5769713b51 Version bump 0.2.9.1 2022-07-31 23:21:29 -05:00
codemann8 ae9ba04f24 Version bump 0.2.9.1 2022-07-31 23:05:38 -05:00
codemann8 baaa6fcfc7 Prevent unwanted 'allowed' Crossed OWR option 2022-07-31 22:55:36 -05:00
codemann8 57209296e8 Necessary ROM Fixes
- Changed Inverted MSU-1 to trigger opposite world track changes
- Fixed mirror portal issue in Inverted
- Fixed TR Peg Puzzle issue
2022-07-31 22:35:00 -05:00
codemann8 2c9efecd38 Ensure GT Bosses are unique in Unique Boss Shuffle 2022-07-31 21:56:21 -05:00
codemann8 578c4d8065 Lite/Lean now considers Cave Pottery options 2022-07-30 09:35:25 -05:00
codemann8 ea26311072 Version bump 0.2.9.0 2022-07-29 22:39:47 -05:00
codemann8 8721858e2c Version bump 0.2.9.0 2022-07-29 22:37:38 -05:00
codemann8 a9fa2a326f Scaling infinite loop check to number of players 2022-07-29 21:35:27 -05:00
codemann8 383a2a274d Catching infinite loop at balance_money_progression 2022-07-29 21:33:10 -05:00
codemann8 a36d65ef81 Adding sprite patch for Apples so they don't prevent kill rooms from opening 2022-07-29 21:29:32 -05:00
codemann8 eca58ebcca Adjusted sprite alignment when coming from a chest 2022-07-29 16:45:21 -05:00
codemann8 1e0a046151 Fixed 4 digits collection rate in credits issue 2022-07-29 16:41:29 -05:00
codemann8 fcd871ae43 Fixed Multiworld support for Bonk Drop shuffle 2022-07-29 12:39:00 -05:00
codemann8 e218b8dc97 Reserving bonk drop slot for Murahdahla tree 2022-07-28 19:52:32 -05:00
codemann8 abdf4cd258 ROM Fixes
- Fixed Aga2 check on Ganon vulnerability
- Fixed disappearing mirror portals in Inverted+CrossedOWR
2022-07-28 16:05:00 -05:00
codemann8 ceff7688c4 Fixed issue with bonk drops getting enabled in non-bonk drop 2022-07-27 18:02:42 -05:00
codemann8 5ded3be276 Rename Drop Shuffle to Enemy Drop Shuffle in spoiler 2022-07-27 18:01:56 -05:00
codemann8 fb064b5950 Guarantee Big Magic on non-Aga Bonk Location 2022-07-27 08:24:34 -05:00
codemann8 0da1ec78f6 Fixed Aga rules on Bonk Locations? 2022-07-26 22:57:42 -05:00
codemann8 ce269daa88 Improvements to Bonk Drop Shuffle
- Trees revert color when collected
- Fixed issue with sprites getting stuck in rocks
2022-07-26 21:06:09 -05:00
aerinon 4267c2dde5 Minor bug in intensity 3, pottery setting not drop shuffle for Desert Tiles 2. 2022-07-25 12:13:50 -06:00
codemann8 b877ddb4d7 Making file output prefix always OR 2022-07-24 21:49:28 -05:00
codemann8 79448be9d4 Fixed error with pot rule in OWR accessibility check 2022-07-24 21:35:47 -05:00
codemann8 e1cc74c05c Suppressing meta output if outputting spoiler 2022-07-24 21:27:40 -05:00
codemann8 3983bf347f Fixed Namespace error in Mystery with Bonk Drop option 2022-07-24 20:57:58 -05:00
codemann8 9ef8f54e5b Added Multiworld Support for Bonk Drops 2022-07-24 16:21:21 -05:00
codemann8 a97ee6c57a Implemented Bonk Drop Shuffle 2022-07-24 16:19:26 -05:00
codemann8 58afaa52e8 Fixed issue with bonk prize on screen 2B 2022-07-24 14:56:25 -05:00
codemann8 afcec5d0dc Fixed wrong loot ID for 5 arrows items 2022-07-24 13:56:36 -05:00
codemann8 db15fdfbdc Shifted AddReceivedItemExpanded data table down, will affect people patching itemgfx 2022-07-24 13:49:28 -05:00
codemann8 97455dc140 Implemented Bonk Drop Shuffle 2022-07-24 12:50:37 -05:00
codemann8 a5729b51a2 Adding new option for Bonk Drop Shuffle 2022-07-24 12:42:08 -05:00
codemann8 360a61a65c Fixed issue with pre-opened pyramid when it shouldn't be 2022-07-22 10:57:28 -05:00
codemann8 ce9cb8de26 619 2022-07-22 10:55:35 -05:00
codemann8 fb02ae0159 Adding Zelda Delivered rule to Agahnim 1 rules if Standard 2022-07-21 10:46:56 -05:00
codemann8 79f35582e8 Adding Zelda Delivered rule to Agahnim 1 rules if Standard 2022-07-20 21:57:06 -05:00
codemann8 349b6df74c Version bump 0.2.8.0 2022-07-12 02:03:32 -05:00
codemann8 77451e4194 Version bump 0.2.8.0 2022-07-12 02:01:29 -05:00
codemann8 5e0ec96c66 Fixed issue with playthrus for Murahdahla+Beatable 2022-07-12 01:32:16 -05:00
codemann8 359b283b94 Suppress playthru for nologic 2022-07-11 17:47:16 -05:00
codemann8 426d5d3e84 Fixed beatable only check in OWR validation 2022-07-11 17:45:09 -05:00
codemann8 ae271b0e73 Removing some permament negative effects of using copy_world 2022-07-11 17:44:18 -05:00
codemann8 91f7bc8cef Suppress playthru for nologic 2022-07-11 17:40:08 -05:00
codemann8 10caf09492 Fixed issue with filename always outputting DR, not OR 2022-07-09 10:34:11 -05:00
codemann8 51535d7a10 Added Zelda Delivered rule to Flute usage if Standard 2022-07-08 22:12:59 -05:00
codemann8 673ac9ac23 Reverted some code to fix Trinity 2022-07-08 16:17:10 -05:00
codemann8 92bc88bd41 Adapted changes to pre-set overworld flags to new initial sram system 2022-07-08 12:25:54 -05:00
codemann8 aec7b7077d Adapted changes to pre-set overworld flags to new initial sram system 2022-07-08 12:13:34 -05:00
codemann8 df86503941 Merged in DR v1.0.1.0 2022-07-08 10:59:00 -05:00
aerinon f06e7c7fd3 Merged in Volatile work 2022-07-07 14:20:41 -06:00
aerinon d9f0e2a7b6 Options added for door_type_mode and new partitioned mode 2022-07-06 10:06:29 -06:00
aerinon 04fc0b442d Hotfix for enemizer and pot substitutions 2022-06-30 11:51:34 -06:00
aerinon 2f821632e1 Spelling and grammar 2022-06-29 13:01:34 -06:00
aerinon d488df6d18 Pot substitutions for certain items 2022-06-29 12:58:10 -06:00
aerinon 2e9d132985 Large refactor underway.
Wrote new main method
Implemented trap door shuffle to some degree
Still needs the other types
2022-06-28 13:05:38 -06:00
aerinon b13e15f999 Merge branch 'DecoupledDoors' into Synthesis
# Conflicts:
#	BaseClasses.py
#	DoorShuffle.py
2022-06-23 10:59:44 -06:00
aerinon b426d47a0a Merge branch 'Customizer' into StandardThrone
# Conflicts:
#	Main.py
2022-06-23 10:38:18 -06:00
aerinon 8ec852a737 Merge branch 'DoorDevVolatile' into Customizer
# Conflicts:
#	Main.py
2022-06-23 10:37:38 -06:00
aerinon fe814005d6 Waterfall of Wishing logic exit fix revised 2022-06-23 10:36:51 -06:00
aerinon 1972500e31 Merge branch 'Customizer' into StandardThrone
# Conflicts:
#	DungeonGenerator.py
#	Main.py
#	RELEASENOTES.md
2022-06-22 13:08:38 -06:00
aerinon c487634d3d Merge branch 'DoorDevVolatile' into StandardThrone
# Conflicts:
#	Main.py
#	RELEASENOTES.md
#	Rom.py
#	data/base2current.bps
2022-06-22 10:55:55 -06:00
aerinon 64048ba58d Merge branch 'DoorDevVolatile' into Customizer
# Conflicts:
#	Main.py

Also fixed a bug with lite/lean
2022-06-22 10:53:06 -06:00
aerinon 377989d406 Update release notes and version 2022-06-22 10:43:39 -06:00
aerinon f5307dacc1 Waterfall logic fix. Inverted seems to have been fixed years ago 2022-06-17 15:12:37 -06:00
aerinon 8d140c9bf8 Spoiler refactor 2022-06-17 14:36:51 -06:00
aerinon 31bee77c4c Mirror scroll behavior during escape altered. Pray I do not alter it further 2022-06-16 12:35:16 -06:00
aerinon b938bef8fa Check package requirements before importing them 2022-06-16 10:46:53 -06:00
aerinon 4397492aca Fix follower despawn when entering maiden's cell and she's not there due to Blind not being the boss 2022-06-16 06:58:41 -06:00
aerinon 8a6b05fe8f Merge branch 'DoorDevVolatile' into Customizer
# Conflicts:
#	Main.py
#	Rom.py
2022-06-15 16:56:57 -06:00
aerinon 32aebb2ad1 Pottery fix for item counting because of shop conflict 2022-06-15 16:55:20 -06:00
aerinon 25905fe3f3 Capitalization fixes
Highlight part of the text in red (experimental)
2022-06-14 13:22:24 -06:00
aerinon 5dce2daa0b Standard throne room changes 2022-06-14 12:29:57 -06:00
Catobat 24e919c4a7 Fix Insanity 2022-06-13 20:51:11 +02:00
Catobat 6e9d949439 Shuffle Back of Tavern 2022-06-13 20:38:24 +02:00
codemann8 eff94e0c16 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-06-10 17:54:15 -05:00
codemann8 d9d7a2afab Version bump 0.2.7.3 2022-06-10 17:53:29 -05:00
codemann8 483c32365b Minor capitalization 2022-06-10 17:46:05 -05:00
aerinon e9433e56c0 Missing player 2022-06-07 08:12:13 -06:00
aerinon 96f25d15a9 Settings code fix 2022-06-07 08:10:19 -06:00
codemann8 5cc809a93c Added new DPad invert options for just L/R and just U/D 2022-05-28 22:57:41 -05:00
aerinon 14571508ae Init work on decoupling doors 2022-05-25 10:31:20 -06:00
aerinon 3052bd7585 Spelling 2022-05-25 10:28:15 -06:00
aerinon ac651253fe Fix a couple bugs on generation 2022-05-24 11:07:06 -06:00
aerinon e40c4290c9 Fix yaml parsing 2022-05-24 10:18:59 -06:00
aerinon 041443be3d Fix windows absolute path parsing 2022-05-24 10:18:47 -06:00
aerinon 9a6b7c624d Minor fix for mystery 2022-05-24 10:18:23 -06:00
aerinon dbb69359aa Fix customizer GUI yaml selection 2022-05-24 10:17:31 -06:00
aerinon 8d5fe30889 Fix wording 2022-05-24 10:16:36 -06:00
aerinon 8fd010985f Merge branch 'DoorDevVolatile' into Customizer
# Conflicts:
#	DoorShuffle.py
#	ItemList.py
#	Main.py
2022-05-24 10:09:36 -06:00
aerinon 752c063a9a Mailmap fix 2022-05-24 10:00:40 -06:00
aerinon 42c6e18655 Mailmap 2022-05-24 09:36:52 -06:00
aerinon 3df1072f0a Fix bombbag bug 2022-05-24 09:31:12 -06:00
aerinon f9fdd6ede9 Note for fix 2022-05-24 09:29:41 -06:00
aerinon 481516cc4c SSL not verified for alttpr.com/sprites 2022-05-24 09:29:27 -06:00
aerinon 6076441fbf Fix some interior doors during key door identification as missing one reachable side 2022-05-24 09:29:17 -06:00
codemann8 0c32cac4f8 Fixed bush crab logic to only allow in enemizer 2022-05-23 13:34:06 -05:00
codemann8 d5f75ff7c5 Updated tree pull logic to also include ability to kill most things 2022-05-22 15:53:26 -05:00
codemann8 5eb04bc41f Added bush crabs to rupee farm logic 2022-05-22 15:53:13 -05:00
codemann8 592d24cbf8 Updated ROM build 2022-05-21 21:03:21 -05:00
codemann8 e3b9348977 Updated ROM build
-Fixed mirror portal bugs from Crossed OWR
-Updated OWR credits (now including Catobat)
2022-05-21 21:01:42 -05:00
aerinon 62ec084a98 DungeonCompletion bitfield 2022-05-19 10:36:51 -06:00
aerinon b0ea301c20 Typo 2022-05-18 16:08:41 -06:00
aerinon afdb8ebac8 DungeonCompletion fixed
Minor issue with dungeon counters fixed
2022-05-18 15:04:20 -06:00
aerinon bcc77759b7 Update tourney winners 2022-05-18 15:01:24 -06:00
codemann8 bcf30ae5c2 Some additional tile swap corrections 2022-05-17 17:34:49 -05:00
codemann8 2c41d369e7 Oops 2022-05-16 14:18:41 -05:00
codemann8 5cd8310094 Oops 2022-05-16 14:05:13 -05:00
codemann8 f708a3155e Fixed default TF pieces in Trinity 2022-05-16 14:02:30 -05:00
codemann8 4d550a38e8 Fixed default TF pieces in Trinity 2022-05-16 14:01:23 -05:00
codemann8 377660a1f5 Merge branch 'pr/8' into OverworldShuffleDev 2022-05-14 11:23:30 -05:00
aerinon e1bf283e1c Fix help 2022-05-13 16:37:27 -06:00
aerinon 7025f6756c Text for a few lowercase spot 2022-05-13 16:09:49 -06:00
aerinon a48a73bcb7 MultiClient fix for shop sram move 2022-05-13 16:09:03 -06:00
codemann8 ce1e3c23b0 Including other OW modes that affect the output filename 2022-05-11 14:38:33 -05:00
codemann8 3993c210c0 Added Crossed OW to spoiler log when Grouped 2022-05-11 14:37:37 -05:00
codemann8 e6c51589f4 Adding Special OW areas to spoiler log 2022-05-11 14:35:44 -05:00
codemann8 0707d9ab34 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-05-10 08:10:27 -05:00
codemann8 9aff3d0b90 Version bump 0.2.7.2 2022-05-10 08:09:38 -05:00
codemann8 47d2aad9bb Reformatting TF Room texts 2022-05-10 08:04:42 -05:00
codemann8 165fc26e33 Add temporary new rule for Bomb Bag +5 upgrades 2022-05-10 08:03:07 -05:00
codemann8 ed4dbc350f Adding mirror connection for Lake Hylia Water D 2022-05-05 23:27:23 -05:00
codemann8 fb62c0c1fd Add lowercase letters to credits end screen 2022-05-05 23:25:09 -05:00
codemann8 701b72462f Unscramble lowercase letters for new font 2022-05-05 18:26:27 -05:00
codemann8 6f1fb6a38c Fixed broken graph issue with Lake Hylia Water D 2022-05-05 07:52:42 -05:00
codemann8 82aa0b5d79 Fixed issue where some water regions are unreachable because they weren't ever checked 2022-05-05 07:50:08 -05:00
codemann8 1eefa5dbde Randomize Special Transitions 2022-05-04 16:48:55 -05:00
codemann8 46dfb2f036 Merge pull request #7 from Catobat/Special
Randomize Special Transitions
2022-05-04 16:46:07 -05:00
codemann8 54c8efe464 Simplified OWR tile group reorganization 2022-05-04 12:10:54 -05:00
codemann8 56b2e0e5e4 Adding an Auto default for Pre-open Pyramid option 2022-05-04 11:36:28 -05:00
codemann8 1c2b27933b Simplified OWR edge group reorganization 2022-05-03 23:40:02 -05:00
codemann8 ee07ac59a7 Fixed minor issue in ER with glitched regions that aren't in any OWTileGroup 2022-05-03 22:08:44 -05:00
aerinon 6ab426b9f3 Fix for keydrops/enemy drops to not be repeatable 2022-05-03 13:55:39 -06:00
codemann8 8531c1005c Updated branch suffix 2022-05-02 05:56:47 -05:00
codemann8 9575344c7f Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-05-02 05:56:18 -05:00
codemann8 b30a5b2652 Version bump 0.2.7.1 2022-05-02 05:55:56 -05:00
codemann8 cd92524193 Adding proper versioning for differing branches 2022-05-02 05:50:27 -05:00
codemann8 0704389cb3 Infinite loop detection for connect_inaccessible_regions 2022-05-02 05:49:28 -05:00
codemann8 b517c5305f Including mystery seed number in spoiler log so it is easier to match them with rom filename 2022-05-02 05:48:17 -05:00
codemann8 7821fac8c3 Adding proper versioning for differing branches 2022-05-02 05:46:08 -05:00
Catobat 4db69b8779 Randomize Special Transitions 2022-05-01 01:25:32 +02:00
aerinon ea745ff22e Hotfix for paired doors
Also made dashable filter work
2022-04-30 15:28:29 -06:00
aerinon ecf6a0bd10 Version bump
Generation fix for inverted
2022-04-29 08:10:08 -06:00
aerinon f93ecf9412 New baserom with various fixes for both font and multiclient issue with pottery
Bump TFH limit to 850. It throws an error if you try to generate with too many pieces.
2022-04-28 16:27:37 -06:00
aerinon 7a35bbfc41 Fixed typing issue.
New baserom for minor multiclient issue with pot switches
2022-04-27 13:48:20 -06:00
aerinon 496e63e13b Merge branch 'DoorDevVolatileSRAM' of https://github.com/cassidoxa/ALttPEntranceRandomizer into cassidoxa-DoorDevVolatileSRAM
# Conflicts:
#	Rom.py
#	data/base2current.bps
2022-04-26 16:24:17 -06:00
cassidoxa 3fe0683fe5 Change pot addresses 2022-04-23 01:25:34 -04:00
aerinon b514df76c3 Prize letters and numbers
Minor bug with max keys: prevent negative values
2022-04-21 15:44:52 -06:00
aerinon e0a6f26279 Font work 2022-04-21 13:19:50 -06:00
aerinon a9797bfd83 Merge branch 'DoorDevUnstable' into DoorDevVolatile
# Conflicts:
#	Main.py
#	RELEASENOTES.md
#	Rom.py
#	data/base2current.bps
2022-04-21 13:18:06 -06:00
aerinon 1c4e3e09ba Major only update (split pot keys and key drops) 2022-04-21 13:13:41 -06:00
aerinon 39ccc59849 Update example 2022-04-21 12:43:41 -06:00
codemann8 5858f7c1da Add major_only algorithm to code 2022-04-21 13:27:57 -05:00
codemann8 e303476ea9 Implement new overworld map draw routine for Mixed OWR 2022-04-21 13:27:00 -05:00
codemann8 a6eeab9994 Fixed Links icon on map check 2022-04-21 13:26:03 -05:00
aerinon 86128c76ff Add major_only algorithm to code 2022-04-21 11:33:31 -06:00
aerinon 7dd5cc0e36 Merge branch 'DoorDevVolatile' into Customizer
# Conflicts:
#	BaseClasses.py
#	ItemList.py
#	Main.py
2022-04-21 11:14:40 -06:00
aerinon 31aeb8a776 Pottery fixes for Room0127
Added mystery flag for future use
2022-04-21 11:03:49 -06:00
cassidoxa 16dfb2ad7b Fix swordless 2022-04-20 22:10:02 -04:00
cassidoxa 163988ca1b New SRAM changes 2022-04-20 22:00:05 -04:00
codemann8 92e04f9e0b Implement new overworld map draw routine for Mixed OWR 2022-04-20 18:40:01 -05:00
aerinon a035beca1e Minor ohko fix 2022-04-20 14:07:18 -06:00
aerinon 31a279d63d Trinity goal added 2022-04-20 14:06:55 -06:00
aerinon 5cc04ed675 Msu resume bug on patcher
Check for retro arrows in pots
2022-04-20 14:00:16 -06:00
codemann8 1c6a730627 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-04-20 10:32:19 -05:00
codemann8 4be6b09c7b Changelog 2022-04-20 10:32:09 -05:00
codemann8 27478113db Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-04-20 10:14:40 -05:00
codemann8 e0e2026a8c Version bump 0.2.7.0 2022-04-20 10:14:14 -05:00
codemann8 b10510ce3e Changed some icon coords for mapchecks 2022-04-20 10:13:31 -05:00
aerinon abf57e0255 Fix for a map bug (link not shown when eastern prize is) 2022-04-20 09:08:55 -06:00
aerinon 4880f8017a Pottery fix for vanilla hera key 2022-04-20 08:51:32 -06:00
aerinon 735727cd69 Pottery fix for vanilla hera key 2022-04-20 08:51:12 -06:00
codemann8 359778ac01 Fixed map check compatibility with Mixed OW 2022-04-20 00:07:11 -05:00
codemann8 5beed02ade Aerinon fix for WorldMapIcon_tile table 2022-04-19 21:35:36 -05:00
aerinon 940c179e28 Documentation update 2022-04-19 14:40:27 -06:00
aerinon 606148bdbe Minor map feature 2022-04-19 14:34:44 -06:00
aerinon 26e8e23fce Initial work on new pottery modes 2022-04-19 13:56:39 -06:00
codemann8 22e5c3e46d Setting world flags on OW subtiles as well 2022-04-19 11:30:49 -05:00
codemann8 d4cdbdf83d Fixed Flute Shuffle to not perform RNG on subsequent attempts 2022-04-18 09:28:13 -05:00
codemann8 0cbd32c184 Allowing Sanc to swap in Mixed OW if ER or Open+CrossedDR or CrossedOW 2022-04-17 11:18:36 -05:00
codemann8 abe4948a17 Simplified rules on when Sanc/Castle/Links can swap in Mixed OW 2022-04-17 10:24:30 -05:00
codemann8 08fdd14fa2 Simplified rules on when Sanc/Castle/Links can swap in Mixed OW 2022-04-17 10:20:24 -05:00
codemann8 bc5bc52b12 Disallowing Sanc to be swapped in Mixed OW if Open/NonCrossed DR/Non ER 2022-04-17 09:29:33 -05:00
codemann8 4a8a8a0630 Fixed issue with infinite loop in Flute Shuffle in Inverted 2022-04-17 08:33:02 -05:00
codemann8 8da3b2067f Added remaining RNG influencers to spoiler log 2022-04-16 11:11:47 -05:00
codemann8 550a8203c3 Changed OW map in attract mode to show LW map always 2022-04-15 10:49:29 -05:00
codemann8 2a51f5bb3b Merged in DR v1.0.0.3 2022-04-15 10:45:12 -05:00
aerinon b3c9f1cf03 List nearly everything in custom yaml (spoiler skip and shuffled not the same right now) 2022-04-14 10:16:51 -06:00
aerinon c7de8dad79 Minor bug in dungeon_only algoithm (also affected fallback grouping in major_only and vanilla) 2022-04-13 14:27:45 -06:00
aerinon e1f85efbef Fixes for overworld_map map mode 2022-04-13 13:31:47 -06:00
aerinon 833b570af6 Customizer item_pool updates 2022-04-13 13:22:15 -06:00
codemann8 f91d7922b4 Fix from Aerinon for map/compass check for dungeon location in map checks 2022-04-10 19:18:25 -05:00
codemann8 f838f73eda Fixed some issues with Flute Spot output on spoiler 2022-04-08 20:59:12 -05:00
codemann8 8eaa20653b Added missing references to Activated Flute 2022-04-08 20:17:20 -05:00
codemann8 c64c0e3301 Fixed bad parenthesis issue 2022-04-08 11:42:33 -05:00
codemann8 72343f8c28 Fixed issue with flute access with Activated flute 2022-04-08 11:41:11 -05:00
codemann8 ab350ff683 Allow AT and GT icons to show on map checks in Mixed OW 2022-04-05 13:17:25 -05:00
codemann8 ff7d164a64 Allow AT and GT icons to show on map checks in Mixed OW 2022-04-05 11:31:19 -05:00
codemann8 396ff21ac5 Fixed map check for GT skull icon to check if Aga2 defeated rather than if pyramid hole opened 2022-04-05 11:30:34 -05:00
codemann8 4af276c1b8 Changed map checks in Mixed OWR to show dungeons in appropriate world 2022-04-05 08:26:23 -05:00
aerinon 52a0e88d12 Minor ohko fix 2022-04-04 14:29:40 -06:00
aerinon cf227aafc0 Trinity goal 2022-04-04 13:37:07 -06:00
codemann8 106b8369bf Exit with error when infinite loop detected in flute shuffle 2022-03-31 08:58:52 -05:00
codemann8 6a1d012a9a Various fixes found from full compare of DR Unstable 2022-03-30 23:52:03 -05:00
codemann8 fdf21b2d5b Various fixes found from full compare of DR Unstable 2022-03-30 23:50:29 -05:00
aerinon 730847fa07 Merge branch 'DoorDevVolatile' into Customizer
# Conflicts:
#	DoorShuffle.py
2022-03-29 14:32:24 -06:00
aerinon c560e0d275 owg shorthand in mystery 2022-03-29 14:31:24 -06:00
aerinon 68c2d06d85 Rain state prevention fix
Also, disallowed door behind Throne Room to be dashable/bombable in standard/hc
2022-03-29 14:30:20 -06:00
aerinon 69bae0f338 Merge branch 'DoorDevVolatile' into Customizer
# Conflicts:
#	DoorShuffle.py
2022-03-29 13:30:49 -06:00
aerinon 8bc446fbc5 Logic refinements for Skull X Room and GT Falling Torches 2022-03-29 13:28:05 -06:00
aerinon 2ca8d61c0b Arghus splash fix
Don't bother checking the ssl cert for that call
2022-03-29 12:21:09 -06:00
aerinon b5684cbf7d Minor bug with ER customization 2022-03-29 12:13:19 -06:00
codemann8 200ef7c897 Fixed AT/GT prize relevance 2022-03-28 09:59:51 -05:00
aerinon 95280e8705 Cherry pick fix for district+shopsanity 2022-03-28 09:32:03 -05:00
codemann8 1eae786c43 Fixing some incorrect AT/GT swap things 2022-03-28 03:05:58 -05:00
codemann8 908ae254bb Text 2022-03-27 23:32:05 -05:00
codemann8 dab40f1a98 Some further merging 2022-03-27 23:31:52 -05:00
codemann8 fd7d9f7121 Merged in DR v1.0.0.2 2022-03-27 14:56:16 -05:00
aerinon 8ec16d46ce Dashable forbidden
Minor logic refinement for Spiky Hint Cave
2022-03-25 15:35:46 -06:00
aerinon 031ec9983f Forfeit multiworld option fix for shops and pots
GT junk fill reworked for pottery lottery
2022-03-25 14:54:28 -06:00
aerinon 5e07e49798 Fix documentation and example
Fix msu_resume issue
Fix empty locations
Throw error on unknown items
2022-03-25 08:43:11 -06:00
aerinon 27b836f16d Merge branch 'DoorDevVolatile' into Customizer 2022-03-25 08:00:30 -06:00
aerinon 901cdff47e Hammerdash + pots fixed so it won't put link in a weird state
Freeze + hammer on enemies that drop keys (or items in dropshuffle) fixed
Inverted bug fixed
2022-03-23 14:29:54 -06:00
aerinon dfb9ebfbdb Customizer main work 2022-03-22 16:13:31 -06:00
codemann8 6914562cdc Minor text formatting 2022-03-19 06:10:08 -05:00
codemann8 438ca4b901 Minor fix to flute SFX for pre-activated flute 2022-03-18 23:22:16 -05:00
aerinon 97377c9749 Merge pull request #129 from Phlyers/DoorDevVolatile
Ice Antechamber pots 3,4 require hammer
2022-03-16 08:37:49 -06:00
aerinon 18f6849fdc fix collection rate 2022-03-14 16:11:57 -06:00
Josh Gerson d70b6cfb42 Ice Antechamber pots 3,4 require hammer 2022-03-12 22:37:53 -05:00
aerinon 64b0740e50 Various shuffled links house fixes 2022-03-12 12:33:14 -07:00
aerinon bfca2c2ad3 Fix for GT Crystal Conveyor not requiring Somaria/Bombs to get through 2022-03-11 17:11:23 -07:00
aerinon 4e43f38332 Separated Collection Rate counter from experimental
Added MSU Resume option
Ensured pots in TR Dark Ride need lamp
Fix for Links House being at Maze Race (did not generate)
2022-03-09 15:42:00 -07:00
aerinon 6f7a2e234d Merge in Unstable updates 2022-03-08 08:58:29 -07:00
aerinon 1ebb49fa59 Update notes 2022-03-08 08:48:49 -07:00
aerinon 042b9a9fa0 Pottery counting fixes
Add major_only algorithm to code
2022-03-08 08:47:25 -07:00
aerinon 6fa2cce79d Factorial fix 2022-03-08 08:14:28 -07:00
aerinon 341a4f4631 District hint work 2022-03-08 08:13:49 -07:00
codemann8 5e6623d351 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-03-07 20:20:42 -06:00
codemann8 6b028e5d4c Version bump 0.2.6.1 2022-03-07 20:20:20 -06:00
codemann8 d23a2332fe Fixed mirror bonk issue incorrectly leaving a mirror portal behind 2022-03-07 20:20:05 -06:00
codemann8 b4c2e0df5f Fixed mirror bonk issue incorrectly leaving a mirror portal behind 2022-03-07 20:12:47 -06:00
codemann8 f5010e5212 More text updates 2022-03-07 19:05:46 -06:00
codemann8 dcc20883c9 Fixed issue with mirror portal not spawning when entering OW from the DW in Crossed OWR 2022-03-07 19:05:21 -06:00
aerinon 285dc48a2b Couple minor rule fixes 2022-03-07 11:14:44 -07:00
aerinon f040b5fad3 Every pot you pick up that wasn't part of the location pool does not count toward the location count
Fix for items spawning where a thrown pot was
Fix for vanilla_fill, it now prioritizes heart container placements
Fix for dungeon counter showing up in AT/HC in crossed dungeon mode
2022-03-07 10:48:31 -07:00
aerinon d69742bccb Baserom fix 2022-03-04 17:54:46 -07:00
aerinon 833a5d8320 Merge branch 'DoorDev' into DoorDevUnstable
# Conflicts:
#	Main.py
#	RELEASENOTES.md
2022-03-04 16:49:41 -07:00
aerinon ccdbeb6423 Note for fix 2022-03-04 16:46:46 -07:00
aerinon e89a143052 SSL not verified for alttpr.com/sprites 2022-03-04 16:46:06 -07:00
aerinon 922bc6d2d0 Fix some interior doors during key door identification as missing one reachable side 2022-03-04 16:45:51 -07:00
aerinon bce288f897 Retro + pottery fixed 2022-03-04 15:10:22 -07:00
aerinon a12216da0b Pottery counts and despawning items fixed 2022-03-04 14:53:30 -07:00
aerinon 0b64b15e9e Fix for old pot shuffle
Fix for mystery startinventory
Update mystery example
2022-02-25 13:18:37 -07:00
aerinon 78442ab41a Note for fix 2022-02-24 14:40:34 -07:00
aerinon f0a4be3be9 SSL not verified for alttpr.com/sprites 2022-02-24 14:39:45 -07:00
aerinon dd18f13930 Trash ditching method rebalanced for lots of triforce pieces
Added a few places Links House shouldn't go when shuffled
Ped goal + vanilla sword = random sword in pool
2022-02-24 14:39:07 -07:00
aerinon b7e307f4c1 BPS flag for Mystery
Expanded logic options for mystery
Fixed a shopsanity+district bug
Fixed the keysanity menu not showing map marks
2022-02-24 14:06:34 -07:00
aerinon 4717449c35 Used create rom flag to indicate if sfc file should be generated or not 2022-02-24 10:10:51 -07:00
aerinon 2b0e891ee9 Usestartinventory ignored 2022-02-24 10:04:59 -07:00
codemann8 7a0c039233 Some changes to lowercase text for dungeon items 2022-02-24 06:06:20 -06:00
codemann8 9312a95ad5 Fixed issue with mirror portal deleting after mirror bonk in Crossed OW 2022-02-22 19:56:05 -06:00
codemann8 a0d51327b8 Fix capitalization issue with hints 2022-02-21 04:40:13 -06:00
codemann8 c5ab2b8853 More text capitalizations/updates 2022-02-21 03:57:41 -06:00
codemann8 c37736a5b1 Some text updates 2022-02-21 03:26:45 -06:00
codemann8 f58030da9e Updating tournament winners 2022-02-21 03:26:01 -06:00
aerinon 2e859e3327 minor revision 2022-02-18 13:17:15 -07:00
aerinon ba15fe7b49 Update docs and version 2022-02-18 08:20:13 -07:00
aerinon 4d7567f4c7 Fix SFX note 2022-02-17 14:56:23 -07:00
aerinon 60d805b00a Fix SFX 2022-02-17 14:42:37 -07:00
aerinon b024311aaa BPS support 2022-02-17 14:00:00 -07:00
aerinon ccb7ced735 Lighter pottery modes 2022-02-16 14:02:21 -07:00
aerinon 76aed82843 Added versioning for code
Fixed bug in standard where Links S&Q was usable before delivering Zelda
2022-02-16 12:59:45 -07:00
aerinon 4dfd602308 Boss fix and rules for Ice Refill added 2022-02-15 17:03:24 -07:00
aerinon 7747a1f204 Unique boss shuffle mode 2022-02-15 16:29:52 -07:00
aerinon 73d4d4b4bb Fix for Hera Basement Cage item inheriting last pot checked
Update indicators on keysanity menu for overworld map option
2022-02-15 12:21:24 -07:00
codemann8 9869c6b5f8 Improving some TF text 2022-02-11 19:44:56 -06:00
codemann8 c103857ace Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-02-10 21:23:05 -06:00
codemann8 4bbf0f6d4f Version bump 0.2.6.0 2022-02-10 21:22:53 -06:00
codemann8 6abed682bf Capitalizing first letter of hint tiles 2022-02-10 21:05:42 -06:00
aerinon 600343683a Revert SRAM changes 2022-02-10 08:36:30 -07:00
aerinon 49accbd2b1 Many bugfixes
* Fixed inverted generation issues with pottery option
* Moved SRAM according to SRAM standard
* Removed equitable algorithm
* Upped TFH goal limit to 254
* Cuccos should no longer cause trap door rooms to not open
* Added double click fix for install.py
* Fix for pottery item palettes near bonkable torches
* Fix for multiworld progression balancing would place Nothing or Arrow items
2022-02-09 14:19:10 -07:00
codemann8 46cf11e8a3 Fixed issue with TR Peg Puzzle Portal not working 2022-02-07 19:21:04 -06:00
codemann8 c375c120e9 Fixed issue with TR Peg Puzzle Portal not working 2022-02-07 18:00:31 -06:00
codemann8 b04968beee Fixed issue with OWR Layout + Insanity ER 2022-02-07 15:37:12 -06:00
codemann8 f07ea8126c Fixed issue with OWR Layout + Insanity ER 2022-02-07 15:32:58 -06:00
codemann8 85bdc93a5a Fixed issue with OWR Layout+Shopsanity 2022-02-07 15:32:40 -06:00
codemann8 05a7a99115 Enabled new font + lowercase hint text updates 2022-02-06 21:43:50 -06:00
codemann8 b13712aabf Enabled new font + lowercase hint text updates 2022-02-06 15:39:07 -06:00
codemann8 d3bf6883b7 Enabled new font + lowercase hint text updates 2022-02-06 07:41:06 -06:00
codemann8 90484ac6c4 Enabled new text font 2022-02-04 16:08:12 -06:00
codemann8 a7a148ed18 Adding 'O' to ROM header to indicate a seed from OWR branch 2022-02-04 06:47:33 -06:00
codemann8 9263c80cce Merged in Upstream ER changes
-Fixed Witch invisible item bug
-Added new font changes, not enabled yet
2022-02-04 06:10:57 -06:00
codemann8 5b03292c2c Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-02-03 06:59:42 -06:00
codemann8 08a8d9223c Version bump 0.2.5.3 2022-02-03 06:59:24 -06:00
codemann8 7a186e647f Simplified AT/GT swap condition check 2022-02-03 06:57:56 -06:00
codemann8 d60b4c61ce Simplified AT/GT swap condition check 2022-02-03 06:54:42 -06:00
codemann8 75d097c4b6 Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world 2022-02-03 06:46:06 -06:00
codemann8 7d391da21d Added Flute Spots to spoiler log 2022-02-03 06:35:54 -06:00
codemann8 22243c8dfa Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world 2022-02-03 06:14:22 -06:00
codemann8 392cb7187c Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world 2022-02-03 06:12:18 -06:00
codemann8 7e7efb0533 Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world 2022-02-03 00:25:13 -06:00
codemann8 e9fd006d2b Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world 2022-02-02 19:53:15 -06:00
codemann8 ee215dbfa7 Fixed issue with Links House swapped in OW Tile Swap 2022-02-02 19:50:41 -06:00
aerinon 64c19bc651 Logic fixes for pots in TR Hub and TR Dark Ride
Fix for district + shopsanity
Typo correction
2022-01-31 16:35:11 -07:00
codemann8 251a614717 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-28 00:27:09 -06:00
codemann8 b53fd17e43 Added Light Hype Fairy to bombable doors 2022-01-28 00:26:53 -06:00
codemann8 1a847863a7 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-28 00:07:10 -06:00
codemann8 220c4b5a70 Version bump 0.2.5.2 2022-01-28 00:06:51 -06:00
codemann8 c3e288f40f Added starting boots and psuedoboots options to example mystery yaml 2022-01-26 09:49:59 -06:00
aerinon da89ab1006 Bug fixes for pottery lottery changes 2022-01-24 16:04:16 -07:00
aerinon 8d99ccafc5 Fix doc
Remove vestiges of shuffleswitches
2022-01-21 16:26:12 -07:00
aerinon 2f0d64103e Merge branch 'StandingItems' into DoorDevVolatile
# Conflicts:
#	Rules.py
#	source/item/FillUtil.py
2022-01-21 16:21:59 -07:00
aerinon e76bc92e42 Fix bombbag bug 2022-01-21 16:15:51 -07:00
aerinon 5211b305e6 Re-worked settings for pottery lottery
Fixed multiworld support for lottery
2022-01-21 16:10:33 -07:00
codemann8 3c2b009aab Added Spiral Mimic Ledge Extend region to list of isolated regions 2022-01-21 09:52:20 -06:00
codemann8 b804c74d6f Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-20 01:12:59 -06:00
codemann8 0e700098d9 Version bump 0.2.5.1 2022-01-20 01:12:45 -06:00
codemann8 09700d2d67 Fixed issue with Inverted Kak Portal missing rule 2022-01-19 22:09:18 -06:00
codemann8 baeabd0f3a Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-19 04:09:14 -06:00
codemann8 78a7d5f850 Version bump 0.2.5.0 2022-01-19 04:09:00 -06:00
codemann8 185e7f967d Restored vanilla Ice Palace terrain for Inverted 2022-01-19 03:43:37 -06:00
codemann8 a61a3d3693 Fixed Hera boss music to correctly read boss defeated flag 2022-01-19 02:31:54 -06:00
codemann8 17b12bd5c7 Restoring vanilla terrain for glitched Inverted modes 2022-01-19 01:48:17 -06:00
codemann8 b01a6f7cd8 Removing unnecessary indirect connections 2022-01-19 01:46:08 -06:00
codemann8 9dd88ad8f8 Restoring vanilla terrain for glitched Inverted modes 2022-01-19 01:44:00 -06:00
codemann8 2cd0fa3b5c Fixed world flag on Mountain Cave start 2022-01-19 01:39:36 -06:00
codemann8 054aa84270 Fixed start as bunny for Bomb Shop 2022-01-19 00:42:02 -06:00
codemann8 00d78e5c3f Fixed issue with spawning on Pyramid/HC Ledge with old man 2022-01-19 00:23:57 -06:00
codemann8 36a6f21021 Fixed issue with Inverted Mirror Bonks not getting applied appropriately 2022-01-18 03:14:40 -06:00
codemann8 4f730844f6 Made flute SFX louder for preactivated flute item get 2022-01-15 20:56:56 -06:00
codemann8 593ce8086a Only start at Big Bomb Shop if not ER 2022-01-15 18:00:33 -06:00
codemann8 5dc8f59f73 Links House tile can now be Tile Swapped 2022-01-15 17:57:46 -06:00
codemann8 c2f6799885 Only start at Big Bomb Shop if not ER 2022-01-15 17:37:16 -06:00
codemann8 f6d309ca76 Logic rules for Inverted TR Peg Puzzle 2022-01-15 14:31:23 -06:00
codemann8 39421533fe Logic and region changes for EDM Spiral Mimic Bridge in Inverted 2022-01-15 14:25:32 -06:00
codemann8 0bc72f77cf Restored vanilla ladder at Dark Graveyard in Inverted 2022-01-15 13:30:02 -06:00
codemann8 44c63e2004 Some Inverted terrain changes for EDM 2022-01-15 12:41:39 -06:00
codemann8 430953d340 Removed ladder from DDM 2022-01-15 12:24:44 -06:00
codemann8 abdf019719 Changed Inverted Flute Spot 1 to Top of DDM 2022-01-15 12:15:39 -06:00
codemann8 95bc7609e4 Added pre-activated flute to item pool in Inverted 2022-01-15 04:11:23 -06:00
codemann8 dab0c16d7e Added flute SFX to itemget if collecting a pre-activated flute 2022-01-15 04:08:28 -06:00
codemann8 770ac31945 Reorganized starting data tables 2022-01-14 13:01:45 -06:00
codemann8 14d670e3ec Start in BBS in Inverted, replacing LH/BBS entrance swap 2022-01-13 22:30:34 -06:00
codemann8 9282d84fd6 Preopened OW doors when starting location exits there 2022-01-13 22:11:27 -06:00
codemann8 af00bdec1e Start in BBS in Inverted, replacing LH/BBS entrance swap 2022-01-13 19:49:08 -06:00
codemann8 f083a41045 Minor ER fix for extra starting locations to work correctly 2022-01-13 19:37:08 -06:00
aerinon d0f38ec659 Setup release notes and version 2022-01-13 17:11:37 -07:00
aerinon e0ff23158a Readme updates 2022-01-13 17:01:13 -07:00
aerinon b55583c524 Merge branch 'DoorDevUnstable' into DoorDev
# Conflicts:
#	Main.py
#	RELEASENOTES.md
#	Rom.py
#	data/base2current.bps
2022-01-13 15:23:49 -07:00
aerinon 9fd73e08bb Districting considers the Tavern North entrance
Major items are counted differently
Minor edits
2022-01-13 15:13:22 -07:00
aerinon d6e74c638f Fix a bug and update the rom 2022-01-13 15:06:08 -07:00
codemann8 fb482729a8 Flute start if Kakariko Village in opposite world 2022-01-12 03:24:51 -06:00
codemann8 5a9f109883 Reversed Old Man Cave entrance placement in Inverted 2022-01-12 03:14:24 -06:00
codemann8 8ade8e79b5 Fixed issue with OW layout validation error with reversible lists 2022-01-12 02:54:24 -06:00
codemann8 d01ddabcaf Fixed issue with duplicate regions in OW sectors 2022-01-12 02:53:38 -06:00
aerinon bcf1ce297c Bunch of logic fixes for various pots
Vanilla fill support for potsanity
Fix for playthrough error
2022-01-07 14:46:25 -07:00
codemann8 44eb10a9db Reversed Old Man spawn on OW in Inverted 2022-01-06 18:48:47 -06:00
codemann8 81a5f80c7d Reversed Old Man spawn on OW in Inverted 2022-01-06 18:41:11 -06:00
aerinon 481e34d2f0 Minor fix for bombbag + TFH 2022-01-06 16:22:56 -07:00
aerinon f9c1219785 Merge branch 'DoorDevVolatile' into StandingItems
# Conflicts:
#	Rom.py
#	data/base2current.bps
2022-01-06 16:09:42 -07:00
aerinon fab5f5bb70 Merge branch 'DoorDevUnstable' into DoorDevVolatile
# Conflicts:
#	Main.py
#	Rom.py
#	data/base2current.bps
2022-01-06 16:06:51 -07:00
codemann8 c1e60c33c9 Some Inverted terrain changes for EDM 2022-01-06 12:45:58 -06:00
codemann8 b27fed99f7 Some Inverted terrain changes for EDM 2022-01-06 11:42:00 -06:00
codemann8 81702c4eca Some Inverted terrain changes for EDM 2022-01-06 11:41:38 -06:00
codemann8 596c26a462 Merged in DR v0.5.1.7 2022-01-06 02:23:24 -06:00
aerinon 4f3ff95f81 -Baserom update
-Incorporate some rom PRs
-Updated Houlihan to exit to wherever Link's House is (inverted, too)
2022-01-05 14:37:10 -07:00
codemann8 b7505eca52 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-05 03:27:53 -06:00
codemann8 e15b1dad57 Implemented OWR reachability guarantee 2022-01-05 03:27:44 -06:00
codemann8 e7c8b23bc0 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-05 03:00:33 -06:00
codemann8 6163f7e857 Implemented OWR reachability guarantee 2022-01-05 03:00:16 -06:00
codemann8 df9eec52ce Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-05 02:54:31 -06:00
codemann8 e3d35c1d29 Version bump 0.2.4.0 2022-01-05 02:54:17 -06:00
codemann8 a1fc3d4701 Fixed issue with incorrect parity calculation for Whirlpool Shuffle 2022-01-05 02:53:19 -06:00
codemann8 f5641c063a Implemented OWR reachability guarantee 2022-01-05 02:26:50 -06:00
aerinon 45bb92151f -Fix for Inverted Mode: Dark Lake Hylia shop sells a blue potion
-Fix for Ijwu's enemizer: Boss door in Thieves' Town no longer closes after the maiden hint
-AllowAccidentalMajorGlitches set for no logic
2022-01-04 22:10:42 -07:00
codemann8 2541e6d7a0 Fixed issue with CLI vs GUI for TFH args 2022-01-04 20:38:11 -06:00
aerinon 515f6dafed Standing Items refinement - starting testing no keydrops and pot shuffle
Fairly substantial change to Crossed Sector distribution due to so many pots making it fail
2022-01-04 15:48:27 -07:00
codemann8 d6c7e3a964 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-03 23:19:11 -06:00
codemann8 51c03ffd2b Fixed default TF pieces from CLI 2022-01-03 23:18:54 -06:00
codemann8 df72e2e445 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2022-01-03 18:10:42 -06:00
codemann8 4ce7fd15c9 Version bump 0.2.3.6 2022-01-03 18:10:28 -06:00
codemann8 dab0fb4a2f Changing trinity to 8/10 default TF pieces 2022-01-03 16:03:20 -06:00
codemann8 35b1e27e85 Restructured triforce piece pool allocation, capped at 128 2022-01-03 16:02:02 -06:00
codemann8 51cac40bab Restructured triforce piece pool allocation, capped at 128 2022-01-03 15:59:22 -06:00
codemann8 a6f791e7b7 Fixed issue in multiworld where some players dont have a custom item pool 2022-01-02 16:35:17 -06:00
codemann8 766e498356 Fixed issue in multiworld where some players dont have a custom item pool 2022-01-02 16:32:27 -06:00
codemann8 2d291ef3fb Fixed issue in multiworld where some players dont have a custom item pool 2022-01-02 16:18:38 -06:00
codemann8 d79a0c83fe Fixed issue with Trinity + Multiworld 2022-01-02 16:04:27 -06:00
codemann8 5d6cef773f Undo map check behavior in Trinity 2022-01-02 16:00:08 -06:00
codemann8 9f7d62a081 Fixed spoiler log and pooling issues with custom TFH amounts 2021-12-31 12:52:29 -06:00
codemann8 291b8e38da Map checks in Trinity are treated like wild maps 2021-12-31 02:25:40 -06:00
codemann8 da080992b2 Added new Trinity goal 2021-12-30 23:45:00 -06:00
codemann8 acd42515a7 Added new Trinity goal 2021-12-30 23:42:21 -06:00
codemann8 9a7e4c5f16 Added new Trinity goal 2021-12-30 22:41:50 -06:00
codemann8 f0b7a472d8 Fixed issue with Pyramid Hole access when screen is swapped 2021-12-30 22:31:29 -06:00
codemann8 d41a5244ae Simplified tile swap check code 2021-12-29 18:16:46 -06:00
codemann8 cf86aedb79 Simplified tile swap check code 2021-12-27 14:28:15 -06:00
codemann8 29d11abfcf Added infinite loop detection 2021-12-26 12:01:03 -06:00
codemann8 29d7e3b237 Added infinite loop detection 2021-12-26 12:00:04 -06:00
codemann8 b4a873755e Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-12-24 16:00:50 -06:00
codemann8 76bb0e2aa1 Version bump 0.2.3.5 2021-12-24 16:00:37 -06:00
codemann8 8fe377902a Move mirror portal off screen during mirror bonk in Crossed OW 2021-12-22 10:51:19 -06:00
codemann8 2b8e9d8602 Move mirror portal off screen during mirror bonk in Crossed OW 2021-12-22 10:49:52 -06:00
codemann8 3c74fcf947 Added infinite loop detection 2021-12-22 10:38:17 -06:00
codemann8 0df739b283 Added infinite loop detection 2021-12-21 10:35:54 -06:00
codemann8 a731bc0799 Fixed issue with player number getting overwritten during OWR/ER 2021-12-21 10:14:47 -06:00
codemann8 e600f472d2 Fix deterministic issues in repeat seed generation 2021-12-20 14:32:30 -06:00
codemann8 ca4032f6ba Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-12-19 20:29:48 -06:00
codemann8 5e2bbe68cb Version bump 0.2.3.4 2021-12-19 20:29:31 -06:00
codemann8 d79adbf3c8 Fix deterministic issues in repeat seed generation 2021-12-19 19:59:30 -06:00
codemann8 7699c1fc63 Fixed Blue Potion not showing up in Dark Lake Shop in Inverted 2021-12-19 19:56:27 -06:00
codemann8 f2600db3f3 Added new OW Crossed option None (Allowed) to support legacy functionality of when invalid values are used 2021-12-19 19:55:44 -06:00
aerinon b2f2565271 Standing Items initial commit 2021-12-16 16:02:11 -07:00
codemann8 07a956a3a4 Fixed issue with logic not correctly placing Blue potion in Dark Lake Shop 2021-12-16 16:17:51 -06:00
codemann8 fdbda7a9c1 Fixed issue with spoiler output of OW Tile Swaps 2021-12-16 15:43:10 -06:00
codemann8 c910785211 Fixed Lake Shop not having Blue Potion in Inverted 2021-12-16 14:27:13 -06:00
codemann8 abfe08ab6d Improvement to FF damage fix to insta-warp Link to destination when Link exceeds bounds of current screen 2021-12-13 23:17:29 -06:00
codemann8 4ae211e213 Fixed spoiler json structure for map output 2021-12-11 17:11:58 -06:00
codemann8 7f871681bb Added dynamic flute spot reservation 2021-12-10 16:42:26 -06:00
codemann8 d2dc33638e Merged in DR v0.5.1.6 2021-12-07 04:51:43 -06:00
aerinon c651d1d584 Merge branch 'DoorDevUnstable' into DoorDevVolatile
# Conflicts:
#	Main.py
2021-12-06 15:41:19 -07:00
aerinon 74155ec5ae Version and release note update 2021-12-06 15:28:19 -07:00
aerinon d710e08ea0 Rules fixes - TT locations not foribben by default to have big key
Can push paradox block with mirror in glitched modes
2021-12-06 15:25:55 -07:00
codemann8 303beef0db Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-12-06 09:30:07 -06:00
codemann8 940837e7ee Fixed issue with OW Layout and OW Crossed failing layout validation 2021-12-06 09:29:57 -06:00
codemann8 8cebe24b36 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-12-06 09:21:53 -06:00
codemann8 aa2ea18232 Version bump 0.2.3.3 2021-12-06 09:21:35 -06:00
codemann8 37841ab311 Fixed issue with OW Layout and OW Crossed failing layout validation 2021-12-06 09:09:34 -06:00
codemann8 838ada0a0b Fixed mirror portals showing up in DW 2021-12-06 07:43:38 -06:00
codemann8 db6403db2c Remove import 2021-12-04 17:20:02 -06:00
codemann8 4e4b08da4f Initial approach to eliminating inaccessible regions resulting from OW Layout Shuffle 2021-11-30 11:37:20 -06:00
codemann8 b4173044d7 Modeled Woods Pass regions more correctly 2021-11-30 11:27:44 -06:00
codemann8 3e43b12508 Caching OW sectors in World object for future shared use between ER and OWR 2021-11-30 03:40:43 -06:00
codemann8 7861b4e8a7 Moved OW sector and region search to OW class 2021-11-27 06:25:30 -06:00
codemann8 745c82d957 Minor formatting 2021-11-26 00:36:24 -06:00
codemann8 2826b1967f Fix mirror portals getting erased when changing worlds 2021-11-24 15:58:19 -06:00
codemann8 e13ca58485 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-24 15:57:39 -06:00
codemann8 c883690ea3 Version bump 0.2.3.2 2021-11-24 15:57:25 -06:00
codemann8 7ba0f97b23 Fix mirror portals getting erased when changing worlds 2021-11-24 15:56:20 -06:00
codemann8 8823cc6e7c Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-24 12:38:55 -06:00
codemann8 1ca4905089 Version bump 0.2.3.1 2021-11-24 12:38:35 -06:00
codemann8 3ef1f4bb52 Omit displaying identical paths in spoiler log 2021-11-24 12:31:58 -06:00
codemann8 7d9ccdb033 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-24 04:23:45 -06:00
codemann8 0795eb50c1 Version bump 0.2.3.0 2021-11-24 04:23:23 -06:00
codemann8 ae5e1cc511 Omit displaying identical paths in spoiler log 2021-11-24 03:33:10 -06:00
codemann8 043a108577 Restructuring spoiler output to support future types of map text output 2021-11-24 03:14:23 -06:00
codemann8 f06cee8927 Restructuring spoiler output to support future types of map text output 2021-11-24 02:54:16 -06:00
codemann8 df6ea16f3a Minor tweak to Big Bomb Shop showing up in spoiler 2021-11-24 02:52:18 -06:00
codemann8 6506f6d077 Minor tweak to Big Bomb Shop showing up in spoiler 2021-11-24 00:47:46 -06:00
codemann8 b8855efe76 Fixed incorrect mirror rule 2021-11-23 22:33:39 -06:00
codemann8 a563b930cc Modeled mirror portal re-entry logic with followers 2021-11-23 22:32:17 -06:00
codemann8 62d6512e9f Fix mirror portals getting erased when changing worlds 2021-11-22 09:41:02 -06:00
codemann8 6a5c6be9ac Fix mirror portals getting erased when changing worlds 2021-11-22 09:08:16 -06:00
codemann8 cf614e4dff Fixed mirror portals getting erased when changing worlds 2021-11-20 00:35:37 -06:00
aerinon 10a440e4ee Potential fix for money balancing 2021-11-19 16:09:00 -07:00
aerinon 500ec07174 Add bomb assumptions to certain bosses 2021-11-19 16:03:41 -07:00
aerinon 577935b7e7 Typos and grammar refinement 2021-11-18 16:46:42 -07:00
aerinon 32816fb7db Documentation of fill algorithms 2021-11-17 16:31:19 -07:00
aerinon 4c2887c0a1 Fix baserom 2021-11-15 16:23:53 -07:00
aerinon ba8f15b6e0 Clean up and vanilla fill improvements 2021-11-15 16:22:50 -07:00
codemann8 18e4fc6e6c Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-14 17:12:52 -06:00
codemann8 e65ca4752e Version bump 0.2.2.3 2021-11-14 17:12:42 -06:00
codemann8 64bc9189c5 Fixed Inverted Double-Swap issue 2021-11-14 17:08:50 -06:00
codemann8 6918c791bd Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-11 17:33:33 -06:00
codemann8 48699036ed Version bump 0.2.2.2 2021-11-11 17:33:20 -06:00
codemann8 d92f5382bd Fixed Triforce Hunt goal 2021-11-11 17:15:41 -06:00
codemann8 9db079fbbe Fixed Mystery filename to not spoil OWR 2021-11-09 18:57:45 -06:00
codemann8 796171ab4d Fixed issue with Whirlpool Shuffle with Grouped OW Crossed 2021-11-09 18:46:06 -06:00
codemann8 e31f41e7a9 Fixed issue with Whirlpool Shuffle with Grouped OW Crossed 2021-11-09 17:40:31 -06:00
codemann8 8c05a3bd35 Fixed issue with Whirlpool Shuffle with Grouped OW Crossed 2021-11-09 17:30:16 -06:00
codemann8 b1bbf92c6d Better approach for Links House/Bomb Shop ER hint 2021-11-09 16:13:01 -06:00
codemann8 48ab97da75 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-09 14:57:33 -06:00
codemann8 067580892f Version bump 0.2.2.1 2021-11-09 14:57:19 -06:00
codemann8 1df52df5a9 Fixed issue with Whirlpool Shuffle not following Polar rules 2021-11-09 14:56:11 -06:00
codemann8 3f59e93bfd Added OW Tile Swaps to spoiler log 2021-11-09 14:41:22 -06:00
codemann8 9714604da8 Fixed issue with Lite ER not placing some caves appropriately 2021-11-09 14:08:22 -06:00
codemann8 af675cf6f7 Improvements to hints
Removed irrelevant hints in Lite/Lean ER
Added Links House hint in ER
2021-11-09 11:11:29 -06:00
codemann8 5c2592cfe0 Fixed flute exits to be LW tiles only 2021-11-08 04:47:07 -06:00
codemann8 36a75b7c99 Allow normal Link speed with Old Man if not in his cave or on WDM 2021-11-07 16:25:23 -06:00
codemann8 61f94ad9a5 Minor change for OWG edge classification 2021-11-07 15:00:09 -06:00
codemann8 b82d647bf9 Changed Big Bomb logic to BFS method 2021-11-06 15:51:00 -05:00
codemann8 4fab658b88 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-06 04:51:59 -05:00
codemann8 1bbbd30a71 Readme update 2021-11-06 04:51:50 -05:00
codemann8 a82ac2bb77 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-06 04:45:19 -05:00
codemann8 53106c9b1e Version bump 0.2.2.0 2021-11-06 04:45:02 -05:00
codemann8 46abc05ada Minor spoiler log formatting 2021-11-06 04:42:35 -05:00
codemann8 a4c1fd5049 Minor logic fix to minor glitch rule 2021-11-06 04:35:14 -05:00
codemann8 5bffd0c7e1 Some corrections to Ledges and OWG connections 2021-11-05 20:52:43 -05:00
codemann8 03a0efe69f Some corrections to Ledges and OWG connections 2021-11-05 20:26:12 -05:00
codemann8 4dd8ff4de1 Added Smith/Purple Chest pathing 2021-11-05 20:08:01 -05:00
codemann8 f15f29b2c4 Added Smith/Purple Chest pathing 2021-11-05 19:53:32 -05:00
codemann8 97ce86fd77 Added Smith/Purple Chest pathing 2021-11-05 19:45:56 -05:00
codemann8 f0d128d9a0 Moved special Big Bomb pathing to Pyramid Crack 2021-11-05 16:27:31 -05:00
codemann8 87f0cdd3fd Initial red bomb pathing 2021-11-05 12:28:16 -05:00
codemann8 9ce4f2abfc Minor code move 2021-11-04 21:36:56 -05:00
codemann8 b251df440a Added pseudo items/locations in prep for Big Bomb logic 2021-11-04 21:34:31 -05:00
codemann8 891c2d3565 Fix issue with Crossed ER trying to use a previously consumed entrance 2021-11-03 23:16:35 -05:00
codemann8 34cea05444 Fixed bomb rules to require pearl when applicable 2021-11-03 23:15:05 -05:00
codemann8 b152b6ad73 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-11-02 18:29:06 -05:00
codemann8 e6805f26c0 Version bump 0.2.1.3 2021-11-02 18:28:53 -05:00
codemann8 3d0e8502ba Minor spoiler log changes 2021-11-02 18:14:40 -05:00
codemann8 8a495e1b81 Merged in DR v0.5.1.5 2021-11-02 18:14:17 -05:00
codemann8 a433629d1c Fixed boss music 2021-11-02 17:18:00 -05:00
aerinon 61f659a511 Initial fill changes
Merge branch 'Bias' into DoorDevVolatile

# Conflicts:
#	Rom.py
2021-11-02 16:03:21 -06:00
aerinon 4131896f93 Release notes for restricted boss item 2021-11-02 15:40:15 -06:00
aerinon 3369528596 Merge branch 'DoorDevUnstable' into DoorDevVolatile
# Conflicts:
#	Main.py
#	Rom.py
#	data/base2current.bps
2021-11-02 15:31:14 -06:00
aerinon 90f7016f49 Update release notes and version
Remove tileset fix (I like the other more visually)
2021-11-02 15:25:34 -06:00
aerinon f8ed4f0c38 Merge branch 'DRFix' of https://github.com/Catobat/ALttPDoorRandomizer into Catobat-DRFix 2021-11-02 15:19:07 -06:00
Catobat 1b1292f6b8 ROM fixes 2021-11-01 23:29:06 +01:00
Catobat 59dd62e3ce Fix some settings being mandatory in weight files 2021-11-01 21:24:54 +01:00
Catobat 5bac1ba5cc Add support for Subweights 2021-11-01 21:04:54 +01:00
codemann8 e2c51b5dc4 Minor stuff missing 2021-11-01 13:30:46 -05:00
codemann8 8dab54ba9b Added new spot type checks for OW exits 2021-11-01 13:29:26 -05:00
Catobat 01e4c2bff7 Include bottle refills in spoiler 2021-11-01 17:58:01 +01:00
codemann8 de41f6b7b4 Fake flipper kill fix reversal and replacement 2021-11-01 11:03:49 -05:00
codemann8 6cfcdf039c Preserve Sanc music change in Standard 2021-11-01 02:09:29 -05:00
codemann8 d7e4ada0e2 Play Sanc music when arriving in Sanc in Standard 2021-10-31 21:02:50 -05:00
codemann8 057f8cbeba Fixed Shuffle Ganon CLI/GUI issue 2021-10-31 19:57:40 -05:00
codemann8 fe358e921a Added missing Starting Equipment section in spoiler log 2021-10-31 19:47:57 -05:00
codemann8 1056a6d3ad Fixed Shuffle Ganon CLI/Gui issue 2021-10-31 18:53:09 -05:00
codemann8 e2afe98b75 Fixed issue with shuffling Ganon/GT via CLI 2021-10-31 15:57:32 -05:00
codemann8 0b5c1e70ae Fix issue with SP not flooding lobby in vanilla DR/ER 2021-10-31 00:08:21 -05:00
codemann8 0d6565d6f0 Fixed issue with whirlpools not changing world in Crossed OW 2021-10-31 00:07:23 -05:00
codemann8 c9307d3640 Fix issue with SP not flooding lobby in vanilla DR/ER 2021-10-30 18:47:14 -05:00
aerinon e78f9218f5 Merge branch 'Ambrosia' into DoorDevVolatile
# Conflicts:
#	BaseClasses.py
#	CLI.py
#	Main.py
2021-10-29 15:26:51 -06:00
aerinon d84a3832a6 Merge branch 'DoorDevUnstable' into DoorDevVolatile 2021-10-29 11:50:35 -06:00
aerinon 3a41314003 Shufflelinks and bombbag added to settings code 2021-10-29 11:50:16 -06:00
codemann8 9a902ef98d Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-28 21:42:54 -05:00
codemann8 8efed3a829 Version bump 0.2.1.2 2021-10-28 21:42:43 -05:00
codemann8 3bdbc4e268 Fixed issue with whirlpools not changing world in Crossed OW 2021-10-28 21:41:22 -05:00
codemann8 ec392524e5 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-28 14:01:39 -05:00
codemann8 d336c18144 Version bump 0.2.1.1 2021-10-28 14:01:28 -05:00
codemann8 ebd301e4e5 Fixed various issue involving dropdown entrances getting chosen for non-dropdowns 2021-10-28 13:55:48 -05:00
codemann8 4b0d8fe762 Fixed infinite loop issue and better error handling in ER 2021-10-28 12:55:12 -05:00
codemann8 3cd8f4a741 Adding no_race CLI option for Mystery 2021-10-28 01:01:53 -05:00
codemann8 a965e854a7 Changed spoiler output to occur in stages rather than once at the end 2021-10-28 00:21:46 -05:00
codemann8 a5ceb2f61c Moving shuffling dropdowns to later in modes where HC isn't placed early
This fixes unwanted cross-world scenarios
2021-10-27 22:33:15 -05:00
codemann8 deb3015105 Fixed issue with Links House candidate list in ER is blank 2021-10-27 22:02:21 -05:00
codemann8 d22d421527 Fixed issue with Links House candidate list in ER is blank 2021-10-27 22:01:02 -05:00
codemann8 7f3a373b68 Fixed output path in Mystery to use the saved settings if not specified on CLI 2021-10-27 21:59:34 -05:00
aerinon 1525a949ca Merge branch 'DoorDevUnstable' into DoorDevVolatile 2021-10-27 15:02:47 -06:00
aerinon c8f1e611f4 Mystery test suite 2021-10-27 15:02:33 -06:00
aerinon 4b0c2afa98 Retro + enemizer fix for arrows under pots 2021-10-27 14:30:25 -06:00
aerinon 3b3fe7f8ca Bonk fairy (light) standard er restriction 2021-10-27 13:29:07 -06:00
codemann8 842f0e35e7 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-27 01:42:46 -05:00
codemann8 152adde3cb Version bump 0.2.1.0 2021-10-27 01:42:32 -05:00
codemann8 34e115a263 Implemented Whirlpool Shuffle 2021-10-27 01:22:03 -05:00
codemann8 c8e04ff8b6 Fixing some Lite ER to not be treated as cross-world 2021-10-27 01:20:56 -05:00
codemann8 0dea19791b Unnecessary tautology check 2021-10-27 01:19:55 -05:00
codemann8 08ab32537b Implemented Whirlpool Shuffle 2021-10-27 01:19:01 -05:00
codemann8 19506ef379 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-26 16:04:58 -05:00
codemann8 32d6a55838 Changelog update 2021-10-26 16:04:41 -05:00
codemann8 ff7bd3d641 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-26 14:29:18 -05:00
codemann8 a6be79c4a1 Version bump 0.2.0.0 2021-10-26 14:29:03 -05:00
codemann8 92e272e617 Efficiency improvement of ER 2021-10-26 13:52:32 -05:00
codemann8 84793d784a Moved flute icon location for clarity 2021-10-26 13:51:15 -05:00
aerinon 62c348fe7c Capacity upgrade fairy now sells nothing useful (nor could downgrade your sword) 2021-10-25 16:31:36 -06:00
codemann8 0d46f40241 Renamed Lite+ ER to Lean ER 2021-10-25 13:22:42 -05:00
codemann8 a34b2b3674 Fixed issue with inaccessible regions not getting connected 2021-10-25 13:05:21 -05:00
codemann8 0b6c629b86 Repurposed Lite ER to a beginner friendly ER mode 2021-10-24 20:32:33 -05:00
codemann8 e7c1cbda63 Remove outdated hammer rule for Pyramid Exit Ledge Drop 2021-10-23 19:27:08 -05:00
codemann8 1ad99fb9bf Fixed issue where Pyramid Exit leads to Pyramid instead of HC Ledge 2021-10-23 19:26:20 -05:00
codemann8 74c586320b Smith deletion on S+Q only if cannot reach from start 2021-10-22 18:32:00 -05:00
aerinon 9f8d87f7e3 Merge branch 'DoorDevUnstable' into DoorDevVolatile
# Conflicts:
#	Rom.py
2021-10-22 15:59:07 -06:00
codemann8 13ae8accc4 Smith deletion on S+Q only if cannot reach from start 2021-10-22 00:25:10 -05:00
aerinon 1acad6a4f4 Merge pull request #126 from cassidoxa/inverted-portals-dr
Fix typo in inverted LW portal removal
2021-10-21 22:43:05 -06:00
codemann8 b46452f748 Fixed portal to match grass in Inverted 2021-10-21 22:18:59 -05:00
codemann8 73402a2e67 Merged in DR v0.5.1.4 2021-10-21 21:47:02 -05:00
codemann8 4c4c188413 Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffleDev 2021-10-21 21:45:50 -05:00
cassidy a1ca99700a Fix typo in inverted LW portal removal
my bad
2021-10-21 22:36:50 -04:00
aerinon 9b5e6c8beb Updated baserom and release notes 2021-10-21 16:49:05 -06:00
aerinon 593355f839 Quadrant glitch mistake reversion
Fix for inverted diggable portals
2021-10-21 16:34:27 -06:00
aerinon c90092f70a Merge pull request #125 from cassidoxa/inverted-portals-dr
Remove diggable light world portals in inverted
2021-10-21 16:32:45 -06:00
aerinon dc7d4940d9 Overworld map code 2021-10-21 16:29:09 -06:00
cassidy 25be090f75 Remove diggable light world portals in inverted 2021-10-21 17:02:56 -04:00
aerinon 12846df681 Accounted for bomb usage in Mire 2 (non-enemizer, of course) 2021-10-21 14:34:21 -06:00
aerinon 551d46e5f4 Bug fix for inaccessible region function (always used player 1's HC Ledge) 2021-10-21 14:20:22 -06:00
aerinon a4848c5baf Baserom update 2021-10-21 14:17:26 -06:00
codemann8 3cded722ff Allow Sanc/Grave to Tile Swap when Standard + Crossworld ER 2021-10-19 22:14:31 -05:00
codemann8 3d9aeca81f Fixed issue with Old Man exit not deliverable with starting equipment 2021-10-19 21:52:03 -05:00
codemann8 10b8b1d666 Allowing for more areas where Old Man can exit in ER 2021-10-19 17:02:08 -05:00
codemann8 d6906576a0 Fixed issue in Inverted ER where Links or Chapel end up too close to each other 2021-10-19 16:14:20 -05:00
codemann8 c266abb456 Rearranged spoiler log output 2021-10-18 21:47:28 -05:00
codemann8 87f2e84b03 Placing Dark Chapel before Links in ER 2021-10-18 20:42:57 -05:00
codemann8 f1d511b26e Fixed issue with Blacksmith using wrong pool in Lite ER 2021-10-18 20:40:31 -05:00
codemann8 f8ce8ae1e2 Fixed incorrect cross-pooling for Lite/Lite+ ER 2021-10-17 21:36:46 -05:00
codemann8 302633dc73 Added new experimental Lite+ ER mode 2021-10-17 20:32:17 -05:00
codemann8 42b185115a In Lite ER place Old Man after connecting inaccessible regions 2021-10-17 20:30:00 -05:00
codemann8 0126e7ab48 Improving the multi-entrance connection fill routine 2021-10-17 19:42:13 -05:00
codemann8 f04dc94a8c Fixed issue in Inverted Lite ER with Dark Chapel placement 2021-10-17 15:01:59 -05:00
codemann8 f01b75595d Fix issue with subsequent seed generations placing invalid entrances 2021-10-17 12:20:31 -05:00
codemann8 d638ee8595 Fix Old Man exiting from Old Man House in ER 2021-10-16 17:23:28 -05:00
codemann8 0a0bf48809 Including Big Bomb Shop in shuffler in Lite ER 2021-10-16 15:26:17 -05:00
codemann8 9d2b578556 Removed HC bias when crossworld ER is used 2021-10-16 14:35:15 -05:00
codemann8 6b7146867a Added new Lite (fka. Beginner) ER mode 2021-10-16 13:59:52 -05:00
codemann8 46c1105e4d Added new Lite (fka. Beginner) ER mode 2021-10-16 13:56:35 -05:00
codemann8 2be7de56df Fixed issue with Flute Shuffle menu cancel now working when no OWR is enabled 2021-10-16 13:51:51 -05:00
codemann8 e994be11f6 Added new Lite (fka. Beginner) ER mode 2021-10-16 13:47:55 -05:00
codemann8 395090d58f Fixed Houlihan error in ER on subsequent generations 2021-10-16 13:37:08 -05:00
codemann8 f958e2a3ea Fixed some errors, properly junk filling entrances in Simple ER 2021-10-15 20:02:42 -05:00
codemann8 62e925d589 Some additional fixes 2021-10-15 00:43:21 -05:00
codemann8 579f6c609d Added Mystery options for OWG and Shuffle Ganon 2021-10-15 00:42:42 -05:00
codemann8 c7c20372b4 Oops 2021-10-14 23:29:08 -05:00
codemann8 600ea25003 Initial check-in for ER rewrite 2021-10-14 22:13:47 -05:00
codemann8 9d7663c648 Adding new shared/utility functions 2021-10-14 22:01:56 -05:00
codemann8 6aeabc5e66 Added rule changes that only apply to reachability checks, prior to actual game simluation 2021-10-14 14:15:51 -05:00
codemann8 1327408a01 Fixed some mode specific things that get enabled in OWR 2021-10-14 14:12:26 -05:00
codemann8 7ed4ad2304 Some general error prevention and corrections 2021-10-14 14:12:01 -05:00
codemann8 0a187ba14c Added Bat Cave Ledge Peg exit 2021-10-14 14:01:38 -05:00
codemann8 876b9adb94 Fixed some mode specific things that get enabled in OWR 2021-10-14 13:45:53 -05:00
codemann8 743e840087 Fixed some incorrect names 2021-10-14 13:38:29 -05:00
codemann8 f9b7b2f926 Reordered functions, no change 2021-10-14 13:29:39 -05:00
codemann8 3e6d447857 Added Bat Cave Ledge Peg exit 2021-10-14 13:25:47 -05:00
codemann8 2e5a5f351e Allows starting flute to give access without reaching Kakariko Village 2021-10-14 13:13:24 -05:00
codemann8 3c3ec43b77 Added new spot_types for OW logical edges 2021-10-07 01:22:04 -05:00
codemann8 f31b867029 Fixed issue with Chaos/Limited OWR with Keep Similar off not using edge arrays 2021-10-07 01:05:08 -05:00
codemann8 916d32350d Fixed issue with Chaos/Limited OWR with Keep Similar off not using edge arrays 2021-10-07 00:59:27 -05:00
codemann8 1f92895222 Added mirror edge to Pyramid Exit Ledge 2021-10-06 20:45:29 -05:00
codemann8 a0c795d70d Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-06 12:02:44 -05:00
codemann8 6c6142f1d8 Version bump 0.1.9.4 2021-10-06 12:02:29 -05:00
codemann8 c08cb5c530 Actually reverting Dark Sanc to original state for good 2021-10-06 12:00:48 -05:00
codemann8 71b59f7e4a Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-06 10:48:26 -05:00
codemann8 64d6f22b71 Fix 2021-10-06 10:48:14 -05:00
codemann8 3a9a0e04b6 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-05 22:01:37 -05:00
codemann8 cc9f41a2b7 Fix for Houlihan/Links House issue in ER 2021-10-05 22:01:14 -05:00
codemann8 bbaa44aa0e Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-05 21:00:58 -05:00
codemann8 7ea9d54ba3 Reverted Dark Chapel ER change 2021-10-05 21:00:41 -05:00
codemann8 c56480d43b Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-05 20:27:06 -05:00
codemann8 b42b6034e1 Fixed generation error on Houlihan connection line 2021-10-05 20:26:49 -05:00
codemann8 228e7ce332 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-05 19:47:16 -05:00
codemann8 80ae3eecc2 Version bump 0.1.9.3 2021-10-05 19:47:05 -05:00
codemann8 e9c4486e1c Minor accuracy improvements to ER algorithm 2021-10-05 19:35:18 -05:00
codemann8 e94431a1b6 Changed Dark Sanc to 2way connection in ER 2021-10-05 19:34:11 -05:00
codemann8 249591e1f6 Simplified Houlihan designation in ER 2021-10-05 19:32:53 -05:00
codemann8 457421f54a Minor accuracy improvements to ER algorithm 2021-10-05 19:30:38 -05:00
codemann8 116ffe6bd1 Fix Links House default placement in Inverted ER 2021-10-05 19:08:29 -05:00
aerinon a23315f783 Disarm EG glitch on mirror in most modes
Added a check flag for the disarm on most transitions so if can be armed when wanted
2021-10-05 14:13:24 -06:00
aerinon 28b87428cc Changed bias named. Added districting 2021-10-05 13:58:30 -06:00
codemann8 354d4ab1fc Fix Links House default placement in Inverted ER 2021-10-04 21:56:53 -05:00
codemann8 37dd6f874a Moved Lake Hylia flute spot to east south shore 2021-10-04 19:38:29 -05:00
codemann8 83f21bab07 Prevent writes to ROM if invalid combinations of OW shuffle are used 2021-10-03 09:09:39 -05:00
codemann8 2c21d95e57 Minor filename output change 2021-10-02 20:00:37 -05:00
codemann8 3edb0834ac Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-02 14:32:40 -05:00
codemann8 237e1eccc5 Fixed mystery example yml 2021-10-02 14:32:21 -05:00
codemann8 85d442c578 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-10-02 14:09:34 -05:00
codemann8 ac75575b5e Version bump 0.1.9.2 2021-10-02 14:07:46 -05:00
codemann8 21525b6d18 Removal of OW world code in copy_world, in prep for ER rewrite 2021-10-02 13:46:32 -05:00
codemann8 c99805f47d Minor tweaks in prep for ER rewrite 2021-10-02 13:45:14 -05:00
codemann8 c54bd67ddc Extended new entrance/exit pool to all other connect functions 2021-10-02 13:40:14 -05:00
codemann8 9bff9e010d Extended new entrance/exit pool to all other connect functions 2021-10-02 13:38:30 -05:00
codemann8 ae5a7906a6 Fixed spoiler log to consider non-boolean Crossed OW values 2021-10-02 10:16:35 -05:00
codemann8 cb51117c70 Fixed Mystery to consider new Crossed/Mixed structure 2021-10-02 09:59:23 -05:00
codemann8 43fbd9c49c Added entrance and exit pool framework to ER 2021-09-30 18:49:51 -05:00
codemann8 56b8492985 Added entrance and exit pool framework to ER 2021-09-30 18:48:53 -05:00
aerinon 035621e420 Rupee bow forbids certain lobbies in HC in standard
Allow a lobby in keydrop shuffle
Key rule fix when bk isn't possible
Added controller awareness to world traversal
2021-09-28 14:57:17 -06:00
codemann8 54b6b3dc05 Minor entrance formatting and rearrangement 2021-09-28 15:29:51 -05:00
codemann8 dd1ec0ce52 Moved dungeon-related connections to one area 2021-09-28 15:14:02 -05:00
codemann8 ced1c77852 Moved Dungeon Full shuffle logic to external function 2021-09-28 15:12:46 -05:00
codemann8 a11c23bde9 Moving Tavern North to mandatory connections 2021-09-28 15:09:29 -05:00
aerinon 058b78cff9 Massage fix 2021-09-23 16:10:07 -06:00
codemann8 ecacba55a4 Merged in DR v0.5.1.2 2021-09-17 11:12:05 -05:00
aerinon ee545b3543 Merge branch 'Ambrosia' into Bias 2021-09-16 16:15:10 -06:00
aerinon 9e04417072 Merge branch 'DoorDevUnstable' into Ambrosia 2021-09-16 16:12:45 -06:00
aerinon 1eda6cfa9a Fix lambda by binding bk_name at lambda creation 2021-09-16 15:46:40 -06:00
aerinon ddd3aaf9a2 More prize door refinement
Incorporating drop entrances better in the find proposal algorithm
2021-09-16 15:20:29 -06:00
aerinon bce3bcf4fe Remove stonewall pre-opening code in favor of dynamic softlock prevention (Promoted from experimental) 2021-09-14 16:02:31 -06:00
aerinon eab9404398 Allow Blind's Cell to be shuffled if Blind is not the boss 2021-09-14 15:40:55 -06:00
aerinon c5f6c46bd8 Remove unique annotation from FastEnum class 2021-09-14 15:24:23 -06:00
aerinon c64d499bab Maps/compasses should not be advancement items if the restriction is none 2021-09-14 15:03:51 -06:00
aerinon a9b872b88d Ambrosia logic fixes 2021-09-14 15:02:45 -06:00
aerinon 391db7b5c4 Clustered bias algorithm
Fixes for various other algorithms
2021-09-14 15:02:18 -06:00
aerinon ebf237cca3 Ambrosia logic fixes 2021-09-14 15:00:55 -06:00
aerinon ef998a2f7f Merge branch 'Ambrosia' into Bias 2021-09-10 09:18:49 -06:00
aerinon a6e49513be Merge branch 'DoorDevUnstable' into Ambrosia 2021-09-10 09:17:23 -06:00
aerinon a7fffd3267 More refinement for prize locked parts of a dungeon and key rule interaction 2021-09-10 09:13:20 -06:00
aerinon ec7c1489c7 Removed rails flag and just edited the object table for prevent mode in mixed travel
Updated rails in PoD Arena to prevent hovering better
2021-09-07 16:25:42 -06:00
aerinon e48dbe3d27 Prize relevance refinement
Subtle change on bk restriction - only restrict if bk was determined to be the way forward
2021-09-02 18:10:49 -06:00
aerinon 2760841836 Prevent keys doors on door pairs that loop on themselves in the same supertile. (Excludes dead ends)
Thus, there's not chance for a keys to be wasted.
2021-09-02 17:00:36 -06:00
aerinon cb8a168b6c Merge pull request #123 from Catobat/ItemPool
Fix money balancing with reduced item pool
2021-09-01 15:57:14 -06:00
codemann8 4656dee601 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-31 19:49:52 -05:00
codemann8 e8ef3bfc9b Version bump 0.1.9.1 2021-08-31 19:44:58 -05:00
codemann8 d066b133f1 Merged in DR v0.5.1.1 2021-08-31 19:39:23 -05:00
codemann8 4567901cd9 Base ROM changes from upstream DR 2021-08-31 19:29:26 -05:00
aerinon 84fb47ba9d Couple of big key logic fixes - one with bk forced
Another with bk assumed to be found early in dungeon
Catobat map check fix from rom
2021-08-31 15:36:38 -06:00
aerinon 10c01034fd Minor rom fix 2021-08-31 14:10:47 -06:00
aerinon dad6016498 Rom features: update cutofftable
Add a multiworld ram slot for item that just got grabbed
2021-08-30 15:57:45 -06:00
aerinon 07287d85a7 Improve exclusion calculation 2021-08-30 15:21:25 -06:00
aerinon 67c4fee636 Boss shuffle fix - fixes some bias discovered by krebel 2021-08-30 15:20:27 -06:00
codemann8 e03fa2f542 Fixed missing flipper rule for IP Leave 2021-08-27 18:30:36 -05:00
codemann8 30aeeedb6e Fixed missing flipper rule for IP Leave 2021-08-27 16:43:16 -05:00
aerinon 91fbcd38da Fix shop hints in ER modes where shops are not located vanilla 2021-08-27 15:13:37 -06:00
aerinon 9e7223795f Fix for path checking. should get pinball more often 2021-08-27 15:03:27 -06:00
aerinon 759e9979da Rule fix for bigkey shuffle, use the always_allow for the big key, but require it for every other item 2021-08-26 15:51:12 -06:00
aerinon 23352c3bf7 Correct promotion of map and compass to advancement to add that logic 2021-08-26 15:36:12 -06:00
aerinon 4e8a8d2840 Compass/Map can be progressive
Fixed filter_for_potential_bk_locations
Changed rules to use dungeon_table
2021-08-26 15:33:27 -06:00
aerinon 5c835dc243 Fix can_beat_game error
Add start_region awareness to door finder combinations
Added dungeon table
2021-08-26 15:33:08 -06:00
aerinon 1f884649d1 Remove unnecessary imports 2021-08-26 15:32:35 -06:00
aerinon 5614dea2b5 Fix can_beat_game error
Add start_region awareness to door finder combinations
Added dungeon table
2021-08-26 15:28:42 -06:00
aerinon 746a739339 Main structure for various biased fills
Lots of help around correctly reserving locations
2021-08-26 15:27:05 -06:00
aerinon 4d776e0fee Compass/Map can be progressive
Fixed filter_for_potential_bk_locations
Changed rules to use dungeon_table
2021-08-26 15:25:29 -06:00
aerinon 6f06dbcd04 Fix can_beat_game error
Add start_region awareness to door finder combinations
Added dungeon table
2021-08-26 15:21:10 -06:00
codemann8 5bf5f5388c Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-26 08:02:24 -05:00
codemann8 af96bce77b Version bump 0.1.9.0 2021-08-26 08:02:06 -05:00
codemann8 51269bc1b3 Updated OW GUI layout 2021-08-26 06:00:00 -05:00
codemann8 a755453061 Updated baserom
- Fixes TR Pegs issue when fluting direct to TR Pegs from area with hammerpegs
- Changed Crossed OW to only affect Link state on world change
2021-08-26 00:55:37 -05:00
codemann8 0b05ec9927 Improved accuracy of Crossed OW flag in ROM 2021-08-25 02:22:59 -05:00
codemann8 151506d130 Play SFX on crossworld transition in Crossed OW 2021-08-25 02:22:21 -05:00
codemann8 0f8efed663 Fixed Limited OW to abide by Keep Similar option 2021-08-24 23:26:57 -05:00
codemann8 16e004060f Fixed issue with Grouped/Mixed+None/Chaos Crossed shuffles 2021-08-24 04:53:55 -05:00
codemann8 b2bcdfd286 Expanded and restructured OW Shuffle to include more Crossed options 2021-08-24 02:39:24 -05:00
codemann8 d1b0b57d53 Retain Link state on transition in Crossed OW unless bunny 2021-08-21 18:19:57 -05:00
codemann8 c3e713fcf7 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-20 23:02:09 -05:00
codemann8 3da44b6b94 Changelog update 2021-08-20 23:01:56 -05:00
codemann8 ade332dad2 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-20 22:56:27 -05:00
codemann8 365f11564a Version bump 0.1.8.2 2021-08-20 22:56:14 -05:00
codemann8 2471bc2f10 Fixed Bunny/Lonk issues in Crossed OW 2021-08-20 22:48:05 -05:00
codemann8 eb9dc8df75 Fixed Flute crashes 2021-08-20 20:44:13 -05:00
aerinon f259e8bdc8 Boss item restriction logic added
Reserved location logic started
2021-08-20 14:32:54 -06:00
codemann8 f051e3a0b2 Some Inverted situations getting applied/removed in Mixed OW 2021-08-20 14:08:29 -05:00
codemann8 d2610a891f Merged in DR v0.5.1.0 2021-08-20 13:10:27 -05:00
codemann8 22bbbaa521 Fixed issue with vanilla key logic check 2021-08-20 12:33:19 -05:00
codemann8 80fc18146a Fixed issue with Keep Similar getting turned on incorrectly in Mystery 2021-08-20 12:30:42 -05:00
aerinon b2a6e4a7d4 Update release notes 2021-08-20 10:06:45 -06:00
aerinon 939d495be7 Merge in combinatoric key logic from keyLogicAttempt1 branch 2021-08-20 10:03:40 -06:00
codemann8 94a70dbac9 Fixed spoiler log to show Crossed OW in all cases 2021-08-20 08:11:58 -05:00
codemann8 a04184f3e6 Fixed spoiler log to show Crossed OW in all cases 2021-08-20 08:11:32 -05:00
codemann8 b130b0b76b Fixed issue with Mixed and Crossed getting turned on incorrectly in Mystery 2021-08-20 08:09:45 -05:00
codemann8 ed1332b691 Combined grouping combinations of Parallel+NonCrossed and Vanilla+Crossed 2021-08-20 05:47:15 -05:00
codemann8 7b0ca2ef6d Fix for keeping Std connections vanilla in Standard+Parallel OW 2021-08-20 05:00:06 -05:00
codemann8 08ecf261a4 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-19 21:54:07 -05:00
codemann8 ee244f2b24 Actually fixed Mixed flag problems 2021-08-19 21:53:45 -05:00
codemann8 4ad6931d89 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-19 20:38:07 -05:00
codemann8 af1960fe66 Version bump 0.1.8.1 2021-08-19 20:37:55 -05:00
codemann8 b58a194956 Fixed Parallel+Crossed failing generation 2021-08-19 20:34:02 -05:00
codemann8 bae81b58ce Moved OW flag checks to global variable 2021-08-19 20:02:12 -05:00
codemann8 4e8758c647 Fixed missing OW flag check changes 2021-08-19 18:48:44 -05:00
aerinon 4e91e627e1 Split dungeon refinement
Prize relevance refinement
2021-08-19 16:21:42 -06:00
aerinon 25bc968b62 Key counts for vanilla fixed 2021-08-19 16:15:05 -06:00
codemann8 03e9f24ce2 Fixed infinite loop issue in OW Shuffle 2021-08-19 09:58:41 -05:00
codemann8 340e4f766e Added new indirect connections in prep for Big Bomb rules 2021-08-19 08:38:52 -05:00
codemann8 f2432e13fb Added new Dark Graveyard North region 2021-08-19 08:37:46 -05:00
codemann8 e06b99854b Fixed missing Swordless Mire entry rule 2021-08-19 08:36:25 -05:00
codemann8 621e6442ce Fixed Standard mode to exclude Flute exits from traversal logic 2021-08-18 09:23:13 -05:00
codemann8 c943435a23 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-17 15:08:01 -05:00
codemann8 ec327ca5a9 Version bump 0.1.8.0 2021-08-17 15:07:50 -05:00
codemann8 5fb394aba1 Fixed issue with Pyramid Hole not shuffling 2021-08-17 10:26:05 -05:00
codemann8 f68522edac Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffleDev 2021-08-16 22:52:31 -05:00
codemann8 8ff463b5c7 Plando support for OW edges 2021-08-16 22:50:03 -05:00
codemann8 323235ba26 Fixed issue with Sanc in TR start as bunny if TR tile is swapped 2021-08-16 22:47:43 -05:00
codemann8 be6203e3f0 Moved Crossed OW Shuffle to its own setting, Renamed Tile Swap to Mixed 2021-08-16 22:46:26 -05:00
aerinon e34218c7a9 Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable 2021-08-16 15:30:37 -06:00
aerinon 71079269fa Total keys fix for key logic
(Basic reductions do not affect amount of keys placed while crossed does)
2021-08-16 15:29:40 -06:00
aerinon b53a005545 Fix for last ditch problems
Special bk adjustments
Exception for self locking key doors in key lock checker
2021-08-16 15:28:20 -06:00
codemann8 7b81c5d9da Minor code cleanup 2021-08-16 00:55:07 -05:00
codemann8 181e6e6f84 Minor fix Pyramid Entrance hint in Insanity ER 2021-08-16 00:38:52 -05:00
codemann8 cda70f783a Removal of legacy ER shuffles 2021-08-13 22:11:58 -05:00
aerinon 54004118f5 Minor bug during exploration 2021-08-13 14:41:35 -06:00
aerinon 678e5eb091 Multi-entrance crystal doesn't propagate between dungeons
Multi-entrance: don't use unreachable entrances for reachable stats
2021-08-13 14:41:04 -06:00
codemann8 acf20cb552 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-13 05:37:00 -05:00
codemann8 651f057adc Version bump 0.1.7.4 2021-08-13 05:36:49 -05:00
codemann8 2b4c4a6595 Various Mixed OW Shuffle (Inverted) fixes 2021-08-13 05:31:07 -05:00
codemann8 899e044447 Separated default connections to grouped lists 2021-08-13 05:10:47 -05:00
codemann8 8373ea2e19 Merged in DR v0.5.0.2 2021-08-13 04:58:27 -05:00
codemann8 e3695e6d56 Fixed issue with shuffling dropdowns in Mixed OW shuffle 2021-08-13 03:37:01 -05:00
aerinon fd24c016e2 Total keys fix for key logic
(Basic reductions do not affect amount of keys placed while crossed do)
2021-08-12 15:59:01 -06:00
aerinon e052468dba Merge pull request #122 from StructuralMike/DoorDevUnstable
Change the bomblogic-CLI to bombbags and add it to the example mystery yaml
2021-08-12 13:53:58 -06:00
aerinon 6205dc2cb0 Merge in unstable changes 2021-08-12 13:50:34 -06:00
aerinon de6f3683d0 Fixed bug with sfx_shuffle in mystery 2021-08-12 13:45:51 -06:00
aerinon d6a56e645e Bug with MutliClient that didn't register shop locations unless you were in one 2021-08-12 13:45:20 -06:00
aerinon 9153dbd382 Fixed a problem that cropped up in retro+vanilla with big key placement 2021-08-12 13:44:47 -06:00
aerinon 7623de396c Fixed some bk special handling 2021-08-12 13:39:32 -06:00
codemann8 2f957df3fa Fixed issue with Swapped Ganon Hole not being accessible 2021-08-11 20:59:44 -05:00
StructuralMike dcba2be757 Bombbag instead of Bombbags 2021-08-11 16:29:12 +02:00
codemann8 cb16a33da9 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-11 06:11:54 -05:00
codemann8 e8c46cf251 Version bump 0.1.7.3 2021-08-11 06:11:41 -05:00
codemann8 b3a3adb2f0 Various music fixes
MSU-1 LW2 track changes on Aga1 Kill instead of ped pull
Fixed ambient SFX stutter issue
2021-08-11 06:05:46 -05:00
StructuralMike 44efe51e02 Changing the cli to be bombbags over bomblogic
Bombbags seemed better over bomblogic which is more ambiguous when considering new stuff OW and the bomb-only modes.

Also added bombbags to the example yaml
2021-08-11 10:22:54 +02:00
StructuralMike cf8d716b37 Merge pull request #3 from aerinon/DoorDevUnstable
Door dev unstable
2021-08-11 10:11:40 +02:00
codemann8 9fa89d9d3d Fixed issue with vanilla OW failing to pick a filename 2021-08-08 18:38:51 -05:00
Catobat 579c3bfd23 Fix money balancing with reduced item pool 2021-08-06 14:17:24 +02:00
aerinon feb9177871 Ignore certain rules when bk isn't available in contradiction checking 2021-08-04 13:46:30 -06:00
aerinon d7e326f71d Key checking in dungeons limited to single player for speed
Spoiler traversal fixes and speed
Bug with boss shuffle spoiler in MW fixed
Perf enhancement fix for pot shuffle
2021-08-04 12:08:17 -06:00
codemann8 8677a0313c Fix LW/DW marking in copy_world 2021-08-03 20:36:10 -05:00
codemann8 d71a246dc1 Excluding water regions from flute access 2021-08-03 20:30:25 -05:00
codemann8 917e8a920c Made flute pathing visible in spoiler log 2021-08-03 17:33:45 -05:00
codemann8 6d98636626 Made flute pathing visible in spoiler log 2021-08-03 17:28:20 -05:00
aerinon 4b29408911 Perf enhancement fixes 2021-08-03 13:49:46 -06:00
aerinon e10c765bc2 Key logic 2021-08-03 12:16:29 -06:00
aerinon 24b01cfcc7 Performance optimizations 2021-08-03 09:26:41 -06:00
aerinon aeb910e274 Various fixes:
Full boss shuffle samples without replacement
Vanilla doors simply unmarks ugly smalls
Money balance: handle multiworld solvent players better
Perf for item pool adjustment
Add loglevel to Mystery
2021-08-03 08:43:47 -06:00
codemann8 229747b4a4 Added dynamic flute exits 2021-08-03 09:29:16 -05:00
codemann8 bcde69fad2 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-02 20:33:31 -05:00
codemann8 935b257ad9 Minor formatting 2021-08-02 20:33:19 -05:00
aerinon cd86e14677 Merge in Unstable changes 2021-08-02 15:26:43 -06:00
aerinon bcaee735a2 SFX shuffle added 2021-08-02 15:24:13 -06:00
aerinon c8dcdcc62c Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable 2021-08-02 15:23:43 -06:00
aerinon cab5f22390 Merge pull request #121 from StructuralMike/DoorDevUnstable
Define bomb upgrade as advancement before beemizer
2021-08-02 15:22:06 -06:00
aerinon 1871b7ee6e Merge branch 'SFXShuffle' into DoorDevUnstable 2021-08-02 12:40:52 -06:00
aerinon 50296915a7 Uncertain key rule change (keeping my eye on it) 2021-08-02 12:40:29 -06:00
aerinon 8a361e9672 Various refinements and fixes to key logic and generation 2021-08-02 12:39:48 -06:00
codemann8 1961a16084 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-08-02 04:23:32 -05:00
codemann8 3f9edbc599 Version bump 0.1.7.2 2021-08-02 04:23:16 -05:00
codemann8 bb5830686e Fixed music algorithm in OW Shuffle 2021-08-02 04:20:49 -05:00
codemann8 6332b48c3a Removed convenient portal on DM for OW Layout Shuffle 2021-08-01 23:49:26 -05:00
StructuralMike c06477c0f2 Update ItemList.py 2021-07-29 15:51:56 +02:00
StructuralMike 4c15c193f4 Set bomb upgrades as advancement before beemizer
Beemizer can replace bomb upgrades in bomblogic unless they're tagged as advancement earlier
2021-07-29 15:27:49 +02:00
codemann8 b6f913596b Fixed Mystery to not spoil OW Shuffle in filename 2021-07-29 07:10:46 -05:00
codemann8 39dd9e6caa Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-29 06:51:30 -05:00
codemann8 730b97b37f Fixed Flute Shuffle overwriting OW Swap in Mystery 2021-07-29 06:51:18 -05:00
codemann8 91e407f7db Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-29 03:52:30 -05:00
codemann8 64fd35f7fc Version bump 0.1.7.1 2021-07-29 03:52:19 -05:00
codemann8 25667b6c01 Fixed mystery terminology for OW modes 2021-07-29 03:51:51 -05:00
codemann8 166b24c4b2 Fixed mystery terminology for OW modes 2021-07-29 03:46:57 -05:00
codemann8 c14ad502cd Adding tree pulls, bush crabs, and stun prizes to logic consideration 2021-07-29 03:40:45 -05:00
codemann8 e28d2c331d Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-28 21:19:24 -05:00
codemann8 e9957d87dd Added bomb caves to bomb logic 2021-07-28 21:06:19 -05:00
codemann8 b06d868c5b Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-28 20:52:09 -05:00
codemann8 f9da22f920 Version bump 0.1.7.0 2021-07-28 20:51:54 -05:00
codemann8 10be4c8bb1 Added bomb logic to OW and removed starting rupees/bombs in Mixed OW Shuffle 2021-07-28 20:51:01 -05:00
codemann8 19dca02c6e Added bomb logic to OW and removed starting rupees/bombs in Mixed OW Shuffle 2021-07-28 20:11:38 -05:00
codemann8 e1b8428d58 Merged in DR v0.5.0.1 2021-07-28 17:36:14 -05:00
codemann8 263a7d1db9 Minor formatting and trimming 2021-07-28 17:31:06 -05:00
codemann8 c04cb27aa9 Merged in DR v0.5.0.1 2021-07-28 17:09:31 -05:00
aerinon d70f2ee355 Small changes for bomblogic 2021-07-28 15:21:51 -06:00
aerinon 46de270923 Merge branch 'DoorDevUnstable' of https://github.com/StructuralMike/ALttPDoorRandomizer into StructuralMike-DoorDevUnstable 2021-07-27 16:16:53 -06:00
aerinon 65c583c082 Initial work on dungeon prize logic in key layouts 2021-07-27 16:00:05 -06:00
aerinon ce24017297 typo 2021-07-27 13:13:18 -06:00
aerinon c182e73b77 Mystery can apply reduce_flashing 2021-07-27 11:33:58 -06:00
aerinon bbad1d1d8b Version bump
Mystery can apply reduce_flashing
2021-07-27 11:33:10 -06:00
aerinon a1eb077f28 Boss music fix 2021-07-27 11:32:38 -06:00
aerinon 066d239b70 Boss music fix 2021-07-27 08:58:31 -06:00
codemann8 14079b373f Fix for boss music not playing in non-DR modes 2021-07-27 02:40:51 -05:00
aerinon 0975b64519 Merge pull request #120 from compiling/DoorDevUnstable
Extra warnings / checks
2021-07-26 13:06:46 -06:00
aerinon 322273673b stage unstable for next release cycle 2021-07-26 12:19:45 -06:00
aerinon 59e875dc6d updated readme and version 2021-07-26 11:28:45 -06:00
StructuralMike 9247c547d3 Update ItemList.py 2021-07-26 11:12:47 +02:00
StructuralMike e5e90fc805 Remove default bomb upgrades from shop 2021-07-26 11:09:24 +02:00
compiling 4d90ca9181 Add python version warning to the translation file. 2021-07-25 19:48:07 +10:00
compiling dc950112d9 Fix Aga rule for standard - should be Zelda + normal requirements. 2021-07-25 18:17:10 +10:00
compiling 4d8bfe0e22 Check for headered roms before passing to enemizer. 2021-07-25 18:15:51 +10:00
compiling c981b362d2 Add warning for old python versions. 2021-07-25 18:15:11 +10:00
StructuralMike 779c7d78c0 New hookshot cave region definitions 2021-07-24 17:22:48 +02:00
StructuralMike cce5adc453 Good bee cave & spiral cave logic for bombs
Good bee cave requires bombs to access.
Spiral cave is never assumed to be transversable as a super bunny, so it makes sense to force bombs OR can_kill_most_things if the cave is in the LW.
2021-07-24 14:21:22 +02:00
codemann8 dfa027b7aa Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-23 16:31:58 -05:00
codemann8 a8f92b5932 Undo ER Inverted AT changes from DR 2021-07-23 16:24:26 -05:00
codemann8 ec43ed2d39 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-23 16:19:13 -05:00
codemann8 330f4000a4 Version bump 0.1.6.9 2021-07-23 16:18:58 -05:00
codemann8 a4303fb4ab Updating securerandom for OW shuffle 2021-07-23 16:09:53 -05:00
codemann8 a897a8d52d Merged in DR v0.4.0.12 2021-07-23 16:08:32 -05:00
aerinon 8ed6b3fad2 Exception for DP back on basic,intensity level 1 (simply can't make a passage) 2021-07-23 12:37:41 -07:00
StructuralMike 051a47e0cd Bomblogic added 2021-07-23 20:35:48 +02:00
aerinon bfd5c5ceeb Update notes 2021-07-23 10:09:54 -07:00
aerinon c522a1b001 Aga Tower shouldn't choose inverted links house if not shuffled 2021-07-23 10:09:01 -07:00
aerinon 367a7be068 Update notes 2021-07-23 10:08:41 -07:00
aerinon c6ed7bcd04 Merge branch 'DoorDevUnstable' of https://github.com/ardnaxelarak/ALttPDoorRandomizer into ardnaxelarak-DoorDevUnstable 2021-07-23 10:04:02 -07:00
aerinon 5b39494edf Credit collection rate refactor
Music fixes and moving hooks
2021-07-23 09:45:12 -07:00
aerinon 46bfcb4dde Aga Tower shouldn't choose inverted links house if not shuffled 2021-07-23 08:39:31 -07:00
aerinon 23846dc475 credits again 2021-07-22 16:28:27 -07:00
aerinon 37b4d04d47 Inverted pathing fix (Castle S&Q may be required) 2021-07-22 16:26:27 -07:00
aerinon 8c1e746556 Inverted pathing fix (Castle S&Q may be required) 2021-07-22 16:26:08 -07:00
aerinon df0218c7a1 last ditch swap fixes 2021-07-22 16:09:28 -07:00
codemann8 9611d0757c Removed possibility to not remove flute spot from pool when chosen 2021-07-18 21:55:27 -05:00
codemann8 f54b095aab Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-18 06:10:41 -05:00
codemann8 4c1412f2de Version bump 0.1.6.8 2021-07-18 06:10:27 -05:00
codemann8 36f60c78b0 Fixed incorrect Collection Rate in credits 2021-07-18 06:08:02 -05:00
codemann8 a13975e4ff Implemented smarter Balanced Flute Shuffle 2021-07-18 06:07:27 -05:00
codemann8 bdde8591a7 Converted Tile Regions to bidict object 2021-07-16 19:47:47 -05:00
codemann8 dc0916b975 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-16 18:34:20 -05:00
codemann8 e12fda8a26 Changelog update 2021-07-16 18:34:08 -05:00
codemann8 6bd4a656aa Changelog update 2021-07-16 18:33:21 -05:00
codemann8 4054615516 Removed sortedcontainers dependency 2021-07-16 15:10:34 -05:00
codemann8 90026a839b Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-16 13:01:58 -05:00
codemann8 35162a50f9 Version bump 0.1.6.7 2021-07-16 13:01:41 -05:00
codemann8 e31af840cc Added minor commented data as prep 2021-07-16 12:51:44 -05:00
codemann8 b4cb3f2825 Merged in DR v0.4.0.11 2021-07-16 12:49:39 -05:00
codemann8 29039fef91 Moved Inverted specific entrances to mode-specific list 2021-07-16 12:43:08 -05:00
codemann8 dd2b7effcb Fixed AT/GT rules to follow Mode instead of OW Swap 2021-07-16 12:42:14 -05:00
codemann8 5cf0274aac Added flute spots to world copy 2021-07-16 12:41:25 -05:00
codemann8 94a1c3ad1c Fixed spoiler log to show more detail for Flute Shuffle 2021-07-16 12:09:45 -05:00
codemann8 eb7c901a69 Merge pull request #5 from compiling/OverworldShuffleDev
Copy owswaps so that the world used to generate the playthrough has correct logic.
2021-07-16 11:55:13 -05:00
compiling 2e60b374a6 Copy owswaps so that the world used to generate the playthrough has correct logic. 2021-07-16 22:36:33 +10:00
aerinon 68dc27902b SFX Shuffle initial implementation 2021-07-15 16:02:07 -07:00
aerinon 06486e88a2 Cutoff rug addition 2021-07-15 10:33:04 -07:00
aerinon a123661eca Don't fix ugly smalls in vanilla 2021-07-15 10:32:25 -07:00
aerinon b56f8d4136 Std+Retro: key logic for escape and exclude some bow logic sectors
Bug with reachable doors
2021-07-15 08:03:33 -07:00
codemann8 bd60c3f1c0 Split Tile Groups to reference new Tile Regions object 2021-07-14 14:30:02 -05:00
aerinon ff16a256b7 Merge branch 'Catobat-BombWalls' into DoorDevUnstable 2021-07-13 13:19:55 -07:00
aerinon 15a9436e6d Merge branch 'BombWalls' of https://github.com/Catobat/ALttPDoorRandomizer into Catobat-BombWalls 2021-07-13 13:19:38 -07:00
aerinon b5aae926e7 Minor baserom updates 2021-07-13 13:19:14 -07:00
aerinon 9ef24a610d Bug with key flooding (events that would flood the key are not unresolved)
Last ditch placement efforts for when things get stuck (crossed standard mostly)
2021-07-13 10:38:14 -07:00
aerinon 8c2b6f3bd2 Can't have a key at blind unless you can crack the floor and deliver the maiden 2021-07-12 15:54:38 -07:00
codemann8 fc2457678f Allowed Mountain Entry and West DM to be shuffled independenty in OW Tile Swap 2021-07-12 01:51:22 -05:00
Catobat 0ade4c5795 Counters no longer needed 2021-07-12 04:21:34 +02:00
Catobat 6f990aecc1 More bomb door candidates 2021-07-12 01:28:52 +02:00
codemann8 8ca7189dc1 Consolidated some logic for Vanilla/Dungeon ER 2021-07-11 14:45:27 -05:00
codemann8 ab0625e413 Fixed issue with Pyramid Exit leading to vanilla Pyramid Exit Ledge instead of HC Ledge 2021-07-11 12:26:09 -05:00
codemann8 38f1d78f9a Minor formatting 2021-07-11 12:25:24 -05:00
codemann8 43ac239b1c Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-10 13:53:45 -05:00
codemann8 0224aeb4a4 Version bump 0.1.6.6 2021-07-10 13:53:38 -05:00
codemann8 e89442a3a0 Merged in DR v0.4.0.9 2021-07-10 13:51:04 -05:00
codemann8 0571dc881b Removing Central Bonk Rocks from Tile Swap pool in Standard 2021-07-10 13:49:33 -05:00
aerinon e6b5d62e5d Merge Unstable changes 2021-07-09 15:27:47 -07:00
aerinon 940369d3ec Rename fake boots to pseudo boots
Doc updates
2021-07-09 15:13:01 -07:00
aerinon c52a8e3390 Fix --hints flag on CLI 2021-07-09 15:00:49 -07:00
aerinon 3bf96a156c Fix --hints flag on CLI 2021-07-09 15:00:14 -07:00
aerinon 63fcdf9424 Merge Unstable fixes 2021-07-09 11:02:40 -07:00
aerinon 3f0f15650a Fix for stats and p/c indicator 2021-07-09 10:55:37 -07:00
aerinon 28dd7d0f3c Merge branch 'SwampFix' of https://github.com/Catobat/ALttPDoorRandomizer into Catobat-SwampFix 2021-07-09 10:50:05 -07:00
codemann8 5373a6ea85 Removing Central Bonk Rocks from Tile Swap pool in Standard 2021-07-08 20:28:18 -05:00
codemann8 c6e0f4fc14 Added Rain state guards for Dark Bonk Rocks 2021-07-08 14:09:17 -05:00
codemann8 322f70a979 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-07-07 20:10:30 -05:00
codemann8 218902b9e9 Version bump 0.1.6.5 2021-07-07 20:10:19 -05:00
codemann8 30efdfb65d Better handling of when sortedcontainers is missing 2021-07-07 19:53:49 -05:00
codemann8 02d3b46ae4 Merged in DR v0.4.0.8 2021-07-07 19:45:14 -05:00
aerinon 9c65dff66f Merge branch 'DoorDevUnstable' into KeyLogicAttempt1 2021-07-07 16:24:23 -07:00
aerinon ffcc78f95c Fake boots checkbox/argument 2021-07-07 16:23:16 -07:00
Catobat 2dd89197f3 Reset variable between attempts 2021-07-08 01:09:30 +02:00
Catobat 86a19249ab Fix Swamp Portal check 2021-07-08 00:58:58 +02:00
aerinon fb22c88ace Baserom update 2021-07-07 14:04:50 -07:00
codemann8 d110555691 Reduced chance of diagonal flute spot 2021-07-07 12:24:48 -05:00
codemann8 11f77f78d2 Reduced chance of diagonal flute spot 2021-07-07 12:01:41 -05:00
aerinon 3cb981d6ae Merge branch 'DoorDevUnstable' into KeyLogicAttempt1 2021-07-06 13:46:14 -07:00
aerinon f21dace6d5 A couple minor generation issues
Updated release note
2021-07-06 13:45:45 -07:00
aerinon 0f29d2c2b0 Credit stats fix for now 2021-07-06 13:26:36 -07:00
aerinon 3cc4175160 Attempt at catching bps issues 2021-07-06 13:22:24 -07:00
aerinon 0607cf67ef Insanity: blacksmith/bomb shop placement shouldn't preclude another multi-exit cave from exiting there 2021-07-06 13:21:51 -07:00
aerinon 96e4ba3e2e Insanity: blacksmith/bomb shop placement shouldn't preclude another multi-exit cave from exiting there 2021-07-06 13:20:28 -07:00
codemann8 0b1562dab8 Fixed Stumpy 2021-07-06 14:44:40 -05:00
codemann8 0dd5516e07 Renamed Hammer Pegs regions 2021-07-06 14:44:13 -05:00
codemann8 26ee44fa21 Version bump 0.1.6.4 2021-07-06 14:35:14 -05:00
codemann8 a420d80d93 Fixed Stumpy not loading 2021-07-06 14:31:25 -05:00
codemann8 491580bead Added OW Shuffle examples to sample Mystery yaml file 2021-07-06 12:16:04 -05:00
codemann8 e2604d992e Fixed Frogsmith spawn to load correct sprite and accept him at home 2021-07-06 12:15:17 -05:00
codemann8 3d4cc99ac5 Added install instruction 2021-07-04 13:13:44 -05:00
codemann8 e789531e36 Fixed local_install.py to work when double-clicked 2021-07-04 12:29:46 -05:00
codemann8 e43c67ee80 Fixed local_install.py to work when double-clicked 2021-07-04 12:07:03 -05:00
codemann8 b0a7237744 Version bump 0.1.6.3 2021-07-04 11:42:22 -05:00
codemann8 c3b6699c34 Adding OW Rando credits 2021-07-04 11:38:34 -05:00
codemann8 ca37a55046 Adding OW Rando credits 2021-07-04 11:29:44 -05:00
codemann8 433a1dfc35 Doing GitHub's work for them and ACTUALLY merging in DR v0.4.0.7 changes 2021-07-04 11:23:08 -05:00
aerinon 7fde95e5d7 Small refinements for key logic 2021-07-02 16:13:02 -06:00
codemann8 6e49f38bce Updated install instructions 2021-07-02 00:29:34 -05:00
codemann8 ad26921d96 Updated install instructions 2021-07-02 00:22:29 -05:00
aerinon 3fd096844c Fixed the shop spoiler when multiworld balancing 2021-07-01 16:52:16 -06:00
aerinon 1fb849c137 Fixed the shop spoiler when money balancing is needed 2021-07-01 16:48:39 -06:00
aerinon 1a7c3faa76 Fixed some enemizer mystery settings
Added an easy way to turn off unkillable thieves
2021-07-01 16:25:55 -06:00
aerinon f15832f85e Refinement - Missing blocked_connections added - appropriate checklists
Optimization - Exp Cache - which is somewhat problematic with the playthrough logic
2021-07-01 16:00:47 -06:00
codemann8 02248768ec Version bump 0.1.6.2 2021-06-30 02:08:14 -05:00
codemann8 0bca3d881c Fixed bad flute data 2021-06-30 02:05:15 -05:00
codemann8 97dcf31af9 Fixed bad flute data 2021-06-29 22:59:53 -05:00
codemann8 f8e758634b Fixed Inverted Kakariko Portal to require glove 2021-06-29 22:55:45 -05:00
codemann8 301e88a6e9 Implemented Balanced Flute Shuffle
Doesn't consider OW Layout Shuffle
2021-06-29 18:03:47 -05:00
aerinon b21564d5aa Combinatoric approach revised (KLA1)
Backported some fixes
2021-06-29 16:34:28 -06:00
codemann8 2394e07e4b Made flute spots order on menu based on OW Slot rather than OWID 2021-06-29 17:28:51 -05:00
codemann8 4b994b173e Added midpoint data to OW Edges 2021-06-29 16:26:06 -05:00
karafruit 3896066193 Reimplement --securerandom
Seeds should be reproducable without the flag passed, and unreproducable with the flag passed.
With --securerandom, generate a 9-char alphanumeric string to use to make filenames differ.
2021-06-29 11:13:17 -07:00
codemann8 a4e3ed1e4f Version bump 0.1.6.1 2021-06-29 03:35:43 -05:00
codemann8 0a1f01040d Removed ROM buffer reads 2021-06-29 03:32:03 -05:00
codemann8 7379f7c7d9 Fixed some wrong ER code in Insanity 2021-06-29 03:30:57 -05:00
codemann8 170d18191c Fixed Houlihan to exit out where Links House does 2021-06-29 03:06:51 -05:00
codemann8 84454a348b Fixed bad flute data 2021-06-29 02:13:38 -05:00
codemann8 f62a165353 Switching rom buffer writes to function call 2021-06-29 01:07:14 -05:00
codemann8 cd16b8c60b Forced Pedestal and Hobo to we swapped together in OW Tile Shuffle, due to those areas sharing the same supertile 2021-06-28 13:01:57 -05:00
codemann8 d2ac1d097d Version bump 0.1.6.0 2021-06-27 19:11:33 -05:00
codemann8 27560a7457 Reorganized OW Shuffle GUI 2021-06-27 19:11:05 -05:00
codemann8 42eddaed28 Initial Flute Shuffle implementation 2021-06-27 19:10:44 -05:00
codemann8 d3fd54600f Added ability to cancel out of flute menu by pressing X 2021-06-27 14:50:28 -05:00
codemann8 15ffecb6fb Moved Game Options settings up in GUI 2021-06-25 18:47:18 -05:00
codemann8 cc3ac49c57 Rearranged OW Shuffle GUI 2021-06-25 16:36:00 -05:00
codemann8 8911b6eb31 Version bump 0.1.5.3 2021-06-25 15:25:14 -05:00
codemann8 62e7732091 Fixed issue with Frog WS and Dig Game ES were getting duplicated in edge pool 2021-06-25 15:22:47 -05:00
codemann8 e62b2678bb Fixed Aga portal mirror bonk issue 2021-06-25 13:03:34 -05:00
codemann8 f4e5202bf2 Fixed VRAM issue 2021-06-24 14:47:57 -05:00
codemann8 e0ee300809 Version bump 0.1.5.2 2021-06-24 14:38:36 -05:00
codemann8 ea2a148e78 Partial revert of VRAM adjustment 2021-06-24 14:36:12 -05:00
codemann8 62ed585a24 Version bump 0.1.5.1 2021-06-23 18:08:32 -05:00
codemann8 078c09bfdf Fixed issue with Flute Spot 7 not logically linking to correct area 2021-06-23 18:05:01 -05:00
codemann8 a55db99a6a Fixed logic bug with TR Portal in Inverted 2021-06-23 17:00:23 -05:00
aerinon 62fff1f6e1 Update text
Add ganon jokes for when there are no silvers
2021-06-23 13:42:23 -06:00
codemann8 5c55f383b1 Made generation fail if issue with no parallel link found 2021-06-23 11:35:26 -05:00
codemann8 df2f355bc5 Version bump 0.1.5.0 2021-06-23 11:20:30 -05:00
codemann8 36f6092399 Merge branch 'DoorDevUnstable' into OverworldShuffleDev 2021-06-23 11:16:09 -05:00
codemann8 a6b4ac61ae Merged DR 0.4.0.7 2021-06-23 11:01:06 -05:00
codemann8 860854b0dc Fixed horizontal VRAM loading glitch on megatiles 2021-06-23 08:42:29 -05:00
codemann8 8f2651c33b Added starting bombs and rupees for OW Mixed/Crossed 2021-06-23 05:38:58 -05:00
codemann8 177a7ee44a Whoops 2021-06-23 05:34:09 -05:00
codemann8 6cd6dca6a3 Initial Tile Shuffle Implementation 2021-06-23 03:09:27 -05:00
aerinon 11dcc719fb Stop attempting to download link sprite
Create link sprite from local rom if missing
Fixing output_path bugs in the adjuster and sprite display
2021-06-22 16:05:41 -06:00
aerinon f77015ab00 Baserom update 2021-06-22 13:13:15 -06:00
aerinon 8c5a4be480 Ranged crystal switch logic tweaked
Couple of minor bugs fixed
2021-06-22 13:04:37 -06:00
aerinon 23ffc61667 Sprite author credit
Reduce flashing option
2021-06-07 11:13:28 -06:00
codemann8 3e9a72e5b7 Moved OW shuffle group reorganization to separate function for readability 2021-06-07 11:12:31 -05:00
codemann8 de2aff6724 Adding new GUI/CLI option for OW Tile Swap 2021-06-07 10:52:47 -05:00
codemann8 78d89497c3 Made new HC region for Inverted access to Bush-blocked area 2021-06-07 08:50:08 -05:00
codemann8 b1446361fd Removed unused edge grouping 2021-06-06 10:42:28 -05:00
codemann8 5f53cf62bb Marking OWEdge exits separately from Entrances 2021-06-06 10:41:41 -05:00
codemann8 afcc9bbbe0 Minor rename 2021-06-06 08:49:46 -05:00
codemann8 563e2ba5b0 Version bump 0.1.4.3 2021-06-04 22:01:55 -05:00
codemann8 98a7047168 Merged DR 0.4.0.6 2021-06-04 21:58:27 -05:00
aerinon c45dab6a7c Bee trap pricing 2021-06-04 16:37:20 -06:00
codemann8 f26e427a57 Indentation 2021-06-03 16:58:19 -05:00
aerinon 139fe4d47f Full clipping of rug on marked rooms 2021-06-03 14:05:26 -06:00
aerinon 7442d66211 Old Man House bunny spawn
Cutoff bounding box implemented
Added a couple more lobby possibilities
2021-06-03 13:56:57 -06:00
codemann8 6c09dfdc5f Version bump to 0.1.4.2 2021-06-03 11:45:27 -05:00
codemann8 1186c24c3f Merged DR v0.4.0.5 2021-06-03 11:36:24 -05:00
codemann8 efad9179e4 Added map terrain changes specific to OW Shuffle 2021-06-03 10:55:07 -05:00
codemann8 0ed01e6840 Added convenient portals on WDM for OW Shuffle 2021-06-03 08:05:52 -05:00
codemann8 16734d9ee5 Added convenient portals on WDM for OW Shuffle 2021-06-03 07:37:35 -05:00
codemann8 e227033692 Made world checks table-based rather than based on OW ID 2021-06-03 00:50:57 -05:00
aerinon c81865b33f Remove cap upgrades for hard/expert
Replace cap upgrades with red rupees in shopsanity
2021-06-02 13:28:33 -06:00
aerinon 63d49c5775 Beemizer stuff 2021-06-02 11:15:22 -06:00
aerinon 46ccfedcdc Blind Attic hint in crossed
Hint default change to False, moved GUI checkbox
2021-06-02 10:51:21 -06:00
aerinon 5c60f1996e Merge branch 'Player' of https://github.com/Catobat/ALttPDoorRandomizer into Catobat-Player 2021-06-01 14:52:53 -06:00
aerinon e0479922cc Msu minor fix
Bosses simple fix
Boss shuffle mystery fix
2021-06-01 14:52:23 -06:00
aerinon 87c4c0811a Inverted fix for insanity 2021-06-01 09:33:15 -06:00
codemann8 a32d37a233 Minor reorganization of code/data placement 2021-05-30 06:43:52 -05:00
codemann8 51278877ba Delete 001.link.1.zspr 2021-05-29 10:54:46 -05:00
Catobat b071191e9b Remove unreachable code 2021-05-29 17:02:29 +02:00
Catobat 4243494b66 Write Pot Shuffle setting to spoiler 2021-05-29 16:57:34 +02:00
Catobat 9fbfa337d7 Fix missing "[player]"s 2021-05-29 16:52:22 +02:00
codemann8 41f5c62973 Fixed issue with Swordless not giving silvers in restrictive item pool modes 2021-05-29 08:29:36 -05:00
codemann8 ec467d85d7 Version bump to 0.1.4.1 2021-05-28 21:00:51 -05:00
codemann8 1123d686d5 Fixed issues with generating Inverted and Insanity seeds 2021-05-28 20:58:16 -05:00
codemann8 4e3d506d4c Merged in DR Insanity shuffle issue fix 2021-05-28 20:57:11 -05:00
codemann8 23096a9724 Replaced unnecessary Inverted entrance lists 2021-05-28 20:00:09 -05:00
aerinon dfe824069a Insanity restrictions lifted on multi-entrance caves and dungeon exits 2021-05-28 16:01:09 -06:00
codemann8 aad2038899 Moved Inverted Pyramid Entrance to HC Ledge 2021-05-26 21:17:45 -05:00
codemann8 6caa4b5438 Moved Inverted Pyramid Entrance to HC Ledge 2021-05-26 21:08:57 -05:00
aerinon f49dffa91a Fix typo 2021-05-26 08:37:50 -06:00
codemann8 4288e73f83 Minor text output change 2021-05-26 03:51:28 -05:00
codemann8 9da5888d4d Version bump 2021-05-26 02:59:18 -05:00
codemann8 5f919617fe Renamed regions and exits related to Mountain Entry 2021-05-26 02:58:45 -05:00
codemann8 80f2ac7a3f Completed initial Inverted implementation 2021-05-25 21:10:51 -05:00
codemann8 6bdd63be45 Renamed regions and exits related to Mountain Entry 2021-05-25 20:29:53 -05:00
codemann8 a56db37d6f Fixed missing Flipper check for Kakariko Pond Whirlpool 2021-05-25 20:26:31 -05:00
codemann8 667b568630 Version Bump 0.1.3.1 2021-05-24 18:47:27 -05:00
codemann8 78a1f31d74 Moved Shuffle Links option in GUI 2021-05-24 18:20:14 -05:00
codemann8 8545f6696d Merged in DR v0.4.0.4 2021-05-24 18:16:02 -05:00
aerinon fff7cd691e Added the --shufflelinks option
Moved bunny spawn to experimental
Baserom bugfixes
2021-05-24 15:14:23 -06:00
codemann8 63eabfa2a1 More Inverted Prepwork 2021-05-24 04:54:32 -05:00
codemann8 a76d7f7cfd Fixed Standard generation 2021-05-24 04:08:28 -05:00
codemann8 a9325ea355 More Inverted improvements 2021-05-24 00:39:41 -05:00
codemann8 9d70a8c19d Update TestSuite with OW shuffle options 2021-05-23 23:20:20 -05:00
codemann8 daae593aa8 Added logging to OW class 2021-05-23 16:10:46 -05:00
codemann8 9b20583d01 Fixed incorrect OW connection destinations 2021-05-23 16:10:20 -05:00
codemann8 9aca8af16d More Inverted changes 2021-05-23 07:50:30 -05:00
codemann8 f796a421cf Fixed mirrorless_path check to ensure actual mirrorless path 2021-05-23 07:37:21 -05:00
StructuralMike e77ae23359 fixing my illogical logic 2021-05-21 12:44:29 -06:00
codemann8 ae698a1181 Reordered OW connections 2021-05-21 07:59:53 -05:00
codemann8 e363773810 Initial Inverted implementation
Missing Flute and mirror exits
Missing removal and redirection of deprecated inverted rules
2021-05-20 05:47:42 -05:00
codemann8 b342896ff7 Moved static OW data to OWEdges 2021-05-19 04:59:33 -05:00
codemann8 5be9983159 Updated Base ROM with MSUMuteFix 2021-05-19 04:58:35 -05:00
aerinon 8f00f7969b Actually restrict Sanctuary from being a DW lobby in non-crossed ER modes 2021-05-17 13:41:32 -06:00
codemann8 8faacaaa42 Added HC Main Gate to Standard list of exits that require Zelda Delivery 2021-05-16 14:34:21 -05:00
codemann8 6538cc4907 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-05-16 05:18:56 -05:00
codemann8 d0d301ef7c Documention update 2021-05-16 05:18:36 -05:00
codemann8 9ff3a4d5b4 Version bump 2021-05-16 05:12:15 -05:00
codemann8 63b2b807ec Removed exit intended for Inverted 2021-05-16 05:11:48 -05:00
codemann8 1f84bd2c81 Base ROM Update 2021-05-16 05:07:35 -05:00
codemann8 39fab2627a Version Un-bump 2021-05-16 05:07:04 -05:00
codemann8 ec2bb720c0 Version bump 2021-05-16 04:51:01 -05:00
codemann8 92ecee096a Merged DR v0.4.0.2 2021-05-16 04:50:44 -05:00
codemann8 2a394cc880 Initial check-in for OWG logic
Includes renames and reorganizations
2021-05-16 04:41:43 -05:00
aerinon 9f877d8811 Some bugs fixes 2021-05-14 16:47:47 -06:00
aerinon f2318b821a Experimental no longer pre-opens stone walls
Updated baserom
Fixed a standard bug where the exits to the ledge would be unavailable if the pyramid was pre-opened
DR ASM optimization
Removed Archery Game from Take-Any caves in inverted
Fixed a problem with new YAML parser
2021-05-13 12:17:31 -06:00
codemann8 9110ac4e9c Reorganized Cave Regions 2021-05-13 06:39:17 -05:00
codemann8 0448ceeb7e Hide OW Edges in Spoiler if vanilla 2021-05-13 06:01:58 -05:00
codemann8 f4e79c200a Merging DR v0.4 - OWG logic/keylogic//YAML 2021-05-12 05:35:33 -05:00
codemann8 ac753ef607 Initial Inverted changes 2021-05-12 00:26:49 -05:00
aerinon 7764432683 Experimental no longer pre-opens stone walls 2021-05-11 16:34:34 -06:00
aerinon 73cf088091 Update release notes 2021-05-11 13:37:00 -06:00
aerinon da4a9a596a Merge branch 'DoorDev' into DoorDevUnstable 2021-05-11 13:28:28 -06:00
aerinon 0e50ab2023 Readme update 2021-05-11 13:27:49 -06:00
aerinon 20ee644bcb Merge branch 'DoorDevVolatile' into DoorDevUnstable
# Conflicts:
#	Main.py
2021-05-11 13:01:11 -06:00
aerinon 6852d80cb7 Merge pull request #111 from aerinon/DoorDevUnstable
Door dev unstable
2021-05-11 12:59:12 -06:00
aerinon 99d8981eb9 Switch to stable versioning 2021-05-11 12:51:23 -06:00
codemann8 a6c3e5c1ac Added Pearl rule for Circle of Bushes area bush 2021-05-11 00:29:41 -05:00
codemann8 bdabe98ad2 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-05-10 22:44:00 -05:00
codemann8 10bb813ce2 Fixed filename generation issue with Layout Shuffle change 2021-05-10 22:43:29 -05:00
codemann8 01c8f5f917 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-05-10 11:39:15 -05:00
codemann8 586efbd757 Version bump 2021-05-10 11:38:01 -05:00
codemann8 c7b0620681 Added guaranteed Flute hint in OW shuffle 2021-05-10 10:14:22 -05:00
codemann8 a7b148383c Added OW flags to ROM 2021-05-09 19:46:22 -05:00
codemann8 15c2d13de3 Added Parallel to list that enables OW Shuffle 2021-05-09 19:35:03 -05:00
codemann8 1f3f20b923 Merged Parallel Worlds into OW Layout Shuffle setting 2021-05-09 19:06:13 -05:00
codemann8 1f735882d9 Update README.md 2021-05-07 04:23:07 -05:00
codemann8 61204b1a7e Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-05-07 04:21:13 -05:00
codemann8 22c32a43c9 Version bump 2021-05-07 04:19:24 -05:00
codemann8 847e8e528b Fix for Standard 2021-05-07 04:15:44 -05:00
codemann8 5ffc62a046 Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffleDev 2021-05-06 04:24:36 -05:00
codemann8 c53c262420 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-05-06 04:24:10 -05:00
codemann8 db804e7cc9 Updated changelog 2021-05-06 04:23:52 -05:00
codemann8 3f27e2e144 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-05-06 03:12:35 -05:00
codemann8 50c8753076 Updated gitignore 2021-05-06 03:12:14 -05:00
codemann8 8bec82c4e0 Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-05-06 01:21:27 -05:00
codemann8 ef4ca73e82 Version bump 2021-05-06 01:18:03 -05:00
codemann8 d897333db6 Final tweaks to Parallel Worlds mode 2021-05-06 01:16:23 -05:00
aerinon d36cf2f732 Version bump slight change 2021-05-05 16:54:20 -06:00
aerinon eed80b4afe Version bump and fixes 2021-05-05 14:24:20 -06:00
aerinon 07308b7192 Fix standard_stair_check 2021-05-05 14:23:40 -06:00
aerinon 247071b718 Fix standard_restricted 2021-05-05 14:23:30 -06:00
aerinon b0098b623c Fix standard_stair_check 2021-05-05 14:22:45 -06:00
codemann8 d1b82e5910 Implemented Parallel Worlds functionality 2021-05-05 15:15:58 -05:00
aerinon 7a94f4ba3a Fix standard_restricted 2021-05-05 08:42:40 -06:00
codemann8 a5e17526da Adding new GUI/CLI option for Parallel Worlds 2021-05-04 21:42:07 -05:00
aerinon 8e2a7874aa Revert TestSuite changes (add owg) 2021-05-04 16:37:30 -06:00
aerinon a12ebfaf50 Merge branch 'StructuralMike-BombSwitchDevUnstable' into DoorDevVolatile 2021-05-04 16:30:27 -06:00
aerinon 78a4e0b26b Merge branch 'BombSwitchDevUnstable' of https://github.com/StructuralMike/ALttPDoorRandomizer into StructuralMike-BombSwitchDevUnstable 2021-05-04 16:30:14 -06:00
aerinon 6c98c537e2 Better mystery compatibility with old values 2021-05-04 16:29:52 -06:00
aerinon a2fcad1e22 Version update with release notes
Switch to safe loader
2021-05-04 16:26:45 -06:00
aerinon a3b5cb4baa Merge branch 'DoorDevOWG' of https://github.com/compiling/ALttPEntranceRandomizer into compiling-DoorDevOWG 2021-05-04 16:15:28 -06:00
codemann8 f77a0d95fa Updated Readme 2021-05-04 06:21:28 -05:00
codemann8 26e3aee96b Adding new GUI/CLI option for Parallel Worlds 2021-05-04 06:21:06 -05:00
codemann8 29f6e95e1d Create CHANGELOG.md 2021-05-03 23:32:29 -05:00
codemann8 8d2c2add28 Bad code 2021-05-03 19:32:13 -05:00
codemann8 e4bff2c75e Implemented a new shuffling algorithm 2021-05-03 03:34:03 -05:00
codemann8 cc5b1ab60f Renamed some areas 2021-05-02 21:30:25 -05:00
codemann8 ace09795dd Merge branch 'OverworldShuffleDev' into OverworldShuffle 2021-05-02 20:33:19 -05:00
codemann8 7e118d0559 Version update 2021-05-02 20:32:51 -05:00
codemann8 07ec0b0195 Removed unnecessary data 2021-05-02 20:29:23 -05:00
codemann8 63d77314e6 Keep Link's position if within incoming gap 2021-05-02 19:56:53 -05:00
codemann8 ecf3e4607e Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffleDev 2021-05-01 12:57:41 -05:00
codemann8 f2d1f051d3 Added rule for SW back dropdown 2021-05-01 12:51:46 -05:00
compiling a5d2e12ffc Fix accidental change to pot room name 2021-05-01 10:45:44 +10:00
aerinon c359efebf4 Merge branch 'DoorDevUnstable' into DoorDevVolatile 2021-04-30 15:55:42 -06:00
aerinon 70a3f2e53e Remove link sprite. Updated bob sprite 2021-04-30 15:55:00 -06:00
aerinon 817833d0fa Standard generation bugs fixed 2021-04-29 15:19:50 -06:00
compiling 5139a7fef1 Remove duplicated copy code 2021-04-30 00:24:38 +10:00
compiling a886018b55 Exclude sewer to sanctuary connection for mirror wrap to pyramid fairy. 2021-04-29 22:45:34 +10:00
compiling 5ea663032a Don't reject seed if the swamp trenches or ice block can't be reached. 2021-04-29 22:43:01 +10:00
compiling 07733484e1 Fix exception with split dungeons 2021-04-29 22:41:39 +10:00
compiling 1c93db414f Fix inverted Aga Tower handling 2021-04-29 19:38:52 +10:00
compiling a934670627 Turn off TR key validation for OWG. 2021-04-29 19:28:31 +10:00
codemann8 131d6e8da7 Update README.md 2021-04-29 01:26:01 -05:00
codemann8 9ff475bfb8 Update OverworldShuffle.py 2021-04-29 01:20:09 -05:00
codemann8 21ebe4e43b Fix Camera Unlock issue 2021-04-29 01:19:31 -05:00
codemann8 8d8d59e00a Disable progression on Pyramid Fairy temporarily 2021-04-29 01:19:14 -05:00
aerinon acff37e6e7 Merge branch 'StructuralMike-DoorDevUnstable' into DoorDevVolatile 2021-04-27 14:09:31 -06:00
aerinon 7b0e38f76c Merge branch 'DoorDevUnstable' of https://github.com/StructuralMike/ALttPDoorRandomizer into StructuralMike-DoorDevUnstable
# Conflicts:
#	Rom.py
2021-04-27 14:09:13 -06:00
aerinon 766d06b462 Merge branch 'DoorDevUnstable' of https://github.com/compiling/ALttPEntranceRandomizer into compiling-DoorDevUnstable 2021-04-27 14:07:07 -06:00
aerinon ab5458cf1a Version bump 2021-04-27 14:00:37 -06:00
aerinon 7a74ba8999 Shopsanity price re-work 2021-04-27 14:00:00 -06:00
codemann8 d2b89ed4e6 Corrected default value for door shuffle 2021-04-27 10:11:29 -05:00
compiling 639a3ec383 Fix inverted checks
Fix superbunny / dungeon revive rules due to late binding
Fix inverted swamp patch
Fix most unit tests (dungeons still broken)
2021-04-27 23:51:12 +10:00
compiling df2b12774d Fix broken connection between superbunny bottom and top 2021-04-27 18:33:32 +10:00
compiling db1a37b374 Create glitch connections in advance for dungeon generation.
Add overworld glitches to the gui.
2021-04-27 18:12:24 +10:00
codemann8 6a1a02632a Merge branch 'OverworldShuffle' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffle 2021-04-26 18:02:04 -05:00
codemann8 24e1f6815c Updated version 2021-04-26 18:01:54 -05:00
codemann8 3bfb76d36e Merge pull request #2 from Catobat/OWFix2
Fix transitions for real
2021-04-26 18:00:51 -05:00
codemann8 c6e80cb238 Merge branch 'OverworldShuffle' into OWFix2 2021-04-26 18:00:37 -05:00
codemann8 d33fc5ce09 Implemented Keep Similar Together 2021-04-26 17:50:21 -05:00
codemann8 4a326a5463 Fix default value of new Keep Similar option 2021-04-26 17:34:32 -05:00
codemann8 7c2cff562a Adding new GUI/CLI option for Keep Similar Together 2021-04-26 15:47:21 -05:00
codemann8 ae1af5e038 Adding new GUI/CLI option for Keep Similar Together 2021-04-26 15:20:42 -05:00
Catobat 8cc1b20d18 Change defaults 2021-04-26 21:54:52 +02:00
Catobat 032c3d20d5 Fix transitions for real 2021-04-26 21:52:45 +02:00
codemann8 48bf44001d Minor formatting 2021-04-26 14:14:42 -05:00
compiling 1433c987f1 Simple dungeon revive logic (only considering reviving in the first room for now) 2021-04-25 23:21:10 +10:00
codemann8 f95d3cae0c Update README.md 2021-04-24 17:16:58 -05:00
codemann8 3b10b1a277 Minor efficiency 2021-04-24 15:25:00 -05:00
codemann8 1cc93232e7 Update version 2021-04-24 15:04:33 -05:00
codemann8 3666cdf857 Merge pull request #1 from Catobat/OWFix
Fix for vanilla transition glitch (and possibly transition to ID 0 glitch)
2021-04-24 15:03:49 -05:00
Catobat 49889be13c Fix rare transition glitches (hopefully) 2021-04-24 21:12:45 +02:00
codemann8 60d34f6fb2 Updated version 2021-04-23 19:11:30 -05:00
codemann8 6f8a1c345b Modified some Big Red Bomb rules for OW shuffle 2021-04-23 19:11:11 -05:00
codemann8 4dd1d4306f Removed and fixed unnecessary rules for OW locations 2021-04-23 19:10:23 -05:00
codemann8 9951c5b0ea Fixed duplicate Pyramid Ledge location 2021-04-22 21:51:33 -05:00
codemann8 a1bcae56dc Updated OW Version 2021-04-22 14:30:40 -05:00
codemann8 7754f1202c Fixed Standard mode 2021-04-22 14:30:24 -05:00
codemann8 d242da01bd Fixed issue with outputting spoiler log 2021-04-22 14:28:02 -05:00
codemann8 c9aa65c33c Changed default to Lobby Shuffle, but Door still set to Vanilla 2021-04-22 13:22:48 -05:00
codemann8 314a938cb0 Updated GUI/CLI with new OW versioning 2021-04-22 13:17:17 -05:00
codemann8 b6893b155e Baserom update 2021-04-22 13:15:00 -05:00
codemann8 b06dbdab8d Removed setting the LW/DW flag on transition 2021-04-22 13:14:17 -05:00
codemann8 12056f68d6 Changed defaults for Door and OW 2021-04-22 10:52:16 -05:00
codemann8 b5875134aa Update README.md 2021-04-21 20:48:36 -05:00
codemann8 d2f9a23692 Added a version number to indicate both base door rando AND ow rando together 2021-04-21 15:30:58 -05:00
codemann8 6fde7b49a4 Merge branch 'OverworldShuffle' of https://github.com/codemann8/ALttPDoorRandomizer into OverworldShuffle 2021-04-21 15:07:25 -05:00
codemann8 bde52317cd Patch enabled to allow Frogsmith to enter multi-entrance caves 2021-04-21 15:07:23 -05:00
codemann8 2c209e3e21 Updated readme 2021-04-21 14:07:05 -05:00
compiling 9852352027 Temp 2021-04-21 18:40:54 +10:00
codemann8 3373c3f523 Updated baserom 2021-04-21 00:08:46 -05:00
codemann8 36beba3fdc Fixed incorrect transition data for special areas 2021-04-21 00:07:24 -05:00
codemann8 6d1ae86c46 Fixed bad transition data 2021-04-21 00:06:55 -05:00
codemann8 374cfc40e5 Fixed issue with DW transitions causing hardlocking mapwrap crashes 2021-04-21 00:05:48 -05:00
codemann8 b88c49f278 Fixed visual issue with megatiles using VRAM 2021-04-21 00:02:28 -05:00
codemann8 834cc26241 Added missing flipper logic 2021-04-20 23:43:08 -05:00
codemann8 2297a3e67f Formatted ER entrance data 2021-04-19 19:24:17 -05:00
codemann8 642c0c2a10 Fixed incorrect data 2021-04-19 19:23:43 -05:00
codemann8 b3c3eb6d2c Milestone release: first alpha version 2021-04-19 02:43:06 -05:00
codemann8 a2cda2f34c Milestone update, all transition tests work, megatiles have a visual problem 2021-04-18 13:37:55 -05:00
compiling 30baec65af Merge remote-tracking branch 'remotes/origin/Dev-owg' into DoorDevUnstable 2021-04-18 14:28:29 +10:00
compiling b6fe468164 Import inverted pyramid fairy rules from Entrance Rando 2021-04-18 13:25:04 +10:00
compiling 7a255a008e Fix moved locations in copy_world routine. 2021-04-18 13:25:04 +10:00
compiling 72d980394c Add setting code to logs 2021-04-18 13:25:04 +10:00
aerinon 02d6905438 Fix for retro "shops" 2021-04-15 15:11:40 -06:00
codemann8 4a0bf1f123 Fixed off-by-one issue on writing dest to ROM 2021-04-13 19:11:37 -05:00
StructuralMike b42e4db472 potential retro-fix 2021-04-13 16:58:08 +02:00
codemann8 2b0cc0fc0d Updated baserom after merge 0.3.1.7u 2021-04-12 13:34:50 -05:00
codemann8 160f0732dd Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffle 2021-04-12 13:32:14 -05:00
codemann8 ade6dfc416 New destinations now write to ROM 2021-04-12 12:23:26 -05:00
codemann8 894acbd939 Milestone successful transition to midpoint 2021-04-07 12:15:26 -05:00
codemann8 db3cee7229 Formatting 2021-04-02 14:37:24 -05:00
codemann8 877d523367 Converted data tables to little endian 2021-04-02 13:49:55 -05:00
codemann8 6091d96dc0 Split transition table by direction 2021-04-01 12:36:26 -05:00
codemann8 71ef1c3252 Added data tables, began initial ASM structure 2021-03-31 21:27:23 -05:00
StructuralMike 80849ebd3b TR Crystal Maze
Added a commented out possibility for TR Crystal Maze backwards ranged crystal.
2021-03-27 21:22:56 +01:00
StructuralMike ac46d4d8aa Update mystery yaml parser to a maintained package module
Tested on both local files and url-files and works great.
2021-03-27 12:43:00 +01:00
codemann8 a89a17515d Adding initial ASM, infinite loop at Links 2021-03-24 14:02:50 -05:00
codemann8 19684bcdfa Merged and fixed Shopsanity with OW shuffle 2021-03-24 14:02:07 -05:00
StructuralMike 76a106da06 Update Rules.py 2021-03-22 21:15:58 +01:00
StructuralMike 3f9b6234c2 Mire fishbone barrier bypass 2021-03-22 21:12:26 +01:00
aerinon 960b8de237 Merge pull request #104 from StructuralMike/DoorDevUnstable
gui startinginventory with Magic Cape
2021-03-22 11:33:14 -06:00
StructuralMike c663c9edaa Update Rom.py 2021-03-19 17:36:54 +01:00
StructuralMike 06357f5f21 minor cleanup 2021-03-19 17:35:09 +01:00
StructuralMike d9d664f7ba minor cleanup 2021-03-19 17:29:45 +01:00
StructuralMike 9b06c6d947 Magic Cape in the GUI --> Cape 2021-03-19 09:19:41 +01:00
StructuralMike ad8dbcd01c Merge branch 'DoorDevUnstable' into BombSwitchDevUnstable 2021-03-18 23:19:20 +01:00
StructuralMike 83aa2cb006 Merge pull request #2 from aerinon/DoorDevUnstable
Door dev unstable
2021-03-18 23:18:56 +01:00
aerinon 46d891f401 Update release notes 2021-03-18 13:55:24 -06:00
aerinon bb9977d410 Merge branch 'DoorDevUnstable' of https://github.com/miketrethewey/ALttPDoorRandomizer into miketrethewey-DoorDevUnstable 2021-03-18 13:53:33 -06:00
aerinon 906134800b Fixed the error with TFH counter turned on for wrong modes
Updated pip requirements for MultiClient
Fixed Big bomb rules for Inverted (merge mistake)
2021-03-18 13:53:19 -06:00
StructuralMike 16ba877e86 Merge branch 'DoorDevUnstable' into BombSwitchDevUnstable 2021-03-18 17:19:52 +01:00
StructuralMike 49987e96df Update TestSuite.py 2021-03-18 17:18:23 +01:00
StructuralMike b20127163a Merge pull request #1 from aerinon/DoorDevUnstable
Door dev unstable
2021-03-18 17:16:16 +01:00
StructuralMike 5b37b32c8d Revert "Revert "Update .gitignore""
This reverts commit 5073b9e630.
2021-03-18 16:33:25 +01:00
StructuralMike 5073b9e630 Revert "Update .gitignore"
This reverts commit f95270587f.
2021-03-18 16:19:42 +01:00
StructuralMike 099f8e65dc Update DoorShuffle.py 2021-03-18 11:20:32 +01:00
StructuralMike eee2dcaf35 Update DoorShuffle.py 2021-03-18 10:24:27 +01:00
StructuralMike ced093fe32 PoD Bow statue crystal fix 2021-03-18 09:29:31 +01:00
Mike A. Trethewey 4c9fc3464b Ubuntu is on Focal now 2021-03-18 00:42:17 -07:00
Mike A. Trethewey b4c5346b9c Update CI 2021-03-18 00:32:25 -07:00
Mike A. Trethewey e48a69d9e9 Extrapolate requirements file 2021-03-17 23:58:20 -07:00
Mike A. Trethewey d6a433e467 Add pathing intelligence 2021-03-17 17:50:51 -07:00
randall.rupper 27ed4ecd04 Small Shopsanity price adjustments
Fixed a subtle error with shop shields and progressive shields - should result in more successful generation
2021-03-17 14:37:39 -06:00
randall.rupper 7b9deb2190 Merge branch 'DoorDevUnstable' of https://github.com/Fouton/ALttPDoorRandomizer into Fouton-DoorDevUnstable
some refinements too

# Conflicts:
#	ItemList.py
2021-03-16 15:15:48 -06:00
StructuralMike 763bb6c36d Update Rules.py 2021-03-16 22:15:18 +01:00
StructuralMike 13c2022bc9 BombSwitchDev 2021-03-16 22:05:10 +01:00
randall.rupper 3c81e377e5 Fix for intensity 3 inverted lobbies if lobbies are chosen to be vanilla
Flooded pots not actually able to be flooded in some potshuffles
2021-03-16 14:23:52 -06:00
randall.rupper 7ef186134a Merge branch 'StructuralMike-TFH-fix' into DoorDevUnstable 2021-03-16 14:14:35 -06:00
StructuralMike 40119b3a5f Retro-Standard can't have bow on uncle
I don't know if the best solution is to exclude the bow from the options, or to have uncle give bow + arrows. I think the former is better as buying your arrow is part of retro.
2021-03-16 17:34:08 +01:00
StructuralMike 6bf3479e08 TFH playthrough fix
copy_world overwrites Murahdahla's logic and either needs to be reset through set_rules to work properly.
2021-03-16 14:15:56 +01:00
StructuralMike 9f00862e04 Merge branch 'DoorDevUnstable' of https://github.com/Aerinon/ALttPDoorRandomizer into DoorDevUnstable 2021-03-16 13:27:07 +01:00
StructuralMike f95270587f Update .gitignore 2021-03-16 13:26:21 +01:00
Mike A. Trethewey ed2813c85e Make local install a little smarter 2021-03-16 00:58:09 -07:00
Mike A. Trethewey 61980e859d What's a script name? 2021-03-15 22:22:59 -07:00
Mike A. Trethewey f769ada8eb Markdown is hard 2021-03-15 22:19:28 -07:00
Mike A. Trethewey 3a370eb9f9 Update BUILDING.md 2021-03-15 22:17:33 -07:00
Mike A. Trethewey da62fe98ba Update build instructions 2021-03-15 22:15:19 -07:00
StructuralMike 82220b40d6 Small error 2021-03-13 18:42:44 +01:00
StructuralMike 77e4102ab6 Small error 2021-03-13 14:00:14 +01:00
Fouton c47090ce61 Add files via upload 2021-03-12 22:15:27 -05:00
Fouton 1aa770e33a Add files via upload 2021-03-12 21:58:19 -05:00
Fouton 6526d1b877 Add files via upload 2021-03-12 21:48:51 -05:00
Fouton 05413011a9 Add files via upload 2021-03-12 21:46:54 -05:00
Fouton d62b11742b Add files via upload 2021-03-12 21:45:27 -05:00
Fouton 08a5e2f27f Add files via upload 2021-03-12 21:22:35 -05:00
aerinon 749b94fa9f Merge pull request #97 from krelbel/chaosfix
Fix chaos boss/enemy shuffle
2021-03-12 16:33:48 -07:00
StructuralMike b3da0bcbcf Updated rules for killrooms and killdrops with bomb-logic in mind 2021-03-12 23:43:57 +01:00
Fouton 2e07fc2dd0 Add files via upload 2021-03-12 16:57:42 -05:00
Fouton 0865288581 Add files via upload 2021-03-12 16:53:08 -05:00
Fouton 2a1eb07d73 Add files via upload 2021-03-12 16:51:16 -05:00
Fouton 1e63d3957d TFH Futures 2021-03-12 16:41:58 -05:00
Fouton 8d933b82de TFH Futures 2021-03-12 16:41:35 -05:00
StructuralMike 8689bd6a4c Crystals that can be hit with pots
Moved the can_hit_crystal() function to rules where it belongs, and applied it to all instances of crystals in rooms that don't have pots.
2021-03-12 17:07:17 +01:00
StructuralMike e1ddd02097 Missing crystal in Hera Beetles 2021-03-12 14:03:19 +01:00
StructuralMike 89be12ee3d Update Rules.py 2021-03-12 11:48:08 +01:00
StructuralMike f63d1f5470 SP Crystal room 0HKO consideration 2021-03-12 10:21:27 +01:00
StructuralMike 4d1b6a3420 more Double Switch shenanigans 2021-03-11 17:08:07 +01:00
StructuralMike f60764f062 Double Switch Room being obnoxious 2021-03-11 15:13:15 +01:00
StructuralMike eb6c71798c Tidying up and adding final(?) interaction points 2021-03-11 12:33:46 +01:00
StructuralMike 2e998af865 Mainly double switch room logic 2021-03-10 23:49:16 +01:00
krelbel 5210bbe4e0 Fix chaos boss/enemy shuffle
Update BaseClasses.py to make make_code()'s byte 6 handle "chaos" boss/enemy shuffle the same as "random".
2021-03-09 22:10:30 -08:00
randall.rupper fd7728235d Fix for multiworld progression balancing with shopsanity off 2021-03-09 16:14:16 -07:00
randall.rupper 9a2474f8ca Merge branch 'DoorDevUnstable' of https://github.com/compiling/ALttPEntranceRandomizer into compiling-DoorDevUnstable 2021-03-09 13:40:52 -07:00
StructuralMike 7f36036ced Removed unneccesery PoD Arena crystal 2021-03-09 13:08:56 +01:00
StructuralMike f66245149b Pod Main crystal always in logic with pots 2021-03-09 12:11:26 +01:00
StructuralMike 766a72bf8b Update Bosses.py 2021-03-09 11:28:11 +01:00
StructuralMike b68eff5b77 Update BaseClasses.py 2021-03-09 10:23:05 +01:00
StructuralMike dfe1ec5537 Update Bosses.py 2021-03-09 10:18:20 +01:00
StructuralMike f33d8a5279 Refined crystal rules 2021-03-09 09:40:50 +01:00
StructuralMike 5b0f877310 small fix 2021-03-08 22:11:06 +01:00
StructuralMike 1a0432d860 Update base2current.bps 2021-03-08 22:07:48 +01:00
StructuralMike 6f62c41ec3 Removed futuro-stuff 2021-03-08 22:07:01 +01:00
StructuralMike ccb8ff75df Minor 2021-03-08 21:49:48 +01:00
StructuralMike 0ec7719c86 Update TestSuite.py 2021-03-08 21:14:15 +01:00
StructuralMike 5298a7f210 TR Crystal Maze 2021-03-08 20:58:22 +01:00
StructuralMike 5534cab01b Minor typos 2021-03-08 17:19:31 +01:00
StructuralMike 5cdb446a75 Update TestSuite.py 2021-03-08 16:11:47 +01:00
StructuralMike c05a2df632 Update TestSuite.py 2021-03-08 16:01:34 +01:00
StructuralMike 874a2692f5 Update TestSuite.py 2021-03-08 15:45:54 +01:00
StructuralMike e8a51ffb3a GT Crystal rooms 2021-03-08 14:45:00 +01:00
StructuralMike 8eca5bf79e Some more Hera Lobby
Also, Hookshot cave reverted as it doesnt work that way...
2021-03-08 11:20:07 +01:00
StructuralMike 3a75b2dafd lots of PoD crystal logic 2021-03-07 17:28:12 +01:00
StructuralMike 5c5cb7f531 1xPoD and 1xTR crystal room 2021-03-07 12:35:28 +01:00
StructuralMike ed47f99e8a Update Doors.py 2021-03-06 19:45:28 +01:00
StructuralMike bf78758ade Tower of Hera crystal regions working 2021-03-06 19:38:12 +01:00
StructuralMike 5ef1ceb136 ToH Crystal Switch Region WIP 2021-03-06 17:56:45 +01:00
compiling ef08bf33d5 Reset Skull Pinball logical state between generation attempts. 2021-03-06 12:26:58 +11:00
StructuralMike b64cebc467 Delete bomb_notes.me.txt 2021-03-05 21:45:36 +01:00
StructuralMike aeda137498 Simple switch rules 2021-03-05 21:43:41 +01:00
StructuralMike 25d24dc15f Update .gitignore 2021-03-05 21:04:30 +01:00
StructuralMike 06b172ee32 Initial full rules commit 2021-03-05 20:10:21 +01:00
Mike A. Trethewey 7e3080d78b Merge pull request #3 from aerinon/DoorDevUnstable
Update from Aerinon
2021-03-05 10:32:27 -08:00
randall.rupper dc5cd2b744 Merge branch 'DoorDev' into DoorDevUnstable
# Conflicts:
#	Main.py
#	RELEASENOTES.md
2021-03-05 10:43:05 -07:00
randall.rupper b108398545 Make the adjust and "open output path" actions consistent 2021-03-05 08:58:38 -07:00
StructuralMike e46b382ed1 Initial dungeon bomb rules 2021-03-05 14:40:42 +01:00
StructuralMike 08bf1dd125 Basepatch stuff 2021-03-04 23:49:04 +01:00
StructuralMike a21423ee9c Small boss rule 2021-03-04 23:46:19 +01:00
randall.rupper 91c0114d32 Settings file added 2021-03-04 14:05:25 -07:00
StructuralMike 464dd652c6 basepatch changes 2021-03-04 21:35:45 +01:00
randall.rupper 9a5be8644c Fixed Ganon's silver hints for shops 2021-03-04 11:11:55 -07:00
Thomas Prescott e5b9019828 remove unused import 2021-03-03 08:02:50 -06:00
StructuralMike f8e6692dea Update Rom.py 2021-03-03 14:42:12 +01:00
StructuralMike 8a203c3158 All futuro code - apart from logic 2021-03-03 13:38:37 +01:00
StructuralMike 6f39648666 Initial futuro settings implementation 2021-03-03 12:34:59 +01:00
Thomas Prescott 1bac04a24c formatting, and fix output 2021-03-02 20:12:24 -06:00
Thomas Prescott 7674e7dafb hack in a thing to use a settings file for generation 2021-03-02 19:34:29 -06:00
aerinon 4e9e564154 Set theme jekyll-theme-slate 2021-03-01 10:04:05 -07:00
aerinon 6a5bdbee6b Mostly a fix for Blind outside of TT when Blind is the boss of TT (boss enemizer)
Remove RaceRandom use for now
2021-02-27 15:33:05 -07:00
aerinon 7c35b4d14e Minor gui bugfix 2021-02-26 11:26:04 -07:00
Mike A. Trethewey f7df6c0e69 Fixes
Change Spoiler default to True
Set base rom to actually do the thing
2021-02-26 02:13:11 -08:00
Mike A. Trethewey ff763c4542 Merge pull request #2 from aerinon/DoorDevUnstable
Update from Aerinon
2021-02-26 01:42:48 -08:00
aerinon f6d1dc282b Minor bugfix update 2021-02-25 16:51:07 -07:00
aerinon f1fd2c2759 Revert "Merge branch 'DoorDevUnstable' of https://github.com/miketrethewey/ALttPDoorRandomizer into miketrethewey-DoorDevUnstable"
This reverts commit 3448693f52, reversing
changes made to f2c021500d.
2021-02-25 16:16:20 -07:00
aerinon af441a8e9b Merging in base er changes 2021-02-25 15:26:29 -07:00
aerinon 5dded84a4c Merge pull request #88 from KevinCathcart/Dev
Dev
2021-02-24 15:31:36 -07:00
aerinon 3448693f52 Merge branch 'DoorDevUnstable' of https://github.com/miketrethewey/ALttPDoorRandomizer into miketrethewey-DoorDevUnstable 2021-02-24 15:24:25 -07:00
aerinon f2c021500d Merge branch 'Portals' of https://github.com/Catobat/ALttPDoorRandomizer into Catobat-Portals 2021-02-24 15:23:34 -07:00
aerinon d14c9b5758 Object reading improvements in utils 2021-02-24 13:29:10 -07:00
Mike A. Trethewey 33d05c1b1f Fix Selectors 2021-02-23 01:38:10 -08:00
Mike A. Trethewey 37b778c71e Merge pull request #1 from aerinon/DoorDevUnstable
Update from Aerinon
2021-02-22 16:03:56 -08:00
aerinon 90d45cc371 Potion shop crash in non-shopsanity modes 2021-02-22 14:47:24 -07:00
Catobat f6394cd7f2 Only shuffle dungeon order in Crossed 2021-02-21 14:54:51 +01:00
Catobat 27b9257981 Portal fixes and adjustments 2021-02-21 14:43:49 +01:00
codemann8 c4d326fb68 Added OW shuffle to filename settings hash 2021-02-18 22:44:53 -06:00
codemann8 87381e495c Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffle 2021-02-18 22:44:17 -06:00
aerinon 4ee60db31a Documentation clean up and including the non-progressive shields. 2021-02-18 16:09:46 -07:00
aerinon 9d32a85b89 Progressive limits ignored for shop items (multiworld)
Multi Client improvements to reporting
2021-02-18 13:39:03 -07:00
aerinon 8d22dd1a3d Bringing in Unstable2 changes 2021-02-18 13:19:08 -07:00
aerinon 5945360f58 Silvers issue in swordless 2021-02-18 10:01:52 -07:00
codemann8 2235aab579 Initial OW Shuffle asm hooks 2021-02-18 10:00:22 -06:00
aerinon 2af9ffbda4 Notes and version update
Fix hera double count
2021-02-17 15:23:46 -07:00
aerinon 309260a1e2 Merge branch 'DoorDevUnstable' of https://github.com/miketrethewey/ALttPDoorRandomizer into MikeQoL 2021-02-16 13:59:24 -07:00
aerinon 9bce09aad6 Merge branch 'InroomStairFix' into Unstable2 2021-02-16 13:58:31 -07:00
aerinon b36c03a8b4 Pot shuffle repair 2021-02-16 13:34:00 -07:00
Catobat 5a8139258d PoD Mimics 2 portal flexibility 2021-02-16 20:00:21 +01:00
Mike A. Trethewey f13dba3512 QoL Improvements
Update SpriteSomething collections page for Z3Link sprites
Add Diagnostics button to the GUI
2021-02-15 19:36:20 -08:00
aerinon 26f7b1c993 Notes/version
Baserom update
2021-02-15 13:36:34 -07:00
aerinon 3b8773ea33 Update item counter for mystery
Fixed bug with door restart
Made retro keys more lenient with door shuffle
2021-02-13 21:11:31 -07:00
aerinon 352592bd00 Key logic error with odd_counter and child doors
Fix the Lone Pot doors (E/W) swapped
2021-02-13 21:09:57 -07:00
aerinon f83b28adb6 -Disallowed Swamp Lobby in Hyrule Castle in Standard mode
-Prevent defeating Aga 1 before Zelda is delivered to the Sanctuary. (He can't take damage)
-Fix for Ice Jelly room when going backward and enemizer is on
-Fix for inverted - don't start as a bunny in Dark Sanctuary
-Fix for non-ER Inverted with Lobby shuffle. Aga Tower's exit works properly now.
2021-02-13 21:08:06 -07:00
aerinon 8083c8c179 Minor fix to ensure the key logic is correct when selling keys 2021-02-13 20:59:40 -07:00
aerinon 2caf5abe4a Update item counter for mystery
Fixed bug with door restart
Made retro keys more lenient with door shuffle
2021-02-13 20:58:59 -07:00
codemann8 4639129401 Remove OW Shuffle stuff from ER 2021-02-13 10:52:51 -06:00
Catobat 74a8ec6486 Minor fixes for in-room stairs 2021-02-12 23:01:50 +01:00
codemann8 06e8556cf2 Added Overworld Shuffle to spoiler log 2021-02-11 02:18:40 -06:00
codemann8 00a4ff11e5 Adding OverworldShuffle.py 2021-02-10 22:19:04 -06:00
codemann8 12ccbc45d3 Added Overworld Shuffle parameter to CLI and Gui 2021-02-10 22:16:49 -06:00
codemann8 b11054e6bf Added Overworld Shuffle parameter to CLI and Gui 2021-02-10 22:11:50 -06:00
aerinon 2765f9bec0 - Settings code added (prototype)
- Mystery.py updates
- Blind maiden sequence restored if Blind is shuffled to TT
- Spoiler updated
- Fix for standard in vanilla ER
- Minor shopsanity discount
2021-02-09 16:31:12 -07:00
codemann8 965b886c2d Moved list of OW connections to be shuffled to its own list 2021-02-08 12:42:39 -06:00
codemann8 10bf6fcb2f Added temporary flute exit on Link's House tile to deal with flute logic 2021-02-08 12:41:37 -06:00
codemann8 167ad64f29 Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffle 2021-02-08 12:02:11 -06:00
codemann8 7423f76e82 Update EntranceShuffle.py 2021-02-08 11:58:29 -06:00
aerinon 7a22db5dd4 -Disallowed Swamp Lobby in Hyrule Castle in Standard mode
-Prevent defeating Aga 1 before Zelda is delivered to the Sanctuary. (He can't take damage)
-Fix for Ice Jelly room when going backward and enemizer is on
-Fix for inverted - don't start as a bunny in Dark Sanctuary
-Fix for non-ER Inverted with Lobby shuffle. Aga Tower's exit works properly now.
2021-02-05 15:05:16 -07:00
aerinon 1faf8c168c Only print lobbies if shuffling doors
Couple shopsanity bugs
2021-02-03 16:29:14 -07:00
aerinon 4e71b97403 Merging in shop work
Updated release notes and testsuite
2021-02-03 13:04:35 -07:00
aerinon 09cae6e640 Shopsanity multiworld and rupee progression balancing 2021-02-03 10:49:29 -07:00
aerinon f21687bd32 Update release notes and version 2021-02-01 16:30:47 -07:00
aerinon f8a0ba1816 merge in inroom staircases 2021-02-01 10:07:53 -07:00
aerinon b5f3c752e6 Shop work:
- Potion shop
- Cap Fairy blacklist
- Item counter increased over 255
- Inverted work
- Static sram for shops
- Price adjustments (and discounts)
2021-02-01 09:57:20 -07:00
Catobat 43b0f95877 Shuffle in-room stairs 2021-01-30 00:35:41 +01:00
aerinon f143e0d166 Merge in unstable 2021-01-28 21:20:32 -07:00
aerinon c411f5543c Couple minor problems addressed 2021-01-14 13:47:21 -07:00
aerinon f45ae1c97b Fix to portal/rooms resets 2021-01-12 14:38:34 -07:00
aerinon f72d287441 Merge in Door Dev 2021-01-11 13:49:47 -07:00
aerinon 0f93a01a37 Fix auto release notes 2021-01-11 13:38:30 -07:00
aerinon a835eb3fb8 Typo 2021-01-11 13:33:03 -07:00
aerinon 0beeeebce6 Ci change 2021-01-11 13:31:54 -07:00
aerinon 4213129cdc Ci change 2021-01-11 13:28:15 -07:00
aerinon 001eadee56 Version bump 2021-01-11 11:43:25 -07:00
aerinon 58b53b885c Update release notes 2021-01-11 11:43:03 -07:00
aerinon 7704291d87 Merge branch 'miketrethewey-DoorRelease' into DoorDev 2021-01-11 11:35:55 -07:00
aerinon 8c2ceecd28 Note to self: evaluate this big key rule implication after the big key sphere refactor 2021-01-11 10:28:50 -07:00
aerinon d64a4e63a2 A lot of generation improvements and bug squashing 2021-01-08 16:31:33 -07:00
Mike A. Trethewey 741a440b40 Update CI to Release on push 2021-01-08 04:23:34 -08:00
Mike A. Trethewey 47d545119e Reorder sprite links 2021-01-08 03:55:01 -08:00
Mike A. Trethewey 05f27f3bde Fix empty folder 2021-01-08 03:47:26 -08:00
Mike A. Trethewey 3ed88ebd1d Fix pathing 2021-01-08 03:41:39 -08:00
Mike A. Trethewey 46420f10af Move sprites back to ./data 2021-01-08 03:31:21 -08:00
Mike A. Trethewey bca36d79ac Fix sprite loader... again 2021-01-08 03:17:46 -08:00
Mike A. Trethewey a3553e7860 Shift Sprites about 2021-01-08 02:44:49 -08:00
Mike A. Trethewey 3d3b8c8985 Just do stuff local 2021-01-08 02:26:30 -08:00
Mike A. Trethewey 880010ae24 ReadMe doesn't exist there 2021-01-08 01:00:42 -08:00
Mike A. Trethewey 6acecc6254 Add Data folders 2021-01-08 00:56:13 -08:00
Mike A. Trethewey fdbfa6fc5d Py3 updates expanduser
Same on Win/Linux
2021-01-08 00:40:55 -08:00
Mike A. Trethewey dacf5e8ba7 Use Console for debugging 2021-01-08 00:23:03 -08:00
Mike A. Trethewey eadb888199 Move Build Scripts again 2021-01-07 23:54:22 -08:00
Mike A. Trethewey fbc844fa4b Move Build Specs 2021-01-07 23:36:20 -08:00
Mike A. Trethewey 735f19fbd6 Update Build Script 2021-01-07 23:34:15 -08:00
aerinon 5a426b194d Merge pull request #78 from aerinon/DoorDevUnstable
Door dev unstable to door dev main
2021-01-04 13:57:37 -07:00
aerinon 3053942243 Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable 2021-01-04 13:24:19 -07:00
aerinon b14ecddc22 Merge pull request #77 from cassidoxa/enemizer
Inform user when enemizer returns non-zero exit code, log the error c…
2021-01-04 13:24:12 -07:00
aerinon e67653577e Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable 2021-01-04 13:23:34 -07:00
aerinon c12980700f Merge pull request #76 from Berserker66/patch-1
Don't load local rom twice
2021-01-04 13:23:28 -07:00
aerinon 0636a3f6c5 Merge branch 'compiling-DoorDevUnstable' into DoorDevUnstable 2021-01-04 13:20:57 -07:00
aerinon 86b4e39831 Merge branch 'DoorDevUnstable' of https://github.com/compiling/ALttPEntranceRandomizer into compiling-DoorDevUnstable 2021-01-04 13:20:33 -07:00
aerinon 711488945e Clean up for next alpha release 2021-01-04 13:18:30 -07:00
cassidoxa d6d19158a7 Inform user when enemizer returns non-zero exit code, log the error content 2020-12-29 14:59:22 -05:00
Fabian Dill 80e3e98fb4 Don't load local rom twice
skip extra LocalRom() init
2020-12-22 09:06:29 +01:00
aerinon 80d642996d Merging in unstable 2020-12-18 16:23:57 -07:00
codemann8 80ed21ef1a Removed old unused rules 2020-12-17 11:13:30 -06:00
codemann8 cf22327ad4 Renamed DM Broken Bridge 2020-12-17 11:13:06 -06:00
codemann8 d6d862db3c Added terrain rules for Purple Chest Area Rocks 2020-12-17 11:12:19 -06:00
aerinon 2a05e94970 Fix Desert Wall pre-opened logic for the portal re-factor 2020-12-15 12:18:32 -07:00
codemann8 b08cc996ee Rearranged logic rules 2020-12-13 20:01:14 -06:00
codemann8 51d340ce1e Added renamed regions to standard ZeldaDelivered exclusions 2020-12-12 07:30:24 -06:00
codemann8 0627acb662 Added debugging output 2020-12-12 07:02:20 -06:00
codemann8 1add1222e1 Split duplicate exits into unique 2020-12-12 06:56:36 -06:00
codemann8 2e5af373a5 Replaced some old region references to OW shuffle names 2020-12-12 05:13:30 -06:00
codemann8 6860b3a907 Added OW Shuffle Rules 2020-12-12 03:33:22 -06:00
codemann8 37a8fb1027 Added vanilla connections for initial OW shuffle logic 2020-12-11 04:14:48 -06:00
codemann8 96ed4e5794 Fixed names of some regions 2020-12-11 03:56:38 -06:00
codemann8 51e4d6398f Added all mirror mandatory connections 2020-12-10 15:45:01 -06:00
codemann8 d32c8bc0ba Conversion of mandatory connections to OW tile connections 2020-12-10 11:38:11 -06:00
codemann8 dee0dfc088 Reordered mandatory connections for easier comparison later 2020-12-10 11:34:51 -06:00
codemann8 3ed5cbd674 Minor rename of Region 2020-12-10 11:34:15 -06:00
codemann8 4458ccb4f7 Various fixes, renames, adjustments to OW Regions 2020-12-10 10:38:17 -06:00
codemann8 1ce4f0f2a2 Initial conversion to OW intra-tile regions 2020-12-10 07:16:30 -06:00
aerinon 91b5380e3a Update release notes 2020-12-09 14:32:12 -07:00
aerinon 77cf9e6883 Repair hera basement cage to not count Byrna 2020-12-09 14:29:18 -07:00
aerinon 85d05f625b Generation improvements
Potential fix for overworld problem
2020-12-08 11:24:44 -07:00
aerinon 5c9c9947f3 Minor bugfix 2020-12-08 08:54:49 -07:00
aerinon b80ea7c85a Inverted shopsanity
Randomize shopkeepers
One other fix
2020-12-07 14:01:04 -07:00
aerinon 71e07dcd5a Merge branch 'DoorDevUnstable' into ShopGenWork 2020-12-07 11:59:24 -07:00
aerinon 1b690aaba1 Fixing generation errors 2020-12-07 11:53:20 -07:00
aerinon 51affaf0ca Merge branch 'DoorDevUnstable' into ShopGenWork 2020-12-05 10:38:22 -07:00
aerinon fc13549ccf Swamp Flooded Room logic re-work
Fix a minor bug
2020-12-05 10:37:58 -07:00
aerinon e834fd85a1 Initial Shopsanity
Retro work
2020-12-03 16:25:51 -07:00
aerinon ba3bd4b648 Generation improvements
Bomb/dash doors removed from experimental
2020-12-02 15:13:42 -07:00
aerinon 32e7544775 Generation improvements 2020-12-01 15:00:53 -07:00
compiling c02a890aba Fix logs indicating pots are shuffled when they aren't. 2020-12-01 18:29:38 +11:00
compiling 70a206fd22 Fix issue with copying locations (fixes moon pearl logic during playthrough generation). 2020-12-01 18:20:48 +11:00
aerinon 64b539706c Sprite updates 2020-11-30 15:59:49 -07:00
aerinon ad00c2aea7 Merge branch 'error' into DoorDevUnstable 2020-11-30 15:57:18 -07:00
aerinon 1b060f893b Prevent HUD from showing key counter when in the overworld. (Aga 2 doesn't always clear the dungeon indicator)
Fixed key logic regarding certain isolated "important" locations
Fixed a problem with keydropshuffle thinking certain progression items are keys
A couple of inverted rules fixed (from an outstanding ER pull request)
A more accurate count of which locations are blocked by the big key in Ganon's Tower
Updated base rom to 31.0.7 (includes potential hera basement cage fix)
2020-11-30 15:54:39 -07:00
aerinon a402a8ba75 Merge branch 'DoorDevUnstable' of github.com:aerinon/ALttPDoorRandomizer into DoorDevUnstable 2020-11-25 23:04:26 -07:00
aerinon 90fc60a9f0 Compiling pot shuffle 2020-11-25 23:03:49 -07:00
aerinon ef3bc0aee0 Spoiler log improvements
Fix multi-entrance checks
Tower lobby door pairing fixed
2020-11-25 23:00:54 -07:00
aerinon 5106bd3960 Merge pull request #72 from miketrethewey/DoorDevUnstable
Door dev unstable
2020-11-24 19:39:37 -07:00
aerinon 5b9919153e Merging of pot shuffle 2020-11-24 12:57:11 -07:00
aerinon cd9b574e90 Removal of key doors no longer overwrites lobby status
Fixed the 4 ER entrances when Desert back is a connector
2020-11-23 15:28:54 -07:00
compiling e6d9fc71a9 Fix FastEnum compatibility with normal enums - use IntFlag to allow bitwise operations and interpreting as raw integers. 2020-11-21 23:01:22 +11:00
aerinon 22f749e767 Keysanity menu bugfix
Inverted ER + intensity 3 fix
Swamp Trench 1 locking flippers fix
Fix for lobbies overwriting logic in TR Hub (and elsewhere)
Repaired exits that were wrongly affected by entrance fixes
2020-11-20 14:00:40 -07:00
aerinon f5327bc0e6 Fix trock entrances when intensity >= 3
Keysanity menu countdowns
Standard rain state
Multi-entrance dungeon bosses
This dungeon/universl key drops skip pose
More rupee candidates to remove for retro
2020-11-19 16:26:45 -07:00
aerinon b8dc174f87 (Merge)
Fix trock entrances when intensity < 3
Fix outputpath setting in settings.json
2020-11-16 13:20:39 -07:00
aerinon 7756528da3 Fix trock entrances when intensity < 3
Fix outputpath setting in settings.json
2020-11-16 13:15:23 -07:00
aerinon 61fb954c9c Merge branch 'bps_basepatch' of https://github.com/compiling/ALttPEntranceRandomizer into BpsWork 2020-11-16 11:13:39 -07:00
aerinon 4dda394a90 Added option to keep original palettes in crossed dungeon mode
If sanc if in a DW dungeon because of crossed+ ER, then you start in bunny form
Mirroring from sanc to the portal is now in logic
Another fix for animated tiles (fairy fountains)
GT Big Key stat changed on credits

Some standard logic fixes for lobbies (more outstanding)
2020-11-16 10:51:26 -07:00
aerinon 11154e1544 Crossed dungeon palette refinement
Fixed some entrances that require reset otherwise
Fixed TR lobbies that need to be bombed
Fixed animated tiles in lobbies
Fixed wallmaster+lamp problem
Fixed some key rules that caused item requirements to be ignored
Fixed Old Man cave to be properly one-way in the graph
Fixed some odd key logic issues
2020-11-12 12:18:00 -07:00
aerinon 7d3bb07382 Fix /missing command 2020-11-12 06:31:44 -07:00
Mike A. Trethewey a4b10a3393 Merge branch 'DoorDevUnstable' of https://github.com/miketrethewey/ALttPDoorRandomizer into DoorDevUnstable 2020-11-11 00:21:34 -08:00
Mike A. Trethewey 3f083992c1 Merge pull request #20 from aerinon/DoorDevUnstable
Door dev unstable
2020-11-11 00:15:07 -08:00
Mike A. Trethewey 44fe965baf Merge pull request #19 from aerinon/DoorDev
Update DoorDev
2020-11-11 00:13:49 -08:00
Mike A. Trethewey 5f2b4041f9 Make a simpler installer script 2020-11-11 00:08:42 -08:00
aerinon d3cde6c901 Messing around with HC/Sewer ID
Compass code uses original addresses
2020-11-09 16:13:29 -07:00
aerinon 6162fddf47 Lots of bugfixes - see notes 2020-11-09 13:54:03 -07:00
compiling 3ee5f59a19 Add python and pip instructions to the readme. 2020-11-08 15:25:16 +11:00
compiling 3b32735e10 Fix enemizer - read the basepatch and update base2current.json before calling enemizer. 2020-11-08 15:17:28 +11:00
compiling bdddd3c0de Set location's parent_region when moving it.
Fix copy_world to handle moved locations
2020-11-08 12:33:31 +11:00
compiling af488e653e Allow key drop pots to be shuffled anywhere if they contain general items 2020-11-08 12:00:19 +11:00
compiling 793eb30dec Update PotShuffle.py for keydrop shuffle changes 2020-11-08 11:53:31 +11:00
compiling 8ca529aa6a Fix enemizer - read the basepatch and update base2current.json before calling enemizer. 2020-11-08 11:20:37 +11:00
compiling 078b5eeb85 Merge remote-tracking branch 'remotes/origin/DoorDevUnstable' into DoorDevUnstable 2020-11-07 18:48:26 +11:00
aerinon cdf5f23b75 Potential multiworld fixes for keydropshuffle 2020-11-03 10:19:22 -07:00
aerinon f62ba51469 Baserom re-factor of compass code
Scrolling fix
2020-11-03 10:17:46 -07:00
aerinon 4a4868bb5b Version bump 2020-11-02 12:40:43 -07:00
compiling fdcd179186 Fix copy_world for insanity shuffle (dungeon exits do not lead to the same place as the corresponding entrance) 2020-11-02 15:03:48 +11:00
compiling a5b1f228df Handle Sanctuary as an additional entrance in the middle of a dungeon. 2020-11-02 11:56:53 +11:00
compiling 5442f05a79 Update find_accessible_entrances to work with lobby shuffle 2020-11-02 11:22:03 +11:00
compiling 31c0540cc8 Merge remote-tracking branch 'remotes/origin/dungeon_entrance_fix' into DoorDevUnstable 2020-11-02 10:28:54 +11:00
compiling 6c531620e5 Make it possible to generate standard / retro / vanilla doors. 2020-11-02 10:21:34 +11:00
compiling 62e0981568 Fix entrances list for non-lobby shuffle. 2020-11-02 10:20:38 +11:00
compiling 3e1b5a03a0 Make standard x retro work
Fix no logic generation
Remove a duplicate function in Main.py
2020-10-31 15:10:11 +11:00
compiling b4160358bc Fix a typo 2020-10-31 14:47:08 +11:00
compiling dc5319ae97 Don't fix fake worlds for glitched modes.
Pre-open pyramid for crystals goal with entrance shuffles that don't move Ganon (vanilla, dungeon-only shuffles)
2020-10-31 14:37:34 +11:00
compiling c6c4b58c93 Remove dead code.
Fix imports.
2020-10-31 10:40:12 +11:00
compiling e62d095d28 Connect hyrule_castle_exits to light world exits in standard dungeonsfull shuffle when there are no mandatory exits.
Fix GT key logic to only allow placing a small key in the map room when the playthrough algorithm can reach it (due to limitations of the key logic).
2020-10-31 10:22:43 +11:00
compiling 6ff039e67a Fix some more multiworld conflict issues 2020-10-31 10:20:00 +11:00
compiling 0cc3b888e9 Fix bunny glitch rules for Tower of Hera (requires a sword to hit the switch) and Mini Moldorm Cave (pits prevent clearing in superbunny state) 2020-10-31 10:17:39 +11:00
compiling 9dbe591fe9 Fix up no logic entrance rules - create all the OWG transitions, but don't apply any logic 2020-10-31 10:17:22 +11:00
compiling 665e7b1497 Reduce mandatory exits for OWG logic to only those that cannot be reached by glitches 2020-10-31 10:13:33 +11:00
compiling ef294ab0d3 Fix copy world. 2020-10-31 10:05:28 +11:00
compiling 171b9430c8 Remove Ice Palace Clip from logic. 2020-10-30 18:11:11 +11:00
compiling 184f9db922 Split mirror glitches into clips and offsets, with different rules (offsets need boots).
Fix inverted mirror rules - DM Descent is a mirror offset, East DM access is a mirror wrap (not in logic).
Add mirror clip to Desert East entrance (from east Mire Shed).
Add inverted mirror offset to hyrule castle ledge (placing a portal on the houlihan exit).
2020-10-30 18:09:40 +11:00
compiling ccb3056f53 Go back to the old copy_world routine, and fix it to work with dynamic connections. 2020-10-30 17:42:04 +11:00
compiling 3c27a64478 Go back to a custom copy_world implementation. copy.deepcopy doesn't handle big graphs very well (stackoverflow). 2020-10-30 17:42:03 +11:00
compiling 1bd3ccfdc5 Require flippers for returning to dark lake hylia from Ice Palace / Capacity Fairy. 2020-10-30 17:40:25 +11:00
compiling 10bf0870df Make Pyramid Fairy offset mirror require access to Hyrule Castle Courtyard through the secret passage entrance (the normal route is not possible if you killed Agahnim). 2020-10-30 17:39:18 +11:00
compiling 86da66fd0b Add OWG clip to dark world floating island. 2020-10-30 17:38:08 +11:00
compiling 3bbad7bd91 Fix some multiworld merge issues 2020-10-30 17:35:32 +11:00
compiling 2d6910024f Combine bunny rules calculation for inverted and normal. 2020-10-30 17:19:19 +11:00
compiling 07fe3191e6 Add inverted bomb shop rules for race game left (insanity shuffle). 2020-10-30 17:12:11 +11:00
compiling 71e5fd7d26 Require moon pearl and flippers to exit the Waterfall of Wishing cave in inverted. 2020-10-30 17:08:04 +11:00
compiling b1853e2ad9 Refactor OWG rules to keep them separate from no glitches.
Add logic for superbunny access to Sahasrahla's closet (with boots)
Add logic for superbunny through Two Brother's House (with boots)
Fix superbunny logic for spiral cave and mini moldorm cave - requires a sword
Add logic for waterwalking into Waterfall Cave
Add clip to Ice Palace entrance (requires boots, pearl and flippers)
Add extra clips to inverted owg logic - PoD and Dark Lake Hylia Ledge are now in logic with just boots
Add clip to flute point 6 into inverted owg logic - some light world locations are now accessible with boots and mitts, but no pearl or mirror.
2020-10-30 17:04:36 +11:00
compiling 82449763b7 Add OWG tests 2020-10-30 16:45:09 +11:00
compiling ad9db670a2 Merge branch 'master' into Dev-owg 2020-10-30 16:00:22 +11:00
aerinon d3e643b9c6 Finish bps work
Fixing a couple bugs
2020-10-29 15:46:27 -06:00
aerinon a02dcd0ba4 Basic Bps work 2020-10-29 12:11:27 -06:00
aerinon cade01b489 GUI work and revert find_accessible_entrances for main dungeon generation 2020-10-27 14:45:22 -06:00
aerinon abb59308ef Merge in some PRs (Ganon hint and Vanilla key logic edit) 2020-10-27 11:52:19 -06:00
aerinon 62d7ae0327 Version bump - auto-assign reviewers to PRs 2020-10-27 11:39:24 -06:00
aerinon c1d46796fe Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2020-10-27 11:38:54 -06:00
aerinon 471ab3d50e Hint work (Lobby, Ganon, Keydropshuffle)
Preliminary multiworld work
2020-10-27 11:37:47 -06:00
aerinon 6a1e35308b Merge branch 'DoorDev' into DoorDevUnstable 2020-10-27 11:20:15 -06:00
aerinon 465721480b Merge pull request #66 from compiling/dungeon_entrance_fix
Dungeon entrance fix (key logic)
2020-10-27 11:08:55 -06:00
aerinon 5e0e297614 Merge pull request #67 from compiling/HintFix
Fix Ganon's Silvers hint for crossed dungeon shuffle
2020-10-27 11:08:13 -06:00
aerinon a77ecb4e13 Update documentation slightly 2020-10-26 11:51:55 -06:00
aerinon 8c73947ad7 Bug fix for vanilla BK at Ball n Chain guard
Bug fix for camera unlock
Bug fix for bad pseudo layer at PoD Map Balcony
Minor fix for non-retro key hud info
2020-10-26 11:46:52 -06:00
compiling 138f047636 Create base2current.json from the bps patch for enemizer. 2020-10-26 18:38:55 +11:00
compiling 8f2b068313 Refine hints for crossed dungeon shuffle regardless of the hints setting, since they are also used for the Ganon silvers hint.
Move Hera Basement to the list of inconvenient dungeon locations to exclude it from crossed shuffle.
2020-10-26 18:02:42 +11:00
compiling c3c6cabea6 Find accessible entrances for key logic and later steps by exploring the entire world including other dungeons.
Dungeon generation will still use the old method, since it needs to dynamically change as dungeons are added.
2020-10-24 09:58:32 +11:00
aerinon a1782e3edc Bug fix for vanilla standard key rules 2020-10-23 15:25:49 -06:00
aerinon c0f6c3fd52 Bug fix for intensity 3 + enemizer (just taking it out for now)
Lobbies added to spoiler
2020-10-23 15:07:55 -06:00
aerinon d89801c72c Key Hud redesign continued
Keydropshuffle prototype
2020-10-23 12:59:18 -06:00
compiling 2a2f72a360 Bps patching 2020-10-17 22:03:02 +11:00
aerinon 7aca24b10f Standard + Crossed bug with Hyrule Castle
Big Key logic for standard
Some generation issues with ER
Redesigned Map/Compass section of Keysanity menu
2020-10-09 16:02:39 -06:00
aerinon 38be9e6ec0 Generation improvements
Hera Lobby fix
Added gauntlet 3 to cut carpet
2020-10-07 16:33:43 -06:00
CaitSith2 0ff0a1cf76 No longer need the sh versions of the test. 2020-09-28 13:19:17 -07:00
CaitSith2 50639c8428 Rewrite the testing scripts into Python 2020-09-28 13:14:47 -07:00
aerinon 7bc2d803eb Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2020-09-24 16:05:17 -06:00
aerinon f275dfb218 Test files 2020-09-24 16:03:16 -06:00
aerinon 96fe4a62f5 Test files 2020-09-24 15:32:02 -06:00
aerinon adc27c4dbc Generation improvements 2020-09-24 15:30:35 -06:00
aerinon 99f262cc72 Lobby logic improvements
Cutoff entrance rug re-work
2020-09-21 16:38:15 -06:00
aerinon d2ea578df8 Merge in door dev unstable 2020-09-17 15:23:06 -06:00
aerinon 46d4fd4b91 Merge pull request #63 from aerinon/DoorDevUnstable
Door dev unstable moving to stable
2020-09-17 14:58:25 -06:00
aerinon 357a09d5b7 Added intensity parameter. Clean up for next alpha release 2020-09-16 15:01:01 -06:00
aerinon 7653c95fd7 Minor fixes for a few lobbies 2020-09-15 16:13:54 -06:00
aerinon f881d1d133 Merge pull request #62 from CaitSith2/patch-5
Add two more rooms that need rug cuts.
2020-09-15 15:57:14 -06:00
CaitSith2 18f115faef Add two more rooms that need rug cuts. 2020-09-15 12:47:27 -07:00
aerinon 907b13b59a Minor key door fix 2020-09-09 16:15:39 -06:00
aerinon 309dc40f08 Minor ASM reorg
Fix for bonking across the TR chest gap
2020-09-09 16:03:43 -06:00
Catobat 1339bd4bc5 Add Hookshot edge for Hera Big Chest 2020-09-09 16:02:05 -06:00
aerinon 973bf02b1d Palette refinement
Sanctuary starting dungeon and mirror target
Sanctuary limited to LW in open mode (non-crossed/insanity ER)
2020-09-09 15:49:00 -06:00
compiling 7c9e02b182 Pot shuffle 2020-09-06 18:01:44 +10:00
aerinon 804309565b Bulk of Lobby randomization work 2020-08-28 12:42:20 -06:00
compiling ce835aaee6 Pot Shuffle in-progress 2020-08-21 17:17:48 +10:00
aerinon 18447cfe3e Torch+ChestKey counter bug fixed
Total Keys on keysanity menu fixed
Changed X and grayish circular symbol for new O character
Fixed a key logic error
Fixed unplaced items bug to remove red rupees
2020-08-18 15:21:35 -06:00
aerinon 49e799f658 Fixed two minor bugs 2020-08-17 11:23:12 -06:00
aerinon 53a5d6a98f Incorporating CrossGenWork2 branch again 2020-08-14 16:27:37 -06:00
aerinon 459e3cdc26 Merge branch 'DoorDevUnstable' of github.com:aerinon/ALttPDoorRandomizer into DoorDevUnstable 2020-08-14 16:24:26 -06:00
aerinon b37dc454ad Crossed Dungeon generation work
-Added more path checking to dungeon gen
-Found and squashed a pair of infinite loops
2020-08-14 16:12:41 -06:00
aerinon 2eb6c1ebc0 Crossed Dungeon generation work
-Added a bunch of crystal switch logic
-Added a check for maiden backtracking
-OrderedFrozenSet to prevent randomization leaks with the same seed
-A few key improvements from an outstanding PR
2020-08-13 16:23:40 -06:00
aerinon df52ca2730 Crossed Dungeon generation work
-Rewrite of step 3b for accuracy - verified acceptable speed
--Can now detect an impossible balance situation and restart
-Eliminated false negatives in step 4 (still need to rework false positives)
-Minor key logic improvement
2020-08-04 15:24:24 -06:00
aerinon 2aa2266a9c Merge pull request #56 from Berserker66/DoorDevUnstable
Report extraneous or insufficient items as warning.
2020-08-03 21:36:14 -06:00
Fabian Dill cba2ecb80e Report extraneous or insufficient items as warning. 2020-08-02 01:14:57 +02:00
aerinon 24177fa8b8 Crossed Dungeon generation work
--Introduced reachable_switches
--Calculate total completion in equation resolution
--Prioritized one-way connections over neutral/neutral_profitable sectored but not over dead-ends
--Simplified finding good complex branching candidates - just re-used equations routine
--Valid multi choice for global polarity when fixing parity
--Added total dungeon charge as critieria when fixing parity
--Pinball used for navigation in skull 2, marked appropriately (particularly with Ice Cross in Skull 2)
--Equation resolution detects used benefits with unreached_doors benefits
--Greedy equation finder not longer used destination/entrance sectors of the wrong split dungeon
--Required connections don't overestimate benefits
--Introduced the concept of crystal switches and doors blocked by blue barriers to equations
2020-07-22 17:11:20 -06:00
aerinon b4fd8f6bdc Bug fix for attic blind
Bug fix for simple dungeon shuffles making HC your DW access with door shuffle on
Bug fix for accessibility: none
Moved bk/key info to keysanity screen
Added chest total to keysanity screen
2020-07-13 17:11:36 -06:00
aerinon 6574b5708a Merge remote-tracking branch 'origin/DoorDevUnstable' into DoorDevUnstable 2020-06-25 16:17:13 -06:00
aerinon ed20ff5f63 Bug fixes for crashes involving new baserom 2020-06-25 16:16:56 -06:00
aerinon b5d18c4b4d Merge pull request #53 from CaitSith2/patch-3
player names moved in new basepatch
2020-06-23 16:45:06 -06:00
aerinon 50f55b8008 New baserom (31.0.5)
Updated release notes
2020-06-23 16:43:15 -06:00
CaitSith2 db88e6bd3e player names moved in new basepatch 2020-06-13 13:29:59 -07:00
aerinon a51820e2cf New baserom
Asar compatibility
Potential SRAM fix
2020-06-12 16:01:11 -06:00
aerinon 6f94ca5bee Potential fix for bottle issues 2020-06-08 13:07:11 -06:00
aerinon 5ab4b29937 Merge branch 'DoorDev' of github.com:aerinon/ALttPDoorRandomizer into DoorDevUnstable 2020-06-08 13:01:57 -06:00
aerinon c9a379e652 Merge pull request #52 from Berserker66/patch-1
Fix triforce hunt logic
2020-06-08 11:14:33 -06:00
Fabian Dill d6aef7316d Fix triforce hunt logic
Access to Murahdahla's Triforce requires ">" 20 triforce pieces by default. This leads to 21 pieces available in beatable only and it means a hard crash if on tries to set it to 30 out of 30, as has_beaten_game cannot find a 31st triforce piece to beat the game
2020-06-08 18:03:09 +02:00
aerinon 0b943b01e8 Merge branch 'compiling-DoorPerf' into DoorDevUnstable 2020-05-29 16:20:04 -06:00
aerinon 3b4e19b5de Fixes for compatibility with compiling perf
Couple fixes for standard+ER
2020-05-29 16:19:32 -06:00
aerinon d9d497ba62 Merge branch 'DoorPerf' of https://github.com/compiling/ALttPEntranceRandomizer into compiling-DoorPerf 2020-05-26 14:35:12 -06:00
aerinon 2b441134fe Fixed a problem with edges when those are turned off (experimental not on)
Fixed a problem with standard requiring you to go through the tapestry backwards to save Zelda
Added debugging features to help figure out some bugs
2020-05-26 14:34:24 -06:00
aerinon 2d8d4ebf4a Added the stz $047a for pod eg glitch
Standard generation improvements (Bomb escape rework)
Vanilla+ER generation improvements
2020-05-22 13:45:00 -06:00
aerinon ae7ce076af Open edges math fix (indices corrected in tables)
Spoiler lists bosses
Enemizer settings fix
Swamp flooded ladder's fix (Crossed mostly)
Spoiler encoding issue fixed
2020-05-20 10:51:56 -06:00
compiling 8b1bb810c1 Link requires flippers to exit the water from Diver Down state in Swamp. 2020-05-17 22:42:46 +10:00
compiling ac8cd92ab6 Remove logging line for missing module - seems to not work properly and CI should handle it. 2020-05-13 20:16:49 +10:00
aerinon 337dbf311d Some generation improvements (bk checked better, backtrack added re-attempts)
No logic skips more key logic
Some prototyping new key rules
2020-05-12 15:03:39 -06:00
compiling c817e9ce91 Fix issue with crossed generation (Save and Quit entrance is not handled) 2020-05-12 21:38:37 +10:00
compiling c7103e6919 Add fast-enum requirement to ci 2020-05-12 21:19:01 +10:00
compiling 0700af4dbd Logic updates to Spike Cave, Bosses
Fix Bomb rules to exclude Spectacle Rock Cave for inverted
Require a weapon for Castle Tower kill rooms
2020-05-12 21:03:35 +10:00
compiling 1217236621 Replace world exploration with a faster algorithm - use BFS and keep track of all entrances that are currently blocked by progression items.
New algorithm also obsoletes sweep_for_crystal_access
Set up door and entrance caches in advance
Replace CrystalBarrier with FastEnum for bitfield arithmetic
2020-05-12 21:03:35 +10:00
compiling cf70210ed1 Fix pre_validate rejecting Desert Palace when no chests are in the back. 2020-05-09 20:40:01 +10:00
Fabian Dill cc7145c6b8 remove collections_extended dependency and replace with much faster stdlib Counter 2020-05-09 20:37:26 +10:00
aerinon 300db22725 Some ER generation improvements
Attempt at Attic Hint Tile
Stonewall detection improved by not excluding drops
2020-05-05 13:24:51 -06:00
aerinon aeb3b3d4b1 Forgot straight stairs in vanilla 2020-05-02 15:15:21 -06:00
aerinon 0705ccaeda Edge rom changes and minor mystery defensive coding 2020-05-02 15:09:23 -06:00
aerinon 79c4889e07 Merge remote-tracking branch 'origin/EdgeWork' into EdgeWork
# Conflicts:
#	asm/edges.asm
2020-04-29 21:20:47 -06:00
aerinon 467507b505 Straight Stairs trap doors
Straight Stairs adjustment for different door types
2020-04-28 17:05:58 -06:00
compiling 6418a86c1b Require a weapon for Inverted Castle Tower 2020-04-28 20:16:14 +10:00
compiling f391f0a3c1 Bunny revive is not possible in Sanctuary. 2020-04-28 20:16:13 +10:00
compiling 0215254c89 All superbunny to spiral cave item (with sword) 2020-04-28 20:16:13 +10:00
compiling 461db9d1ba Allow superbunny into tavern
Fix inverted Kings Grave logic
2020-04-28 20:16:06 +10:00
compiling 67a0afc6fa More moon pearl / superbunny fixes
Use the Catfish region properly, so Catfish Descent works.

# Conflicts:
#	InvertedRegions.py
2020-04-28 20:16:05 +10:00
compiling 65b8e128b0 Allow superbunny into the Blind's Hideout entrance. 2020-04-28 20:15:36 +10:00
compiling f964175d64 Allow clipping into the GT entrance 2020-04-28 20:15:11 +10:00
compiling 21eea4277b Always require pearl for Swamp (Superbunny cannot do anything) 2020-04-28 20:15:10 +10:00
compiling 2decfd1f0b Separate superbunny cave into 2 regions.
For OWG, allow superbunny in superbunny cave with no mirror when entering from the bottom
Fix boots clip logic to desert teleporter ledge and TR teleporter
Fix mirror wrap logic for pyramid fairy
For insanity shuffle, exiting Superbunny Cave bottom is now in logic.
2020-04-28 20:15:10 +10:00
compiling db811f198c Fix another bunny rule bug. 2020-04-28 20:15:09 +10:00
compiling 9c2dec9cec Fix OWG bunny rules 2020-04-28 20:15:09 +10:00
compiling c8a30bb749 Dark Desert Teleporter requires the mitts 2020-04-28 20:15:09 +10:00
compiling e8fef8fc7b Fix moon pearl checks to avoid requiring moon pearl for mirror accessible locations. 2020-04-28 20:15:08 +10:00
compiling 1f504d0a79 Inverted - make the blacksmith, purple chest, bottle merchant and master sword pedestal accessible without the moon pearl.
# Conflicts:
#	test/inverted/TestInvertedDarkWorld.py
#	test/inverted/TestInvertedLightWorld.py
2020-04-28 20:15:08 +10:00
compiling 3b979f4a57 Fix Waterfall entrance being inaccessible with the flippers.
Fix Spectacle Rock and Bombos Tablet requiring moon pearl
2020-04-28 20:14:56 +10:00
aerinon 45016ed5ce Merge Unstable into EdgeWork 2020-04-24 14:02:47 -06:00
aerinon 810942cf69 DungeonGen bug
Animated tiles fix
2020-04-23 16:18:56 -06:00
aerinon 946c7bbcef Merge in DoorDev changes
Revert ci changes
2020-04-21 16:06:49 -06:00
aerinon 53ddd1963c Split dungeon combinations - runs through combinations if few enough
Odd builders - new algorithm for testing entire set then making a decision
Force groupings updated to be smarter about it - needs to apply elsewhere
2020-04-21 16:03:07 -06:00
aerinon 0bb7e7caf8 update ci to build dev releases for now 2020-04-17 14:13:27 -06:00
aerinon 88b93d2649 Bump version 2020-04-17 14:08:52 -06:00
aerinon 1f2edde2e5 Add minor notes 2020-04-17 14:07:39 -06:00
aerinon bc06b86311 Multiworld torch key fix 2020-04-16 15:52:19 -06:00
aerinon 57cd5575da Merge branch 'patch-1' of https://github.com/zig-for/ALttPEntranceRandomizer into zig-for-patch-2 2020-04-16 14:31:55 -06:00
compiling 247137e43a Remove mirror clips from Inverted / No Glitches 2020-04-15 23:09:07 +10:00
compiling 8525f07e87 Set TR key rules last, so that entrance requirements are known. 2020-04-15 23:09:07 +10:00
zig-for 8aab7715be Red and Blue Pendant are switched
Found this today.

This leads to the Spoiler log (and thus my bot) giving the wrong Pendant values.

https://github.com/sporchia/alttp_vt_randomizer/blob/master/app/Item.php#L147-L149
```            new Item\Pendant('PendantOfCourage', [0x37, 0x04, 0x38, 0x62, 0x00, 0x69, 0x01], $world), // Green
            new Item\Pendant('PendantOfWisdom', [0x38, 0x01, 0x32, 0x60, 0x00, 0x69, 0x03], $world), // Red
            new Item\Pendant('PendantOfPower', [0x39, 0x02, 0x34, 0x60, 0x00, 0x69, 0x02], $world), // Blue```

https://github.com/Berserker66/MultiWorld-Utilities/commit/5996d6d9785682e498e7b5b25551a382fa2b6c36
2020-04-15 00:13:41 -07:00
aerinon aed4251f13 Merge branch 'DoorDevUnstable' into CrossGenWork 2020-04-13 14:54:59 -06:00
aerinon d02cc2bb15 Fix compassshuffle/mapshuffle menu flags 2020-04-13 14:49:04 -06:00
aerinon e1cd520ea9 Merge unstable into CrossGen 2020-04-10 15:17:31 -06:00
aerinon 09bd392fd0 Bugfix to map info
Bugfix to dungeon reminder on death
2020-04-10 11:19:05 -06:00
aerinon acd430378d Minor fix to vanilla doors 2020-04-09 17:32:06 -06:00
aerinon ff3577358d Version bump
Release notes updated
2020-04-09 17:14:42 -06:00
aerinon 8e7ed89723 Formatting
Json spoiler tied to jsonout arg
Fixed Default Link sprite button again
Removed odd return from local_path (need to test this with bundle)
2020-04-09 17:02:40 -06:00
aerinon b86ffc3378 Merge branch 'miketrethewey-dev' into DoorDevUnstable 2020-04-09 15:55:42 -06:00
aerinon 23e6c5b14d Merge branch 'dev' of https://github.com/miketrethewey/ALttPDoorRandomizer into miketrethewey-dev 2020-04-09 15:55:27 -06:00
aerinon 954a5fa09f Merge branch 'CaitSith2-patch-1' into DoorDevUnstable 2020-04-09 15:54:34 -06:00
aerinon e7c2e63166 Formatting 2020-04-09 15:53:58 -06:00
aerinon f6f7d8add3 Merge branch 'patch-1' of https://github.com/CaitSith2/ALttPEntranceRandomizer into CaitSith2-patch-1 2020-04-09 15:51:17 -06:00
aerinon 7f935d6ff9 Fix fire speed for ice palace rooms 2020-04-08 17:04:33 -06:00
aerinon 4fe97f9b7f Adjusted map info to be experimental
Moved mirror scroll to be standard in non-vanilla door shuffles
Fixed potential duplicate map issues
2020-04-08 15:56:03 -06:00
CaitSith2 e6f6ccf610 Add Big Key/Map/Compass (Agahnims Tower) ...
... to list of items that can be started with.
2020-04-07 19:04:52 -07:00
aerinon 114ed784f1 Torch keys counted like chest
Moved the total key counter to a count down on the left.
Added the BK indicator
Attempt to fix dungeon counters and fish error in Mystery.py
Removed double rom patch
AT map added.
5 chests min for all dungeons
2020-04-07 16:50:02 -06:00
Mike A. Trethewey 4c35b39e35 Fix Hints toggle on CLI 2020-04-07 02:17:25 -07:00
Mike A. Trethewey c9d6b87d94 Update .gitignore 2020-04-05 12:14:41 -07:00
Mike A. Trethewey ab5f2ab521 JSON Spoiler output 2020-04-05 09:50:01 -07:00
aerinon bb402ff7f2 Dungeon reminder added to hud for Crossed dungeons
Blinking red square added to hud and it indicates a boss room is close by. Only appears if you have the compass. (Basic & Crossed)
Key counters added to hud if you have found the map. (Crossed only)
2020-04-03 15:45:55 -06:00
aerinon e30f66742b MirrorScroll block erase removed
Standard+Crossed ammo issue addressed
Fix for vitreous' eye dropping keys
Fix for vanilla linking doors (hc back hallway)
2020-04-02 13:15:08 -06:00
aerinon 01bff51707 Fixed some minor issues
Started work on Straight Stairs
2020-04-01 12:48:04 -06:00
aerinon c968621ba3 Tons of edge work:
--Refactor of scrolling
--Addition of edge math
--Tied linking doors to DR Flag
--Fixed vanilla linking doors
2020-03-31 11:00:49 -06:00
Mike A. Trethewey fe6383bc57 Fix Spec files 2020-03-28 19:09:10 -07:00
Mike A. Trethewey 599985e4b1 Use os.path more
Add Enemizer note
2020-03-28 19:03:08 -07:00
aerinon e5a1c59f85 Fix for capacity shop and hobo splash interaction 2020-03-25 15:52:57 -06:00
aerinon 8ceb1f4585 CI change 2020-03-24 10:50:25 -06:00
aerinon 8f545fc6d1 Merge branch 'DoorDev' into EdgeWork 2020-03-24 10:49:28 -06:00
Mike A. Trethewey 6c484745a2 Keep EnemizerCLI 2020-03-24 01:35:14 -07:00
Mike A. Trethewey 01a1190b58 Fix bugs 2020-03-24 01:26:14 -07:00
Mike A. Trethewey 7aa6195bf0 Add Diags to CLI 2020-03-24 00:44:03 -07:00
Mike A. Trethewey 871278a17a Restrict AutoRelease 2020-03-23 21:50:37 -07:00
Mike A. Trethewey 406806a70b Outfilename shenanigans 2020-03-23 21:41:09 -07:00
Mike A. Trethewey ff678659f9 Add Suppress Spoiler 2020-03-23 21:39:45 -07:00
Mike A. Trethewey 0b8014b9b4 Merge pull request #16 from aerinon/DoorDev
Update DoorDev
2020-03-23 20:20:58 -07:00
aerinon 0b13db754d Fixing some seed reporting 2020-03-23 15:40:56 -06:00
aerinon 4fc15e84fc Bump version
Set shuffleganon to default to True
2020-03-23 14:15:17 -06:00
Mike A. Trethewey e4311832a5 Merge branch 'DoorDev' into dev 2020-03-23 00:53:24 -07:00
Mike A. Trethewey 215a4d039f Pull in fixes from Multiworld 2020-03-22 16:32:15 -07:00
Mike A. Trethewey 133ad920c7 Merge pull request #14 from aerinon/DoorDev
Update DoorDev
2020-03-22 02:59:41 -07:00
Mike A. Trethewey 8513b7f270 Fix var loading again
Update Deprecated Args
Parse CLI
Parse Settings
Fix defaults
Fix priority
Add Enemizer error
Fix Custom Item Array again
Make output more verbose
Fix double-negative options
2020-03-22 02:53:40 -07:00
aerinon ceea586389 Merge remote-tracking branch 'origin/EdgeWork' into EdgeWork 2020-03-20 21:08:47 -06:00
aerinon 53a5376693 Merge branch 'DoorDev' into EdgeWork 2020-03-20 13:32:00 -06:00
aerinon 9a65e45813 Refinement on BK restriction logic 2020-03-20 13:08:38 -06:00
aerinon de2a3bf5c1 Version change and note for later 2020-03-20 12:24:36 -06:00
aerinon a18f5c4d51 Key logic rework for placement rules
--exhaustive per key_counter
--contradictions between rules
Mire Lobby chest fix
2020-03-20 09:05:07 -06:00
Mike A. Trethewey f28b1d15c6 Fix widget loader 2020-03-12 16:47:39 -07:00
Mike A. Trethewey d359ce4b07 Merge branch 'DoorDev' into ci-dev 2020-03-12 16:24:54 -07:00
Mike A. Trethewey 8cc55c5999 Merge pull request #12 from aerinon/DoorDev
Minor bugfix with Ice Tall Hint
2020-03-12 16:24:35 -07:00
Mike A. Trethewey 4b0f30a85f Implement prelim enums 2020-03-12 16:16:15 -07:00
aerinon 269de35590 Minor bugfix with Ice Tall Hint 2020-03-12 09:13:09 -06:00
Mike A. Trethewey d8ea5b0fd0 Merge branch 'DoorDev' into ci-dev 2020-03-12 04:17:05 -07:00
Mike A. Trethewey 0ad5c4158e Merge pull request #10 from aerinon/DoorDev
Update DoorDev
2020-03-12 04:09:44 -07:00
Mike A. Trethewey fc8ebad37f Promote default 2020-03-12 04:05:26 -07:00
Mike A. Trethewey 755c401da1 Slim down adjust & custom 2020-03-12 03:50:19 -07:00
Mike A. Trethewey 0cb7eaa417 Slim down args 2020-03-12 03:31:39 -07:00
aerinon 999fafbbeb Missed adding enum in merge 2020-03-11 16:28:21 -06:00
aerinon 9d75561dc3 Merge branch 'DoorDev' into EdgeWork 2020-03-11 15:09:51 -06:00
aerinon 2d9d108430 Merge in DoorDev 2020-03-11 14:33:53 -06:00
aerinon 3fdf9e8624 Unvalidated gen work 2020-03-11 14:21:14 -06:00
aerinon f87a2e8a85 Clean up some asm that's not ready 2020-03-11 14:19:22 -06:00
aerinon ceeb23669a Experimental flag issue
Turned off unprepared experimental feature that snuck in
2020-03-11 14:02:16 -06:00
aerinon c67cd478a1 Fixed problem with Inverted+ER
Fixed problem with Vanilla doors+Retro
Fixed Keylock issue with Ice Cross
Merged in compiling's fix for keyshuffle
ER Infinite Loop detection
2020-03-11 12:25:49 -06:00
aerinon 90e6e8762e Merge branch 'compiling-DoorDev' into DoorDev 2020-03-11 10:48:42 -06:00
Mike A. Trethewey f69d86eca6 Test Linux user folder 2020-03-10 22:10:56 -07:00
Mike A. Trethewey 50a960114a Fix Worlds 2020-03-10 21:48:15 -07:00
Mike A. Trethewey e485b39842 Different Notes 2020-03-10 21:32:54 -07:00
Mike A. Trethewey 0c1dc36335 Move MW to Bottom 2020-03-10 21:31:42 -07:00
Mike A. Trethewey 3e9880a6db Merge branch 'translation' into ci-dev 2020-03-10 21:09:20 -07:00
Mike A. Trethewey 721896d5a8 Forgot to pass the fish 2020-03-10 18:58:54 -07:00
Mike A. Trethewey 79c6047415 Fix Seed again 2020-03-10 18:47:16 -07:00
Mike A. Trethewey 83d9398a19 Reorder args 2020-03-10 18:29:23 -07:00
Mike A. Trethewey e2943b21dc Fix Seed & Player Names 2020-03-10 18:21:36 -07:00
Mike A. Trethewey 3338e96822 Add seed to end of output log per generation 2020-03-10 17:46:58 -07:00
Mike A. Trethewey a80602517d Fix generation 2020-03-10 17:37:15 -07:00
Mike A. Trethewey e901f0f1f5 Ugh, I think I did it 2020-03-10 17:23:23 -07:00
Mike A. Trethewey 58bb9fffba Strip Bottom 2020-03-10 02:57:20 -07:00
Mike A. Trethewey 014aa3519c Strip Multiworld 2020-03-10 01:44:48 -07:00
Mike A. Trethewey 3f282fe15c Strip Generation 2020-03-09 20:40:24 -07:00
Mike A. Trethewey ceceee68df Strip Enemizer
Foundation for GUI translation
2020-03-09 19:10:40 -07:00
Mike A. Trethewey ff51821701 Moar translation
German
Refactor some English/Spanish
2020-03-09 04:51:57 -07:00
Mike A. Trethewey 37a1b70f3b Pass the fish better 2020-03-09 03:53:08 -07:00
Mike A. Trethewey ca7fc4d0f6 Hack in Spanish 2020-03-09 02:25:25 -07:00
Mike A. Trethewey b25e46b160 Factor out CLI text 2020-03-09 01:11:48 -07:00
Mike A. Trethewey 5bb0a0da26 Check for 6MB 2020-03-08 15:59:24 -07:00
Mike A. Trethewey 04404714d9 Update wiki and ci stuff 2020-03-08 15:52:05 -07:00
aerinon 9935563802 Left transition fix 2020-03-07 22:37:39 -07:00
aerinon d3696a2752 Prototype edge debugging 2020-03-07 22:15:27 -07:00
Mike A. Trethewey dce7dd3936 Implement shallow translation 2020-03-07 17:11:12 -08:00
Mike A. Trethewey d5b80380f2 Merge branch 'DoorDev' into ci-dev 2020-03-07 14:42:43 -08:00
Mike A. Trethewey ca36374e37 Merge pull request #8 from aerinon/DoorDev
Update DoorDev
2020-03-07 14:39:42 -08:00
Mike A. Trethewey a424719fbd Wiki Doors 2020-03-07 14:38:08 -08:00
compiling 857c13849e Fix double counting keys during placement with keysanity. 2020-03-08 09:35:07 +11:00
aerinon 2b8044d89d Fixed problem with keyshuffle option without bigkeyshuffle - attmept 2 2020-03-07 09:29:32 -07:00
aerinon b0eb7fb85d Fixed problem with keyshuffle option without bigkeyshuffle 2020-03-07 09:19:38 -07:00
aerinon 7072684505 Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2020-03-07 09:10:02 -07:00
aerinon c1783082d8 Lots of cross gen work 2020-03-05 16:47:57 -07:00
Mike A. Trethewey 061852cbd3 Merge branch 'DoorDev' into ci-dev 2020-03-04 14:05:49 -08:00
Mike A. Trethewey 93d77d91d9 Merge pull request #6 from aerinon/DoorDev
Gui fixes for clocks/dungeon_counters
2020-03-04 14:01:17 -08:00
aerinon 39ea777cf9 Gui fixes for clocks/dungeon_counters
Map fix for settings
2020-03-04 13:57:29 -07:00
Mike A. Trethewey c61bd00af6 Update Utils.py 2020-03-04 02:44:31 -08:00
Mike A. Trethewey ccd48dfa4d Sanity checks 2020-03-04 02:33:42 -08:00
Mike A. Trethewey 85587848d6 Meh, shoot from hip 2020-03-04 02:22:32 -08:00
Mike A. Trethewey dd1a3d416f chmod both 2020-03-04 02:06:08 -08:00
Mike A. Trethewey b1d9633c15 Set exec flag 2020-03-04 01:38:41 -08:00
Mike A. Trethewey d533a92e16 Meh 2020-03-04 01:27:25 -08:00
Mike A. Trethewey 6476f96398 Ooh, Run IDs 2020-03-04 01:25:45 -08:00
Mike A. Trethewey 126a7793a4 Try to fix Linux save path 2020-03-04 01:22:45 -08:00
Mike A. Trethewey 27c685f211 Meh, chase that rabbit later 2020-03-04 01:19:05 -08:00
Mike A. Trethewey b8bf4910e4 Make it Trouble, make it Tuple 2020-03-04 01:06:18 -08:00
Mike A. Trethewey dde662b263 What's RTFM? 2020-03-04 01:04:03 -08:00
Mike A. Trethewey 5b988818b7 Add to analysis 2020-03-04 01:00:33 -08:00
Mike A. Trethewey 92cec430ff See if this fixes this damn dll 2020-03-04 00:54:42 -08:00
Mike A. Trethewey 9884e86459 Merge branch 'gui-improvements-update' into ci-dev 2020-03-04 00:02:16 -08:00
Mike A. Trethewey 4968e72a3b Document stuff, add a couple things
Add Retro World State (Open & Retro on)
Add SpriteSomething plug to sprite selector
Fix Custom Item Pool loading to use disct instead of list
2020-03-03 23:43:43 -08:00
Mike A. Trethewey e093431b00 Merge pull request #4 from aerinon/DoorDev
Update DoorDev
2020-03-03 21:20:11 -08:00
aerinon 84d639ab60 Merge DoorDev fixes 2020-03-03 12:49:59 -07:00
aerinon 5e2a5f2e8e Bugfix for a key lock 2020-03-03 12:39:52 -07:00
aerinon 549607c72a Bugfix for rupee20
Bugfix for Triforce hunt
Bugfix for python issue
Mystery experimental option
Mystery open pyramid refined
Mirror Scroll turned off if door shuffle is vanilla (even if experimental)
2020-03-03 09:37:09 -07:00
aerinon 5aef551f7c More & better forced connection detection 2020-03-03 08:25:52 -07:00
Mike A. Trethewey 2f0d76ba91 Merge branch 'DoorDev' of https://github.com/aerinon/ALttPDoorRandomizer into aerinon-DoorDev 2020-03-03 07:05:23 -08:00
Mike A. Trethewey e9af70463a Bring closer to v18 2020-03-03 06:56:46 -08:00
aerinon 62caf015c0 Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2020-03-02 19:58:42 -07:00
aerinon 83a9c4bdcf Merge in latest door dev changes 2020-03-02 15:41:44 -07:00
aerinon 34774eb2d5 Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2020-03-02 15:25:46 -07:00
aerinon c9656d1ac9 Made count default "none" 2020-03-02 15:25:26 -07:00
aerinon 7ecb416c07 Increment version 2020-03-02 15:13:04 -07:00
aerinon 8bdbf5d6b2 Saves sprite settings
Save on exit feature
Some formatting changes
2020-03-02 15:04:46 -07:00
Mike A. Trethewey 61fbb00217 Prepare for new SpriteSomething URLs 2020-02-29 15:56:40 -08:00
aerinon a20f5423fd Minor gui fixes 2020-02-28 16:35:45 -07:00
aerinon 6daa436f08 Generation Fix
* Added step to adjust parity before complete neutralization
2020-02-28 15:00:02 -07:00
aerinon bdf59e293b Merge pull request #41 from compiling/DoorDev
Bug fixes
2020-02-28 12:58:07 -07:00
compiling d7939e0296 Fix GT boss shuffle for crossed dungeons. 2020-02-28 23:32:12 +11:00
aerinon 06562ed3ea Generation Fixes
*  Entrance dead end and branch calculation fixed
*  Parity checks added to global
*  Forced dead end checks in split dungeons
2020-02-27 15:53:19 -07:00
Mike A. Trethewey 54bc0aeae8 Make a prerelease for now 2020-02-27 03:05:28 -08:00
Mike A. Trethewey a46f84b3ae Update ci.yml 2020-02-27 02:53:23 -08:00
Mike A. Trethewey 055ad6bd71 Update ci.yml 2020-02-27 02:51:42 -08:00
Mike A. Trethewey 4063b538d0 Delete __init__.py 2020-02-27 02:50:43 -08:00
Mike A. Trethewey c5f08f7b27 Back to drafts 2020-02-27 02:43:38 -08:00
Mike A. Trethewey f1ad50e14b Test not a draft 2020-02-27 02:38:20 -08:00
Mike A. Trethewey e42e50c5a7 Try conditional again? 2020-02-27 02:33:21 -08:00
Mike A. Trethewey e40c7e4332 Can I cheat the ID? 2020-02-27 02:31:51 -08:00
Mike A. Trethewey bd042072f5 Operators 2020-02-27 02:27:42 -08:00
Mike A. Trethewey bcd56da5c1 Try again 2020-02-27 02:25:28 -08:00
Mike A. Trethewey dbd727208a Pre/Release 2020-02-27 02:23:03 -08:00
Mike A. Trethewey 8e7da9467f Do PreRelease 2020-02-27 02:06:35 -08:00
Mike A. Trethewey 1b889845c3 Not nearly as big as SpriteSomething 2020-02-27 01:56:22 -08:00
Mike A. Trethewey 089012b594 Strings are dumb 2020-02-27 01:47:49 -08:00
Mike A. Trethewey 7f38ccaf74 Create RELEASENOTES.md 2020-02-27 01:45:07 -08:00
Mike A. Trethewey cc6a675864 Go big or go home 2020-02-27 01:44:07 -08:00
Mike A. Trethewey 2e19a32053 Don't git clean App Version files 2020-02-27 01:30:16 -08:00
Mike A. Trethewey aeeb5dba11 Folders are dumb 2020-02-27 01:25:47 -08:00
Mike A. Trethewey 637eb111b8 Open for writing 2020-02-27 01:20:17 -08:00
Mike A. Trethewey ee52953cca Try App Version again 2020-02-27 01:17:04 -08:00
Mike A. Trethewey 74f3e89547 Move GUI to Source folder to avoid conflicts 2020-02-27 01:10:49 -08:00
Mike A. Trethewey a256dc1ae3 Skin that cat later 2020-02-27 01:00:43 -08:00
Mike A. Trethewey 1b4d6a1ec4 Update install.py 2020-02-27 00:59:33 -08:00
Mike A. Trethewey 9025d8204c Up four 2020-02-27 00:54:30 -08:00
Mike A. Trethewey 2075dc773e Package management 2020-02-27 00:47:17 -08:00
Mike A. Trethewey 1f8c0ddc59 Buh? 2020-02-27 00:43:07 -08:00
Mike A. Trethewey f09346e5cb Try to fix Mac again, write version number 2020-02-27 00:40:35 -08:00
Mike A. Trethewey 0a2e9cde39 Revert "Break out Mac into multiple VMs"
This reverts commit 0fab8c2450.
2020-02-27 00:19:10 -08:00
Mike A. Trethewey 0fab8c2450 Break out Mac into multiple VMs
See if this works to get both binaries for MacOSX
2020-02-27 00:16:17 -08:00
qadan 59974c2fbe add zora ledge too 2020-02-26 15:19:56 -04:00
qadan 5b03cb82ba add kings grave area, waterwalk regions 2020-02-26 15:11:24 -04:00
Mike A. Trethewey cd89bb5a95 Put Archive in correct folder 2020-02-26 04:04:09 -08:00
Mike A. Trethewey f0d2e28923 Moar Mac sanity checks; rename archive 2020-02-26 03:58:58 -08:00
Mike A. Trethewey cae638d7aa Do stuff if we've got filenames but only do it once 2020-02-26 03:45:48 -08:00
Mike A. Trethewey 0fb4e47568 Import sys for mac check 2020-02-26 03:40:11 -08:00
Mike A. Trethewey 5897cb0b80 Moar sanity checks 2020-02-26 03:35:32 -08:00
Mike A. Trethewey 0d45f20eae Debug 2020-02-26 03:26:39 -08:00
Mike A. Trethewey 1b62ca2c30 Ignore python scripts 2020-02-26 03:21:35 -08:00
Mike A. Trethewey c2eaa43ed4 Create .gitkeep 2020-02-26 03:16:41 -08:00
Mike A. Trethewey 1bb638d582 Lol, plural 2020-02-26 03:11:34 -08:00
Mike A. Trethewey 568fffc11f Ignore AppVersion for now 2020-02-26 03:08:05 -08:00
Mike A. Trethewey 28e2d83c54 Prepare for release 2020-02-26 03:07:08 -08:00
Mike A. Trethewey 9c59dda0e0 Meh, capitals 2020-02-26 02:53:21 -08:00
Mike A. Trethewey ab33c5c95f Make consistent 2020-02-26 02:50:40 -08:00
Mike A. Trethewey ae1f87143e Move stuff to common folder 2020-02-26 02:48:40 -08:00
Mike A. Trethewey 8103981b0e Fix syntax 2020-02-26 02:46:40 -08:00
Mike A. Trethewey 30e8fd132c Initial CI stuff 2020-02-26 02:44:11 -08:00
Mike A. Trethewey 47f60b5612 Merge pull request #2 from aerinon/DoorDev
Update to DoorDev
2020-02-26 01:40:06 -08:00
compiling 531a1d6423 Inverted Bomb Shop can't go on Spectacle Rock Cave bottom entrances
Fix inverted bomb rules for Inverted Big Bomb Shop, Inverted Dark Sanctuary, Inverted Links House.
2020-02-26 18:38:49 +11:00
aerinon 1dbd7e95e2 -Multiworld key rule fix
-Minor generation fix
2020-02-25 15:16:18 -07:00
aerinon 72a94e1e4f Vanilla fixes for 100% locations 2020-02-24 08:53:03 -07:00
aerinon 268975263e Rom generation fixes 2020-02-24 06:54:52 -07:00
Mike A. Trethewey c3a7f69c4b Prelim build scripts 2020-02-23 22:46:50 -08:00
Mike A. Trethewey 97f771fe42 Fix stuff 2020-02-23 22:01:44 -08:00
Mike A. Trethewey 66c57e38b0 Fix CLI precedence 2020-02-23 21:38:22 -08:00
Mike A. Trethewey 01e1e719db Implement Starting Inventory 2020-02-23 17:53:51 -08:00
Mike A. Trethewey baec0e4548 Fix Custom Item Pool (again again) 2020-02-23 16:21:39 -08:00
Mike A. Trethewey 55fee9317d Add Enemizer CLI download 2020-02-22 02:49:11 -08:00
Mike A. Trethewey 7a3855a17a Fix Custom Item Pool (again) 2020-02-22 02:43:56 -08:00
Mike A. Trethewey 16f997a03b Add some additional sprite data
Plug ALttPR Sprite Previews page
Shameless plug for SpriteSomething
2020-02-22 01:56:50 -08:00
Mike A. Trethewey e898ae078b Try to fix some options 2020-02-22 01:43:39 -08:00
Mike A. Trethewey bd6685d719 Fix erroneous counts 2020-02-22 01:20:08 -08:00
Mike A. Trethewey 1d0191e8b0 Merge pull request #1 from aerinon/DoorDev
Update to DoorDev
2020-02-22 00:59:19 -08:00
Mike A. Trethewey 6134cf7058 Condense Item Rando options 2020-02-22 00:54:35 -08:00
Mike A. Trethewey 0aa7750b97 Condense Game Options 2020-02-22 00:52:02 -08:00
Mike A. Trethewey ad49e2cff7 Standardize Entrando options
Was basically already condensed
2020-02-22 00:47:34 -08:00
Mike A. Trethewey 2f93bcca9c Condense Enemizer options 2020-02-22 00:42:52 -08:00
Mike A. Trethewey 8adc2e92d5 Condense Custom Item Pool options 2020-02-22 00:24:53 -08:00
Mike A. Trethewey 531d7799d6 Condense Adjust options 2020-02-22 00:18:56 -08:00
Mike A. Trethewey 6c9fdcd203 Update Widgets to be able to use grid 2020-02-21 23:47:29 -08:00
qadan 45f8ec51b2 account for some more things 2020-02-21 20:30:23 -04:00
aerinon c2e22a6223 Merge branch 'DoorDev' into EdgeWork 2020-02-21 16:26:50 -07:00
aerinon 7064b1de77 Logic additions for basic+experimental 2020-02-21 16:26:18 -07:00
aerinon e6b37af515 Version bump 2020-02-20 16:46:39 -07:00
aerinon e416e46130 Placement rules implemented for checking key placement 2020-02-20 16:45:51 -07:00
Mike A. Trethewey dbaaef662a Fix a bunch of stuff
Defaults from settings file, then CLI, then canned defaults
Fix Adjust settings
Fix Custom Item Array settings
Create error message for Enemizer Not Found
2020-02-20 01:04:53 -08:00
qadan 77b366d093 what's that doing there 2020-02-19 21:09:38 -04:00
qadan 60f0ffdab3 typo 2020-02-19 20:50:36 -04:00
qadan 2936dfcd93 fix mirror bunny stuff 2020-02-19 19:00:31 -04:00
aerinon c23e37e60e Merge branch 'keylock-validation' of https://github.com/compiling/ALttPEntranceRandomizer into keylock-validation 2020-02-19 13:27:20 -07:00
aerinon dfd0bc41ce -Key shuffler fix (needs some more testing)
-Mirror Scroll should now choose correct spawn point
-Desert Wall Slide fixed for Skull/Desert builders
2020-02-19 13:24:12 -07:00
aerinon 6f3040415d Tested a lot of north edges 2020-02-19 12:50:37 -07:00
qadan 6f38664a80 hecked a copy paste 2020-02-19 10:19:58 -04:00
Mike A. Trethewey d82c4c9d70 Fix some stuff 2020-02-19 03:53:45 -08:00
Mike A. Trethewey 143b7b539d Merge branch 'DoorDev' into gui-improvements 2020-02-19 03:34:47 -08:00
Mike A. Trethewey 6e47cd78e0 Dungeon Counters option 2020-02-19 03:32:01 -08:00
compiling 8fc9132746 Ignore impossible key counters when checking key placement. 2020-02-19 22:20:14 +11:00
compiling ed3e2da663 Log all missing chests, not just non-keys. 2020-02-19 22:20:14 +11:00
compiling b321410e5a Keylock checks:
Big Chest only available after the big key is found
Bosses are always required locations
Don't check for 100% locations - failure rate is too high
2020-02-19 22:20:14 +11:00
compiling 8ad28542a4 Check for key locks after placing dungeon items. 2020-02-19 22:20:13 +11:00
Mike A. Trethewey 8c4bc60312 Arrayify Frames for each page 2020-02-19 03:14:08 -08:00
Mike A. Trethewey 1f90e90372 JSONify Custom Item Pool 2020-02-19 02:51:59 -08:00
Mike A. Trethewey e78bb54eab JSONify Adjust options 2020-02-19 01:53:56 -08:00
Mike A. Trethewey 7c3c67ec13 JSONify Generation options 2020-02-19 01:37:40 -08:00
Mike A. Trethewey f2de282249 JSONify Game Options 2020-02-19 01:35:41 -08:00
Mike A. Trethewey c848792c69 JSONify Multiworld options 2020-02-19 01:29:48 -08:00
qadan 0ed41f6b13 fixing bunny revival, and other bunny stuff 2020-02-18 20:22:33 -04:00
aerinon 2116bb6d0d Merge branch 'chest-counters' of https://github.com/compiling/ALttPEntranceRandomizer into DoorDev 2020-02-18 13:35:02 -07:00
aerinon 6e11a4bbac Fixes for mirror scroll
Fix for Stonewall + Ice Cross
Fix for Ice Cross key doors
Changed how key doors are chosen in a slightly better manner (pairs them earlier)
2020-02-18 13:15:41 -07:00
Mike A. Trethewey 2a1e9726b1 JSONify Dungeon Rando options 2020-02-17 01:26:21 -08:00
Mike A. Trethewey 20bc14ba12 JSONify Enemizer options
Fix set_sprite when cancelling custom sprite file selector
2020-02-17 00:45:37 -08:00
Mike A. Trethewey 663ed3442a JSONify Entrando options 2020-02-17 00:10:02 -08:00
Mike A. Trethewey 9de01fbdb5 Don't need to gen Crystals options anymore
It's been transliterated into the JSON instead
2020-02-17 00:05:05 -08:00
Mike A. Trethewey 2b68d7c74e JSONify Item Randomizer options 2020-02-17 00:03:54 -08:00
Mike A. Trethewey 88a3074e74 Dictify remainder of Custom options 2020-02-16 23:43:59 -08:00
Mike A. Trethewey 2f026daab1 Dictify first column of Custom 2020-02-16 03:11:23 -08:00
Mike A. Trethewey 2eb060931b Dictify Adjust options 2020-02-16 02:58:21 -08:00
Mike A. Trethewey 4c35dea722 Dictify Generation Setup options 2020-02-16 02:55:01 -08:00
Mike A. Trethewey 09611075fe Dictify Game Options 2020-02-16 02:52:25 -08:00
Mike A. Trethewey 650911c826 Dictify Multiworld options 2020-02-16 02:39:26 -08:00
Mike A. Trethewey 7298cbfbc0 Dictify Enemizer Options 2020-02-15 07:28:13 -08:00
Mike A. Trethewey 783d259307 Dictify Entrando Options
Fix null arg issue
2020-02-15 07:20:27 -08:00
Mike A. Trethewey ec2224d0fc Dictify Item Rando options 2020-02-15 07:13:40 -08:00
Mike A. Trethewey bba2058a5b Dictify Dungeon Rando options 2020-02-15 06:55:10 -08:00
Mike A. Trethewey 20396e4798 Fix Widgets 2020-02-15 06:31:04 -08:00
Mike A. Trethewey e6b5bb7e04 Streamline guiargs 2020-02-15 06:15:13 -08:00
Mike A. Trethewey 901e5fc0c6 Fix precedence of vars 2020-02-15 03:52:33 -08:00
Mike A. Trethewey 01fd3d418f Split Adjust vars
Still populate with Game Options page
2020-02-15 03:17:46 -08:00
Mike A. Trethewey 8c07302e3b Arrayify Load args 2020-02-15 03:14:01 -08:00
Mike A. Trethewey cd0bc5b1e0 Sort Bottom args 2020-02-15 02:49:47 -08:00
Mike A. Trethewey b80dedb938 Sort Generation args 2020-02-15 02:48:43 -08:00
Mike A. Trethewey c6e6b31f9c Sort Game Options args 2020-02-15 02:46:46 -08:00
Mike A. Trethewey f27bacd901 Sort Multiworld args 2020-02-15 02:45:17 -08:00
Mike A. Trethewey 45b64b5587 Sort Dungeon Rando args 2020-02-15 02:35:19 -08:00
Mike A. Trethewey 62ba989b92 Sort Enemizer args 2020-02-15 02:34:10 -08:00
Mike A. Trethewey 5defbf727a Sort Entrance args 2020-02-15 02:32:49 -08:00
Mike A. Trethewey 31f7b83990 Sort Items args 2020-02-15 02:31:20 -08:00
Mike A. Trethewey f321344541 Fix count complaints 2020-02-15 02:27:24 -08:00
Mike A. Trethewey 7a12d02816 Generation Widgets 2020-02-15 02:24:04 -08:00
Mike A. Trethewey 88f7e34670 Game Options Widgets
Eventually split from Adjust
2020-02-15 02:23:20 -08:00
Mike A. Trethewey cbb7a3e932 Multiworld Widgets 2020-02-15 02:21:47 -08:00
Mike A. Trethewey 4dd8bfa67f Dungeon Rando Widgets 2020-02-15 02:21:01 -08:00
Mike A. Trethewey 947778bc55 Enemizer Widgets 2020-02-15 02:20:05 -08:00
Mike A. Trethewey 5488c288af Entrance Widgets 2020-02-15 02:19:14 -08:00
Mike A. Trethewey 35570ecb38 Item Widgets 2020-02-15 02:18:03 -08:00
Mike A. Trethewey 0df66f37d9 Bottom Widgets 2020-02-15 02:15:22 -08:00
Mike A. Trethewey 08ec529c75 Initialize variables 2020-02-15 02:14:16 -08:00
Mike A. Trethewey 9384c504dd Ints like being numbers 2020-02-15 02:08:49 -08:00
Mike A. Trethewey ab4b164a62 Return proper var 2020-02-15 02:06:52 -08:00
Mike A. Trethewey 8f32c30177 Pythonify values 2020-02-15 02:06:14 -08:00
Mike A. Trethewey 047c344bb0 Copy/paste error 2020-02-15 02:03:56 -08:00
Mike A. Trethewey 87345becc0 Arrayify Custom 2020-02-15 02:03:11 -08:00
Mike A. Trethewey afa96412d1 Arrayify Adjust 2020-02-15 02:02:04 -08:00
Mike A. Trethewey 62f6642edb Arrayify Generation Setup
Eventually split from Adjust
2020-02-15 01:59:48 -08:00
Mike A. Trethewey 2aef6b438c Arrayify Game Options
Eventually split from Adjust
2020-02-15 01:58:58 -08:00
Mike A. Trethewey 50526c1f5b Arrayify Multiworld 2020-02-15 01:57:19 -08:00
Mike A. Trethewey 19534a6e2a Arrayify Dungeon Rando
Fix item rando references
2020-02-15 01:56:43 -08:00
Mike A. Trethewey a3e80b9481 Arrayify Enemizer 2020-02-15 01:55:00 -08:00
Mike A. Trethewey 8a6d53a8ae Arrayify Entrance Rando 2020-02-15 01:54:20 -08:00
Mike A. Trethewey 03598c54a4 Arrayify Item Rando 2020-02-15 01:53:06 -08:00
Mike A. Trethewey 3fe2c02824 Arrayify more stuff
Ignore settings file
Rip out working_dirs in favor of settings
Set main pages to array
Set bottom frame to array
2020-02-15 01:41:21 -08:00
aerinon 62efaebb4d Merge branch 'DoorDev' into gui-improvements
# Conflicts:
#	Gui.py
2020-02-14 21:24:05 -07:00
aerinon b76a5f954d first edge function 2020-02-14 16:35:17 -07:00
compiling 320b06142f Make dungeon counters a config setting 2020-02-14 19:29:58 +11:00
aerinon 8d97eede65 -Sprite selection fix
-Scrollbar added
-Experimental checkbox added
-Settings file created
-Random sprite work for settings file
2020-02-13 13:53:04 -07:00
aerinon cad62c59ab Some Initial Tables for Edge transitions 2020-02-13 08:35:25 -07:00
compiling afe1cdf283 Always show dungeon chest counter with cross-dungeons. 2020-02-13 20:49:44 +11:00
qadan f8b6af472b copy paste error 2020-02-12 19:49:11 -04:00
qadan 5294524c25 rules for superbunny in TR/Hera 2020-02-12 19:38:42 -04:00
aerinon 6bd05982ae Bunny impassible rules for doorways 2020-02-12 14:19:29 -07:00
qadan 1e31c26a29 invalid glitch 2020-02-12 13:44:51 -04:00
aerinon d0369fe1c6 Add experimental checkbox to gui 2020-02-12 10:29:52 -07:00
aerinon 1ea5c1f4b2 Fix for Full ER Shuffle so that Hyrule Castle cannot be crossworld when doors are shuffled. 2020-02-12 09:25:06 -07:00
AmazingAmpharos ced3e8ab37 Update base ROM
Oops, forgot to ever do this, erroneously assumed it was done before.
2020-02-12 09:52:22 -04:00
Mike A. Trethewey d037bfc70e Custom Item Pool page needs some adjustments
Width of last column wider now that "Triforce Pieces Required" was added.
2020-02-12 04:31:15 -08:00
Mike A. Trethewey fafd44b770 Merge branch 'DoorDev' into gui-improvements 2020-02-12 04:27:45 -08:00
Mike A. Trethewey 7a38d3afc4 Remove Experimental 2020-02-12 04:23:57 -08:00
Mike A. Trethewey 7189d6a5ed Sprite Selection still not quite working
Closer, no compile errors, doesn't actually perform injection
2020-02-12 04:18:16 -08:00
Mike A. Trethewey 6dd67c0e0b Fix Custom Item Pool 2020-02-12 02:53:01 -08:00
qadan 09a5b71a2d inverted issues 2020-02-11 18:39:49 -04:00
qadan e94131ab1d bugfixes, starting boots 2020-02-11 18:25:09 -04:00
qadan d235ebbe01 add OWGSets 2020-02-11 18:13:50 -04:00
qadan cf7327bb52 and another 2020-02-11 18:12:30 -04:00
qadan 86e66fef99 little typos 2020-02-11 18:10:20 -04:00
qadan 2ba2f48f92 overworld glitches ruleset 2020-02-11 18:07:38 -04:00
aerinon 2309eccad5 Merge branch 'doors-shops' of https://github.com/cassidoxa/ALttPEntranceRandomizer into ShopCode 2020-02-11 14:57:03 -07:00
aerinon 1f7c27009e Whole ton of things:
-Experimental Flag
--Mirror Scroll
--Mortal GT Minibosses
--Random door kinds
-Crossed Mode
--Standard logic
--Nothing Items
--GT Trash fill skip
--Too many keys in retro
--Hint work
--Spoiler clarification
--Aga 1 logic
-Misc
--Retro nothing item
--Bombable/Dashable matching
--ER+Inverted Logic fix
--Logic for GT Gauntlet/Wizzrobes
--Logic for PoD Sexy Statue switch
2020-02-11 14:40:58 -07:00
Daniel Aitken 66acd540a7 Merge pull request #1 from KevinCathcart/Dev
Dev
2020-02-11 17:01:38 -04:00
Mike A. Trethewey a3f3d6debe Bind mouse wheel to Spinboxes 2020-02-11 05:21:24 -08:00
Mike A. Trethewey 8ac47db507 Pretty Custom options
List index out of range when trying to generate game file using Custom Item Pool
2020-02-11 05:04:00 -08:00
Mike A. Trethewey fdc55cc8a1 Pretty Adjust options 2020-02-11 02:37:05 -08:00
Mike A. Trethewey 0ade328e27 Standardize width of selectboxes 2020-02-11 02:31:05 -08:00
Mike A. Trethewey 8788a2bec2 Pretty Generation Setup options 2020-02-11 02:25:09 -08:00
Mike A. Trethewey 88bb18f12f Pretty Game Options options 2020-02-11 02:17:50 -08:00
Mike A. Trethewey 64e0d8ebcf Pretty Multiworld options 2020-02-11 01:59:41 -08:00
Mike A. Trethewey 3065d17d63 Pretty Dungeon options 2020-02-11 01:28:15 -08:00
Mike A. Trethewey a830c20a53 Pretty Enemizer options 2020-02-11 00:50:07 -08:00
Mike A. Trethewey f9fcfee57b Pretty Entrando options 2020-02-09 15:53:45 -08:00
Mike A. Trethewey 18e0008a99 Pretty Item Rando options 2020-02-08 23:59:58 -08:00
Mike A. Trethewey cc8ce4a623 Fix Custom item pool 2020-02-08 19:04:16 -08:00
Mike A. Trethewey 03431f0b83 Implement save system
Add to .gitignore
Add to default CLI args
Add to each page that needs it
* Rom Adjuster
* Seed
* Generation attempts
* Enemizer CLI path
* Base ROM
* Multiworld worlds
* Multiworld names
2020-02-08 19:01:15 -08:00
Mike A. Trethewey 2c91550e50 Factor out CLI args 2020-02-08 16:51:35 -08:00
Mike A. Trethewey 0e57f13235 Hook up Gui.py to CLI args 2020-02-08 16:40:10 -08:00
Mike A. Trethewey 9d3f378d9f Factor out Custom Item Pool 2020-02-08 16:31:28 -08:00
Mike A. Trethewey 96b4144022 Fix Adjuster script 2020-02-08 16:25:44 -08:00
Mike A. Trethewey b80ae5a171 Sort Adjust Frame
Make it look like Game Options frame for consistency
2020-02-08 16:16:15 -08:00
Mike A. Trethewey acbb775775 Factor out Bottom Frame
Factor out ArgParser
Factor out working dirs for future
Bind everything to the main window so that Custom tab doesn't complain
2020-02-08 15:11:46 -08:00
Mike A. Trethewey 5d62d9bd5e Sort Generation Options
Fix a couple Dungeon Shuffle things
Coming back to implement working dirs
2020-02-08 14:11:42 -08:00
Mike A. Trethewey 65750d2571 Sort Game Options
Placate Adjuster in the interim
2020-02-08 14:00:54 -08:00
Mike A. Trethewey cd8c3f78f3 Sort Multiworld
Coming back to implement working dirs
2020-02-08 11:55:36 -08:00
Mike A. Trethewey 934245f785 Sort Dungeon Randomizer 2020-02-08 11:50:00 -08:00
Mike A. Trethewey 479da54dc1 Sort Enemizer
Coming back to implement working dirs
2020-02-08 11:44:24 -08:00
Mike A. Trethewey 441a3a7452 Sort Entrance Randomizer 2020-02-08 11:08:58 -08:00
Mike A. Trethewey 1059c9b40a Sort Item Randomizer 2020-02-08 11:00:51 -08:00
Mike A. Trethewey cdd246f811 Prepare pages for elements 2020-02-08 10:31:12 -08:00
Mike A. Trethewey 98c7ee02f2 Move everything out of work area
Move stuff to a throwaway tab for now
Create packages for eventual destinations of stuff
2020-02-08 10:17:55 -08:00
aerinon ce1b28e3bd typo 2020-02-08 06:53:20 -07:00
cassidoxa 1f09357138 Refactor shop code to only patch changed custom shops 2020-02-07 12:17:31 -05:00
aerinon 8cac03f4a3 Minor bug fixes
--E-W fixed on interior door in Aga Tower
--Crossed+Enemizer bug with GT minibosses
--Vanilla bug with pre-open stonewall flag
2020-02-07 08:45:21 -07:00
aerinon 2fe6e37126 Bringing cross gen work into door dev dor now. 2020-02-06 15:14:37 -07:00
aerinon bda5b27c44 Stonewall generation changed to pre-open wall if necessary.
GT Mini bosses no longer drop heart containers.
Crystal switch logic during generation updated.
2020-02-06 15:12:52 -07:00
aerinon 37176357b3 Merge branch 'DoorDev' into CrossGenWork 2020-02-05 20:29:04 -07:00
aerinon c57797cdef Change error to warning 2020-02-05 20:28:27 -07:00
aerinon 77d47d778f updated to match DoorDev
Hint for TT Attic
2020-02-05 15:24:36 -07:00
aerinon 9737cdf5f1 Key issues
--PoD Vanilla Stairway
--Boss should not be allowed key
--Scale back on aggressive layouts
Merge of attic hint
Non-chest keys hints added for figuring out how to get rid of them
2020-02-05 15:23:13 -07:00
aerinon 0338ae642c Merge of various fixes 2020-02-04 16:49:22 -07:00
aerinon 30657cc48f Merge branch 'DoorDev' of https://github.com/ninjamask/ALttPDoorRandomizer into attichint 2020-02-04 16:39:57 -07:00
aerinon 34656a7564 Minor gui update 2020-02-04 16:34:56 -07:00
Michael Fleischer 4780cf18b5 oops a little debug mistake 2020-02-04 22:12:19 +01:00
Michael Fleischer 4cd63196f9 Disallow hint to be in the attic 2020-02-04 22:07:55 +01:00
ninjamask a3682262e1 TT Attic Hint 2020-02-04 21:44:58 +01:00
ninjamask d47f016576 TT Attic Hint 2020-02-04 21:36:59 +01:00
aerinon fd9486ded9 Bump version 2020-02-03 16:24:50 -07:00
aerinon 349c8c722c Merge branch 'DoorDev' of https://github.com/compiling/ALttPEntranceRandomizer into compiling 2020-02-03 16:18:25 -07:00
compiling 6b0d1dd517 Revert change to Inverted Ganons Tower entrance hint (inverted is actually a different entrance). 2020-02-02 11:45:23 +11:00
codemann8 4c7c4ae00a Fixed broken defaulted Gui parameters 2020-02-01 18:16:38 -06:00
compiling eb98f3d265 Inverted Ganons Tower dungeon was renamed. 2020-02-01 18:08:34 +11:00
aerinon 4b48c5e125 Generation refinement 2020-01-31 16:11:46 -07:00
aerinon e9a55c8cf4 Minor breakthrough on cross generation 2020-01-30 16:28:02 -07:00
aerinon 0dc7eb7079 Merge branch 'DoorDev' into CrossGenWork 2020-01-29 13:01:29 -07:00
aerinon 79d2151f86 Bump to 0.0.9 2020-01-29 12:46:17 -07:00
aerinon b532971946 Bump to 0.0.9 2020-01-29 12:39:22 -07:00
aerinon 83f0194a54 Merge branch 'DoorDev' of https://github.com/compiling/ALttPEntranceRandomizer into compiling-merge 2020-01-29 12:38:33 -07:00
aerinon f8f347a68d Merge branch 'BugFix' into DoorDev 2020-01-29 12:37:38 -07:00
aerinon 4d717c7e4b Default values for quickswap/disablemusic
Possible fix for Aga Kill room for enemizer
Hammer required for TT Big Chest
2020-01-29 12:35:59 -07:00
aerinon d50af93f2a More cross gen refinement 2020-01-29 12:34:31 -07:00
aerinon aac0d0486d Ball n Chain compass fix 2020-01-29 06:26:49 -07:00
compiling 710ed9b011 Require Hammer for Thieves' Town - Big Chest 2020-01-29 19:05:36 +11:00
compiling 1a2c83be4c Update insanity shuffle hole targets (and legacy shuffles).
Update hole target addresses.
2020-01-28 20:35:08 +11:00
aerinon c619e3018b Key math fix
Turn off vanilla validation if ER is on
2020-01-27 09:17:29 -07:00
compiling ba6c73861a Remove comments in yaml files.
Throw a meaningful error if the door-shuffle setting is invalid.
2020-01-26 21:46:18 +11:00
compiling 3150e0f161 No-Logic fix - don't try to spread crystal access if the current state is nothing 2020-01-26 18:16:00 +11:00
compiling a370b34aca Turn off vanilla TR key logic checks when TR can be entered from back
- will need to be based on which entrances are available and how the inaccessible entrances link
2020-01-26 15:29:14 +11:00
compiling ee8feaed55 Fix skull woods exit:
- Remove from list of unreachable exits (Moth may be in a different section)
- Fix vanilla check to account for multiworld
2020-01-26 14:15:43 +11:00
aerinon dc9a4a1303 Re-factoring polarity and branching issues 2020-01-24 16:44:20 -07:00
aerinon bd50ad9d77 Minor bugfixes 2020-01-24 16:43:35 -07:00
aerinon 59e9fb82f5 Several bug fixes for yesterday's debacle 2020-01-24 08:51:34 -07:00
aerinon f6179cda03 Merge with doordev 2020-01-23 16:45:25 -07:00
aerinon 1e2daffc5b Stonewall fix and preliminary crossed generation issues 2020-01-23 16:43:01 -07:00
aerinon a57a52e286 Bump version 2020-01-23 09:39:58 -07:00
aerinon 34a8b6e496 Merge branch 'DoorDev' into Inverted 2020-01-23 09:39:02 -07:00
aerinon 3937f4d9e9 Door shuffle setting added to spoiler 2020-01-23 09:10:11 -07:00
compiling 33b849a176 Speed hacks
- reduce the regions being checked every iteration when updating
- only sweep for crystal access when new locations are found, and when starting a new sphere
2020-01-23 20:08:37 +11:00
compiling b5ea688847 Add inverted door shuffle 2020-01-23 19:53:04 +11:00
aerinon 6264fa3b93 Merge branch 'DoorDev' into StonewallFix 2020-01-22 13:37:20 -07:00
aerinon 4c0c8ea21a Key and crystal sweep fixes 2020-01-22 12:35:13 -07:00
aerinon 560bbb2fda Merge branch 'DoorDev' into StonewallFix 2020-01-22 08:32:52 -07:00
aerinon da46cb6cfe Merge of StandardTest 2020-01-22 08:24:28 -07:00
aerinon eff78a2389 More key logic fixes 2020-01-21 16:32:31 -07:00
aerinon 7c03332b0b Merge of compiling's multidoors branch into mine 2020-01-21 14:12:55 -07:00
aerinon 744f9dfea7 Rom update and added dungeon events 2020-01-21 14:01:57 -07:00
compiling 6659965cd4 Check game is winnable before creating the rom. 2020-01-21 23:46:08 +11:00
compiling 4339c606be Reverse the normal and bk_restricted door rules, if the bk_restricted rule requires more small keys (prevents placing a big key from softlocking the game later). 2020-01-21 23:41:01 +11:00
compiling 0a8892806e Fix some dungeon generation errors:
TR fails if the Big Chest entrance is locked behind another dungeon
Hyrule Castle fails if the only available entrance is Sanctuary
2020-01-21 23:39:43 +11:00
compiling 1586267a80 Ban big keys from locations that will block required freestanding keys
TBD how to handle regular rules
2020-01-21 22:12:06 +11:00
compiling 2c3f5a9aff Recheck region access when sweeping for crystal state succeeds. 2020-01-21 22:09:30 +11:00
compiling d7beb1dfcf Re-add Sweep for crystal access in playthrough algorithm (might not be called when sweeping for keys) 2020-01-21 00:39:17 +11:00
compiling 138003912c Add all entrances as required paths (may be required for inaccessible regions). 2020-01-20 23:57:01 +11:00
compiling 123b49686a Sweep for crystal access instead of all events (since events are manually collected in beatability check) 2020-01-20 23:07:14 +11:00
compiling 74c515eb16 Handle standard mode, vanilla door shuffle. 2020-01-20 22:02:33 +11:00
compiling d3a6dd9138 Fix standard mode checks for per-player settings 2020-01-19 21:23:06 +11:00
compiling 49398fb454 Fix location table 2020-01-19 21:06:38 +11:00
compiling 93b9ebff6c Update base rom. 2020-01-19 18:26:35 +11:00
compiling e0eff76b9b Merge remote-tracking branch 'remotes/multi/multiworld_31' into multidoors 2020-01-19 18:18:43 +11:00
aerinon c08fb4bd5e Initial work for fixing standard (basic only so far) 2020-01-19 18:13:06 +11:00
compiling 4f7aea7dde Sweep for events when checking beatability. 2020-01-19 15:04:11 +11:00
Bonta-kun 7f800de8d0 MultiServer/Client: use logging instead of print and log time on the server 2020-01-18 12:21:57 +01:00
Bonta-kun f843c401c7 MultiClient: signal an event when receiving item data to improve responsiveness 2020-01-18 11:28:08 +01:00
Bonta-kun b36c981eb4 MultiServer: dont notify the team when a player sends himself an item 2020-01-18 11:26:45 +01:00
Bonta-kun e214f78293 Mystery: fix a regression in goals logic 2020-01-18 10:06:50 +01:00
Bonta-kun e941f738ba MultiClient: get rid of packages install hacks, use requirements.txt instead 2020-01-18 10:05:59 +01:00
Bonta-kun f988f7671b --remote_items toggle: items will no longer be stored in the rom, a connection to a multiworld server will be required to receive them 2020-01-18 09:50:12 +01:00
compiling db4ad1b3d0 Don't flood the keys in swamp when balancing multiworld 2020-01-18 15:59:14 +11:00
compiling 9033b5331f Optimise crystal checks a bit - only check regions with out of logic doors. 2020-01-18 14:01:06 +11:00
aerinon b866654541 Stonewall fix attempt - causing long generations right now 2020-01-17 16:36:36 -07:00
aerinon da027d08ea Initial work for fixing standard (basic only so far) 2020-01-17 16:35:18 -07:00
compiling b6d17e5f12 Reintroduce sweep_for_crystal_access - currently required in certain layouts (key door blocks flow of blue-state between reachable rooms) 2020-01-17 21:19:31 +11:00
compiling ee7d795780 Temp remove sweep_for_crystal_access - not required? 2020-01-16 22:15:55 +11:00
aerinon 338f5b4891 Fix compasses for newer rom 2020-01-16 20:24:04 +11:00
compiling ee8c629ac7 Merge commit 'c4ae75bc2b866e4a304614200eac678fd4da4aee' into multidoors 2020-01-16 20:23:43 +11:00
compiling 8aafbf2865 Fix skull woods pinball check 2020-01-16 19:25:10 +11:00
compiling 62e56bc9ee Check if spread_crystal_access should be called when each new region is reached. 2020-01-16 19:21:58 +11:00
aerinon ef6b171233 First stab at fixing crystal switch spread - probably not done. 2020-01-15 16:28:22 -07:00
Bonta-kun 2d26d63cce MultiClient: fix roominfo sort 2020-01-15 03:00:30 +01:00
aerinon 21907e1b41 Fix compasses for newer rom 2020-01-14 16:14:11 -07:00
aerinon c4ae75bc2b Multiworld merge 2020-01-14 15:07:13 -07:00
Bonta-kun 71cd0b917c Rom: fix enemizer patching 2020-01-14 22:13:37 +01:00
Bonta-kun ad278f91d6 Multiworld: clients will now be automatically be identified from the rom name and have their names and teams set by the host, meaning those need to be configured during seed gen
Player names will show up in spoiler log and hint tiles instead of player id
MultiClient: autoreconnect to mw server
2020-01-14 10:42:27 +01:00
aerinon fd83eaa16e Key logic overhaul - hope to have fixed many key locks
Specific keysanity fix
Fixed issue with crossed that created extra keys
2020-01-13 16:34:45 -07:00
aerinon ab04c47fd8 Merge branch 'KeyIssues' into DoorDev 2020-01-13 16:29:21 -07:00
aerinon 444add552c Mixed up some dungeons 2020-01-13 16:14:42 -07:00
Bonta-kun d9592e68fb Fix GT torch potentially overwritting playerid of chests in hope room 2020-01-13 04:07:45 +01:00
Bonta-kun 3e99c3c9a3 MultiClient: auto reconnect to snes 2020-01-13 03:55:33 +01:00
compiling ead7c117a8 Skip the playthrough when run from the gui, if the spoiler isn't being created. 2020-01-12 21:20:14 +11:00
compiling d35c5f5d68 Open pinball room if it blocks the Skull Woods boss room. 2020-01-12 21:19:31 +11:00
compiling 761d11a272 Don't edit rom name after writing it (causes problems for multi client/server checks)
Add door-shuffle type to rom filename.
2020-01-12 11:42:57 +11:00
compiling dfcf6a1be0 Add new and old msu versions 2020-01-12 09:31:36 +11:00
aerinon 526eca50b0 --Fixed Aga Tower staircase (Push statue)
--Petting Zoo rename
--Gui fix for repeated options
--Eliminated bad rule - (It Required Desert BK even if wallslide not in desert)
2020-01-12 09:15:35 +11:00
compiling f713fc238c Add doors to mystery. 2020-01-11 20:00:58 +11:00
compiling 4d35a02e99 Separate doorShuffle for each player
Add doorShuffle to spoiler metadata
2020-01-11 12:01:21 +11:00
aerinon e68286b89c Merge branch 'CrossCompass' into KeyIssues 2020-01-10 16:43:53 -07:00
aerinon 8ff43e50ce Attempt to resolve certain key issues 2020-01-10 16:43:12 -07:00
aerinon 6017165875 Cross mode compass additions
--Added compasses for escape/aga tower
--Removed maps for escape/gt
2020-01-10 16:42:20 -07:00
aerinon f3ebbf1a63 Added code for compass in cross mode 2020-01-10 15:48:57 -07:00
aerinon c6d85a3f06 --Fixed Aga Tower staircase (Push statue)
--Petting Zoo rename
--Gui fix for repeated options
--Eliminated bad rule - (It Required Desert BK even if wallslide not in desert)
2020-01-10 15:35:54 -07:00
compiling a3a706d8c1 Merge remote-tracking branch 'remotes/door_rando/DoorDev' into Dev 2020-01-11 09:17:41 +11:00
compiling dfafa59215 Fix conflicts 2020-01-11 09:04:11 +11:00
compiling e2df282201 Merge remote-tracking branch 'remotes/multi/multiworld_31' into Dev 2020-01-11 08:58:09 +11:00
Bonta-kun 7631bf3041 MultiServer: added a !countdown chat command for convenience 2020-01-10 22:44:07 +01:00
Bonta-kun 82a6961777 MultiClient: default port to 38281 2020-01-10 22:43:01 +01:00
Bonta-kun 2f5a3e24dd Small shops refactor, cleanup some inverted mess 2020-01-10 11:41:22 +01:00
Bonta-kun 239ea0f67c outputpath: use makedirs instead of mkdir 2020-01-10 07:25:16 +01:00
Bonta-kun 39a07a0624 Rom: dont block HC exit in standard with vanilla entrances to match website mystery behavior 2020-01-10 07:15:11 +01:00
Bonta-kun 77ae96cf1b Refactor rom patching now that jsonrom patches can safely be merged 2020-01-10 07:02:44 +01:00
Bonta-kun 6bafdfafe6 Mystery: rom options can be set in weights file, eg
rom:
  sprite:
    random: 1
    randomonhit: 1
    mog: 1
  disablemusic: off
  quickswap:
    on: 1
    off: 0
  menuspeed:
    normal: 1
    instant: 1
    double: 1
    triple: 1
    quadruple: 1
    half: 1
  heartcolor:
    red: 1
    blue: 1
    green: 1
    yellow: 1
    random: 1
  heartbeep:
    double: 1
    normal: 1
    half: 1
    quarter: 1
    off: 1
  ow_palettes:
    default: 1
    random: 1
    blackout: 1
  uw_palettes:
    default: 1
    random: 1
    blackout: 1
2020-01-09 17:46:07 +01:00
Bonta-kun 240cf2d844 Mystery: pot_shuffle (on/off) 2020-01-09 09:13:50 +01:00
Bonta-kun 6bb71802ae Dont tag capacity upgrade shop as replaceable 2020-01-09 08:40:03 +01:00
Bonta-kun 42b85d7a3c Include sphere0 items in the spoiler log and in the playthrough 2020-01-09 08:31:49 +01:00
Bonta-kun 5db7e066da Sprites are now player specific, can be chosen from their sprite name rather than file path, support "random" choice and support "randomonhit" enemizer-only option 2020-01-09 02:30:00 +01:00
aerinon 24a01bef98 Last commit to fix ice cross spilt the area logically in cross-dungeon
Wiki table function
Trap flags for gauntlet doors
2020-01-08 12:43:37 -07:00
Bonta-kun feb925d2b1 Rom: cleaner disable_music patches to match what the website does 2020-01-08 08:17:25 +01:00
Bonta-kun 28011cf675 Built-in palette shuffle (including blackout) 2020-01-08 03:43:48 +01:00
aerinon d6cd94d04b Enemizer support
Logic issue with Ice Cross (Top) fixed
Changed a couple GUI defaults
2020-01-07 13:14:04 -07:00
aerinon fdf580c89c Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2020-01-07 08:53:16 -07:00
aerinon ea685c6a74 Added Mire Torches holes
Fixed simple generation issue with crossed
Typo in gui
Killed the dungeon changer door in throne room
2020-01-07 08:53:06 -07:00
aerinon 787ffb1cf9 Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2020-01-06 21:30:25 -07:00
aerinon 2cadb5a272 Minor typo fix
Fixed some hard-locks in crossed mode
2020-01-06 21:30:09 -07:00
aerinon 19faf41e79 Retro to match Bonta solution
Minor gui updates
2020-01-06 15:56:14 -07:00
aerinon 6569d81e2a Retro to match Bonta solution
Minor gui updates
2020-01-06 15:54:59 -07:00
aerinon f26c83e852 Made the CollectionState crystal switch aware and added crystal rules
Small adjustment to big key forbidding
2020-01-06 15:32:33 -07:00
Bonta-kun 99577d9e4c Mystery: safer strip 2020-01-06 20:14:16 +01:00
Bonta-kun 48305adaa0 Mystery: weights can now specify a default value for convenience, eg:
dungeon_items: full
startinventory:
  Pegasus Boots: on
2020-01-06 20:01:03 +01:00
Bonta-kun 7d05d697dd Mystery: can now roll for starting inventory items, eg:
startinventory:
  Pegasus Boots:
    'on': 1
    'off': 0
  Bombs (3):
    'on': 1
    'off': 1
2020-01-06 19:13:55 +01:00
Bonta-kun 71b4f6e94b Set default value for --enemizercli 2020-01-06 19:13:53 +01:00
Bonta-kun eb7ca4fdf9 Implement --startinventory 2020-01-06 19:13:42 +01:00
Bonta-kun a3657c02aa Multidata/save: moved away from pickle and store a compressed json instead 2020-01-05 20:22:29 +01:00
Bonta-kun 1be0d62d4f MultiClient: allow different protocols if a prefix is present 2020-01-05 20:22:19 +01:00
compiling 0c2580dea9 Fix conflicts 2020-01-05 21:51:07 +11:00
Bonta-kun 28e7819fab Items table: include the 2nd progressive bow 2020-01-04 18:45:42 +01:00
compiling 9803515315 Merge remote-tracking branch 'remotes/door_rando/DoorDev' into Dev 2020-01-04 21:33:42 +11:00
compiling 8efbf7bf08 Merge remote-tracking branch 'remotes/multi/multiworld_31' into Dev 2020-01-04 20:07:29 +11:00
aerinon c475dc746c Better polarity match 2020-01-03 07:22:22 -07:00
compiling 74701b88a1 Swap implementation of Take Any fix to match Multiworld. 2020-01-03 08:36:02 +11:00
aerinon 4d27c2ad88 Merge pull request #16 from aerinon/CompilingDev
Compiling dev
2020-01-02 11:53:52 -07:00
aerinon 66598f7c30 Merge branch 'compiling-Dev2' into CompilingDev 2020-01-02 11:52:46 -07:00
aerinon fea605ae66 Fixing conflicts 2020-01-02 11:52:24 -07:00
aerinon 41af3b8892 Merging of CrossDungeon into DoorDev 2020-01-02 11:42:40 -07:00
aerinon 88849e921c Revert "Revert "Cross Dungeon initial work""
This reverts commit fadc085b67.
2020-01-02 11:37:47 -07:00
aerinon 791d139e6b Merging of DoorDev into Cross - hopefully perserving all cross dungeon stuff 2020-01-02 11:31:33 -07:00
aerinon 438d765627 Directional typos on interior doors fixed.
Better batching support for mass testing of seed generation.

Generation issues fixed:
--Filler now tests with the key in the proposed location to enable alternate key rules
--Key rule checker now only considers key locations that the parent sphere did not have - better key rules
2020-01-02 11:15:27 -07:00
compiling 699b4c55a2 Remove Capacity Upgrade from Take Any locations, to match item randomizer 2020-01-02 16:23:03 +11:00
compiling 584880be20 Add Python 3.8 compatibility - replace deprecated function time.clock with time.perf_counter 2020-01-02 12:38:26 +11:00
compiling 9109d811fc Add shop door ids to tables (used when shop locations are vanilla)
Do not replace Upgrade Fairy with retro shop
2020-01-02 12:33:56 +11:00
Bonta-kun 6966b0a798 Add a --keysanity shortcut to enable all dungeon items shuffles for convenience 2020-01-01 18:42:36 +01:00
Bonta-kun 0de0467b5c Inverted: connect lake hylia island to lw 2020-01-01 18:12:23 +01:00
aerinon 59f819aebd Fixed a couple of generation errors 2019-12-31 21:12:53 -07:00
aerinon dcec274b63 Fix typo 2019-12-31 21:12:18 -07:00
aerinon 511cc62234 Fix typo 2019-12-31 11:44:30 -07:00
Bonta-kun 636a18cee9 Rom: sanitize hint_text input 2019-12-31 15:47:49 +01:00
Bonta-kun 1fc86274cc Items: consumables texts 2019-12-31 15:47:18 +01:00
Bonta-kun 2bce64778d Gui: fix default arguments for multiworld 2019-12-31 01:16:41 +01:00
Bonta-kun 63eecaa96c Fix arguments pre-parsing intercepting --help command 2019-12-30 20:43:43 +01:00
Bonta-kun 7088c148a2 Beemizer: fix potentially replacing all heart containers for progression 2019-12-30 20:28:33 +01:00
aerinon 34352b35fc PoD Key door - wrong position 2019-12-30 11:02:40 -07:00
aerinon 3a5a918012 Mark regions as light/dark world after dungeons are connected up. 2019-12-30 11:02:30 -07:00
aerinon bdc722eaa3 readme updates 2019-12-30 11:02:15 -07:00
aerinon f021530392 Potential stair key door fix 2019-12-30 11:01:31 -07:00
aerinon d0129256df logic fixes 2019-12-30 11:00:47 -07:00
Bonta-kun 8f5d199968 Inverted: Dark Lake Hylia Shop should not be replaceable 2019-12-30 06:46:29 +01:00
Bonta-kun 7aa9622c5e Escape assist: only get infinite bombs with enemizer or bombs/cane/bow start + high hp 2019-12-30 06:42:45 +01:00
Bonta-kun 6c9fde8bee Fix unusable infinite bombs with an empty inventory 2019-12-30 06:26:03 +01:00
Bonta-kun c2e044032b Inverted: fix dw lake hylia shop (blue potion) 2019-12-30 03:30:59 +01:00
Bonta-kun 955d1c2875 Fix ganon's silvers hint with progressive bows 2019-12-30 03:21:01 +01:00
Bonta-kun fe307b1ac7 bzzz bzzz 2019-12-30 03:03:53 +01:00
aerinon 5338c78fe1 PoD Key door - wrong position 2019-12-28 20:54:48 -07:00
Bonta-kun 4281dcc619 Skip enemizer patching with jsonout and no enemizercli 2019-12-28 18:12:11 +01:00
Bonta-kun 93f8a684f1 Move outputpath handling in main(), create path if it doesn't exist 2019-12-28 17:12:27 +01:00
Bonta-kun 41009c85c7 nologic inverted: reachable castle ledge 2019-12-28 01:12:45 +01:00
Bonta-kun 0e3327e0f8 logging: fix retry attempts nr 2019-12-28 01:11:44 +01:00
Bonta-kun 7ccab4bf44 simple inverted: update old_man_entrances after links house shuffle 2019-12-28 01:10:52 +01:00
Bonta-kun 819f6dc975 Retro: fix take any entrances with default connections 2019-12-27 19:11:41 +01:00
Bonta-kun dcc3f7d53b ArgParse: fix missing default arguments 2019-12-27 19:10:40 +01:00
Bonta-kun 197b8bd6c6 Actually enable bombs escape assist 2019-12-27 19:09:58 +01:00
Bonta-kun 52b05c0b4f dont touch the smith single cave doors again please 2019-12-27 19:08:04 +01:00
Bonta-kun fb1e2a657c Rom: fix silvers restriction with hard+ item functionality, also lock swordless swords limit to 0 2019-12-27 01:43:18 +01:00
Bonta-kun 6ca9cddc9a Rom: revert multiworld overflow replacement settings, baserom patch will skip limit checks for multiworld items 2019-12-27 01:04:34 +01:00
aerinon ee3cf80732 Mark regions as light/dark world after dungeons are connected up. 2019-12-24 07:15:34 -07:00
aerinon db3677487f readme updates 2019-12-23 13:56:47 -07:00
aerinon ccd2665256 Potential stair key door fix 2019-12-23 11:21:16 -07:00
aerinon 52f9900e4b logic fixes 2019-12-23 11:15:55 -07:00
Bonta-kun aa080eb455 Include unreachable items in the spoiler log 2019-12-21 13:33:07 +01:00
Bonta-kun 4a16ba74e8 Fix triforce hunt icon showing for every player 2019-12-21 10:42:59 +01:00
aerinon fadc085b67 Revert "Cross Dungeon initial work"
This reverts commit 35c3a07dc3.
2019-12-19 16:24:58 -07:00
aerinon 263b155110 Revert "Potential stair key door fix"
This reverts commit 106e25f120.
2019-12-19 16:24:46 -07:00
aerinon ea53f97289 Removed the sewer dungeon for now to enable Escape Big Key to work. 2019-12-19 16:18:59 -07:00
aerinon 106e25f120 Potential stair key door fix 2019-12-19 15:10:03 -07:00
aerinon 35c3a07dc3 Cross Dungeon initial work 2019-12-19 14:48:09 -07:00
Bonta-kun 0d9983bae0 Rom: fix player names not applying 2019-12-19 10:04:12 +01:00
Bonta-kun 1dfc750020 Gui: only take arguments for p1 when opening 2019-12-18 21:34:57 +01:00
Bonta-kun 5f77aaba06 Individual settings: shufflepots and shufflepalette 2019-12-18 21:20:55 +01:00
Bonta-kun 80d9fda10f Rules: allow triforce pieces to be in other players world 2019-12-18 20:56:58 +01:00
Bonta-kun 2b184d072b Rules: fix trock key logic for the big key chest "always allow" rule 2019-12-18 20:51:38 +01:00
Bonta-kun 9175c22895 Fill: place items for players with no accessibility requirements first 2019-12-18 20:47:35 +01:00
Bonta-kun c2530dce7d Mystery: fix triforcehunt argument 2019-12-18 20:46:16 +01:00
Bonta-kun 8721310cf7 World: include can_access_trock_eyebridge can_access_trock_front can_access_trock_big_chest can_access_trock_middle and fix_fake_world in the player specific attributes 2019-12-18 20:45:51 +01:00
Bonta-kun 4b9e7d715c Mystery: correctly parse oddly indented yaml files 2019-12-18 20:41:59 +01:00
Bonta-kun 2ec59404a2 Mystery: always open the pyramid with fast_ganon 2019-12-18 20:34:08 +01:00
Bonta-kun fea3888b45 Mystery: separate dungeon items shuffling when requested 2019-12-18 20:33:09 +01:00
Bonta-kun 8aad6b6055 Mystery support different weights per player and can now roll different settings for everyone 2019-12-17 22:41:19 +01:00
Bonta-kun c2fabc9f8a Fix player id/name not showing up in rom name 2019-12-17 22:36:23 +01:00
Bonta-kun 3d4142bee4 Gui: properly instantiate the Namespace object and fix default player settings 2019-12-17 21:14:20 +01:00
Bonta-kun 36bdb5f487 Spoiler: reorder some settings for visibility 2019-12-17 21:12:05 +01:00
Bonta-kun a24fe1f3bf World.__init__: group player attributes to remove some redundancy 2019-12-17 21:09:33 +01:00
Bonta-kun 1ecb5fe40b Individual settings: shufflebosses shuffleenemies enemy_health enemy_damage 2019-12-17 15:55:53 +01:00
Bonta-kun 8a5eef11ce Individual settings: hints 2019-12-17 12:22:55 +01:00
Bonta-kun d9281adc07 Individual settings: accessibility 2019-12-17 12:14:29 +01:00
Bonta-kun 642bf65843 Skip the sewers door key check in standard retro since we cannot access the shop yet 2019-12-17 00:19:47 +01:00
Bonta-kun e5246d5d5a Individual settings: retro 2019-12-17 00:16:02 +01:00
Bonta-kun 1315eb55cf Individual settings: map/compass/key/bk shuffle 2019-12-16 21:46:47 +01:00
Bonta-kun dc26dfce77 Individual settings: crystals_ganon crystals_gt openpyramid 2019-12-16 19:09:15 +01:00
Bonta-kun 04f5f2fa84 Multi client/server: log fewer exceptions 2019-12-16 18:39:00 +01:00
Bonta-kun ec1b9eca43 Individual settings: shuffle 2019-12-16 18:24:34 +01:00
Bonta-kun 203147dda1 Individual settings: difficulty and item_functionality 2019-12-16 17:46:21 +01:00
Bonta-kun 0b999abb8a Murahdahla doesn't spawn in rain state so dont put him in logic 2019-12-16 16:55:01 +01:00
Bonta-kun c1788c070d Individual settings: goal 2019-12-16 16:55:00 +01:00
Bonta-kun 9ca755d5b2 Individual settings: swords 2019-12-16 16:54:57 +01:00
Bonta-kun ab28858a8f Individual settings: mode 2019-12-16 16:54:46 +01:00
Bonta-kun 79786c7c9e Individual settings: logic 2019-12-16 13:26:07 +01:00
Bonta-kun b695d3573e Main: change output name to support individual player settings 2019-12-16 13:09:43 +01:00
Bonta-kun a6e7157e17 parse_arguments: players can now override specific settings 2019-12-16 12:52:30 +01:00
Bonta-kun 930dcfb90f Use original item code for maps and compasses in their dungeons 2019-12-16 10:58:25 +01:00
Bonta-kun d33582a3a2 Enable bombs in escape assist with an enemized standard start so you can beat the game 2019-12-16 09:59:16 +01:00
Bonta-kun 261e9c40f9 Mystery: added a script to randomly generate game settings, uses same weights as Sahasrahbot 2019-12-16 02:05:33 +01:00
Bonta-kun fcde1e9cdc Added more enemy shuffle options to be consistent with what's on the website 2019-12-16 01:35:10 +01:00
Bonta-kun feb8bfeced Gui: get default values for missing parameters 2019-12-15 18:10:12 +01:00
Bonta-kun c9d1815080 Moved argument parsing into its own function and allow disabling default values 2019-12-15 18:10:01 +01:00
Bonta-kun 5bdc01e48f Add an option to specify a custom output filename 2019-12-15 17:29:17 +01:00
Bonta-kun 7e9ab6ce27 JsonRom: will behave like an interval map and merge/overwrite segments when appropriate 2019-12-15 16:16:49 +01:00
Bonta-kun 955dce0812 Race rom support (partial) 2019-12-15 16:16:39 +01:00
Bonta-kun e56ea410c6 Gui: set default base rom name 2019-12-15 11:15:00 +01:00
Bonta-kun 842f6bf1ac rom: correct gametype flag 2019-12-15 10:54:49 +01:00
Bonta-kun d608d5ca30 Optimize update_reachable_regions using the new region cache, it is almost twice as fast now 2019-12-14 19:53:19 +01:00
Bonta-kun e4fef05d53 Initialize region cache in initialize_regions() and make it a 2d map for more efficient player filtering 2019-12-14 19:19:08 +01:00
Bonta-kun bf7a2d79fb fill_restrictive: optimize itempool iteration, also fix output itempool for logging 2019-12-14 17:47:36 +01:00
Bonta-kun fc9d1b501b Replace keysanity with map/compass/key/bk shuffle 2019-12-13 22:37:52 +01:00
aerinon 0cd665a1fc Entrance data reader 2019-12-13 06:40:12 -07:00
aerinon 7422eb5ccc Fixed Swordless rules
Added rule for Freezor chest (for crossed and swordless)
Added more "single exit" caves to possible inaccessible regions
Prevented dungeon gen from assuming you could get GT Big Key at Aga 2
Prevented cross-dungeon contamination during key rule gen
Fixed some key-sphere merging problems (I'm ready to get rid of spheres now)
2019-12-12 15:01:12 -07:00
aerinon b18812ef0e Fixing infinite loop caused by not exploring Spiral Cave (712344909)
Fixed not resetting the sampleList after a door needed to be dropped (List index out of range) (966141807, 538815752)
Multiworld support for RoomData
2019-12-12 08:26:29 -07:00
Bonta-kun 6ca08a0fa4 Output rom: put seed and player id/name first in filename 2019-12-12 10:22:54 +01:00
Bonta-kun 25068bcfdd Added an option to pre-open the pyramid hole (aka "fast ganon") 2019-12-12 09:20:32 +01:00
aerinon 45e7e228f6 Fixed a trap door in GT
Tried to remove set sensitivity in KeyDoorShuffle
Added a sophisticated way to find permutations in KeyDoorShuffle
2019-12-11 06:37:54 -07:00
Bonta-kun 4ca063be54 Reimplement random weapon standard start, the previous one did not make sense in a multiworld context and rework castle chests logic, bombs start is now possible 2019-12-11 11:41:05 +01:00
Bonta-kun 6d50e905e1 Fix beatable-only prizes and dungeon items in multiworld 2019-12-11 11:37:05 +01:00
Bonta-kun abfb57af23 ItemList: use a dict for placed_items 2019-12-10 21:21:38 +01:00
Bonta-kun 4cf7412b51 EntranceShuffle: remove default castle connections to light world 2019-12-10 20:00:56 +01:00
Bonta-kun d6ec10d9ca Fill: MW balance: optimize lock check and do a sanity check to make sure the replacement location can receive the item 2019-12-10 19:23:12 +01:00
Bonta-kun d87cb2c380 BaseClasses: do not tag every location as locked by default 2019-12-10 19:21:05 +01:00
Bonta-kun c773b62dfe adjuster: disable_music for the old msu code 2019-12-10 03:21:49 +01:00
Bonta-kun 1a60d263ff client: accept rom names smaller than 21b 2019-12-10 03:01:13 +01:00
Bonta-kun 0dcb5ba73b gui: print exception when gen fails 2019-12-10 02:15:03 +01:00
Bonta-kun f479c8dc23 dont throw on __len__ attribute 2019-12-10 02:14:22 +01:00
Bonta-kun 60b3c83e1a update sprites 2019-12-10 02:13:42 +01:00
aerinon f8218cf2ea Key shuffling rules rework and refinement
--Concept of best key counter and wasted keys added
--Moved softlock checking & added random order to door candidate combinations
2019-12-09 15:05:07 -07:00
Bonta-kun 55a30aa91f multiworld 2019-12-09 19:27:56 +01:00
Bonta-kun ce19713209 Removed usage of deprecated time.clock() 2019-12-09 13:45:45 +01:00
Bonta-kun fe6a032f09 Fixed a bug in the balancing algorithm in non keysanity modes and increased the threshold 2019-12-09 13:43:30 +01:00
compiling ced8e04aae Work around for json patch - split out bow limit into a separate patch so that it can be overridden properly. 2019-12-08 12:41:28 +11:00
cassidoxa 7a6c22c452 Add flippers rule to East Dark World Pier in inverted 2019-12-05 19:20:29 -05:00
aerinon 9dfd93adbc More trap doors (mostly interior)
DungeonGen refinements
--More Big Key door considerations
--Backtracks earlier when hook candidates comes up empty
Minor work on key shuffling - lots of bad rules still
Playthrough gen doesn't flood swamp keys now
2019-12-03 15:50:15 -07:00
aerinon 43ba391df1 Fixed some trap doors in logic
Added the one way after validation chest (can't get to the chest from the door)
Started refining some key logic to relax it / tighten it
2019-12-02 16:36:15 -07:00
aerinon c64b2269c0 Couple minor door fixes
New key logic algorithm - some advanced rules in place to allow more locations
Changed generation to handle big key placement better
2019-11-26 16:43:43 -07:00
aerinon 1467b76d84 Fixed ice palace Hammer Block stairs
Initial work on new key logic - only for vanilla for now
2019-11-22 12:04:36 -07:00
aerinon 91f619e36f Fixed when a multi-entrance cave is initially inaccessible (i.e. Superbunny connects Skull 3 to DDM Ledge)
Fixed some path checking in full where entrances are all over the place
2019-11-21 15:54:51 -07:00
aerinon f6e8584d19 Fixed Death Mountain Return Ledge dungeons
Multiplayer support for inaccessible regions
2019-11-21 14:04:29 -07:00
aerinon 5e9134a74e GT Lobby Up Stairs fixed
Minor typo in help
2019-11-20 13:47:44 -07:00
aerinon 41a8da1b05 Desert Palace interior rooms I skipped 2019-11-19 16:24:08 -07:00
aerinon 6a276ca0b8 MSU Scrolling bug
Crystaroller Stairs fixed
More Full ER support
Added DungeonGen check for hangers without enough hooks
DungeonGen doesn't consider BK door problems unless starting from origin
--This could cause some longer gen times - as the origin is hooked up last
Skull 3 Exit - attempt to fix
2019-11-19 16:00:55 -07:00
aerinon 48494a09ba TR Crystal Maze adjustments
Fixed key door candidate finder to stay within own dungeon
Standard mode support added
Added missed Pre-moldorm chest
Started work on new key logic analyzer
2019-11-19 10:50:44 -07:00
aerinon 644785b140 Ice & TR door bugs 2019-11-19 06:52:36 -07:00
aerinon 52c9cca701 Ice Doors 2019-11-18 22:09:31 -07:00
aerinon b64b2b7d2b Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2019-11-16 21:40:15 -07:00
aerinon 407bac641d Couple of fixes for mire stairs 2019-11-16 21:39:54 -07:00
aerinon 7a87ef8520 More ER support added 2019-11-15 16:36:27 -07:00
aerinon 69c4dc17fd Merge branch 'MinorFixes' into DoorDev 2019-11-15 14:33:19 -07:00
aerinon 093746a0c7 Ganon's Tower added
Some key logic work
2019-11-15 13:50:31 -07:00
aerinon 2ad03af1da Removed Pot Circle from drops (it has unique regions)
Fixed a door in mire
Adjusted stair camera in Swamp
2019-11-14 06:39:27 -07:00
aerinon 77667668c9 Drop entrances not part of dungeon gen 2019-11-12 06:49:52 -07:00
aerinon d365ae5c36 Fixing a couple minor bugs 2019-11-09 19:10:13 -07:00
aerinon e7ddae0dfa Fix a TT open edge (getting caught by door code)
Try to fix Skull exit again
Fix Hera stair key
Some vanilla fixes
2019-11-08 16:51:51 -07:00
aerinon 84851b3979 Gui improvement 2019-11-07 13:15:35 -07:00
aerinon 5718018982 Added Turtle Rock.
Fixed clock -> process_time for Python 3.8
Fixed interior blocked doors
Vanilla logical connections for Ice Cross (Push block)
Dungeon entrance enhancement for TR, Skull, HC (Standard)
Kill on invalid dungeons during key door shuffle
Key logic improvements (Smallkey restrictions, Logic Min/Logic Max for key doors, Big Chest doesn't count for small keys if BK not found yet)
Key door candidate now accounts for "overworld" dungeon traversal
Path checking added some Crystal Logic (Blind's Cell to Boss mostly)
Kill on dungeon gen if taking too long
2019-11-07 12:16:13 -07:00
aerinon f8abf1fe81 Implemented mire 2019-11-05 11:39:13 -07:00
aerinon bad5fff022 Skull 3 entrance fix - could be refined
Thieves Town region addition - couldn't reach certain doors from elsewhere.
Ice Palace trap doors and fixed a couple broken staircases
2019-11-04 13:04:26 -07:00
aerinon 8b7bbc25ff Bug fixes for that one dumb pod spiral staircase 2019-11-04 12:49:25 -07:00
aerinon 0c6ea6a14d Fixed some typos with new interior doors
Used direction abbreviations for the ones missed
2019-11-01 16:28:08 -06:00
aerinon 19e9738c42 Merge branch 'MinorCleanup' into DoorDev
# Conflicts:
#	DoorShuffle.py
#	Doors.py
2019-11-01 16:18:37 -06:00
aerinon e08bf3776a Ice Palace added
Dynamic logical doors added for ice cross w/ push block
Improved crystal switch pathing
Minor update to PoD
2019-11-01 16:13:23 -06:00
aerinon 49cfe923b6 Merge pull request #12 from aerinon/Swamp
Swamp, Skull and TT
2019-10-31 11:20:50 -06:00
aerinon 90c3368f9d Revamped dungeon generation
Revamped key logic generation
Prevent key floods in playthrough/can_beat_game checks
2019-10-31 11:09:58 -06:00
aerinon bc30cc3b42 Minor fix to basic generation for now 2019-10-28 13:55:07 -06:00
aerinon 417fc0797f Shuffling sectors is improved slightly
Changing many logging statements to debug only
2019-10-25 13:56:44 -06:00
aerinon 050ae66bf6 Thieves Town 2019-10-25 13:50:37 -06:00
aerinon b27dd2f64f Finishing up interior doors for Eastern 2019-10-24 22:45:03 -06:00
AmazingAmpharos 1ddfc040f3 Update base ROM
Oops, forgot to ever do this, erroneously assumed it was done before.
2019-10-24 02:13:02 -05:00
AmazingAmpharos acc04e92ce Custom Item Pool Update
This updates the custom item pool feature to support progressive bows and the 10 bomb item. Yes, the latter had existed for a long time and was just never put in properly. The default item pool with the custom item pool feature now matches v31's item distribution instead of whatever the last version with bomb/arrow capacity upgrades' default was. I'm unsure if anyone will actually use this feature even still, but it's now up to date!
2019-10-23 21:31:02 -05:00
AmazingAmpharos 948901c51a Update GUI
The GUI was dysfunctional after the latest round of updates as it failed to address several new v31 features. The GUI should work again with this update and should allow proper interaction with all relevant options. Some aesthetic rework was necessary to account for the new large number of dropdowns.
2019-10-23 20:46:09 -05:00
AmazingAmpharos 63db5ac077 Hints for inverted
A few locations have different internal names in inverted mode, and the hint system used to fail to handle this. Now it will handle this correctly.
2019-10-23 20:45:02 -05:00
aerinon be03fc214d Adding some more interior doors to HC and Eastern 2019-10-22 23:00:07 -06:00
aerinon 8db8d066b4 PoD and Swamp logical dead end detection improved 2019-10-22 15:49:36 -06:00
aerinon 01a4d4b872 Generation tweaks and fixes
- Flooding the keys in swamp
- Logical dead ends
- The pinball exception
2019-10-21 22:32:49 -06:00
aerinon c090bd7003 Early bad loop detection. 2019-10-18 11:56:56 -06:00
aerinon beb15951a0 Skull Woods added
Fixed polarity for stairs
Some swamp fixes
Prep work for dungeons that can require traversal through overworld - like skull woods
Special case for pinball room so it can be in Skull 2 or Skull 1
2019-10-17 16:35:13 -06:00
aerinon 7db3c82e70 More swamp fixes
Removed Left Drain to Right (switch resets)
2019-10-16 06:57:57 -06:00
aerinon 6e4ab638aa Desert Cannonball/Compass fix
Potential PoD stair fix
--Going a down stair in Q1 to a 00 x coord is problematic
PoD stair coordinates
Attempted Swamp layer fix
More swamp fixes
--Note: Left switch resets
2019-10-15 22:38:25 -06:00
aerinon 4d35265e5c Key flood protection in sweep for events
Better loop validation
Small key validation tweaks
2019-10-15 15:15:29 -06:00
aerinon ce626bd093 Unification of exploration logic
Crystal stuff for PoD/Hera
Minor fixes to key logic
2019-10-15 13:01:32 -06:00
aerinon a0fdb25b43 Spirals for Swamp
Swamp Logic
Door definition cleanup
Stabs at Swamp events and Crystal Switches
2019-10-11 16:53:46 -06:00
aerinon d7b5a513bf More swamp door rom data 2019-10-10 21:52:58 -06:00
aerinon 87ff92ba7c Swamp regions and doors 2019-10-09 16:46:26 -06:00
aerinon dc6791da08 Door Types in Spoiler
Some fixes for rooms with ToggleFlag "doors"
2019-10-09 14:26:18 -06:00
aerinon 2ced48c691 Incorporated key logic prototype in the rules.
Relaxed key_layout_validation more (allows keys to lead to more keys)
2019-10-08 16:57:27 -06:00
aerinon db155950f2 Not allowing Lower Layer keydoors for now. vanilla Lttp engine does not handle them
Killed the restrictive Eastern key rules - in prep for real key logic
2019-10-07 14:32:34 -06:00
aerinon 19a78f2a0c Fixed a few spiral bugs
Fixed a problem with door pairing system
2019-10-05 23:15:06 -06:00
aerinon 92ad60bedf Key Door Shuffle algorithm added 2019-10-03 16:27:44 -06:00
aerinon 5cc4fdfa1f Added PoD
Added Logic for Desert,Hera,Aga,PoD
Revamped Logic for HC, Eastern
2019-10-03 09:24:27 -06:00
aerinon fd11e8cde1 Merge branch 'Dev' into DoorDev 2019-10-01 14:35:30 -06:00
aerinon 1f9f9e5656 Merge pull request #11 from KevinCathcart/Dev
Dev
2019-10-01 14:34:44 -06:00
aerinon 8719a4919d Door pairing system initial pass complete
Sucessfully de-coupling of Big Key doors with dumb small key doors behind
Added a bit to trap door fixer so that we can hit the 3rd door in the door list
Added door list position info
2019-10-01 11:26:10 -06:00
AmazingAmpharos e6793e36f2 Inverted logic improvements
This reformats the Rules.py file to no longer have quite so many totally redundant rules between inverted and non-inverted. In the process, it fixes an insanity only issue wherein the magic bat in inverted was set to always require Pearl (only in insanity can this not be true). Additionally, the inverted super bomb rules are completely reworked to be a lot more accurate (including preventing Desert Palace (East) from having the bomb shop at all in inverted insanity) and an obscure case involving non-inverted insanity super bomb return has a logic fix.
2019-10-01 03:17:40 -05:00
AmazingAmpharos bbc71a208f A few inverted fixes
A few inverted fixes
2019-09-30 18:40:44 -05:00
aerinon f12659af9d Fixes to Aga Tower staircases
Lots of initial work on key doors and other door pairs
2019-09-27 22:00:45 -06:00
aerinon 3df4fe08b3 More fixes for problems with staircases (quads 01 & 02) 2019-09-23 23:55:05 -06:00
aerinon 8e50c6d8eb Several fixes for problems with staircases in Hera/AgaTower 2019-09-21 22:15:51 -06:00
aerinon 5eb0e6e379 Aga Tower preliminary check in 2019-09-20 21:24:46 -06:00
aerinon 1aa2d904d3 Spirals Can "connect" to the same direction now. Screws with maps.
Some initial work on key doors. Namely altering the reverse side of Big Key doors that were unreachable in vanilla.
2019-09-19 14:58:50 -06:00
aerinon e66908816d Kill Landing/Warp End "Doors" 2019-09-19 14:44:33 -06:00
aerinon 6534aaecc6 Tower of Hera Door
Logical Doors
2019-09-19 14:40:16 -06:00
randall.rupper 2f659da39f Update to latest baserom (has some MSU-1 stuff)
Minor fix to Armory S door - can't seem to get it right
Minor fix to spirals that cross the horiz quadrant boundary while traversing
2019-09-18 13:01:35 -06:00
randall.rupper 292af3241c Minor logging problem 2019-09-17 14:02:21 -06:00
randall.rupper 27ea522499 Experimental and Crossed mode updated with monte carlo division of sectors 2019-09-17 13:53:30 -06:00
aerinon a38ef2820a Incremental improvements to algorithm.
Can get stuck in loop because it ran into a dead end only option early, not sure how to avoid that.
Also, some landings are considered outstanding doors, that shouldn't happen.
2019-09-16 22:10:25 -06:00
randall.rupper 49e782b050 Intermediate commit to switch from work to home 2019-09-16 21:12:55 -06:00
randall.rupper 6f5121c028 Updated desert to be more compatible with logic changes (no logic yet)
Refactored doors to clean up builder flags.
2019-09-16 15:10:37 -06:00
randall.rupper dc74df793c Merge branch 'DoorDev' into DoorExtension
# Conflicts:
#	DoorShuffle.py
#	Doors.py
#	Regions.py
2019-09-16 14:02:32 -06:00
aerinon ada06cb519 Merge pull request #9 from aerinon/DoorShuffleStandardModeDev
Logic!
2019-09-16 13:06:19 -06:00
tolmar 64bdedf1e3 Loosen EP rules
EP boss rules no longer need BK+bow, since those were actually requirements of the rooms leading up to the boss.
2019-09-15 23:41:08 -07:00
tolmar dda7dbaad4 "Ugly door" support
Ugly doors are doors that we don't want to see from the front:
- south-facing side of a BK door
- other side of one of those keyed staircases that don't actually have a matching key on the other side

This rejects layouts where one would appear.
2019-09-15 23:40:06 -07:00
AmazingAmpharos 4246a8b876 Various hint updates/improvements
This update makes the hint system work much better with simpler shuffles, fixes a bug by which two of the paradox cave entrances had reversed instructions in hints, and prevents the useless hint of there being a skull woods small key in the skull woods pinball room. Progressive Bow is added to the important item list for hints. Further tweaks to some hint language may still be incoming, but this should address the structure of the hint system pretty completely.
2019-09-16 00:51:24 -05:00
AmazingAmpharos a02f1e172d Update my dev branch for v31
Update my dev branch for v31
2019-09-16 00:39:14 -05:00
tolmar 9fa26ef067 Handle multiple startpoints and some blocked doors
Better blocked door handling:
- Start dungeon layout at the entrance
- Hold off on linking from blocked doors until the end of the dungeon, so they either point deeper in, or get added as a loop.
- Now that we care what the start is, properly handle the fact that dungeons have multiple starts.
2019-09-15 21:14:51 -07:00
tolmar 6ac00c2968 Eastern Palace Logic
Works sometimes. Either needs a south-facing big key door hack, or a way to avoid placing big key doors in places where you can see their back.
2019-09-15 11:35:35 -07:00
tolmar 40f345df13 Simple key logic for Escape
Adds ability to make a location for required keys (enemy drops and pots), so the filler knows about them.

Uses the most pessimistic possible rule to make sure you can't keylock yourself in Escape.
2019-09-15 02:28:04 -07:00
tolmar 3a872723b0 Use connect_one_way when doors are blocked
Shuffler doesn't respect blocked doors yet so it may create an unbeatable layout, and the item placer will panic. But that's better than silently giving the player something impossible
2019-09-15 02:24:48 -07:00
tolmar b1e20c9c94 Revert forced keys change
I think I found a better way to do it
2019-09-15 00:27:51 -07:00
tolmar cce2ef12fa Add lamp rules to door entrances 2019-09-15 00:08:56 -07:00
tolmar c8bd17042e More door fixes 2019-09-15 00:08:30 -07:00
tolmar b4028f429a Merge branch 'DoorDev' into DoorShuffleStandardModeDev 2019-09-14 22:15:55 -07:00
tolmar fcd810b4f3 Force pair keydoors 2019-09-14 22:09:21 -07:00
tolmar 8513dff636 Fix some incorrect door keyness 2019-09-14 22:08:32 -07:00
aerinon 4982ef0d9c Starting thinking about a backtracking algorithm 2019-09-14 22:27:38 -06:00
randall.rupper 97c225ab2f Desert Regions, Doors, and fixes associate with the new stuff
Updated generation algorithm to use new Sector object
Moved Dungeon items back for now
Created region lists for ease of grouping
2019-09-13 16:38:23 -06:00
aerinon e739bf94bb Merge pull request #6 from aerinon/DoorShuffleStandardModeDev
Clean up shuffle_dungeon
2019-09-11 13:13:15 -06:00
randall.rupper ec5e8614bc Started addressing trap doors to help indicate when they should be open
Sped up the gfx fixer stuff by moving the dungeon load room to execute only once
Minor optimization to spiral
Moved normal doors to separate file
2019-09-11 12:17:20 -06:00
tolmar b07c71a487 Merge branch 'DoorDev' into DoorShuffleStandardModeDev 2019-09-07 16:44:26 -07:00
tolmar 861195eb8b Add internal key data
Adds forced keys (enemy and pot drops) to regions, adds key doors within supertiles.
2019-09-07 16:39:39 -07:00
aerinon ed6ad04fa0 Fix to spiral stairs outside of dungeons. 2019-09-06 20:32:59 -06:00
tolmar a0b9b1fefe Clean up shuffle_dungeon
Use logger instead of print, loop shuffling until it works.
2019-09-06 18:14:48 -07:00
aerinon 46b7a3a12f Merge remote-tracking branch 'origin/DoorDev' into DoorDev
# Conflicts:
#	asm/spiral.asm
2019-09-06 17:36:33 -06:00
randall.rupper 48f29b3aa5 Merge branch 'Dev' into DoorDev 2019-09-06 14:22:42 -06:00
randall.rupper 1ec963f162 Moved spiral warp point during dark transition (fixed $53 logic)
More spiral layers fixed by adding a 'from layer' bit.
Several edge cases addressed (a couple stairs crossed quadrant boundaries during transition)
2019-09-06 14:21:19 -06:00
aerinon fe8b3e4252 Merge pull request #5 from KevinCathcart/Dev
Keeping up with Dev
2019-09-06 11:02:46 -06:00
randall.rupper 02b3ca5d52 Some spiral layers fixed
Some spiral camera bounds fixed
2019-09-06 09:13:49 -06:00
aerinon 4c49f7a7c2 Another refactor of camera bounds logic 2019-09-05 22:17:35 -06:00
randall.rupper eb3b1eaa44 Working on spiral problems 2019-09-05 21:09:26 -06:00
aerinon c6a1e90043 Merge pull request #4 from aerinon/DoorShuffleStandardModeDev
Add spiral staircases to basic shuffle
2019-09-05 12:51:33 -06:00
tolmar cd3735fc2f Add spiral staircases to basic shuffle
Makes the basic shuffler attempt to link spiral stairs.
2019-09-05 11:29:15 -07:00
randall.rupper 97c9a1603a Merge remote-tracking branch 'origin/DoorDev' into DoorDev 2019-09-04 16:35:17 -06:00
randall.rupper ac01262a31 Refactored normal doors to use a lookup table. Now the door table is <4k
Fixed graphics between HC/Sewers and cross dungeons.
Added base work for spiral staircases in HC/Eastern. (More data needed for other dungeons.)
Added new region to deal with push blocks in Sewers Secret Room
Refactored asm to be in multiple files.
2019-09-04 16:34:59 -06:00
aerinon dfc3d628df Simple readme update 2019-09-02 21:52:50 -06:00
tolmar 274634acfd Merge pull request #2 from aerinon/DoorShuffleStandardModeDev
Fill in standard mode shuffle
2019-08-27 09:45:45 -07:00
tolmar 5a891c68d1 Fill in standard mode shuffle
A bit ugly for now, but it basically works. Still needs logic.
2019-08-26 21:37:31 -07:00
aerinon 1e495de31c Spoiler additions for doors 2019-08-26 21:59:02 -06:00
randall.rupper 02f4ad956d Merge branch 'Dev' into DoorDev 2019-08-26 15:11:11 -06:00
aerinon a328d49245 Merge pull request #1 from KevinCathcart/Dev
Dev
2019-08-26 15:09:11 -06:00
randall.rupper 7f6c593df0 Bug with sanc/pull switch doors fixed.
Bug with doors with offset 2 going to doors with offset 2 was fixed in asm.
Refactor asm code to use Y as 2nd index, which cleaned up code.
Also learned the phb:phk:plb ... plb trick (cleaner than what I was doing)
2019-08-26 15:03:42 -06:00
aerinon 8db381a59c Fixed several layer issue and a couple wrong room indices. Added a notes file in case I want to remember things. 2019-08-23 21:23:42 -06:00
randall.rupper c87c767835 Upgrades doors to be written out by the rom. (No testing today)
Added some various modes to play around with.
Fixed prototype's generation code to run
2019-08-23 16:52:53 -06:00
randall.rupper 2ff60fe377 Base rom edited to contain the asm hack.
Fixed the vanilla linking doors in HC Back Hallway
2019-08-23 10:16:53 -06:00
randall.rupper f2974cf769 Added vanilla info for created regions and fixed initial errors. 2019-08-22 14:49:23 -06:00
randall.rupper ad3770e534 An initial commit.
ASAR asm patch included with test tables.
Eastern and Hyrule Castle regions created from a while ago.
Currently broken because boss prizes are unreachable.
2019-08-22 12:03:55 -06:00
706 changed files with 88625 additions and 11582 deletions
+1
View File
@@ -0,0 +1 @@
* text=auto
@@ -0,0 +1,51 @@
name: Prepare AppVersion
description: Prepare AppVersion document for later use
runs:
using: "composite"
steps:
# checkout commit
- name: Checkout commit
shell: bash
run: |
echo "Checkout commit"
- name: Checkout commit
uses: actions/checkout@v4.1.4
# Set Run Number
- name: Set Run Number
shell: bash
run: |
echo "Set Run Number"
- name: Set Run Number
id: set_run_number
shell: bash
run: |
GITHUB_RUN_NUMBER="${{ github.run_number }}a${{ github.run_attempt }}"
echo "github_run_number=$GITHUB_RUN_NUMBER" >> $GITHUB_OUTPUT
# Prepare AppVersion
#TODO: source/classes/appversion.py writes the tag format
- name: 💬Prepare AppVersion
shell: bash
run: |
echo "💬Prepare AppVersion"
- name: Prepare AppVersion
shell: bash
env:
OS_NAME: ${{ inputs.os-name }}
GITHUB_RUN_NUMBER: ${{ steps.set_run_number.outputs.github_run_number }}
run: |
python -m source.classes.appversion
python ./resources/ci/common/prepare_appversion.py
# upload appversion artifact for later step
- name: 🔼Upload AppVersion Artifact
shell: bash
run: |
echo "🔼Upload AppVersion Artifact"
- name: 🔼Upload AppVersion Artifact
uses: actions/upload-artifact@v4.3.3
with:
name: appversion
path: ./resources/app/meta/manifests/app_version.txt
+88
View File
@@ -0,0 +1,88 @@
name: Build
description: Build app
inputs:
calling-job:
required: true
description: Job that's calling this one
os-name:
required: true
description: OS to run on
python-version:
required: true
description: Python version to install
runs:
using: "composite"
steps:
# checkout commit
- name: Checkout commit
shell: bash
run: |
echo "Checkout commit"
- name: Checkout commit
uses: actions/checkout@v4.1.4
# get parent dir
- name: Get Parent Directory
id: parentDir
uses: ./.github/actions/get-parent-dir
# try to get UPX
- name: Get UPX
shell: bash
run: |
echo "Get UPX"
- name: Get UPX
shell: bash
env:
OS_NAME: ${{ inputs.os-name }}
UPX_VERSION: "4.2.3"
run: |
python ./resources/ci/common/get_upx.py
# run build.py
- name: 💬Build Binaries
shell: bash
run: |
echo "💬Build Binaries"
- name: Build Binaries
shell: bash
run: |
pip install pyinstaller
python -m source.meta.build
# upload problem children
# - name: 🔼Upload Problem Children Artifact
# shell: bash
# run: |
# echo "🔼Upload Problem Children Artifact"
# - name: 🔼Upload Problem Children Artifact
# uses: actions/upload-artifact@v4.3.3
# with:
# name: problemchildren-${{ inputs.os-name }}-py${{ inputs.python-version }}
# path: ./resources/app/meta/manifests/excluded_dlls.json
# if-no-files-found: ignore # 'warn' or 'ignore' are also available, defaults to `warn`
# prepare binary artifact for later step
- name: 💬Prepare Binary Artifact
shell: bash
run: |
echo "💬Prepare Binary Artifact"
- name: Prepare Binary Artifact
shell: bash
env:
OS_NAME: ${{ inputs.os-name }}
run: |
python ./resources/ci/common/prepare_binary.py
# upload binary artifact for later step
- name: 🔼Upload Binary Artifact
shell: bash
run: |
echo "🔼Upload Binary Artifact"
- name: 🔼Upload Binary Artifact
uses: actions/upload-artifact@v4.3.3
with:
name: binary-${{ inputs.os-name }}-py${{ inputs.python-version }}
path: ${{ steps.parentDir.outputs.parentDir }}/artifact
if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn`
+41
View File
@@ -0,0 +1,41 @@
name: 📁Get Parent Directory
description: Get Parent Directory
outputs:
parentDirNotWin:
description: "Parent Directory (!Windows)"
value: ${{ steps.parentDirNotWin.outputs.value }}
parentDir:
description: "Parent Directory (Windows)"
value: ${{ steps.parentDir.outputs.value }}
#########
# actions
#########
# mad9000/actions-find-and-replace-string@5
runs:
using: "composite"
steps:
# get parent directory
- name: Get Repo Name
uses: mad9000/actions-find-and-replace-string@5
id: repoName
with:
source: ${{ github.repository }}
find: "${{ github.repository_owner }}/"
replace: ""
- name: 📁Get Parent Directory Path (!Windows)
uses: mad9000/actions-find-and-replace-string@5
id: parentDirNotWin
with:
source: ${{ github.workspace }}
find: "${{ steps.repoName.outputs.value }}/${{ steps.repoName.outputs.value }}"
replace: ${{ steps.repoName.outputs.value }}
- name: 📁Get Parent Directory Path (Windows)
uses: mad9000/actions-find-and-replace-string@5
id: parentDir
with:
source: ${{ steps.parentDirNotWin.outputs.value }}
find: '${{ steps.repoName.outputs.value }}\${{ steps.repoName.outputs.value }}'
replace: ${{ steps.repoName.outputs.value }}
+49
View File
@@ -0,0 +1,49 @@
name: 💿Install
description: Install app
inputs:
calling-job:
required: true
description: Job that's calling this one
os-name:
required: true
description: OS to run on
python-version:
required: true
description: Python version to install
#########
# actions
#########
# actions/checkout@v4.1.4
# actions/setup-python@v5.1.0
# actions/upload-artifact@v4.3.3
runs:
using: "composite"
steps:
# install python
- name: 💿Install Python
uses: actions/setup-python@v5.1.0
with:
python-version: ${{ inputs.python-version }}
# install modules via pip
- name: 💿Install Modules
shell: bash
env:
OS_NAME: ${{ inputs.os-name }}
run: |
echo "Install Modules"
python ./resources/ci/common/get_pipline.py
# print pipline
- name: PipLine
shell: bash
run: |
echo "PipLine"
cat ./resources/user/meta/manifests/pipline.txt
# upload pipline
- name: 🔼Upload PipLine
uses: actions/upload-artifact@v4.3.3
with:
name: pipline-${{ inputs.calling-job }}-${{ inputs.os-name }}-py${{ inputs.python-version }}
path: ./resources/user/meta/manifests
if: contains(inputs.calling-job, 'test')
@@ -0,0 +1,77 @@
name: 📀->📦Prepare Release
description: Prepare Release for Deployment
inputs:
os-name:
required: true
description: OS to run on
python-version:
required: true
description: Python version to install
#########
# actions
#########
# Artheau/SpriteSomething/get-parent-dir
# actions/checkout@v4.1.4
# actions/download-artifact@v4.1.7
runs:
using: "composite"
steps:
# checkout commit
- name: ✔️Checkout commit
shell: bash
run: |
echo "✔️Checkout commit"
- name: ✔️Checkout commit
uses: actions/checkout@v4.1.4
# get parent dir
- name: 📁Get Parent Directory
shell: bash
run: |
echo "📁Get Parent Directory"
- name: 📁Get Parent Directory
id: parentDir
uses: ./.github/actions/get-parent-dir
# download binary artifact
- name: 🔽Download Binary Artifact
shell: bash
run: |
echo "🔽Download Binary Artifact"
- name: 🔽Download Binary Artifact
uses: actions/download-artifact@v4.1.7
with:
name: binary-${{ inputs.os-name }}-py${{ inputs.python-version }}
path: ./
# download appversion artifact
- name: 🔽Download AppVersion Artifact
uses: actions/download-artifact@v4.1.7
with:
name: appversion
path: ${{ steps.parentDir.outputs.parentDir }}/build
# Prepare Release
- name: 💬Prepare Release
shell: bash
run: |
echo "💬Prepare Release"
- name: Prepare Release
shell: bash
env:
OS_NAME: ${{ inputs.os-name }}
run: |
python ./resources/ci/common/prepare_release.py
# upload archive artifact for later step
- name: 🔼Upload Archive Artifact
shell: bash
run: |
echo "🔼Upload Archive Artifact"
- name: 🔼Upload Archive Artifact
uses: actions/upload-artifact@v4.3.3
with:
name: archive-${{ inputs.os-name }}-py${{ inputs.python-version }}
path: ${{ steps.parentDir.outputs.parentDir }}/deploy
+76
View File
@@ -0,0 +1,76 @@
name: 🏷️Tag Repository
description: Tag a repository
inputs:
repository:
description: "Repository Owner/Name; octocat/Hello-World"
required: true
ref-name:
description: "Reference name; branch, tag, etc"
required: true
github-tag:
description: "Reference to tag with"
required: true
debug:
description: "Debug Mode, won't set tag"
required: false
default: "false"
runs:
using: "composite"
steps:
- name: 🏷️Tag Repository
uses: actions/github-script@v7.0.1
with:
github-token: ${{ env.FINE_PAT }}
script: |
const debug = ${{ inputs.debug }} == "true" || ${{ inputs.debug }} == true;
const repository = '${{ inputs.repository }}';
const owner = repository.substring(0,repository.indexOf('/'));
const repo = repository.substring(repository.indexOf('/')+1);
const ref = '${{ inputs.ref-name }}';
// get git tag
const gitTag = '${{ inputs.github-tag }}';
console.log('Repo Data: ', `${owner}/${repo}@${ref}`)
console.log('Git tag: ', gitTag)
if(gitTag == '') {
let msg = 'Result: 🔴No Git Tag sent, aborting!';
console.log(msg)
core.setFailed(msg)
return
}
// get latest commit
const latestCommit = await github.rest.git.getRef({
owner: owner,
repo: repo,
ref: ref
})
// get latest refs
const latestRefs = await github.rest.git.listMatchingRefs({
owner: owner,
repo: repo
})
let latestTag = ''; // bucket for latest tag
// get last tag in data
for(let thisRef of latestRefs.data) {
if(thisRef['ref'].indexOf('tags') > -1) {
let refParts = thisRef['ref'].split('/');
latestTag = refParts[-1];
}
}
console.log('Latest tag:', latestTag)
if(latestTag != gitTag) {
if(debug) {
console.log(`DEBUG: 🔵Creating '${gitTag}' tag`)
} else {
console.log(`Result: 🟢Creating '${gitTag}' tag`)
github.rest.git.createRef({
owner: owner,
repo: repo,
ref: `refs/tags/${gitTag}`,
sha: latestCommit.data.object.sha
})
}
} else {
console.log('Result: 🟡Not creating release tag')
}
+97
View File
@@ -0,0 +1,97 @@
name: ⏱️Test
description: Test app
inputs:
os-name:
required: true
description: OS to run on
python-version:
required: true
description: Python version to install
#########
# actions
#########
# actions/checkout@v4.1.4
# actions/download-artifact@v4.1.7
# actions/upload-artifact@v4.3.3
# coactions/setup-xvfb@v1.0.1
runs:
using: "composite"
steps:
# download pipline
- name: 🔽Download PipLine
shell: bash
run: |
echo "🔽Download PipLine"
- name: 🔽Download PipLine
uses: actions/download-artifact@v4.1.7
with:
name: pipline-test-${{ inputs.os-name }}-py${{ inputs.python-version }}
path: ./resources/user/meta/manifests
# run tests
- name: 🖥️Test Base
shell: bash
run: |
echo "🖥️Test Base"
- name: 🖥️Test Base
shell: bash
run: |
mkdir -p ./failures
echo "" > ./failures/errors.txt
python -m pip install tqdm
python ./test/NewTestSuite.py
# - name: 🖥️Test Mystery
# shell: bash
# run: |
# echo "🖥️Test Mystery"
# if: contains(inputs.os-name, 'macos')
# - name: 🖥️Test Mystery
# shell: bash
# run: |
# python ./test/MysteryTestSuite.py
# if: contains(inputs.os-name, 'macos')
# upload logs
- name: 🔼Upload Logs
shell: bash
run: |
echo "🔼Upload Logs"
- name: 🔼Upload Logs
uses: actions/upload-artifact@v4.3.3
with:
name: logs-${{ inputs.os-name }}-py${{ inputs.python-version }}
path: ./logs
if-no-files-found: ignore
# print failures
- name: 💬Print Failures
if: failure()
shell: bash
run: |
echo "💬Print Failures"
- name: Print Failures
if: failure()
shell: bash
run: |
ERR_STRING="$(cat ./failures/errors.txt)"
ERR_STRING="${ERR_STRING//'%'/'%25'}"
ERR_STRING="${ERR_STRING//$'\n'/' | '}"
ERR_STRING="${ERR_STRING//$'\r'/' | '}"
ERR_STRING="${ERR_STRING//$'\n'/'%0A'}"
ERR_STRING="${ERR_STRING//$'\r'/'%0D'}"
echo "::error ::$ERR_STRING"
# upload failures
- name: 🔼Upload Failures
if: failure()
shell: bash
run: |
echo "🔼Upload Failures"
- name: 🔼Upload Failures
if: failure()
uses: actions/upload-artifact@v4.3.3
with:
name: failures-${{ inputs.os-name }}-py${{ inputs.python-version }}
path: ./failures
+17
View File
@@ -0,0 +1,17 @@
# Set to true to add reviewers to pull requests
addReviewers: true
# Set to true to add assignees to pull requests
addAssignees: true
# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
- aerinon
# A list of keywords to be skipped the process that add reviewers if pull requests include it
skipKeywords:
- wip
# A number of reviewers added to the pull request
# Set 0 to add all the reviewers (default: 0)
numberOfReviewers: 0
+81
View File
@@ -0,0 +1,81 @@
# GitHub Pages Deployment Workflow
name: 📄 Deploy GitHub Pages
# Deploy on push to DoorDevUnstable branch
on:
push:
branches:
- DoorDevUnstable
# Allow manual trigger
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
# Build job
build:
name: 🔨 Build Site
runs-on: ubuntu-latest
steps:
- name: ✔️ Checkout
uses: actions/checkout@v4
- name: 💎 Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
bundler-cache: false
- name: 💿 Install dependencies
run: |
gem install bundler
bundle config set --local path 'vendor/bundle'
# Create Gemfile if it doesn't exist
if [ ! -f Gemfile ]; then
cat > Gemfile << 'EOF'
source 'https://rubygems.org'
gem 'github-pages', group: :jekyll_plugins
gem 'jekyll-feed'
gem 'jekyll-seo-tag'
gem 'jekyll-sitemap'
gem 'just-the-docs'
EOF
fi
bundle install
- name: 🔨 Build with Jekyll
run: bundle exec jekyll build --baseurl "/ALttPDoorRandomizer"
env:
JEKYLL_ENV: production
- name: 📤 Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./_site
# Deployment job
deploy:
name: 🚀 Deploy to GitHub Pages
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: 🚀 Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
- name: ✅ Deployment complete
run: |
echo "🎉 GitHub Pages deployed successfully!"
echo "📄 Site URL: ${{ steps.deployment.outputs.page_url }}"
@@ -0,0 +1,47 @@
# workflow name
name: 🏷️Tag Repositories
# Fine-grained personal access token
# https://github.com/settings/tokens?type=beta
# token needs perms:
# actions: read/write
# commit statuses: read/write
# contents: read/write
# workflows: read/write
# copy token
# Actions secrets and variables
# github.com/<owner>/<repo>/settings/secrets/actions
# repository secret
# name a new secret "ALTTPER_TAGGER"
# value set to copied token
# fire on
on:
release:
types:
- released
jobs:
# Tag Baserom
tag-baserom:
name: 🖳Tag Baserom
runs-on: ${{ matrix.os-name }}
strategy:
matrix:
os-name: [
# ubuntu-latest
"ubuntu-22.04"
]
steps:
# call checkout
- name: ✔️Checkout commit
uses: actions/checkout@v4.1.4
- name: 🏷️Tag Repository
uses: ./.github/actions/tag-repo
env:
FINE_PAT: ${{ secrets.ALTTPER_TAGGER }}
with:
repository: ${{ github.repository_owner }}/z3randomizer
ref-name: heads/OWMain
github-tag: ${{ github.event.release.tag_name }}
+415
View File
@@ -0,0 +1,415 @@
# workflow name
name: ⏱️Test/🔨Build/🚀Deploy
# fire on
on:
push:
branches:
# - DoorDevUnstable
# - DoorDev
- OverworldShuffle
pull_request:
branches:
# - DoorDevUnstable
# - DoorDev
- OverworldShuffle
# stuff to do
jobs:
# Diagnostics
diags:
# diagnostics
# call checkout
# call install python
# print python version
# call install
# call analyze github actions
# install extra python modules
# run diagnostics
name: 🧮
runs-on: ${{ matrix.os-name }}
continue-on-error: True
strategy:
matrix:
#TODO: OS List to run on
os-name: [
# ubuntu-latest, # ubuntu-22.04
ubuntu-22.04,
macos-latest, # macos-12
windows-latest # windows-2022
]
#TODO: Python Version to run on
python-version: [ "3.12" ]
steps:
# call checkout
- name: ✔️Checkout commit
uses: actions/checkout@v4.1.4
# call install python
- name: 💿Install Python
uses: actions/setup-python@v5.1.0
with:
python-version: ${{ matrix.python-version }}
# print python version
- name: 🐍Python Version
shell: bash
run: |
python --version
# call install
- name: 💿Call Install
uses: ./.github/actions/install
with:
calling-job: diags
os-name: ${{ matrix.os-name }}
python-version: ${{ matrix.python-version }}
# call analyze github actions
- name: ⚙️Analyze used GitHub Actions
shell: bash
run: |
python ./resources/ci/common/list_actions.py
# install extra python modules
- name: 💿Install extra Python Modules
shell: bash
run: |
python -m pip install setuptools
# run diagnostics
- name: 🧮Print Diagnostics
shell: bash
run: |
python -m source.meta.run_diags
# Test
install-test:
# test
# call checkout
# call install
# run tests
name: 💿/⏱️
runs-on: ${{ matrix.os-name }}
continue-on-error: False
strategy:
matrix:
#TODO: OS List to run on
os-name: [
# ubuntu-latest, # ubuntu-22.04
ubuntu-22.04,
macos-latest, # macos-12
windows-latest # windows-2022
]
#TODO: Python Version to run on
python-version: [ "3.12" ]
steps:
# call checkout
- name: ✔️Checkout commit
uses: actions/checkout@v4.1.4
# call install
- name: 💿Call Install
uses: ./.github/actions/install
with:
calling-job: test
os-name: ${{ matrix.os-name }}
python-version: ${{ matrix.python-version }}
# call test
- name: ⏱️Call Test
uses: ./.github/actions/test
with:
os-name: ${{ matrix.os-name }}
python-version: ${{ matrix.python-version }}
# Prepare AppVersion
appversion-prepare:
# prepare appversion
# call checkout
# call install
# call appversion-prepare
name: 💬
runs-on: ${{ matrix.os-name }}
needs: [install-test]
continue-on-error: False
strategy:
matrix:
#TODO: OS List to run on
os-name: [
# ubuntu-latest, # ubuntu-22.04
ubuntu-22.04,
]
#TODO: Python Version to run on
python-version: [ "3.12" ]
steps:
# call checkout
- name: ✔️Checkout commit
uses: actions/checkout@v4.1.4
# call install
- name: 💿Call Install
uses: ./.github/actions/install
with:
calling-job: appversion-prepare
os-name: ${{ matrix.os-name }}
python-version: ${{ matrix.python-version }}
# call appversion-prepare
- name: 💬Call Prepare AppVersion
uses: ./.github/actions/appversion-prepare
# Build
install-build:
# build
# call checkout
# call install
# call build
name: 💿/🔨
runs-on: ${{ matrix.os-name }}
needs: [appversion-prepare]
continue-on-error: False
strategy:
matrix:
#TODO: OS List to run on
os-name: [
# ubuntu-latest, # ubuntu-22.04
ubuntu-22.04,
macos-latest, # macos-12
windows-latest # windows-2022
]
#TODO: Python Version to run on
python-version: [ "3.12" ]
steps:
# call checkout
- name: ✔️Checkout commit
uses: actions/checkout@v4.1.4
# call install
- name: 💿Call Install
uses: ./.github/actions/install
with:
calling-job: build
os-name: ${{ matrix.os-name }}
python-version: ${{ matrix.python-version }}
# call build
- name: 🔨Call Build
uses: ./.github/actions/build
with:
calling-job: build
os-name: ${{ matrix.os-name }}
python-version: ${{ matrix.python-version }}
# Prepare Release
release-prepare:
# prepare release
# call checkout
# install extra python modules
# call prepare release
name: 💿/📀->📦
runs-on: ${{ matrix.os-name }}
needs: [install-build]
continue-on-error: False
strategy:
matrix:
#TODO: OS List to run on
os-name: [
# ubuntu-latest, # ubuntu-22.04
ubuntu-22.04,
macos-latest, # macos-12
windows-latest # windows-2022
]
python-version: [ "3.12" ]
steps:
# call checkout
- name: ✔️Checkout commit
uses: actions/checkout@v4.1.4
# install extra python modules
- name: 💿Install extra Python Modules
shell: bash
run: |
python -m pip install setuptools
# call prepare release
- name: 📀->📦Prepare Release
uses: ./.github/actions/release-prepare
with:
os-name: ${{ matrix.os-name }}
python-version: ${{ matrix.python-version }}
# Deploy Release
# Needs to be top-level for SECRET to work easily
release-deploy:
name: 📀->🚀
runs-on: ${{ matrix.os-name }}
needs: [release-prepare]
strategy:
matrix:
#TODO: OS List to run on
os-name: [
# ubuntu-latest, # ubuntu-22.04
ubuntu-22.04,
]
#TODO: Python Version to run on
python-version: [ "3.12" ]
steps:
# checkout commit
- name: ✔️Checkout commit
uses: actions/checkout@v4.1.4
# install extra python modules
- name: 💿Install extra Python Modules
shell: bash
run: |
python -m pip install pytz requests
# get parent dir
- name: 📁Get Parent Directory
id: parentDir
uses: ./.github/actions/get-parent-dir
# download appversion artifact
- name: 🔽Download AppVersion Artifact
uses: actions/download-artifact@v4.1.7
with:
name: appversion
path: ${{ steps.parentDir.outputs.parentDir }}/build
# download ubuntu archive artifact
- name: 🔽Download Ubuntu Archive Artifact
uses: actions/download-artifact@v4.1.7
with:
# should run on latest explicit ubuntu version
name: archive-ubuntu-22.04-py${{ matrix.python-version }}
path: ${{ steps.parentDir.outputs.parentDir }}/deploy/linux
# download macos archive artifact
- name: 🔽Download MacOS Archive Artifact
uses: actions/download-artifact@v4.1.7
with:
name: archive-macos-latest-py${{ matrix.python-version }}
path: ${{ steps.parentDir.outputs.parentDir }}/deploy/macos
# download windows archive artifact
- name: 🔽Download Windows Archive Artifact
uses: actions/download-artifact@v4.1.7
with:
name: archive-windows-latest-py${{ matrix.python-version }}
path: ${{ steps.parentDir.outputs.parentDir }}/deploy/windows
# determine linux archive asset
- name: ❔Identify Linux Archive Asset
id: identify-linux-asset
shell: bash
run: |
ASSET_LINUX="$(ls ${{ steps.parentDir.outputs.parentDir }}/deploy/linux)"
echo "asset_linux=$ASSET_LINUX" >> $GITHUB_OUTPUT
# determine macos archive asset
- name: ❔Identify MacOS Archive Asset
id: identify-macos-asset
shell: bash
run: |
ASSET_MACOS="$(ls ${{ steps.parentDir.outputs.parentDir }}/deploy/macos)"
echo "asset_macos=$ASSET_MACOS" >> $GITHUB_OUTPUT
# determine windows archive asset
- name: ❔Identify Windows Archive Asset
id: identify-windows-asset
shell: bash
run: |
ASSET_WIN="$(ls ${{ steps.parentDir.outputs.parentDir }}/deploy/windows)"
echo "asset_windows=$ASSET_WIN" >> $GITHUB_OUTPUT
# archive listing
# - name: Archive Listing
# shell: bash
# run: |
# ls -R ${{ steps.parentDir.outputs.parentDir }}/deploy/
# debug info
#TODO: Project Name
- name: 📝Debug Info
id: debug_info
run: |
PROJECT_NAME="ALttPOverworldRandomizer"
echo "project_name=$PROJECT_NAME" >> $GITHUB_OUTPUT
GITHUB_TAG="$(head -n 1 ../build/app_version.txt)"
echo "github_tag=$GITHUB_TAG" >> $GITHUB_OUTPUT
RELEASE_NAME="${PROJECT_NAME} ${GITHUB_TAG}"
echo "release_name=$RELEASE_NAME" >> $GITHUB_OUTPUT
ASSET_PREFIX="${PROJECT_NAME}-${GITHUB_TAG}"
echo "asset_prefix=$ASSET_PREFIX" >> $GITHUB_OUTPUT
echo "Project Name: ${PROJECT_NAME}"
echo "Release Name: ${RELEASE_NAME}"
echo "Asset Prefix: ${ASSET_PREFIX}"
echo "Git Tag: ${GITHUB_TAG}"
echo "Linux Asset: ${{ steps.identify-linux-asset.outputs.asset_linux }}"
echo "MacOS Asset: ${{ steps.identify-macos-asset.outputs.asset_macos }}"
echo "Windows Asset: ${{ steps.identify-windows-asset.outputs.asset_windows }}"
# create a release (OverworldShuffle)
# if: contains(github.ref, 'OverworldShuffle') # branch or tag name
# if: contains(github.event.head_commit.message, 'Version bump') # commit message
- name: 📀->🚀Create a Release (OverworldShuffle)
id: create_release
uses: actions/create-release@v1.1.4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.debug_info.outputs.github_tag }}
release_name: ${{ steps.debug_info.outputs.release_name }}
body_path: CHANGELOG.md
# draft: true
if: contains(github.event.head_commit.message, 'Merge branch') # branch/tag name and commit message
# upload linux archive asset (OverworldShuffle)
#TODO: Make sure we're firing on the proper branches
- name: 🔼Upload Linux Archive Asset (OverworldShuffle)
id: upload-linux-asset
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ steps.parentDir.outputs.parentDir }}/deploy/linux/${{ steps.identify-linux-asset.outputs.asset_linux }}
asset_name: ${{ steps.debug_info.outputs.asset_prefix }}-linux-focal.tar.gz
asset_content_type: application/gzip
if: contains(github.event.head_commit.message, 'Merge branch') # branch/tag name and commit message
# upload macos archive asset (OverworldShuffle)
#TODO: Make sure we're firing on the proper branches
- name: 🔼Upload MacOS Archive Asset (OverworldShuffle)
id: upload-macos-asset
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ steps.parentDir.outputs.parentDir }}/deploy/macos/${{ steps.identify-macos-asset.outputs.asset_macos }}
asset_name: ${{ steps.debug_info.outputs.asset_prefix }}-osx.tar.gz
asset_content_type: application/gzip
if: contains(github.event.head_commit.message, 'Merge branch') # branch/tag name and commit message
# upload windows archive asset (OverworldShuffle)
#TODO: Make sure we're firing on the proper branches
- name: 🔼Upload Windows Archive Asset (OverworldShuffle)
id: upload-windows-asset
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ steps.parentDir.outputs.parentDir }}/deploy/windows/${{ steps.identify-windows-asset.outputs.asset_windows }}
asset_name: ${{ steps.debug_info.outputs.asset_prefix }}-windows.zip
asset_content_type: application/zip
if: contains(github.event.head_commit.message, 'Merge branch') # branch/tag name and commit message
# - name: 🖳Tag Baserom
# uses: ./.github/actions/tag-repo
# env:
# FINE_PAT: ${{ secrets.ALTTPER_TAGGER }}
# with:
# repository: ${{ github.repository_owner }}/z3randomizer
# ref-name: heads/OWMain
# github-tag: ${{ github.event.release.tag_name }}
# if: contains(github.event.head_commit.message, 'Merge branch')
+36 -1
View File
@@ -1,12 +1,20 @@
.idea
.vscode
*_Spoiler.txt
*.bmbp
*.log
*_Spoiler.json
*_Meta.json
*_custom.yaml
*_meta.txt
*.bps
*.pyc
*.sfc
*.srm
*.bst
*.wixobj
build
*.bat
/build
bundle/components.wxs
dist
README.html
@@ -15,3 +23,30 @@ README.html
*multisave
EnemizerCLI/
.mypy_cache/
RaceRom.py
upx/
weights/
/MultiMystery/
/Players/
/QUsb2Snes/
/output/
/enemizer/
visualizations/
resources/user/*
!resources/user/.gitkeep
*.exe
get-pip.py
venv
/test
test_games/
docs/issues/*
docs/ideas/*
data/sprites/official/selan.1.zspr
*.zspr
*errors.txt
*success.txt
+1
View File
@@ -0,0 +1 @@
3.13
+18 -6
View File
@@ -1,11 +1,13 @@
#!/usr/bin/env python3
import argparse
import os
import logging
import textwrap
import os
import sys
import textwrap
from AdjusterMain import adjust
from Rom import get_sprite_from_name
class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
@@ -15,7 +17,8 @@ class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
def main():
parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('--rom', default='ER_base.sfc', help='Path to an ALttP JAP(1.0) rom to use as a base.')
parser.add_argument('--rom', default='ER_base.sfc', help='Path to an ALttPR rom to adjust.')
parser.add_argument('--baserom', default='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc', help='Path to an ALttP JAP(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('--fastmenu', default='normal', const='normal', nargs='?', choices=['normal', 'instant', 'double', 'triple', 'quadruple', 'half'],
help='''\
@@ -31,6 +34,13 @@ def main():
''')
parser.add_argument('--heartcolor', default='red', const='red', nargs='?', choices=['red', 'blue', 'green', 'yellow', 'random'],
help='Select the color of Link\'s heart meter. (default: %(default)s)')
parser.add_argument('--ow_palettes', default='default', choices=['default', 'random', 'blackout'])
parser.add_argument('--uw_palettes', default='default', choices=['default', 'random', 'blackout'])
parser.add_argument('--reduce_flashing', help='Reduce some in-game flashing.', action='store_true')
parser.add_argument('--shuffle_sfx', help='Shuffles sound sfx', action='store_true')
parser.add_argument('--shuffle_sfxinstruments', help='Shuffles sound instruments', action='store_true')
parser.add_argument('--shuffle_songinstruments', help='Shuffles song instruments', action='store_true')
parser.add_argument('--msu_resume', help='Enable MSU resume', action='store_true')
parser.add_argument('--sprite', help='''\
Path to a sprite sheet to use for Link. Needs to be in
binary format and have a length of 0x7000 (28672) bytes,
@@ -38,14 +48,16 @@ def main():
Alternatively, can be a ALttP Rom patched with a Link
sprite that will be extracted.
''')
parser.add_argument('--triforce_gfx', help='Name of the triforce graphics to use.')
parser.add_argument('--names', default='', type=str)
args = parser.parse_args()
# 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)
input('Could not find valid rom for patching at expected path %s. Please run with -h to see help for further information. \nPress Enter to exit.' % args.rom)
sys.exit(1)
if args.sprite is not None and not os.path.isfile(args.sprite):
input('Could not find link sprite sheet at given location. \nPress Enter to exit.' % args.sprite)
if args.sprite is not None and not os.path.isfile(args.sprite) and not get_sprite_from_name(args.sprite):
input('Could not find link sprite sheet at given location. \nPress Enter to exit.')
sys.exit(1)
# set up logger
+60 -13
View File
@@ -1,36 +1,83 @@
import logging
import os
import time
import logging
try:
import bps.apply
import bps.io
except ImportError:
raise Exception('Could not load BPS module')
from Rom import LocalRom, apply_rom_settings
from source.tools.BPS import bps_read_vlv
from Utils import output_path
from Rom import LocalRom, Sprite, apply_rom_settings
def adjust(args):
start = time.perf_counter()
start = time.process_time()
logger = logging.getLogger('')
logger.info('Patching ROM.')
if args.sprite is not None:
if isinstance(args.sprite, Sprite):
sprite = args.sprite
else:
sprite = Sprite(args.sprite)
else:
sprite = None
outfilebase = os.path.basename(args.rom)[:-4] + '_adjusted'
if os.stat(args.rom).st_size in (0x200000, 0x400000) and os.path.splitext(args.rom)[-1].lower() == '.sfc':
rom = LocalRom(args.rom, False)
if os.path.isfile(args.baserom):
baserom = LocalRom(args.baserom, True)
rom.orig_buffer = baserom.orig_buffer
else:
raise RuntimeError('Provided Rom is not a valid Link to the Past Randomizer Rom. Please provide one for adjusting.')
apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic, sprite)
if not hasattr(args,"sprite"):
args.sprite = None
if not hasattr(args,"triforce_gfx"):
args.triforce_gfx = None
apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic,
args.sprite, args.triforce_gfx, args.ow_palettes, args.uw_palettes, args.reduce_flashing, args.shuffle_sfx,
args.shuffle_sfxinstruments, args.shuffle_songinstruments, args.msu_resume)
output_path.cached_path = args.outputpath
rom.write_to_file(output_path('%s.sfc' % outfilebase))
logger.info('Done. Enjoy.')
logger.debug('Total Time: %s', time.perf_counter() - start)
logger.debug('Total Time: %s', time.process_time() - start)
return args
def patch(args):
start = time.process_time()
logger = logging.getLogger('')
logger.info('Patching ROM.')
outfile_base = os.path.basename(args.patch)[:-4]
rom = LocalRom(args.baserom, False)
if os.path.isfile(args.baserom):
rom.verify_base_rom()
orig_buffer = rom.buffer.copy()
with open(args.patch, 'rb') as stream:
stream.seek(4) # skip BPS1
bps_read_vlv(stream) # skip source size
target_length = bps_read_vlv(stream)
rom.buffer.extend(bytearray([0x00] * (target_length - len(rom.buffer))))
stream.seek(0)
bps.apply.apply_to_bytearrays(bps.io.read_bps(stream), orig_buffer, rom.buffer)
if not hasattr(args, "sprite"):
args.sprite = None
if not hasattr(args, "triforce_gfx"):
args.triforce_gfx = None
apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic,
args.sprite, args.triforce_gfx, args.ow_palettes, args.uw_palettes, args.reduce_flashing,
args.shuffle_sfx, args.shuffle_sfxinstruments, args.shuffle_songinstruments, args.msu_resume)
output_path.cached_path = args.outputpath
rom.write_to_file(output_path('%s.sfc' % outfile_base))
logger.info('Done. Enjoy.')
logger.debug('Total Time: %s', time.process_time() - start)
return args
+3238 -358
View File
File diff suppressed because it is too large Load Diff
+192 -89
View File
@@ -1,14 +1,16 @@
import logging
import RaceRandom as random
from BaseClasses import Boss, FillError
from source.enemizer.Bossmizer import boss_adjust
from BaseClasses import Boss
from Fill import FillError
def BossFactory(boss, player):
def BossFactory(boss, player, on_ice=False):
if boss is None:
return None
if boss in boss_table:
enemizer_name, defeat_rule = boss_table[boss]
enemizer_name, normal_defeat_rule, ice_defeat_rule = boss_table[boss]
defeat_rule = ice_defeat_rule if on_ice else normal_defeat_rule
return Boss(boss, enemizer_name, defeat_rule, player)
logging.getLogger('').error('Unknown Boss: %s', boss)
@@ -32,27 +34,31 @@ def LanmolasDefeatRule(state, player):
state.has('Fire Rod', player) or
state.has('Ice Rod', player) or
state.has('Cane of Somaria', player) or
state.has('Cane of Byrna', player) or
(state.has('Cane of Byrna', player) and state.can_use_bombs(player)) or
state.can_shoot_arrows(player))
def MoldormDefeatRule(state, player):
return state.has_blunt_weapon(player)
def HelmasaurKingDefeatRule(state, player):
# TODO: technically possible with the hammer
return state.has_sword(player) or state.can_shoot_arrows(player)
return (state.has('Hammer', player) or state.can_use_bombs(player)) and (state.has_sword(player) or state.can_shoot_arrows(player))
def IceHelmasaurKingDefeatRule(state, player):
return state.can_use_bombs(player) and (state.has_sword(player) or state.can_shoot_arrows(player))
def ArrghusDefeatRule(state, player):
if not state.has('Hookshot', player):
return False
# TODO: ideally we would have a check for bow and silvers, which combined with the
# hookshot is enough. This is not coded yet because the silvers that only work in pyramid feature
# makes this complicated
if state.has_blunt_weapon(player):
return True
return ((state.has('Fire Rod', player) and (state.can_shoot_arrows(player) or state.can_extend_magic(player, 12))) or #assuming mostly gitting two puff with one shot
(state.has('Ice Rod', player) and (state.can_shoot_arrows(player) or state.can_extend_magic(player, 16))))
if state.can_shoot_arrows(player) and state.has('Silver Arrows', player) and state.world.difficulty_adjustments[player] not in ['hard', 'expert']:
return True
return ((state.has('Fire Rod', player) and (state.can_shoot_arrows(player) or state.can_extend_magic(player, 12))) or # assuming mostly getting two puffs with one shot
(state.has('Ice Rod', player) and state.can_use_bombs(player) and (state.can_shoot_arrows(player) or state.can_extend_magic(player, 16))))
def MothulaDefeatRule(state, player):
@@ -62,13 +68,30 @@ def MothulaDefeatRule(state, player):
# TODO: Not sure how much (if any) extend magic is needed for these two, since they only apply
# to non-vanilla locations, so are harder to test, so sticking with what VT has for now:
(state.has('Cane of Somaria', player) and state.can_extend_magic(player, 16)) or
(state.has('Cane of Byrna', player) and state.can_extend_magic(player, 16)) or
state.can_get_good_bee(player)
(state.has('Cane of Byrna', player) and state.can_extend_magic(player, 16))
)
def BlindDefeatRule(state, player):
return state.has_blunt_weapon(player) or state.has('Cane of Somaria', player) or state.has('Cane of Byrna', player)
def IceBlindDefeatRule(state, player):
return (
(
# weapon
state.has_beam_sword(player) or
state.has('Cane of Somaria', player) or
(state.has('Cane of Byrna', player) and state.can_extend_magic(player, 16))
) and
(
# protection
state.has('Red Shield', player) or
(state.has('Cane of Byrna', player) and state.world.difficulty_adjustments[player] not in ['hard', 'expert'])
)
)
def KholdstareDefeatRule(state, player):
return (
(
@@ -76,7 +99,7 @@ def KholdstareDefeatRule(state, player):
(
state.has('Bombos', player) and
# FIXME: the following only actually works for the vanilla location for swordless
(state.has_sword(player) or state.world.swords == 'swordless')
(state.has_sword(player) or state.world.swords[player] == 'swordless')
)
) and
(
@@ -86,52 +109,101 @@ def KholdstareDefeatRule(state, player):
(
state.has('Fire Rod', player) and
state.has('Bombos', player) and
state.world.swords == 'swordless' and
state.world.swords[player] == 'swordless' and
state.can_extend_magic(player, 16)
)
)
)
def IceKholdstareDefeatRule(state, player):
return (
(
state.has('Fire Rod', player) or
(
state.has('Bombos', player) and
# FIXME: the following only actually works for the vanilla location for swordless
(state.has_sword(player) or state.world.swords[player] == 'swordless')
)
) and
(
state.has_beam_sword(player) or
(state.has('Fire Rod', player) and state.can_extend_magic(player, 20)) or
# FIXME: this actually only works for the vanilla location for swordless
(
state.has('Fire Rod', player) and
state.has('Bombos', player) and
(state.has_sword(player) or state.world.swords[player] == 'swordless') and
state.can_extend_magic(player, 16)
)
)
)
def VitreousDefeatRule(state, player):
return state.can_shoot_arrows(player) or state.has_blunt_weapon(player)
return (state.can_shoot_arrows(player) and state.can_use_bombs(player)) or state.has_blunt_weapon(player)
def IceVitreousDefeatRule(state, player):
return (state.can_shoot_arrows(player) and state.can_use_bombs(player)) or state.has_beam_sword(player)
def TrinexxDefeatRule(state, player):
if not (state.has('Fire Rod', player) and state.has('Ice Rod', player)):
return False
return state.has('Hammer', player) or state.has('Tempered Sword', player) or state.has('Golden Sword', player) or \
(state.has('Master Sword', player) and state.can_extend_magic(player, 16)) or \
(state.has_sword(player) and state.can_extend_magic(player, 32))
return (state.has('Hammer', player) or
state.has('Golden Sword', player) or
state.has('Tempered Sword', player) or
(state.has('Master Sword', player) and state.can_extend_magic(player, 16)) or
(state.has_sword(player) and state.can_extend_magic(player, 32)))
def IceTrinexxDefeatRule(state, player):
if not (state.has('Fire Rod', player) and state.has('Ice Rod', player) and state.has_Boots(player)):
return False
return (state.has('Golden Sword', player) or
(state.has('Tempered Sword', player) and state.can_extend_magic(player, 16)) or
((state.has('Hammer', player) or
state.has('Master Sword', player)) and state.can_extend_magic(player, 32))) # rod spam rule
def AgahnimDefeatRule(state, player):
return state.has_sword(player) or state.has('Hammer', player) or state.has('Bug Catching Net', player)
boss_table = {
'Armos Knights': ('Armos', ArmosKnightsDefeatRule),
'Lanmolas': ('Lanmola', LanmolasDefeatRule),
'Moldorm': ('Moldorm', MoldormDefeatRule),
'Helmasaur King': ('Helmasaur', HelmasaurKingDefeatRule),
'Arrghus': ('Arrghus', ArrghusDefeatRule),
'Mothula': ('Mothula', MothulaDefeatRule),
'Blind': ('Blind', BlindDefeatRule),
'Kholdstare': ('Kholdstare', KholdstareDefeatRule),
'Vitreous': ('Vitreous', VitreousDefeatRule),
'Trinexx': ('Trinexx', TrinexxDefeatRule),
'Agahnim': ('Agahnim', AgahnimDefeatRule),
'Agahnim2': ('Agahnim2', AgahnimDefeatRule)
'Armos Knights': ('Armos', ArmosKnightsDefeatRule, ArmosKnightsDefeatRule),
'Lanmolas': ('Lanmola', LanmolasDefeatRule, LanmolasDefeatRule),
'Moldorm': ('Moldorm', MoldormDefeatRule, MoldormDefeatRule),
'Helmasaur King': ('Helmasaur', HelmasaurKingDefeatRule, IceHelmasaurKingDefeatRule),
'Arrghus': ('Arrghus', ArrghusDefeatRule, ArrghusDefeatRule),
'Mothula': ('Mothula', MothulaDefeatRule, MothulaDefeatRule),
'Blind': ('Blind', BlindDefeatRule, IceBlindDefeatRule),
'Kholdstare': ('Kholdstare', KholdstareDefeatRule, IceKholdstareDefeatRule),
'Vitreous': ('Vitreous', VitreousDefeatRule, IceVitreousDefeatRule),
'Trinexx': ('Trinexx', TrinexxDefeatRule, IceTrinexxDefeatRule),
'Agahnim': ('Agahnim', AgahnimDefeatRule, AgahnimDefeatRule),
'Agahnim2': ('Agahnim2', AgahnimDefeatRule, AgahnimDefeatRule)
}
def can_place_boss(world, boss, dungeon_name, level=None):
if world.swords in ['swordless'] and boss == 'Kholdstare' and dungeon_name != 'Ice Palace':
def can_place_boss(world, player, boss, dungeon_name, level=None):
if world.swords[player] in ['swordless'] and boss == 'Kholdstare' and dungeon_name != 'Ice Palace':
return False
if dungeon_name in ['Ganons Tower', 'Inverted Ganons Tower'] and level == 'top':
if dungeon_name == 'Ganons Tower' and level == 'top':
if boss in ["Armos Knights", "Arrghus", "Blind", "Trinexx", "Lanmolas"]:
return False
if dungeon_name in ['Ganons Tower', 'Inverted Ganons Tower'] and level == 'middle':
if dungeon_name == 'Ganons Tower' and level == 'middle':
if boss in ["Blind"]:
return False
# no Trinexx on Ice in doors without doing some health modelling
if world.doorShuffle[player] != 'vanilla' and boss == 'Trinexx':
if dungeon_name == 'Ganons Tower' and level == 'bottom':
return False
if dungeon_name == 'Tower of Hera' and boss in ["Armos Knights", "Arrghus", "Blind", "Trinexx", "Lanmolas"]:
return False
@@ -143,77 +215,108 @@ def can_place_boss(world, boss, dungeon_name, level=None):
return True
def place_bosses(world, player):
if world.boss_shuffle == 'none':
if world.boss_shuffle[player] == 'none':
return
# Most to least restrictive order
if world.mode != 'inverted':
boss_locations = [
['Ganons Tower', 'top'],
['Tower of Hera', None],
['Skull Woods', None],
['Ganons Tower', 'middle'],
['Eastern Palace', None],
['Desert Palace', None],
['Palace of Darkness', None],
['Swamp Palace', None],
['Thieves Town', None],
['Ice Palace', None],
['Misery Mire', None],
['Turtle Rock', None],
['Ganons Tower', 'bottom'],
]
else:
boss_locations = [
['Inverted Ganons Tower', 'top'],
['Tower of Hera', None],
['Skull Woods', None],
['Inverted Ganons Tower', 'middle'],
['Eastern Palace', None],
['Desert Palace', None],
['Palace of Darkness', None],
['Swamp Palace', None],
['Thieves Town', None],
['Ice Palace', None],
['Misery Mire', None],
['Turtle Rock', None],
['Inverted Ganons Tower', 'bottom'],
]
boss_locations = [
['Ganons Tower', 'top'],
['Tower of Hera', None],
['Skull Woods', None],
['Ganons Tower', 'middle'],
['Ganons Tower', 'bottom'],
['Eastern Palace', None],
['Desert Palace', None],
['Palace of Darkness', None],
['Swamp Palace', None],
['Thieves Town', None],
['Ice Palace', None],
['Misery Mire', None],
['Turtle Rock', None],
]
all_bosses = sorted(boss_table.keys()) #s orted to be deterministic on older pythons
placeable_bosses = [boss for boss in all_bosses if boss not in ['Agahnim', 'Agahnim2', 'Ganon']]
used_bosses = []
if world.boss_shuffle in ["basic", "normal"]:
# temporary hack for swordless kholdstare:
if world.swords == 'swordless':
if world.customizer and world.customizer.get_bosses():
custom_bosses = world.customizer.get_bosses()
if player in custom_bosses:
for location, boss in custom_bosses[player].items():
level = None
if '(' in location:
i = location.find('(')
level = location[i+1:location.find(')')]
location = location[:i-1]
if can_place_boss(world, player, boss, location, level):
loc_text = location + (' ('+level+')' if level else '')
place_boss(boss, level, location, loc_text, world, player)
boss_locations.remove([location, level])
used_bosses.append((boss, level))
# temporary hack for swordless kholdstare:
if world.boss_shuffle[player] in ["simple", "full", "unique"]:
if world.swords[player] == 'swordless':
world.get_dungeon('Ice Palace', player).boss = BossFactory('Kholdstare', player)
logging.getLogger('').debug('Placing boss Kholdstare at Ice Palace')
boss_locations.remove(['Ice Palace', None])
placeable_bosses.remove('Kholdstare')
if world.boss_shuffle == "basic": # vanilla bosses shuffled
if world.boss_shuffle[player] in ["simple", "full"]:
if world.boss_shuffle[player] == "simple": # vanilla bosses shuffled
bosses = placeable_bosses + ['Armos Knights', 'Lanmolas', 'Moldorm']
else: # all bosses present, the three duplicates chosen at random
bosses = all_bosses + [random.choice(placeable_bosses) for _ in range(3)]
else: # all bosses present, the three duplicates chosen at random
bosses = placeable_bosses + random.sample(placeable_bosses, 3)
for u, level in used_bosses:
placeable_bosses.remove(u)
logging.getLogger('').debug('Bosses chosen %s', bosses)
random.shuffle(bosses)
for [loc, level] in boss_locations:
loc_text = loc + (' ('+level+')' if level else '')
boss = next((b for b in bosses if can_place_boss(world, b, loc, level)), None)
if not boss:
raise FillError('Could not place boss for location %s' % loc_text)
bosses.remove(boss)
logging.getLogger('').debug('Placing boss %s at %s', boss, loc_text)
world.get_dungeon(loc, player).bosses[level] = BossFactory(boss, player)
elif world.boss_shuffle == "chaos": #all bosses chosen at random
for [loc, level] in boss_locations:
loc_text = loc + (' ('+level+')' if level else '')
try:
boss = random.choice([b for b in placeable_bosses if can_place_boss(world, b, loc, level)])
boss = random.choice([b for b in bosses if can_place_boss(world, player, b, loc, level)])
except IndexError:
raise FillError('Could not place boss for location %s' % loc_text)
bosses.remove(boss)
place_boss(boss, level, loc, loc_text, world, player)
elif world.boss_shuffle[player] == "random": #all bosses chosen at random
for [loc, level] in boss_locations:
loc_text = loc + (' ('+level+')' if level else '')
try:
boss = random.choice([b for b in placeable_bosses if can_place_boss(world, player, b, loc, level)])
except IndexError:
raise FillError('Could not place boss for location %s' % loc_text)
logging.getLogger('').debug('Placing boss %s at %s', boss, loc_text)
world.get_dungeon(loc, player).bosses[level] = BossFactory(boss, player)
place_boss(boss, level, loc, loc_text, world, player)
elif world.boss_shuffle[player] == 'unique':
bosses = list(placeable_bosses)
for u, level in used_bosses:
if not level:
bosses.remove(u)
gt_bosses = []
for [loc, level] in boss_locations:
loc_text = loc + (' ('+level+')' if level else '')
try:
if level:
boss = random.choice([b for b in placeable_bosses if can_place_boss(world, player, b, loc, level)
and b not in gt_bosses])
gt_bosses.append(boss)
else:
boss = random.choice([b for b in bosses if can_place_boss(world, player, b, loc, level)])
bosses.remove(boss)
except IndexError:
raise FillError('Could not place boss for location %s' % loc_text)
place_boss(boss, level, loc, loc_text, world, player)
boss_adjust(world, player)
def place_boss(boss, level, loc, loc_text, world, player):
# GT Bosses can move dungeon - find the real dungeon to place them in
if level:
loc = [x.name for x in world.dungeons if x.player == player and level in x.bosses.keys()][0]
loc_text = loc + ' (' + level + ')'
logging.getLogger('').debug('Placing boss %s at %s', boss, loc_text)
world.get_dungeon(loc, player).bosses[level] = BossFactory(boss, player, level == 'bottom')
+825
View File
@@ -0,0 +1,825 @@
# Changelog
# 0.7.0.3
- Further updates and new yamls for Grid OW Shuffle
- Further customizer options for Grid OW Shuffle like defining screens that should stay together
- Fix buffer sword slash when dashing into water
- Fixed bug with MSU-1 GT2 track not falling back to GT track
- Fix for Kiki unfollowing after certain entrance transition conditions
- Fixed bug/oversight with vanilla_fill and prize_shuffle
- Changed big bomb shop vendor text to be follower agnostic
- Updated crosskeys winners (thanks clearmouse)
- Fixed bug with potential locale determination (thanks Esme)
- \~Merged in DR v1.5.6~
# 0.7.0.2
- Fixed money error for bombbag/take-anys
- Fixed palette issue for map check/flute menu
- Fixed issue with dungeon icons showing in opposite world in Inverted
- Fixed Links position in map checks when in Special OW areas
- Fixed buffered sword issue in OW Shuffle water transitions
- Added PlasmaKappa tribute TF room text
# 0.7.0.1
- Fixed buggy sprites in post-Aga Zora's Domain
- Fixed L/R map switch when in special OW screens
- Fixes issue not able to screen transition if bumped by enemy in water
# 0.7.0.0
- New OW Layout Shuffle Mode: Grid
- Implemented Fog of War for Tile Flip
# 0.6.1.11
- Fixed bonk drops duplicate counting and potentially overwriting arbitrary values
- Fixed boss icons on dungeon map check
- Fixed dungeon counters to autotrack correctly
- Key and chest counts in menu now display consistently (must have dungeon item or have visited dungeon to see the HUD)
- Money balancing will fail in less scenarios
- Fixed issue with Sanc pots not collecting
- Enemizer now allows more enemies on water
- Fix infinite pit fall issue with Old Man follower location
- Fix bad overworld tilemap drawing on HC and Pyramid screens in OW Layout Shuffle
## 0.6.1.10
- Emergency fix for bonk functionality
## 0.6.1.9
- Fixed follower shuffle placement errors
- Fixed pseudoboots ability to open Kings Tomb
- Implemented better accurate coordinates on map check locations
- Fixed janky icons on zoomed-in map check screen
## 0.6.1.8
- Fixed follower placement and logic
- Fixed error with HC Courtyard Tree Pull
## 0.6.1.7
- \~Merged in DR v1.5.2~
- Reverted key count update
## 0.6.1.6
- Fixed bonk drop sparkles in DW
- \~Merged in DR v1.5.1~
- Fixed key count issues
## 0.6.1.5
- Fixed error with non-prize shuffle
## 0.6.1.4
- Fixes for Glitched Rain State (Bonk Shuffle included)
- \~Merged in DR v1.5.0~
- GT Key Logic fix
- New HUD key count behavior
- Pot uncoloring on collection
## 0.6.1.3
- Added new post-gen option to change Triforce Piece GFX
- Added new GFX for 10/11 keys to replace the A/B GFX
- Fixed issue with Follower Sprite GFX after mirroring
- Fixed VRAM issue with Crystal Maiden cutscene
- Some performance updates
- \~Merged in DR v1.4.11~
- Enemizer bans update
## 0.6.1.2
- Various fixes for Custom Goal Framework
- Added custom gfx for Pedestal and Murahdahla
- Re-fixed purple chest follower dupe
- Updated tournament winners texts
## 0.6.1.1
- Fixed issue with Bosses goals in Custom Goal Framework
- Fixed error when using Custom Goals with no extra values
- Added more Custom Goal detail in Spoiler Log
## 0.6.1.0
- New Custom Goal framework (see Customizer.md)
- New 'logic' hint terminology to replace vital/useful terminology
- Removed possibility of duplicated hints
- New fix for hammering pot drops when at sprite limit
- Fixed issue with incorrect Ganon silvers hint
- Fixed issue with Locksmith despawning after purple chest if a follower is stored
- Fixed pogdor glitch (frogdor but at PoD entrance and Kiki following)
- Fixed issue with Duck gfx overwriting GT Cutscene gfx
- New CLI argument to allow external generators to supply a custom ROM Header
- Fixed error with extra argument in MultiServer call
- Added new text if Link's House is placed at any Snitch Lady house
## 0.6.0.8
- Re-fixed issue with Old Man spawning on pyramid
- Allowing Zelda to be in TT Prison for follower shuffle escape
- Fixed error with placing Old Man Cave in ER
- Fixed error when plando'ing followers at locations
## 0.6.0.7
- Emergency fix for GT cutscene GFX
## 0.6.0.6
- Added ability to change GT entry cutscene GFX thru customizer
- Chicken as a standing item is no longer a star gfx
- Fix issue in DR with music silence in pre-Aga room
- Other various music fixes
- Fixed issue with Mystery subweights not correctly evaluating boolean settings
## 0.6.0.5
- Emergency fix for map/key totals in non-DR
## 0.6.0.4
- Fixed pause menu to show compass count and prizes to also show if you've seen them
- Fixed crash when Old Man follower exits with you at his destination entrance
- Old Man fetch cave is no longer restricted from exiting at his destination cave in ER
- Kodongo AI is returned to its vanilla behavior in their vanilla rooms
## 0.6.0.3
- Arrghus' Room has water floor restored in boss shuffle
- Fixed no music in Links House when S+Q from Kakariko
- Fixed issue with Boots not showing in pause menu after collection
- Fixed issue with Kiki running away outside the PoD maze
- Fixed issue with Kiki running away when using Quake
- Fixed issue with lingering purple chest after dropping and mirroring
- Getting Locksmith to follow behaves closer to vanilla
- Fixed issue with Locksmith follower despawning after purple chest item get
- Possible fix for prizes getting placed in major locations
- \~Merged in DR v1.4.10~
- Helmacopter fix
## 0.6.0.2
- Fixed issue with item pool placing items on Zelda Drop Off
- Fix issue with infinite purple chest item get
- Fix issue with Kiki running away on i-frame ledge hops
- Fix issue with bad follower gfx on screens with followers
- Fix issue with Zelda appearing in conditional follower locations
## 0.6.0.1
- Emergency fix for generation errors
## 0.6.0.0
- New Follower Shuffle option (See Readme)
- HMG fixes for key pickup behavior
- Fixed some errors with starting equipment
- Added documentation for some unknown/obscure starting inventory options
- Possible fix for ignorable error message for EXE users
- \~Merged in DR v1.4.9~
- Fixed Moth conveyor issue
## 0.5.1.5
- Fixed rare overworld map check VRAM crash
- Fixed cavestate dark room hidden item issue
- Removed dungeon items from hint pool for nearby dungeon items
- Fixed generation error with shopsanity
- Fixed generation error in ER: empty cave lists being added as candidates
## 0.5.1.4
- Fixed incorrect ganon silvers hint
- \~Merged in DR v1.4.8.1~
## 0.5.1.3
- Fixed some minor issues with mystery multiworld
- Corrected some generation issues with Nearby dungeon item shuffles
## 0.5.1.2
- Many fixes to HMG logic, generation, key collection issues
- Fixed issue with In-Dungeon Prizes getting placed in the same dungeon
- Fixed issue with Old Man getting placed outside of DM in glitched modes
- Fixed issue with Free Terrain water transitions not checking for Pearl requirement
## 0.5.1.0 (+ Hotfix 0.5.1.1)
- New "Nearby" Dungeon Item Shuffle option
- Fixed issue with smith follower getting deleted incorrectly on s+q
- Various generation and logic fixes for HMG/NL
- \~Merged in DR v1.4.6.2~
## 0.5.0.6
- New improved Pseudoboots behavior
- Fixed issue with missing Blue Potion in Dark Lake Shop in Inverted
- Various generation and logic fixes for HMG/NL
- Fixed error with prize plando
- Fixed error with District ER
- Added TT Maiden pathing to spoiler log
- Corrected and improved some pathing logic
## 0.5.0.5
- Fixed issue with vanilla HCBK acting like a small key
## 0.5.0.4
- Fixed dark room item gfx
- Fixed dungeon item pickup behavior in cross-dungeon glitched scenarios
- \~Merged in DR v1.4.6~
- Fixed Sanc & Quit behavior
## 0.5.0.3
- Fixed crash on pedestal
## 0.5.0.2
- \~Merged in DR v1.4.5~
- ER - SW Shuffle Options
- ER - Linked Drops Options
- Many GFX fixes
- Fixes to MSU/music
- No longer delete smith with prize shuffle
- Fixed screen scroll issue in Zora's Domain
- Fixed HUD when drawing A items on DR menu
## 0.5.0.1
- Fixed HP refill interrupting boss cutscenes
- Fixed incorrect compass counts in Prize Shuffle
- Various QoL to Prize Shuffle for less confusion on map checks
- Color-blind support for red crystals (item receipt and map check)
- Added X icon on flute map to indicate you can cancel out of flute menu (Flute Shuffle only)
## 0.5.0.0
- Overworld Map Check has been overhauled
- Dungeon Prize Indicators have changed: P/C no longer display, replaced by G/B/R/1-7
- New Mode: Prize Shuffle
- Death Mountain Return Cave and Paradox Cave (Top) are no longer bunny passable
- \~Merged in DR v1.4.1.12~
## 0.4.0.2
- Fixed issue with Inverted GT entrance not opening
- Potential fox for bonk items duplicating onto other OW items
## 0.4.0.1
- \~Merged in DR v1.4.1.10~
- Fixed issue with bonk items for MW players
- Fixed fake world issues in Glitched modes
- Fixed issue with Flute getting canceled in OWR Layout modes
- Various GFX Fixes
## 0.4.0.0
- Fully merged big base ROM changes from upstream, including FastROM
- \~Merged up to date with DR v1.4.1.8~
- Various GFX re-implementation including new GFX for bee traps, bomb bags, etc.
## 0.3.4.2
- Added Shuffle SFX Instruments as post-gen option
- Fixed some issues with Swapped ER failing to place Old Man Cave
- Changed Inverted 2.0 spawn prompt to display Bomb Shop
- Fixed some minor issues with ER and Vanilla GT
## 0.3.4.1
- Implemented new District ER mode option
- Added alternate boss logic when in GT Ice Basement
- Updated Inverted 2.0 to start in Bomb Shop regardless of ER mode
- Fixed broken customizer features with OWR Tile Flip
- Allowing Insanity ER + Standard to decouple standard entrances
## 0.3.4.0
- \~Merged in DR v1.2.0.23~
- Improved bunny-walking algorithm
- Improved multiworld balancing
- \~Merged in some things from DR v1.4.0.0-v~
- Implemented Hybrid Major Glitches logic (thanks Muffins/Espeon)
- Added sparkles to Bonk Drop locations for better visibility
- Some tweaks/improvements to Shuffle Song Instruments
- Replaced Save Settings on Exit with Settings on Load
- Added new button in GUI to export a Yaml file based on current settings
- Allow starting Aga-Defeated and Old-Man-Rescued in inventory
## 0.3.3.2
- \~Merged in DR v1.2.0.22~
- Added Shuffle Song Instruments as post-gen option
- Allow user to change and save output directory within the GUI
- Fixed issue with Smith not deleting on S+Q when no path is possible
- Fixed various MSU inaccuracies
## 0.3.3.1
- \~Merged in DR v1.2.0.21~
- Fixed issue with Old Man death spawning on Pyramid/Castle
- Fixed issue with Mixed OWR + Flute Shuffle placing spots on large screens
- Fixed issue with mirror portals disappearing in Crossed OWR
- Added more OWR preset yamls + some fixes to the existing ones
## 0.3.3.0
- Added Customizer support for all remaining OWR options
- Added several OWR preset yamls (many ideas are thanks to Catobat)
- Removed Limited Crossed OWR and renamed Chaos Crossed to Unrestricted Crossed
## 0.3.2.2
- Added Customizer support for Flute Shuffle (thanks Catobat)
- Fixed bad Old Man rescue possibility in Swapped ER
- Fixed vanilla placement issue in Swapped ER
- Removed entrance hints in Swapped ER
- Fixed various generation/validation errors
## 0.3.2.1
- \~Merged in DR v1.2.0.20~
- Some minor Swapped ER improvements
- Fixed generation error with Flute Activation
## 0.3.2.0
- New Swapped ER mode option
- Fixed issue with flipper rules not properly getting pearl requirement added
- Fixed minor issues in generating non-crossed ER on subsequent attempts
## 0.3.1.2
- Retro now gives a universal key from bottle vendor fish prize
- Fixed issue with Aga Door preventing Murahduhla Cutscene
- Fixed issue with Ice Cave/Shopping Mall water transitions not flipping in Mixed OWR
- Minor improvements to item GFX draw routine
## 0.3.1.1
- \~Merged in DR v1.2.0.17~
- Various renames/reorganizations of region/rule definition to match upcoming DR world remodel
- Minor improvements to item GFX draw routine
- Minor change to terrain/logic of Spiral/Mimic Ledge in Inverted 2.0
## 0.3.1.0
- Added new Triforce Cutscene when getting Triforce item (turning in TF Pieces)
- Fixed issue with enemy key drops displaying the wrong GFX
- Fixed issue with boss music playing in Hera after boss is defeated
- Fixed issue that limited the Bonk count to cap at 99
- Made Murahdahla interactable on Pyramid in Rainstate
## 0.3.0.8
- All Bonk prize GFX are no longer using the Power Star placeholder GFX
- Fixed issue with dislaying Key GFX during tablet animations
- Fixed issue with DPad input being disabled in Pause Menu if an item GFX is on screen
## 0.3.0.7
- \~Merged in DR v1.2.0.16~
- Major overhaul of how item GFX are drawn on screen
- Bonk prize GFX can now all be displayed simultaneously
- Rupee items that are in-plain-sight are now animated
- Narrow items are now centered within their tile space
- Fixed issue with pottery items showing bad GFX after map check or medallion use
- Fixed issue with bonk drop items causing duplicate sprite spawns
## 0.3.0.6
- \~Merged in DR v1.2.0.15~
- Fixed Tower of Hera music silence issue
- Improved symmetrical GT crystal cutscene
- Changed bonk prizes to not mark as collected unless it is visible on screen
## 0.3.0.5
- Major reorganization to GUI Options
- Corrected various fake world behavior in glitched modes
- Fixed various issues with glitched mode logic
- Various minor logic fixes
## 0.3.0.4
- \~Merged in DR v1.2.0.14~
- Fixed issue with enemy drops on OW enemies
- Fixed issue with magically opened doors
- Inverted + Vanilla ER can now generate
- Fixed issue with Multiworld bonk items not sending to correct player
- Minor improvements to OW Palettes on screen transition
## 0.3.0.3
- Fixed issue with new Cold Fairy Statue location not dropping correct item
- Fixed issue with Multiworld due to new Cold Fairy Statue location
- Improved water collision to only target Heart Piece sprites (rando items)
## 0.3.0.2
- \~Merged in DR v1.2.0.12~
- Fixed some door landing issues
- Added Cold Fairy Statue as a new Bonk Location in Bonk Drop Shuffle
- Added Customizer support for enabling OWR Options
- Removed `Arrows (5)` item from Item Table, replaces with `Arrows (10)`
## 0.3.0.1
- \~Merged in DR v1.2.0.10~
- Fixed some door landing issues
- Added Customizer support for OWR Tile Flips
- Added 'Standard+Inverted' template customizer yaml
- Fixed some ER issues with placing Sanc Drop in non-crossed ER
## 0.3.0.0
- \~Merged in all DR Customizer features since its initial release up to v1.2.0.9~
- Major revamp of Aerinon's ER 2.0 to better support OWR modes
- Fixed various incorrect logic issues (Inverted flute spots, Bomb Shop start, etc)
- Flute is disabled in rain state except glitched modes
## 0.2.11.4
- Fixed broken OWG logic issues
- Gave chickens a base price for shopsanity
- Modeled TR entrance opening to use a logical pseudo-item
## 0.2.11.3
- Fixed error during multiworld generation
- Added proper Old Man pathing to the logic and spoiler playthru
- Removed the delay in spawning sprites when bonking items out of bonk locations
- Removed useless hints in Lite/Lean ER that are already categorically assumed
- Added GT and Links House entrance hints when either are shuffled in the pool
## 0.2.11.2
- Implemented proper Districting with Mixed OWR, affecting Hints and District modes
- Suppressed item locations in spoiler log that are junk or logical
## 0.2.11.1
- Renamed mode: Tile Swap (Mixed) is now called Tile Flip (Mixed)
- Fixed generation errors due to issue with new Farmable item locations
## 0.2.11.0
- New OWR mode option: Free Terrain
- When used with OW Layout Shuffle, land and water transitions are combined into one pool and shuffled, this means land transitions can lead to water and vice versa. There is already tracker support for this change on DunkaTracker. Thanks @Catobat for the work on all of this.
- Glitched modes now have correct fake world behavior in all modes, including Inverted and even Mixed OWR
- Glitched + Mixed OWR now has correct logic (previously it was completely unimplemented)
- Lite ER is back and working!
- There was an issue with ER resulting in regions being inaccessible, this has been fixed.
- Changed Crossworld ER modes so that DW inaccessible areas are resolved before considering LW inaccessible areas, to give the algo a chance to make some of the LW areas accessible thru the DW
- Added new Bomb/Rupee farm logic, which uses pseudo-items, simplifies the graph searching and they even show up in the Playthru Calc (shows a logical path to Farmable Bombs if you ever question how you are able to get early bombs when the opening area is limited)
- Fixed issue with grabbing an item near Murahduhla and freezing the game
- Various logic corrections, including the DR Bumper Cave fix for pottery logic
## 0.2.10.1
- \~Merged v1.0.1.3~
- Fixed Zelda despawn in TT Prison
- Fixed issue with key door usage in rainstate
- Added missing modes to example mystery yaml
## 0.2.10.0
- \~Merged v1.0.1.1-1.0.1.2~
- Removed text color from hint tiles
- Removed Good Bee requirement from Mothula
- Some keylogic/generation fixes
- Fixed a Pottery logic issue in the playthru
- Fixed a generation error in Mixed OWR, resulting in more possible Mixed scenarios (thanks Catobat)
- Added more scenarios where OW Map Checks in Mixed OWR show dungeon prizes in their respective worlds
- Fixed rupee logic to consider Pottery option and lack of early rupees
- Changed Lean ER + Inverted Dark Chapel start is guaranteed to be in DW
- Fixed graphical issue with Hammerpeg Cave
- Fixed logic rule with HC Main Gate to not require mirror if screen is swapped
- Removed Crossed OWR option: "None (Allowed)"
### 0.2.9.1
- Lite/Lean ER now includes Cave Pot locations with various Pottery options
- Changed Unique Boss Shuffle so that GT Bosses are unique amongst themselves
- Changed MSU-1 in Inverted to trigger DW2 track with Aga1 kill and LW2 with 7 crystals
- Fixed disappearing mirror portal issue in Inverted (Hopefully for good)
- Fixed issue with TR Peg Puzzle not spawning portal in some Mixed OWR scenarios
- Removed ability to roll Myserty with phantom Crossed OWR options
### 0.2.9.0
- Added Bonk Drop Shuffle
- Fixed disappearing mirror portal issue in Inverted+Crossed OWR
- Fixed 4-digit collection rate in credits
- Fixed Ganon vulnerability to reference Aga2 boss flag rather than pyramid hole
- Fixed issue with pre-opened pyramid when not expected
### 0.2.8.0
- \~Merged DR v1.0.1.0 - Pottery options, BPS support, MSU Resume, Collection Rate Counter~
- Various improvements to increase generation success rate and reduce generation time
- Fixed issue with playthru recognizing Aga accessibility
- Fixed issue with applying rules correctly to Murahdahla, fixing Murahdahla+Beatable issues
- Fixed issue with Flute+Rainstate, flute use is no longer in logic until Zelda is delivered
### 0.2.7.3
- Restructured OWR algorithm to include some additional scenarios not previously allowed
- Added new Inverted D-pad controls for Social Distortion (ie. Mirror Mode) support
- Crossed OWR/Special OW Areas are now included in the spoiler log
- Fixed default TF pieces with Trinity in Mystery
- Added bush crabs to rupee farm logic (only in non-enemizer)
- Updated tree pull logic to also require ability to kill most things
### 0.2.7.2
- Special OW Areas are now shuffled in Layout Shuffle (Zora/Hobo/Pedestal)
- Fixed some broken water region graph modelling, fixed some reachability logic
- Some minor code simplifications
### 0.2.7.1
- Map checks in Mixed OWR now will show the proper tile images when screens are swapped (ie. Pyramid shows in the LW if that screen is swapped)
- Added mystery seed number to spoiler log, so it is easier to match a spoiler log to a rom filename
- Added proper branch-specific versioning (ie. Dev branch has '-u' suffixing the version number while Release/Main branch does not)
### 0.2.7.0
- \~Merged DR v1.0.0.3 - MANY changes, major things listed below~
- New Item Fills (Districts/Vanilla/Major Location/Dungeon)
- New OW Map Prize Indicators (In ER, map checks can spoil dungeon locations with a user setting)
- Forbidden Boss Items (Exclude certain dungeon items from dropping on bosses)
- Map checks in Mixed OWR now will show dungeon prizes for dungeons actually in the world you map check on
- In Mixed OWR, Sanc screen must stay in LW if the starting location is guaranteed to exit at the Sanc entrance
- Fixed various issues with Flute logic
- Fixed issue that resulted in infinite loops in Flute Shuffle
- Changed map in attract mode to always show a vanilla LW map
- Various improvements to increase generation success rate
### 0.2.6.1
- Fixed issue with mirror bonking deleting portal in Crossed OW
- Fixed issue with mirror portal not spawning when entering the OW from the DW, in Crossed OW
- Updated some text with proper capitalization/spacing
- Updated tournament winners text
### 0.2.6.0
- New text engine font!
- Fixed invisible Witch item bug
- Added 'O' to ROM Header for autotrackers
- Fixed generation error with Shopsanity + OWR Layout
- Fixed OWR validation error with Insanity ER + OWR Layout
- Fixed issue with TR Peg Puzzle not spawning a valid portal
### 0.2.5.3
- Changed AT/GT Swap to favor vanilla, only swapping if GT entrance is the only choice in starting world
- Fixed issue with Links House not swapping in OW Mixed
- Added Flute Spots to spoiler log
- Fixed issue with Light Hype Fairy excluded from bombable door list
### 0.2.5.1
- Fixed missing rule for Inverted VoO Portal access
### 0.2.5.0
- Many updates to Inverted OW Terrain:
- Links House start now spawns in Big Bomb Shop
- Old Man Cave/Bumper Cave returned to vanilla
- Mountain Cave S+Q now spawns in his usual Cave
- Flute Spot 1 is moved to Top of Dark Death Mountain
- Ladder is removed from West Dark Death Mountain
- When finding Flute, it comes pre-activated (will hear SFX on collecting)
- Spiral and Mimic Cave are now bridged together
- TR Peg Puzzle is restored but instead reveals a ladder
- Houlihan now exits same place as Big Bomb Shop does (OWR branch always had this)
- Ice Palace has been re-sealed to vanilla, portal moved to outer edge of moat
- Glitched modes will now use vanilla terrain except where necessary
- Fixed errors with OW Layout Shuffle
- Fixed issue with incorrect Mirror bonking
- Fixed issue with old man follower death to Pyramid
- Fixed Hera boss music not playing when boss not defeated
- \~Merged DR v0.5.1.7 - TT boss trap door fix/Applied Glitched flag~
### 0.2.4.0
- Added Guaranteed OWR Reachability
- Fixed incorrect parity calc for Whirlpool Shuffle
- Fixed error with generating seeds with GUI
- CLI fixes for triforce piece arguments
### 0.2.3.6
- Added Trinity goal (8/10 default TF pieces)
- Many improvements to TFH pool allocation
- Fixed some issues with Multiworld generation with Custom Item Pools
### 0.2.3.5
- Fixed issue with multiworld generation
- Added infinite loop detection
- Move mirror portal off screen during mirror bonk in Crossed OW
### 0.2.3.4
- Fixed major issue with subsequent seeds using same seed/settings resulting different
- Flute Shuffle now awards separated regions a prorated number of flute spots based on size
- Fixed spoiler log, was missing OW Tile Swap map
- Fixed spoiler log JSON output
- Fake flipper damage fix improved to skip the long delay after the scroll
- Fixed missing Blue Potion in Lake Shop in Inverted
- Added legacy OW Crossed option 'None (Allowed)' to support old behavior when invalid option was used in Mystery
- \~Merged DR v0.5.1.6 - Money balancing fix/Boss logic fixes with Bombbag~
### 0.2.3.3
- Added OW Layout validation that reduces the cases where some screens are unreachable
- Fixed issue with mirror portals showing up in DW in Crossed OW
- Corrected Lost/Skull Woods Pass regions to be more accurate
### 0.2.3.0/1/2
- Fixed issue in Crossed OW where mirror portal sprites would disappear when changing worlds
- Added Big Red Bomb logic to support using residual mirror portals for later re-entry
- Suppressed irrelevant paths in spoiler playthru
- Suppressed identical paths in spoiler playthru if multiple locations within the same region contain progression
### 0.2.2.3
- Fixed GT entrance not being opened when Inverted and WDM is Tile Swapped
- The Goal sign is moved to the area where the hole will be (always in opposite world as starting)
### 0.2.2.2
- Fixed Whirlpool Shuffle with Grouped Crossed OW
- Made filename not spoil OWR in Mystery
- Fixed Triforce Hunt goal
### 0.2.2.1
- Allow normal Link speed with Old Man following if not in his cave or WDM
- Fixed issue with Flute exits not getting placed on the correct tiles
- Hints in Lite/Lean ER no longer refer to entrances that are guaranteed vanilla
- Added Links House entrance to hint candidate list in ER when it is shuffled
- Added Tile Swaps ASCII map to Spoiler Log when Tile Swap is enabled
- Fixed issue with Whirlpool Shuffle not abiding by Polar rules
### 0.2.2.0
- Delivering Big Red Bomb is now in logic
- Smith/Purple Chest have proper dynamic pathing to fix logical issues
- Fixed issue with bomb walls in OW not requiring moon pearl in DW
### 0.2.1.3
- New fake flipper handling to allow S+Q rather than insta-kill
- Fixed whirlpools in Crossed OW
- Spoiler fixes, incl. missing Starting Inventory in Spoiler
- Fixed music track change to Sanc music when Standard mode is delivering Zelda
- Fixed SP flooding issue
- Fixed issue with Shuffle Ganon in CLI/GUI
- \~Merged DR v0.5.1.5 - Mystery subweights~
### 0.2.1.2
- Fixed issue with whirlpools not changing world when in Crossed OW
### 0.2.1.1
- Many fixes to ER: infinite loops, preventing cross-world scenarios in non-cross-world modes
- Spoiler log improvements, outputs in stages so a Spoiler is available if an error occurs
- Added no_race option for Mystery
- Fixed output_path in Mystery to use the saved setting if none is specified on CLI
### 0.2.1.0
- Implemented Whirlpool Shuffle
### 0.2.0.0
- Massive overhaul of ER algorithm
- Added 2 new ER modes (Lite and Lean)
- Added new mystery options (Logic/Shuffle Ganon)
- Smith deletion on S+Q only occurs if Blacksmith not reachable from starting locations
- Spoiler log improvements to prevent spoiling in the beginning 'meta' section
- Various minor fixes and improvements
- \~Merged DR v0.5.1.4 - ROM bug fixes/keylogic improvements~
### 0.1.9.4
- Hotfix for bad 0.1.9.3 version
### 0.1.9.3
- Moved flute spot from Northwest Lake Hylia to Southeast Lake Hylia
- Fixed Links House start in Inverted ER
- Minor accuracy improvements to ER, mostly preparations for future work
### 0.1.9.2
- Fixed spoiler log and mystery for new Crossed/Mixed structure
- Minor preparations and tweaks to ER framework (added global Entrance/Exit pool)
- \~Merged DR v0.5.1.2 - Blind Prison shuffled outside TT/Keylogic Improvements~
### 0.1.9.1
- Fixed logic issue with leaving IP entrance not requiring flippers
- \~Merged DR v0.5.1.1 - Map Indicator Fix/Boss Shuffle Bias/Shop Hints~
### 0.1.9.0
- Expanded Crossed OW to four separate options, see Readme for details
- Crossed OW will now play a short SFX when changing worlds
- Improved Link/Bunny state in Crossed OW
- Fixed issue with TR Pegs when fluting directly from an area with hammerpegs
- Updated OW GUI layout
### 0.1.8.2
- Fixed issue with game crashing on using Flute
- Fixed issues with Link/Bunny state in Crossed OW
- Fixed issue with Standard+Parallel not using vanilla connections for Escape
- Fixed issue with Mystery for OW boolean options
- \~Merged DR v0.5.1.0 - Major Keylogic Update~
### 0.1.8.1
- Fixed issue with activating flute in DW (OW Mixed)
- Fixed issue with Parallel+Crossed not generating
- Fixed issue with Standard not generating
- Fixed issue with Swordless not generating
- Fixed logic for Graveyard Ledge and Kings Tomb
### 0.1.8.0
- Moved Crossed to its own checkbox option
- Removed Legacy ER shuffles
- Added OW Shuffle support for Plando module (needs user testing)
- Fixed issue with Sanc start at TR as bunny when it is LW
- Fixed issue with Pyramid Hole not getting shuffled
- \~Merged DR v0.5.0.3 - Minor DR fixes~
### 0.1.7.4
- Fixed issue with Mixed OW failing to generate when HC/Pyramid is swapped
- Various fixes to improve generation rates for Mixed OW Shuffle
- \~Merged DR v0.5.0.2 - Shuffle SFX~
### 0.1.7.3
- Fixed minor issue with ambient SFX stopping and starting on OW screen load
- MSU-1 changed to play LW2 (track 60) when Aga1 is killed instead of ped pull
- Added dynamic flute exits for all LW OW regions
- Improved spoiler log playthru pathing accuracy by including flute routing
- Fixed issue with generating a filename for vanilla OW settings
### 0.1.7.2
- Fixed music algorithm to play correct track in OW Shuffle
- Removed convenient portal on WDM in OW Layout Shuffle
- Fixed Mystery to not spoil OW Shuffle in filename
### 0.1.7.1
- Improved bomb logic to consider tree pulls, bush crabs, and stun prize
- Fixed Mystery to use new updated OW mode terminology
### 0.1.7.0
- Expanded new DR bomb logic to all modes (bomb usage in logic only if there is an unlimited supply of bombs available)
- \~Merged DR v0.5.0.1 - Bombbag mode / Enemizer fixes~
### 0.1.6.9
- \~Merged DR v0.4.0.12 - Secure random update / Credits fix~
### 0.1.6.8
- Implemented a smarter Balanced Flute Shuffle algorithm
- Fixed Collection Rate in credits
- Removed sortedcontainers dependency
### 0.1.6.7
- Mountain Pass and West Death Mountain are now Swapped independently (Old Man rescue is always in your starting world)
- Fixed issue with AT/GT access logic
- Improved spoiler log playthru accuracy
- Fixed Boss Music when boss room is entered thru straight stairs
- Suppressed in-dungeon music changes when DR is enabled
- Fixed issue with Pyramid Exit exiting to wrong location in ER
- \~Merged DR v0.4.0.11 - Various DR changes~
### 0.1.6.6
- \~Merged DR v0.4.0.9 - P/C Indicator / Credits fix / CLI Hints Fix~
### 0.1.6.5
- Reduced chance of diagonal flute spot in Balanced
- \~Merged DR v0.4.0.8 - Boss Indicator / Psuedo Boots / Quickswap Update / Credits Updates~
### 0.1.6.4
- Fixed Frogsmith and Stumpy and restored progression in these locations
- Added Blacksmith/Hammer Pegs to OW Tile Swap pool
### 0.1.6.3
- Fixed borked credits (and missing Sprite Author) when collection rate isn't 216 or if GTBK count isn't /22
- Added OW Rando in credits
- Actually merged in DR v0.4.0.7 (with no thanks to GitHub)
### 0.1.6.2
- Added Balanced option for Flute Shuffle
- Fixed issue with Flute Spot to Mountain Pass softlocking
- Fixed logic bug with Inverted Kakariko Portal
### 0.1.6.1
- Fixed issue with Flute Spot to VoO softlocking
- Fixed Houlihan to exit where Link's House does
- Fixed issue with jsonout not correctly showing rom mods for some OW Shuffle data
### 0.1.6.0
- Added Flute Shuffle setting
- Minor GUI changes
### 0.1.5.3
- Fixed issue with Aga portal mirror bonking in Mixed Shuffle
- Fixed issue with Frog/Dig Game edges duplicating in edge pool, causing Insanity-like behavior
### 0.1.5.2
- Partial revert of horizontal VRAM fix from v0.1.5.0
### 0.1.5.1
- Fixed issue with Flute Spot 7 logically connecting to the wrong area in Mixed/Crossed OW Shuffle
- Fixed issue with TR portal not requiring mitts when tile is swapped
### 0.1.5.0
- Added OW Tile Swap setting
- Fixed horizontal VRAM visual loading glitch on megatiles
- ~\~Merged DR v0.4.0.7 - Fast Credits / Reduced Flashing / Sprite Author in Credits~~ Didn't fully merge
### 0.1.4.3
- \~Merged DR v0.4.0.6 - TT Maiden Attic Hint / DR Entrance Floor Mat Mods / Hard/Expert Item Pool Fix~
### 0.1.4.2
- Modified various OW map terrain specific to OW Shuffle
- Changed World check to table-based vs OW ID-based (should have no effect with current modes)
- \~Merged DR v0.4.0.5 - Mystery Boss Shuffle Fix / Swordless+Hard Item Pool Fix / Insanity+Inverted ER Fixes~
### 0.1.4.1
- Moved Inverted Pyramid Entrance to top of HC Ledge
- Fixed various issues with Inverted and Insanity
### 0.1.4.0
- Initial Inverted Implementation
- Fix for Kakariko Pond no longer requiring fake flipper
### 0.1.3.1
- Various logic fixes and region prep for Inverted
- Fixed muted MSU-1 music in door rando when descending GT Climb stairs
- Fixed Standard + Vanilla (thanks compiling)
- \~Merged DR v0.4.0.4 - Shuffle Link's House / Experimental Bunny Start / 10 Bomb Fix~
### 0.1.3.0
- Added OWG Logic for OW Shuffle
- \~Merged DR v0.4.0.2 - OWG Framework / YAML~
### 0.1.2.2
- Re-purposed OW Shuffle setting to Layout Shuffle
- Merged Parallel Worlds setting into Layout Shuffle
- Added guaranteed Flute hint for OW Shuffle modes
### 0.1.2.1
- Made possible fix for Standard
- \~Merged DR v0.3.1.10 - Fixed Standard generation~
### 0.1.2.0
- Added 'Parallel Worlds' toggle option
- Updated shuffle algorithm
- Renamed some OW areas
### 0.1.1.2
- If Link's current position fits within the incoming gap, Link will not get re-centered to the incoming gap
- Added Rule for Pearl required to drop down back of SW
- \~Merged DR v0.3.1.8 - Improved Shopsanity pricing - Fixed Retro generation~
### 0.1.1.1
- Fixed camera unlocking issue
- Changed default setting for DR to Vanilla
### 0.1.1.0
- Added 'Keep Similar Edges Together' toggle option
- Removed Duplicate Pyramid Ledge location, causing a Warning of unfilled location on generation
### 0.1.0.3
- Modified various logic rule for some OW locations
### 0.1.0.2
- Fixed error generating a bad Spoiler log
### 0.1.0.1
- Separated DR versioning from OR versioning
- Removed LW/DW flag toggle on transitions
### 0.1.0.0
- Initial release
+257
View File
@@ -0,0 +1,257 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**ALttPDoorRandomizer** is a sophisticated dungeon and door randomizer for *The Legend of Zelda: A Link to the Past* (SNES). It extends the standard ALTTP Entrance Randomizer with advanced dungeon shuffling capabilities that can rearrange dungeon interiors at the door and sector level.
- **Repository**: https://github.com/aerinon/ALttPDoorRandomizer
- **Python Version**: 3.10+
- **Current Branch**: DoorDevUnstable (dev branch: NewGeneration)
- **Discord**: #door-rando and #bug-reports channels at ALTTP Randomizer discord
## Development Commands
### Running the Randomizer
```bash
# CLI interface
python DungeonRandomizer.py
# GUI interface
python Gui.py
```
### Dependencies
```bash
# Install platform-specific dependencies
python resources/ci/common/local_install.py
# For multiworld server/client
# Run the same command to install multiworld dependencies
```
### Testing
```bash
# Run test suite
python TestSuite.py
# Run test suite with specific door shuffle mode
python TestSuite.py --dr basic --count 10 --tense 2
# Individual test files (unittest-based)
python -m pytest test/
python -m pytest test/dungeons/TestDarkPalace.py
```
### ROM Generation
```bash
# Basic door shuffle seed
python DungeonRandomizer.py --doorShuffle crossed --intensity 2
# Suppress ROM output (for testing)
python DungeonRandomizer.py --suppress_rom --spoiler none
# Create BPS patch
python DungeonRandomizer.py --bps
```
## Architecture Overview
### Generation Pipeline
The randomizer follows this high-level flow (orchestrated in `Main.py`):
1. **World Setup** → Initialize World object, parse settings, set seed
2. **Region Creation** → Build game regions, locations, entrances (`Regions.py`)
3. **Dungeon Structure** → Create dungeon objects and rooms (`Dungeons.py`, `RoomData.py`)
4. **Door/Entrance Shuffling** → Shuffle dungeon interiors and/or overworld entrances
5. **Logic Rules** → Set access requirements for all locations (`Rules.py`)
6**Item Placement** → Generate item pool and place items with logic constraints (`Fill.py`)
7. **ROM Patching** → Apply changes to base ROM (`Rom.py`)
8. **Output** → Generate ROM file, spoiler log, and/or multiworld data
### Core Data Structures (BaseClasses.py)
- **World**: Container for all game state, regions, dungeons, items, and settings
- **Region**: Geographic area with locations and exits
- **Location**: Item placement spot with access rules
- **Item**: Game items with advancement/priority flags
- **Entrance**: Connections between regions with conditional access
- **CollectionState**: Tracks player's collected items for logic evaluation
### Dungeon Generation System
The dungeon shuffling system uses a three-stage algorithm:
#### 1. DungeonGenLocalSearch (source/dungeon/DungeonGenLocalSearch.py)
**Purpose**: Assigns dungeon sectors to dungeons using constraint satisfaction
**Balancing Constraints**:
- **Polarity**: North/South and East/West door balance
- **Crystal Balance**: Blue/orange barriers must have matching switches
- **Portal Balance**: Entrance distribution
- **Location Balance**: Ensures dungeons have accessible non-big-key locations
- **Branching**: Dead ends vs branches ratio (insufficient branches = unreachable areas)
- **Transitivity**: Validates that doors can actually connect
**Algorithm**: Local search with greedy constraint satisfaction, prioritizing crystal switches → portals → locations → branching → polarity → transitivity
#### 2. DungeonGenTransitivity (source/dungeon/DungeonGenTransitivity.py)
**Purpose**: Validates that door connections are possible for a given sector assignment
**Key Features**:
- Verifies all doors can be validly connected (e.g., North↔South, East↔West, Stairs↔Stairs)
- Propagates crystal switch states through connections
- Detects forced connections and impossible layouts
- Uses depth-first search with constraint propagation
- Handles special mechanics (portals, crystal barriers, special rooms)
#### 3. DungeonStitcherV2 (source/dungeon/DungeonStitcherV2.py)
**Purpose**: Realizes actual door connections from validated sector assignments
**Key Features**:
- Generates random valid door pairings
- Assigns portal connections (dungeon entrances)
- Simulates player traversal to verify connectivity
- Manages crystal barrier state propagation
### Key Logic Components
**Rules.py** (~7000 lines): Sets logical requirements for accessing locations
- Supports multiple logic modes: noglitches, owglitches, hybridglitches, nologic
- Handles multiple key logic algorithms: partial, strict, dangerous, experimental
- Manages dungeon-specific access rules and boss requirements
**Fill.py** (~2000 lines): Item placement algorithms
- **Balanced**: Random distribution
- **Vanilla Fill**: Attempts vanilla item locations when possible
- **Major Location Restriction**: Major items → major locations
- **Dungeon Restriction**: Major items → dungeons
- **District Restriction**: Items distributed by geographic region
**KeyPlacement.py** / **NewKeyLogic.py**: Advanced key door logic
- Handles small key placement with multiple satisfiability algorithms
- Prevents self-locking situations
- Manages big key placement rules
- Validates minimum key requirements for dungeon completion
### Source Module Organization
```
source/
├── dungeon/ # Dungeon generation algorithms and key logic
├── overworld/ # Entrance shuffling (EntranceShuffle2.py)
├── item/ # Item placement utilities (FillUtil.py, District.py)
├── enemizer/ # Enemy randomization system
├── gui/ # GUI components (tkinter-based)
├── rom/ # ROM patching utilities
├── classes/ # Utility classes (BabelFish, CustomSettings)
├── meta/ # Metadata and build tools
└── limited/ # Limited run coordination
```
### Important Files by Size/Complexity
- **DoorShuffle.py** (~8500 lines): Door shuffling orchestration
- **Rules.py** (~7000 lines): Location access logic
- **EnemyList.py** (~6000 lines): Enemy definitions
- **Doors.py** (~5500 lines): Door object definitions
- **Rom.py** (~5500 lines): ROM patching
- **Regions.py** (~5000 lines): World region creation
- **DungeonGenerator.py** (~5000 lines): Legacy dungeon generation
- **EntranceShuffle2.py** (~5000 lines): Entrance shuffling logic
- **BaseClasses.py** (~4000 lines): Core data structures
- **KeyDoorShuffle.py** (~3500 lines): Key door logic
- **PotShuffle.py** (~3500 lines): Pot randomization
## Key Concepts
### Door Shuffle Modes
- **Vanilla**: No shuffling
- **Basic**: Shuffle within each dungeon
- **Partitioned**: Shuffle in pools (Light World, Early Dark World, Late Dark World)
- **Crossed**: Full shuffle between all dungeons
### Intensity Levels
- **Level 1**: Normal doors and spiral staircases
- **Level 2**: + open edges and straight staircases
- **Level 3**: + dungeon lobbies
### Key Shuffle Modes
- **In Dungeon** (keyshuffle=none): Keys restricted to their dungeon
- **Randomized** (keyshuffle=wild): Keys can be anywhere
- **Universal** (keyshuffle=universal): Keys work in any dungeon
### Fill Algorithms (--algorithm)
See Fill.py for implementation details. The algorithm affect where item may be placed.
### Logic Modes
- **noglitches**: Standard logic
- **owglitches**: Overworld glitches (OOB, clips, superbunny)
- **hybridglitches**: + major underworld glitches (not compatible with door shuffle)
- **nologic**: No logical constraints
## Testing Strategy
Tests verify location accessibility with various item combinations:
- **test/dungeons/**: Per-dungeon location access tests
- **test/vanilla/**: Vanilla world logic tests
- **test/owg/**: Overworld glitch logic tests
- **test/inverted/**: Inverted mode tests
- **TestBase.py**: Base test class with utility methods
Use `TestSuite.py` for batch generation testing across modes (Open/Standard/Inverted) and settings.
## Important Development Notes
### Starting Items & Special Items
- **Mirror Scroll**: Dungeon-only mirror (starting item in door shuffle)
- **Bomb Bag**: Optional item that gates bomb usage
- **Pseudo Boots**: Allows dashing but gates certain sequence breaks
### Branch Structure
- **DoorDev**: Main development branch (use for PRs)
- **DoorDevUnstable**: Current working branch
- **Dev/Master**: Do NOT use for PRs
### Git Workflow
Recent commits show work on:
- Limited run coordination
- Custom rooms support
- Key logic improvements (transitivity, portal checks, placement rules)
- Isolated region detection fixes
- Big key placement satisfiability
### Documentation Resources
- **Algorithm.md**: Detailed dungeon generation algorithm documentation
- **docs/ai_context/**: Comprehensive architectural documentation by topic
- **docs/Customizer.md**: Custom seed configuration guide
- **docs/DR_hint_reference.md**: Hint system documentation
- **docs/BUILDING.md**: Build and installation instructions
- **README.md**: User-facing feature documentation
## Common Gotchas
1. **Transitivity Checks**: Most expensive constraint check - always run last
2. **Self-Locking Keys**: Key logic must prevent situations where players cannot access the rest of the dungeon
3. **Crystal Barriers**: Blue/orange barriers require matching switches in dungeon
4. **Portal Distribution**: Each dungeon needs at least one entrance
5. **Branching Balance**: Too many dead ends without branches = unreachable areas
6**Polarity Balance**: N/S and E/W door counts must allow valid connections
## CLI Argument Reference
Key arguments from `resources/app/cli/args.json`:
- `--doorShuffle [vanilla|basic|partitioned|crossed]`
- `--intensity [1|2|3]`
- `--keyshuffle [none|wild|universal]`
- `--key_logic [partial|strict|dangerous|experimental]`
- `--algorithm [balanced|vanilla_fill|major_only|dungeon_only|district]`
- `--logic [noglitches|owglitches|hybridglitches|nologic]`
- `--mode [open|standard|inverted]`
- `--shuffle`: Entrance randomizer options (vanilla, simple, restricted, full, crossed, insanity, etc.)
- `--pottery`: Pot shuffling modes
- `--shopsanity`: Enable shop item randomization
- `--enemizer`: Enemy randomization options
+487
View File
@@ -0,0 +1,487 @@
import argparse
import copy
import json
import os
import shlex
import sys
import textwrap
from source.classes.BabelFish import BabelFish
from source.classes.CustomSettings import CustomSettings
from Utils import update_deprecated_args
class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
def _get_help_string(self, action):
return textwrap.dedent(action.help)
def parse_cli(argv, no_defaults=False):
def defval(value):
return value if not no_defaults else None
# get settings
settings = parse_settings()
lang = "en"
fish = BabelFish(lang=lang)
# we need to know how many players we have first
# also if we're loading our own settings file, we should do that now
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--settingsfile', help="input json file of settings", type=str)
parser.add_argument('--multi', default=defval(settings["multi"]), type=lambda value: min(max(int(value), 1), 255))
parser.add_argument('--customizer', help='input yaml file for customizations', type=str)
parser.add_argument('--print_template_yaml', help='print example yaml for current settings',
default=False, action="store_true")
parser.add_argument('--print_custom_yaml', help='print example plando yaml for current settings and placements',
default=False, action="store_true")
parser.add_argument('--mystery', dest="mystery", default=False, action="store_true")
multiargs, _ = parser.parse_known_args(argv)
if multiargs.settingsfile:
settings = apply_settings_file(settings, multiargs.settingsfile)
player_num = multiargs.multi
if multiargs.customizer:
custom = CustomSettings()
custom.load_yaml(multiargs.customizer)
cp = custom.determine_players()
if cp:
player_num = cp
parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
# get args
args = []
with open(os.path.join("resources", "app", "cli", "args.json")) as argsFile:
args = json.load(argsFile)
for arg in args:
argdata = args[arg]
argname = "--" + arg
argatts = {}
argatts["help"] = "(default: %(default)s)"
if "action" in argdata:
argatts["action"] = argdata["action"]
if "choices" in argdata:
argatts["choices"] = argdata["choices"]
argatts["const"] = argdata["choices"][0]
argatts["default"] = argdata["choices"][0]
argatts["nargs"] = "?"
if arg in settings:
default = settings[arg]
if "type" in argdata and argdata["type"] == "bool":
default = settings[arg] != 0
argatts["default"] = defval(default)
arghelp = fish.translate("cli", "help", arg)
if "help" in argdata and argdata["help"] == "suppress":
argatts["help"] = argparse.SUPPRESS
elif not isinstance(arghelp, str):
argatts["help"] = '\n'.join(arghelp).replace("\\'", "'")
else:
argatts["help"] = arghelp + " " + argatts["help"]
parser.add_argument(argname, **argatts)
parser.add_argument('--seed', default=defval(int(settings["seed"]) if settings["seed"] != "" and settings["seed"] is not None else None), help="\n".join(fish.translate("cli", "help", "seed")), type=int)
parser.add_argument('--count', default=defval(int(settings["count"]) if settings["count"] != "" and settings["count"] is not None else 1), help="\n".join(fish.translate("cli", "help", "count")), type=int)
parser.add_argument('--tries', default=defval(int(settings["tries"]) if settings["tries"] != "" and settings["tries"] is not None else 1), help="\n".join(fish.translate("cli", "help", "tries")), type=int)
parser.add_argument('--customitemarray', default={}, help=argparse.SUPPRESS)
# included for backwards compatibility
parser.add_argument('--multi', default=defval(settings["multi"]), type=lambda value: min(max(int(value), 1), 255))
parser.add_argument('--securerandom', default=defval(settings["securerandom"]), action='store_true')
parser.add_argument('--teams', default=defval(1), type=lambda value: max(int(value), 1))
parser.add_argument('--settingsfile', dest="filename", help="input json file of settings", type=str)
parser.add_argument('--customizer', dest="customizer", help='input yaml file for customizations', type=str)
parser.add_argument('--print_template_yaml', dest="print_template_yaml", default=False, action="store_true")
parser.add_argument('--print_custom_yaml', dest="print_custom_yaml", default=False, action="store_true")
if player_num:
for player in range(1, player_num + 1):
parser.add_argument(f'--p{player}', default=defval(''), help=argparse.SUPPRESS)
ret = parser.parse_args(argv)
if ret.keysanity:
ret.mapshuffle, ret.compassshuffle, ret.keyshuffle, ret.bigkeyshuffle = ['wild'] * 4
if ret.keydropshuffle:
ret.dropshuffle = 'keys' if ret.dropshuffle == 'none' else ret.dropshuffle
ret.pottery = 'keys' if ret.pottery == 'none' else ret.pottery
if ret.retro or ret.mode == 'retro':
if ret.bow_mode == 'progressive':
ret.bow_mode = 'retro'
elif ret.bow_mode == 'silvers':
ret.bow_mode = 'retro_silvers'
ret.take_any = 'random' if ret.take_any == 'none' else ret.take_any
ret.keyshuffle = 'universal'
if ret.ow_unparallel:
ret.ow_parallel = False
if ret.ow_shuffle == 'parallel':
ret.ow_layout = 'wild'
ret.ow_parallel = True
elif ret.ow_shuffle == 'full':
ret.ow_layout = 'wild'
ret.ow_parallel = False
if ret.ow_no_fog:
ret.ow_fog = False
if player_num:
defaults = copy.deepcopy(ret)
for player in range(1, player_num + 1):
playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True)
if playerargs.filename:
playersettings = apply_settings_file({}, playerargs.filename)
for k, v in playersettings.items():
setattr(playerargs, k, v)
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty',
'item_functionality', 'ow_shuffle', 'ow_layout',
'ow_parallel', 'ow_terrain', 'ow_crossed',
'ow_keepsimilar', 'ow_mixed', 'ow_whirlpool',
'ow_fluteshuffle', 'ow_fog', 'flute_mode', 'bow_mode',
'take_any', 'boots_hint', 'shuffle_followers',
'shuffle', 'door_shuffle', 'intensity',
'crystals_ganon', 'crystals_gt', 'bosses_ganon',
'bosshunt_include_agas', 'ganon_item', 'openpyramid',
'mapshuffle', 'compassshuffle', 'keyshuffle',
'bigkeyshuffle', 'prizeshuffle', 'showloot', 'showmap',
'startinventory', 'usestartinventory', 'bombbag',
'shuffleganon', 'overworld_map', 'restrict_boss_items',
'triforce_max_difference', 'triforce_pool_min',
'triforce_pool_max', 'triforce_goal_min',
'triforce_goal_max', 'triforce_min_difference',
'triforce_goal', 'triforce_pool', 'shufflelinks',
'shuffletavern', 'skullwoods', 'linked_drops',
'pseudoboots', 'mirrorscroll', 'dark_rooms',
'damage_challenge', 'shuffle_damage_table',
'crystal_book', 'retro', 'accessibility', 'hints',
'beemizer', 'experimental', 'dungeon_counters',
'shufflebosses', 'shuffleenemies', 'enemy_health',
'enemy_damage', 'shufflepots', 'ow_palettes',
'uw_palettes', 'sprite', 'triforce_gfx', 'disablemusic',
'quickswap', 'fastmenu', 'heartcolor', 'heartbeep',
'remote_items', 'shopsanity', 'dropshuffle', 'pottery',
'keydropshuffle', 'mixed_travel',
'standardize_palettes', 'code', 'reduce_flashing',
'shuffle_sfx', 'shuffle_sfxinstruments',
'shuffle_songinstruments', 'msu_resume',
'collection_rate', 'colorizepots', 'decoupledoors',
'door_type_mode', 'bonk_drops', 'trap_door_mode',
'key_logic_algorithm', 'door_self_loops',
'any_enemy_logic', 'aga_randomness', 'money_balance']:
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
if player == 1:
setattr(ret, name, {1: value})
else:
getattr(ret, name)[player] = value
return ret
def apply_settings_file(settings, settings_path):
if os.path.exists(settings_path):
with open(settings_path) as json_file:
data = json.load(json_file)
for k, v in data.items():
settings[k] = v
return settings
def parse_settings():
# set default settings
settings = {
"lang": "en",
"retro": False,
"bombbag": False,
"mode": "open",
"boots_hint": False,
"logic": "noglitches",
"goal": "ganon",
"crystals_gt": "7",
"crystals_ganon": "7",
"bosses_ganon": "8",
"bosshunt_include_agas": False,
"ganon_item": "silver",
"swords": "random",
"flute_mode": "normal",
"bow_mode": "progressive",
"difficulty": "normal",
"item_functionality": "normal",
"timer": "none",
"progressive": "on",
"accessibility": "items",
"algorithm": "balanced",
"mystery": False,
"suppress_meta": False,
"restrict_boss_items": "none",
# Shuffle Ganon defaults to TRUE
"openpyramid": "auto",
"shuffleganon": True,
"ow_shuffle": "vanilla", # for backwards compatibility
"ow_layout": "vanilla",
"ow_parallel": True,
"ow_unparallel": False,
"ow_terrain": False,
"ow_crossed": "none",
"ow_keepsimilar": False,
"ow_mixed": False,
"ow_whirlpool": False,
"ow_fluteshuffle": "vanilla",
"ow_fog": True,
"ow_no_fog": False,
"shuffle_followers": False,
"bonk_drops": False,
"shuffle": "vanilla",
"shufflelinks": False,
"shuffletavern": True,
'skullwoods': 'original',
'linked_drops': 'unset',
"overworld_map": "default",
"take_any": "none",
"pseudoboots": False,
"mirrorscroll": False,
"dark_rooms": "require_lamp",
"damage_challenge": "normal",
"shuffle_damage_table": "vanilla",
"crystal_book": False,
"shuffleenemies": "none",
"shufflebosses": "none",
"enemy_damage": "default",
"enemy_health": "default",
'any_enemy_logic': 'allow_all',
"shopsanity": False,
"keydropshuffle": False,
"dropshuffle": "none",
"pottery": "none",
"colorizepots": True,
"shufflepots": False,
"mapshuffle": "none",
"compassshuffle": "none",
"keyshuffle": "none",
"bigkeyshuffle": "none",
"prizeshuffle": "none",
"showloot": "never",
"showmap": "map",
"keysanity": False,
"door_shuffle": "vanilla",
"intensity": 3,
"door_type_mode": "original",
"trap_door_mode": "optional",
"key_logic_algorithm": "partial",
"decoupledoors": False,
"door_self_loops": False,
"experimental": False,
"dungeon_counters": "default",
"mixed_travel": "prevent",
"standardize_palettes": "standardize",
'aga_randomness': True,
'money_balance': 100,
"triforce_pool": 0,
"triforce_goal": 0,
"triforce_pool_min": 0,
"triforce_pool_max": 0,
"triforce_goal_min": 0,
"triforce_goal_max": 0,
"triforce_min_difference": 0,
"triforce_max_difference": 10000,
"code": "",
"multi": 1,
"names": "",
"securerandom": False,
"hints": False,
"disablemusic": False,
"quickswap": False,
"heartcolor": "red",
"heartbeep": "normal",
"sprite": None,
"triforce_gfx": None,
"fastmenu": "normal",
"ow_palettes": "default",
"uw_palettes": "default",
"reduce_flashing": False,
"shuffle_sfx": False,
"shuffle_sfxinstruments": False,
"shuffle_songinstruments": False,
"msu_resume": False,
"collection_rate": False,
'spoiler': 'full',
# Playthrough defaults to TRUE
# ROM defaults to TRUE
"calc_playthrough": True,
"create_rom": True,
"bps": False,
"usestartinventory": False,
"custom": False,
"rom": os.path.join(".", "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"),
"patch": os.path.join(".", "Patch File.bps"),
"seed": "",
"count": 1,
"tries": 1,
"startinventory": "",
'beemizer': '0',
"remote_items": False,
"race": False,
"customitemarray": {
"bow": 0,
"progressivebow": 2,
"boomerang": 1,
"redmerang": 1,
"hookshot": 1,
"mushroom": 1,
"powder": 1,
"firerod": 1,
"icerod": 1,
"bombos": 1,
"ether": 1,
"quake": 1,
"lamp": 1,
"hammer": 1,
"shovel": 1,
"flute": 1,
"bugnet": 1,
"book": 1,
"bottle": 4,
"somaria": 1,
"byrna": 1,
"cape": 1,
"mirror": 1,
"boots": 1,
"powerglove": 0,
"titansmitt": 0,
"progressiveglove": 2,
"flippers": 1,
"pearl": 1,
"heartpiece": 24,
"heartcontainer": 10,
"sancheart": 1,
"sword1": 0,
"sword2": 0,
"sword3": 0,
"sword4": 0,
"progressivesword": 4,
"shield1": 0,
"shield2": 0,
"shield3": 0,
"progressiveshield": 3,
"mail2": 0,
"mail3": 0,
"progressivemail": 2,
"halfmagic": 1,
"quartermagic": 0,
"bombsplus5": 0,
"bombsplus10": 0,
"arrowsplus5": 0,
"arrowsplus10": 0,
"arrow1": 1,
"arrow10": 12,
"bomb1": 0,
"bomb3": 16,
"bomb10": 1,
"rupee1": 2,
"rupee5": 4,
"rupee20": 28,
"rupee50": 7,
"rupee100": 1,
"rupee300": 5,
"blueclock": 0,
"greenclock": 0,
"redclock": 0,
"silversupgrade": 0,
"generickeys": 0,
"triforcepieces": 0,
"triforcepiecesgoal": 0,
"triforce": 0,
"rupoor": 0,
"rupoorcost": 10
},
"randomSprite": False,
"outputpath": os.path.join("."),
"settingsonload": "saved",
"outputname": "",
"startinventoryarray": {},
"notes": ""
}
# read saved settings file if it exists and set these
settings_path = os.path.join(".", "resources", "user", "settings.json")
settings = apply_settings_file(settings, settings_path)
if settings["settingsonload"] == "saved":
settings_path = os.path.join(".", "resources", "user", "saved.json")
settings = apply_settings_file(settings, settings_path)
elif settings["settingsonload"] == "lastused":
settings_path = os.path.join(".", "resources", "user", "last.json")
settings = apply_settings_file(settings, settings_path)
return settings
# Priority fallback is:
# 1: CLI
# 2: Settings file(s)
# 3: Canned defaults
def get_args_priority(settings_args, gui_args, cli_args):
args = {}
args["settings"] = parse_settings() if settings_args is None else settings_args
args["gui"] = gui_args
args["cli"] = cli_args
args["load"] = args["settings"]
if args["gui"] is not None:
for k in args["gui"]:
if k not in args["load"] or args["load"][k] != args["gui"]:
args["load"][k] = args["gui"][k]
if args["cli"] is None:
args["cli"] = {}
cli = vars(parse_cli(None))
for k, v in cli.items():
if isinstance(v, dict) and 1 in v:
args["cli"][k] = v[1]
else:
args["cli"][k] = v
args["cli"] = argparse.Namespace(**args["cli"])
cli = vars(args["cli"])
for k in vars(args["cli"]):
load_doesnt_have_key = k not in args["load"]
cli_val = cli[k]
if isinstance(cli_val, dict) and 1 in cli_val:
cli_val = cli_val[1]
different_val = (k in args["load"] and k in cli) and (str(args["load"][k]) != str(cli_val))
cli_has_empty_dict = k in cli and isinstance(cli_val, dict) and len(cli_val) == 0
if load_doesnt_have_key or different_val:
if not cli_has_empty_dict:
args["load"][k] = cli_val
newArgs = {}
for key in ["settings", "gui", "cli", "load"]:
if args[key]:
if isinstance(args[key], dict):
newArgs[key] = argparse.Namespace(**args[key])
else:
newArgs[key] = args[key]
else:
newArgs[key] = args[key]
newArgs[key] = update_deprecated_args(newArgs[key])
args = newArgs
return args
+50
View File
@@ -0,0 +1,50 @@
from dataclasses import dataclass, field
from typing import List
import RaceRandom as random
def _load_entries():
entries = []
with open("data/damage_table.bin", 'rb') as stream:
for sprite in range(0x100):
entries.append([])
for pair in range(8):
byte = stream.read(1)[0]
entries[sprite].append(byte >> 4)
entries[sprite].append(byte & 0x0F)
return entries
@dataclass
class DamageTable:
_entries: List[int] = field(default_factory=_load_entries)
def randomize_sword_subclasses(self):
for sprite in range(0xD8):
for dclass in range(1, 6):
if self._entries[sprite][dclass] > 0:
self._entries[sprite][dclass] = random.randint(1, 7)
def get_bytes(self):
values = []
for sprite in range(0x100):
for dclass in range(0, 16, 2):
cur = self._entries[sprite][dclass] & 0xF
nex = self._entries[sprite][dclass + 1] & 0xF
values.append((cur << 4) | nex)
return values
if __name__ == '__main__':
def print_table(table):
bytelist = table.get_bytes()
for sprite in range(0x100):
for byte in range(8):
print(format(bytelist.pop(0), "02X"), end=" ")
print()
print()
dmg = DamageTable()
print_table(dmg)
dmg.randomize_sword_subclasses()
print_table(dmg)
+4817
View File
File diff suppressed because it is too large Load Diff
+1678
View File
File diff suppressed because it is too large Load Diff
+4257
View File
File diff suppressed because it is too large Load Diff
+102
View File
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
if __name__ == '__main__':
from source.meta.check_requirements import check_requirements
check_requirements(console=True)
import logging
import os
import sys
import RaceRandom as random
import source.classes.diags as diagnostics
from CLI import get_args_priority, parse_cli
from Fill import FillError
from Main import EnemizerError, main
from Rom import get_sprite_from_name
from source.classes.BabelFish import BabelFish
from Utils import close_console, is_bundled
def start():
args = parse_cli(None)
# print diagnostics
# usage: py DungeonRandomizer.py --diags
if args.diags:
diags = diagnostics.output()
print("\n".join(diags))
sys.exit(0)
if is_bundled() and len(sys.argv) == 1:
# for the bundled builds, if we have no arguments, the user
# probably wants the gui. Users of the bundled build who want the command line
# interface shouuld specify at least one option, possibly setting a value to a
# default if they like all the defaults
from Gui import guiMain
close_console()
guiMain()
sys.exit(0)
# ToDo: Validate files further than mere existance
if not args.jsonout and 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)
sys.exit(1)
if any([sprite is not None and not os.path.isfile(sprite) and not get_sprite_from_name(sprite) for sprite in args.sprite.values()]):
if not args.jsonout:
input('Could not find link sprite sheet at given location. \nPress Enter to exit.')
sys.exit(1)
else:
raise IOError('Cannot find sprite file at %s' % args.sprite)
# set up logger
loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[args.loglevel]
logging.basicConfig(format='%(message)s', level=loglevel)
priority = get_args_priority(None, None, args)
lang = "en"
if "load" in priority and "lang" in priority["load"]:
lang = priority["load"].lang
fish = BabelFish(lang=lang)
if args.gui:
from Gui import guiMain
guiMain(args)
else:
count = args.count or 1
tries = args.tries or 1
random.seed(None)
seed = args.seed or random.randint(0, 999999999)
failures = []
attempts = 0
logger = logging.getLogger('')
for seednum in range(count):
for trynum in range(tries):
try:
attempts += 1
main(seed=seed, args=args, fish=fish)
logger.info('%s %s', fish.translate("cli","cli","finished.run"), seednum + 1)
logger.info('')
seed = random.randint(0, 999999999)
break
except (FillError, EnemizerError, Exception, RuntimeError) as err:
failures.append((err, seed))
logger.exception('Attempt %d - %s: %s', trynum, fish.translate("cli","cli","generation.failed"), err)
logger.info('')
seed = random.randint(0, 999999999)
if count > 1 or tries > 1:
for fail in failures:
logger.info('seed %9s failed with: %s', fail[1], fail[0])
if len(failures) > 0:
logger.info('')
fail_rate = 100 * len(failures) / attempts
success_rate = 100 * (attempts - len(failures)) / attempts
logger.info('Generation failure rate: %6.2f%%', fail_rate)
logger.info('Generation success rate: %6.2f%%', success_rate)
if len(failures) == attempts:
sys.exit(1)
if __name__ == '__main__':
start()
+324 -124
View File
@@ -1,38 +1,43 @@
import RaceRandom as random
from BaseClasses import Dungeon
from Bosses import BossFactory
from Fill import fill_restrictive
from Items import ItemFactory
def create_dungeons(world, player):
def make_dungeon(name, default_boss, dungeon_regions, big_key, small_keys, dungeon_items):
dungeon = Dungeon(name, dungeon_regions, big_key, [] if world.retro else small_keys, dungeon_items, player)
def make_dungeon(name, id, default_boss, dungeon_regions, big_key, small_keys, dungeon_items):
dungeon = Dungeon(name, dungeon_regions, big_key, [] if world.keyshuffle[player] == 'universal' else small_keys,
dungeon_items, player, id)
dungeon.boss = BossFactory(default_boss, player)
for region in dungeon.regions:
world.get_region(region, player).dungeon = dungeon
dungeon.world = world
return dungeon
ES = make_dungeon('Hyrule Castle', None, ['Hyrule Castle', 'Sewers', 'Sewer Drop', 'Sewers (Dark)', 'Sanctuary'], None, [ItemFactory('Small Key (Escape)', player)], [ItemFactory('Map (Escape)', player)])
EP = make_dungeon('Eastern Palace', 'Armos Knights', ['Eastern Palace'], ItemFactory('Big Key (Eastern Palace)', player), [], ItemFactory(['Map (Eastern Palace)', 'Compass (Eastern Palace)'], player))
DP = make_dungeon('Desert Palace', 'Lanmolas', ['Desert Palace North', 'Desert Palace Main (Inner)', 'Desert Palace Main (Outer)', 'Desert Palace East'], ItemFactory('Big Key (Desert Palace)', player), [ItemFactory('Small Key (Desert Palace)', player)], ItemFactory(['Map (Desert Palace)', 'Compass (Desert Palace)'], player))
ToH = make_dungeon('Tower of Hera', 'Moldorm', ['Tower of Hera (Bottom)', 'Tower of Hera (Basement)', 'Tower of Hera (Top)'], ItemFactory('Big Key (Tower of Hera)', player), [ItemFactory('Small Key (Tower of Hera)', player)], ItemFactory(['Map (Tower of Hera)', 'Compass (Tower of Hera)'], player))
PoD = make_dungeon('Palace of Darkness', 'Helmasaur King', ['Palace of Darkness (Entrance)', 'Palace of Darkness (Center)', 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness (Bonk Section)', 'Palace of Darkness (North)', 'Palace of Darkness (Maze)', 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness (Final Section)'], ItemFactory('Big Key (Palace of Darkness)', player), ItemFactory(['Small Key (Palace of Darkness)'] * 6, player), ItemFactory(['Map (Palace of Darkness)', 'Compass (Palace of Darkness)'], player))
TT = make_dungeon('Thieves Town', 'Blind', ['Thieves Town (Entrance)', 'Thieves Town (Deep)', 'Blind Fight'], ItemFactory('Big Key (Thieves Town)', player), [ItemFactory('Small Key (Thieves Town)', player)], ItemFactory(['Map (Thieves Town)', 'Compass (Thieves Town)'], player))
SW = make_dungeon('Skull Woods', 'Mothula', ['Skull Woods Final Section (Entrance)', 'Skull Woods First Section', 'Skull Woods Second Section', 'Skull Woods Second Section (Drop)', 'Skull Woods Final Section (Mothula)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)'], ItemFactory('Big Key (Skull Woods)', player), ItemFactory(['Small Key (Skull Woods)'] * 2, player), ItemFactory(['Map (Skull Woods)', 'Compass (Skull Woods)'], player))
SP = make_dungeon('Swamp Palace', 'Arrghus', ['Swamp Palace (Entrance)', 'Swamp Palace (First Room)', 'Swamp Palace (Starting Area)', 'Swamp Palace (Center)', 'Swamp Palace (North)'], ItemFactory('Big Key (Swamp Palace)', player), [ItemFactory('Small Key (Swamp Palace)', player)], ItemFactory(['Map (Swamp Palace)', 'Compass (Swamp Palace)'], player))
IP = make_dungeon('Ice Palace', 'Kholdstare', ['Ice Palace (Entrance)', 'Ice Palace (Main)', 'Ice Palace (Back)', 'Ice Palace (East)', 'Ice Palace (East Top)', 'Ice Palace (Kholdstare)'], ItemFactory('Big Key (Ice Palace)', player), ItemFactory(['Small Key (Ice Palace)'] * 2, player), ItemFactory(['Map (Ice Palace)', 'Compass (Ice Palace)'], player))
MM = make_dungeon('Misery Mire', 'Vitreous', ['Misery Mire (Entrance)', 'Misery Mire (Main)', 'Misery Mire (West)', 'Misery Mire (Final Area)', 'Misery Mire (Vitreous)'], ItemFactory('Big Key (Misery Mire)', player), ItemFactory(['Small Key (Misery Mire)'] * 3, player), ItemFactory(['Map (Misery Mire)', 'Compass (Misery Mire)'], player))
TR = make_dungeon('Turtle Rock', 'Trinexx', ['Turtle Rock (Entrance)', 'Turtle Rock (First Section)', 'Turtle Rock (Chain Chomp Room)', 'Turtle Rock (Second Section)', 'Turtle Rock (Big Chest)', 'Turtle Rock (Crystaroller Room)', 'Turtle Rock (Dark Room)', 'Turtle Rock (Eye Bridge)', 'Turtle Rock (Trinexx)'], ItemFactory('Big Key (Turtle Rock)', player), ItemFactory(['Small Key (Turtle Rock)'] * 4, player), ItemFactory(['Map (Turtle Rock)', 'Compass (Turtle Rock)'], player))
hc_dungeon_items = ['Map (Escape)']
at_dungeon_items = []
if world.mode != 'inverted':
AT = make_dungeon('Agahnims Tower', 'Agahnim', ['Agahnims Tower', 'Agahnim 1'], None, ItemFactory(['Small Key (Agahnims Tower)'] * 2, player), [])
GT = make_dungeon('Ganons Tower', 'Agahnim2', ['Ganons Tower (Entrance)', 'Ganons Tower (Tile Room)', 'Ganons Tower (Compass Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower (Map Room)', 'Ganons Tower (Firesnake Room)', 'Ganons Tower (Teleport Room)', 'Ganons Tower (Bottom)', 'Ganons Tower (Top)', 'Ganons Tower (Before Moldorm)', 'Ganons Tower (Moldorm)', 'Agahnim 2'], ItemFactory('Big Key (Ganons Tower)', player), ItemFactory(['Small Key (Ganons Tower)'] * 4, player), ItemFactory(['Map (Ganons Tower)', 'Compass (Ganons Tower)'], player))
else:
AT = make_dungeon('Inverted Agahnims Tower', 'Agahnim', ['Inverted Agahnims Tower', 'Agahnim 1'], None, ItemFactory(['Small Key (Agahnims Tower)'] * 2, player), [])
GT = make_dungeon('Inverted Ganons Tower', 'Agahnim2', ['Inverted Ganons Tower (Entrance)', 'Ganons Tower (Tile Room)', 'Ganons Tower (Compass Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower (Map Room)', 'Ganons Tower (Firesnake Room)', 'Ganons Tower (Teleport Room)', 'Ganons Tower (Bottom)', 'Ganons Tower (Top)', 'Ganons Tower (Before Moldorm)', 'Ganons Tower (Moldorm)', 'Agahnim 2'], ItemFactory('Big Key (Ganons Tower)', player), ItemFactory(['Small Key (Ganons Tower)'] * 4, player), ItemFactory(['Map (Ganons Tower)', 'Compass (Ganons Tower)'], player))
if world.showloot[player] == 'compass':
if world.dropshuffle[player] == 'underworld' or world.pottery[player] in ['dungeon', 'reduced', 'clustered', 'nonempty', 'lottery']:
hc_dungeon_items.append('Compass (Escape)')
at_dungeon_items.append('Compass (Agahnims Tower)')
elif world.compassshuffle[player] == 'wild':
hc_dungeon_items.append('Compass (Escape)')
if world.keyshuffle[player] == 'wild':
at_dungeon_items.append('Compass (Agahnims Tower)')
ES = make_dungeon('Hyrule Castle', 1, None, hyrule_castle_regions, None, [ItemFactory('Small Key (Escape)', player)], ItemFactory(hc_dungeon_items, player))
EP = make_dungeon('Eastern Palace', 2, 'Armos Knights', eastern_regions, ItemFactory('Big Key (Eastern Palace)', player), [], ItemFactory(['Map (Eastern Palace)', 'Compass (Eastern Palace)'], player))
DP = make_dungeon('Desert Palace', 3, 'Lanmolas', desert_regions, ItemFactory('Big Key (Desert Palace)', player), [ItemFactory('Small Key (Desert Palace)', player)], ItemFactory(['Map (Desert Palace)', 'Compass (Desert Palace)'], player))
ToH = make_dungeon('Tower of Hera', 10, 'Moldorm', hera_regions, ItemFactory('Big Key (Tower of Hera)', player), [ItemFactory('Small Key (Tower of Hera)', player)], ItemFactory(['Map (Tower of Hera)', 'Compass (Tower of Hera)'], player))
PoD = make_dungeon('Palace of Darkness', 6, 'Helmasaur King', pod_regions, ItemFactory('Big Key (Palace of Darkness)', player), ItemFactory(['Small Key (Palace of Darkness)'] * 6, player), ItemFactory(['Map (Palace of Darkness)', 'Compass (Palace of Darkness)'], player))
TT = make_dungeon('Thieves Town', 11, 'Blind', thieves_regions, ItemFactory('Big Key (Thieves Town)', player), [ItemFactory('Small Key (Thieves Town)', player)], ItemFactory(['Map (Thieves Town)', 'Compass (Thieves Town)'], player))
SW = make_dungeon('Skull Woods', 8, 'Mothula', skull_regions, ItemFactory('Big Key (Skull Woods)', player), ItemFactory(['Small Key (Skull Woods)'] * 3, player), ItemFactory(['Map (Skull Woods)', 'Compass (Skull Woods)'], player))
SP = make_dungeon('Swamp Palace', 5, 'Arrghus', swamp_regions, ItemFactory('Big Key (Swamp Palace)', player), [ItemFactory('Small Key (Swamp Palace)', player)], ItemFactory(['Map (Swamp Palace)', 'Compass (Swamp Palace)'], player))
IP = make_dungeon('Ice Palace', 9, 'Kholdstare', ice_regions, ItemFactory('Big Key (Ice Palace)', player), ItemFactory(['Small Key (Ice Palace)'] * 2, player), ItemFactory(['Map (Ice Palace)', 'Compass (Ice Palace)'], player))
MM = make_dungeon('Misery Mire', 7, 'Vitreous', mire_regions, ItemFactory('Big Key (Misery Mire)', player), ItemFactory(['Small Key (Misery Mire)'] * 3, player), ItemFactory(['Map (Misery Mire)', 'Compass (Misery Mire)'], player))
TR = make_dungeon('Turtle Rock', 12, 'Trinexx', tr_regions, ItemFactory('Big Key (Turtle Rock)', player), ItemFactory(['Small Key (Turtle Rock)'] * 4, player), ItemFactory(['Map (Turtle Rock)', 'Compass (Turtle Rock)'], player))
AT = make_dungeon('Agahnims Tower', 4, 'Agahnim', tower_regions, None, ItemFactory(['Small Key (Agahnims Tower)'] * 2, player), ItemFactory(at_dungeon_items, player))
GT = make_dungeon('Ganons Tower', 13, 'Agahnim2', gt_regions, ItemFactory('Big Key (Ganons Tower)', player), ItemFactory(['Small Key (Ganons Tower)'] * 4, player), ItemFactory(['Map (Ganons Tower)', 'Compass (Ganons Tower)'], player))
GT.bosses['bottom'] = BossFactory('Armos Knights', player)
GT.bosses['middle'] = BossFactory('Lanmolas', player)
@@ -40,127 +45,322 @@ def create_dungeons(world, player):
world.dungeons += [ES, EP, DP, ToH, AT, PoD, TT, SW, SP, IP, MM, TR, GT]
def fill_dungeons(world):
freebes = ['Ganons Tower - Map Chest', 'Palace of Darkness - Harmless Hellway', 'Palace of Darkness - Big Key Chest', 'Turtle Rock - Big Key Chest']
all_state_base = world.get_all_state()
dungeon_music_addresses = {'Eastern Palace': [0x1559A],
'Desert Palace': [0x1559B, 0x1559C, 0x1559D, 0x1559E],
'Tower of Hera': [0x155C5, 0x1107A, 0x10B8C],
'Palace of Darkness': [0x155B8],
'Swamp Palace': [0x155B7],
'Thieves Town': [0x155C6],
'Skull Woods': [0x155BA, 0x155BB, 0x155BC, 0x155BD, 0x15608, 0x15609, 0x1560A, 0x1560B],
'Ice Palace': [0x155BF],
'Misery Mire': [0x155B9],
'Turtle Rock': [0x155C7, 0x155A7, 0x155AA, 0x155AB]}
for player in range(1, world.players + 1):
pinball_room = world.get_location('Skull Woods - Pinball Room', player)
if world.retro:
world.push_item(pinball_room, ItemFactory('Small Key (Universal)', player), False)
else:
world.push_item(pinball_room, ItemFactory('Small Key (Skull Woods)', player), False)
pinball_room.event = True
pinball_room.locked = True
hyrule_castle_regions = [
'Hyrule Castle Lobby', 'Hyrule Castle West Lobby', 'Hyrule Castle East Lobby', 'Hyrule Castle East Hall',
'Hyrule Castle West Hall', 'Hyrule Castle Back Hall', 'Hyrule Castle Throne Room', 'Hyrule Castle Behind Tapestry',
'Hyrule Dungeon Map Room', 'Hyrule Dungeon North Abyss', 'Hyrule Dungeon North Abyss Catwalk',
'Hyrule Dungeon South Abyss', 'Hyrule Dungeon South Abyss Catwalk', 'Hyrule Dungeon Guardroom',
'Hyrule Dungeon Armory Main', 'Hyrule Dungeon Armory Boomerang', 'Hyrule Dungeon Armory North Branch',
'Hyrule Dungeon Staircase', 'Hyrule Dungeon Cellblock', 'Hyrule Dungeon Cell', 'Sewers Behind Tapestry',
'Sewers Rope Room', 'Sewers Dark Cross', 'Sewers Water', 'Sewers Dark Aquabats', 'Sewers Key Rat',
'Sewers Rat Path', 'Sewers Secret Room Blocked Path', 'Sewers Secret Room', 'Sewers Yet More Rats',
'Sewers Pull Switch', 'Sanctuary', 'Sanctuary Portal', 'Hyrule Castle West Portal', 'Hyrule Castle South Portal',
'Hyrule Castle East Portal'
]
dungeons = [(list(dungeon.regions), dungeon.big_key, list(dungeon.small_keys), list(dungeon.dungeon_items)) for dungeon in world.dungeons]
eastern_regions = [
'Eastern Lobby', 'Eastern Lobby Bridge', 'Eastern Lobby Left Ledge', 'Eastern Lobby Right Ledge',
'Eastern Cannonball', 'Eastern Cannonball Ledge', 'Eastern Courtyard Ledge', 'Eastern East Wing',
'Eastern Pot Switch', 'Eastern Map Balcony', 'Eastern Map Room', 'Eastern West Wing', 'Eastern Stalfos Spawn',
'Eastern Compass Room', 'Eastern Hint Tile', 'Eastern Hint Tile Blocked Path', 'Eastern Courtyard',
'Eastern Fairies', 'Eastern Map Valley', 'Eastern Dark Square', 'Eastern Dark Pots', 'Eastern Big Key',
'Eastern Darkness', 'Eastern Rupees', 'Eastern Attic Start', 'Eastern False Switches', 'Eastern Cannonball Hell',
'Eastern Single Eyegore', 'Eastern Duo Eyegores', 'Eastern Boss', 'Eastern Boss Spoils', 'Eastern Portal'
]
loopcnt = 0
while dungeons:
loopcnt += 1
dungeon_regions, big_key, small_keys, dungeon_items = dungeons.pop(0)
# this is what we need to fill
dungeon_locations = [location for location in world.get_unfilled_locations() if location.parent_region.name in dungeon_regions]
random.shuffle(dungeon_locations)
desert_regions = [
'Desert Main Lobby', 'Desert Left Alcove', 'Desert Right Alcove', 'Desert Dead End', 'Desert East Lobby',
'Desert East Wing', 'Desert Compass Room', 'Desert Cannonball', 'Desert Arrow Pot Corner', 'Desert Trap Room',
'Desert North Hall', 'Desert Map Room', 'Desert Sandworm Corner', 'Desert Bonk Torch', 'Desert Circle of Pots',
'Desert Big Chest Room', 'Desert West Wing', 'Desert West Lobby', 'Desert Fairy Fountain', 'Desert Back Lobby',
'Desert Tiles 1', 'Desert Bridge', 'Desert Four Statues', 'Desert Beamos Hall', 'Desert Tiles 2',
'Desert Wall Slide', 'Desert Boss', 'Desert Boss Spoils', 'Desert West Portal', 'Desert South Portal', 'Desert East Portal',
'Desert Back Portal'
]
all_state = all_state_base.copy()
hera_regions = [
'Hera Lobby', 'Hera Lobby - Crystal', 'Hera Front', 'Hera Back', 'Hera Front - Crystal', 'Hera Down Stairs Landing',
'Hera Down Stairs Landing - Ranged Crystal', 'Hera Up Stairs Landing', 'Hera Up Stairs Landing - Ranged Crystal',
'Hera Back - Ranged Crystal', 'Hera Basement Cage', 'Hera Basement Cage - Crystal', 'Hera Tile Room',
'Hera Tridorm', 'Hera Tridorm - Crystal', 'Hera Torches', 'Hera Beetles', 'Hera Startile Corner',
'Hera Startile Wide', 'Hera Startile Wide - Crystal', 'Hera 4F', 'Hera Big Chest Landing', 'Hera 5F',
'Hera 5F Pot Block', 'Hera Fairies', 'Hera Boss', 'Hera Boss Spoils', 'Hera Portal'
]
# first place big key
if big_key is not None:
bk_location = None
for location in dungeon_locations:
if location.item_rule(big_key):
bk_location = location
break
tower_regions = [
'Tower Lobby', 'Tower Gold Knights', 'Tower Room 03', 'Tower Lone Statue', 'Tower Dark Maze', 'Tower Dark Chargers',
'Tower Dual Statues', 'Tower Dark Pits', 'Tower Dark Archers', 'Tower Red Spears', 'Tower Red Guards',
'Tower Circle of Pots', 'Tower Pacifist Run', 'Tower Push Statue', 'Tower Catwalk', 'Tower Antechamber',
'Tower Altar', 'Tower Agahnim 1', 'Agahnims Tower Portal'
]
if bk_location is None:
raise RuntimeError('No suitable location for %s' % big_key)
pod_regions = [
'PoD Lobby', 'PoD Left Cage', 'PoD Middle Cage', 'PoD Shooter Room', 'PoD Pit Room', 'PoD Pit Room Blocked',
'PoD Arena Main', 'PoD Arena Main - Ranged Crystal', 'PoD Arena North', 'PoD Arena Bridge', 'PoD Arena Bridge - Ranged Crystal',
'PoD Arena Landing', 'PoD Arena Right', 'PoD Arena Right - Ranged Crystal', 'PoD Arena Ledge', 'PoD Arena Ledge - Ranged Crystal', 'PoD Sexy Statue',
'PoD Map Balcony', 'PoD Map Balcony - Ranged Crystal', 'PoD Fairy Pool', 'PoD Conveyor', 'PoD Mimics 1',
'PoD Jelly Hall', 'PoD Warp Hint', 'PoD Warp Room', 'PoD Stalfos Basement', 'PoD Basement Ledge',
'PoD Big Key Landing', 'PoD Falling Bridge', 'PoD Falling Bridge Mid', 'PoD Falling Bridge Ledge', 'PoD Dark Maze',
'PoD Big Chest Balcony', 'PoD Compass Room', 'PoD Dark Basement', 'PoD Harmless Hellway', 'PoD Mimics 2',
'PoD Bow Statue Left', 'PoD Bow Statue Left - Crystal', 'PoD Bow Statue Right', 'PoD Bow Statue Right - Ranged Crystal',
'PoD Dark Pegs Landing', 'PoD Dark Pegs Right', 'PoD Dark Pegs Middle', 'PoD Dark Pegs Left', 'PoD Dark Pegs Landing - Ranged Crystal',
'PoD Dark Pegs Middle - Ranged Crystal', 'PoD Dark Pegs Left - Ranged Crystal', 'PoD Lonely Turtle', 'PoD Turtle Party',
'PoD Dark Alley', 'PoD Callback', 'PoD Boss', 'PoD Boss Spoils', 'Palace of Darkness Portal'
]
world.push_item(bk_location, big_key, False)
bk_location.event = True
bk_location.locked = True
dungeon_locations.remove(bk_location)
big_key = None
swamp_regions = [
'Swamp Lobby', 'Swamp Entrance', 'Swamp Pot Row', 'Swamp Map Ledge', 'Swamp Trench 1 Approach',
'Swamp Trench 1 Nexus', 'Swamp Trench 1 Alcove', 'Swamp Trench 1 Key Ledge', 'Swamp Trench 1 Departure',
'Swamp Hammer Switch', 'Swamp Hub', 'Swamp Hub Side Ledges', 'Swamp Hub Dead Ledge', 'Swamp Hub North Ledge',
'Swamp Donut Top', 'Swamp Donut Bottom', 'Swamp Compass Donut', 'Swamp Crystal Switch Outer',
'Swamp Crystal Switch Outer - Ranged Crystal', 'Swamp Crystal Switch Inner', 'Swamp Crystal Switch Inner - Crystal',
'Swamp Shortcut', 'Swamp Trench 2 Pots', 'Swamp Trench 2 Blocks', 'Swamp Trench 2 Alcove',
'Swamp Trench 2 Departure', 'Swamp Big Key Ledge', 'Swamp West Shallows', 'Swamp West Block Path',
'Swamp West Ledge', 'Swamp Barrier Ledge', 'Swamp Barrier', 'Swamp Attic', 'Swamp Push Statue', 'Swamp Shooters',
'Swamp Left Elbow', 'Swamp Right Elbow', 'Swamp Drain Left', 'Swamp Drain Right', 'Swamp Flooded Room',
'Swamp Flooded Spot', 'Swamp Basement Shallows', 'Swamp Waterfall Room', 'Swamp Refill', 'Swamp Behind Waterfall',
'Swamp C', 'Swamp Waterway', 'Swamp I', 'Swamp T', 'Swamp Boss', 'Swamp Boss Spoils', 'Swamp Portal'
]
# next place small keys
while small_keys:
small_key = small_keys.pop()
all_state.sweep_for_events()
sk_location = None
for location in dungeon_locations:
if location.name in freebes or (location.can_reach(all_state) and location.item_rule(small_key)):
sk_location = location
break
skull_regions = [
'Skull 1 Lobby', 'Skull Map Room', 'Skull Pot Circle', 'Skull Pull Switch', 'Skull Big Chest', 'Skull Pinball',
'Skull Pot Prison', 'Skull Compass Room', 'Skull Left Drop', 'Skull 2 East Lobby', 'Skull Big Key',
'Skull Lone Pot', 'Skull Small Hall', 'Skull Back Drop', 'Skull 2 West Lobby', 'Skull 2 West Lobby Ledge',
'Skull X Room', 'Skull 3 Lobby', 'Skull East Bridge', 'Skull West Bridge Nook', 'Skull Star Pits',
'Skull Torch Room', 'Skull Vines', 'Skull Spike Corner', 'Skull Final Drop', 'Skull Boss', 'Skull Boss Spoils',
'Skull 1 Portal', 'Skull 2 East Portal', 'Skull 2 West Portal', 'Skull 3 Portal'
]
if sk_location is None:
# need to retry this later
small_keys.append(small_key)
dungeons.append((dungeon_regions, big_key, small_keys, dungeon_items))
# infinite regression protection
if loopcnt < (30 * world.players):
break
else:
raise RuntimeError('No suitable location for %s' % small_key)
thieves_regions = [
'Thieves Lobby', 'Thieves Ambush', 'Thieves BK Corner', 'Thieves Rail Ledge', 'Thieves Compass Room',
'Thieves Big Chest Nook', 'Thieves Hallway', 'Thieves Boss', 'Thieves Pot Alcove Mid', 'Thieves Pot Alcove Bottom',
'Thieves Pot Alcove Top', 'Thieves Conveyor Maze', 'Thieves Spike Track', 'Thieves Hellway',
'Thieves Hellway N Crystal', 'Thieves Hellway S Crystal', 'Thieves Triple Bypass', 'Thieves Spike Switch',
'Thieves Attic', 'Thieves Attic Hint', 'Thieves Attic Switch', 'Thieves Cricket Hall Left',
'Thieves Cricket Hall Right', 'Thieves Attic Window', 'Thieves Basement Block', 'Thieves Blocked Entry',
'Thieves Lonely Zazak', "Thieves Blind's Cell", "Thieves Blind's Cell Interior", 'Thieves Conveyor Bridge',
'Thieves Conveyor Block', 'Thieves Big Chest Room', 'Thieves Trap', 'Revealing Light',
'Thieves Boss Spoils', 'Thieves Town Portal'
]
world.push_item(sk_location, small_key, False)
sk_location.event = True
sk_location.locked = True
dungeon_locations.remove(sk_location)
ice_regions = [
'Ice Lobby', 'Ice Jelly Key', 'Ice Floor Switch', 'Ice Cross Left', 'Ice Cross Bottom', 'Ice Cross Right',
'Ice Cross Top', 'Ice Compass Room', 'Ice Pengator Switch', 'Ice Dead End', 'Ice Big Key', 'Ice Bomb Drop',
'Ice Stalfos Hint', 'Ice Conveyor', 'Ice Conveyor - Crystal', 'Ice Bomb Jump Ledge', 'Ice Bomb Jump Catwalk',
'Ice Narrow Corridor', 'Ice Right H', 'Ice Bomb Drop - Top',
'Ice Pengator Trap', 'Ice Spike Cross', 'Ice Firebar', 'Ice Falling Square', 'Ice Spike Room', 'Ice Hammer Block',
'Ice Tongue Pull', 'Ice Freezors', 'Ice Freezors Ledge', 'Ice Tall Hint', 'Ice Hookshot Ledge',
'Ice Hookshot Balcony', 'Ice Spikeball', 'Ice Lonely Freezor', 'Iced T', 'Ice Catwalk', 'Ice Many Pots',
'Ice Crystal Right', 'Ice Crystal Left', 'Ice Crystal Block', 'Ice Big Chest View', 'Ice Big Chest Landing',
'Ice Backwards Room', 'Ice Anti-Fairy', 'Ice Switch Room', 'Ice Refill', 'Ice Refill - Crystal',
'Ice Fairy', 'Ice Antechamber', 'Ice Boss', 'Ice Boss Spoils', 'Ice Portal'
]
if small_keys:
# key placement not finished, loop again
continue
mire_regions = [
'Mire Lobby', 'Mire Post-Gap', 'Mire 2', 'Mire Hub', 'Mire Hub Right', 'Mire Hub Top', 'Mire Hub Switch',
'Mire Lone Shooter', 'Mire Failure Bridge', 'Mire Falling Bridge - Primary', 'Mire Falling Bridge - Failure',
'Mire Falling Bridge - Chest', 'Mire Map Spike Side', 'Mire Map Spot', 'Mire Crystal Dead End',
'Mire Hidden Shooters', 'Mire Hidden Shooters Blocked', 'Mire Cross', 'Mire Minibridge', 'Mire BK Door Room',
'Mire Spikes', 'Mire Ledgehop', 'Mire Bent Bridge', 'Mire Over Bridge', 'Mire Right Bridge', 'Mire Left Bridge',
'Mire Fishbone', 'Mire South Fish', 'Mire Spike Barrier', 'Mire Square Rail', 'Mire Lone Warp',
'Mire Wizzrobe Bypass', 'Mire Conveyor Crystal', 'Mire Conveyor - Crystal', 'Mire Tile Room', 'Mire Compass Room',
'Mire Compass Chest', 'Mire Neglected Room', 'Mire Chest View', 'Mire Conveyor Barrier', 'Mire BK Chest Ledge',
'Mire Warping Pool', 'Mire Torches Top', 'Mire Torches Bottom', 'Mire Attic Hint', 'Mire Dark Shooters',
'Mire Key Rupees', 'Mire Block X', 'Mire Tall Dark and Roomy', 'Mire Tall Dark and Roomy - Ranged Crystal',
'Mire Crystal Right', 'Mire Crystal Mid', 'Mire Crystal Left',
'Mire Crystal Top', 'Mire Shooter Rupees', 'Mire Falling Foes', 'Mire Firesnake Skip', 'Mire Antechamber',
'Mire Boss', 'Mire Boss Spoils', 'Mire Portal'
]
# next place dungeon items
if world.place_dungeon_items:
for dungeon_item in dungeon_items:
di_location = dungeon_locations.pop()
world.push_item(di_location, dungeon_item, False)
tr_regions = [
'TR Main Lobby', 'TR Lobby Ledge', 'TR Compass Room', 'TR Hub', 'TR Hub Ledges', 'TR Torches Ledge', 'TR Torches',
'TR Roller Room', 'TR Tile Room', 'TR Refill', 'TR Pokey 1', 'TR Chain Chomps Top', 'TR Chain Chomps Top - Crystal',
'TR Chain Chomps Bottom', 'TR Chain Chomps Bottom - Ranged Crystal', 'TR Pipe Pit', 'TR Pipe Ledge',
'TR Lava Dual Pipes', 'TR Lava Island', 'TR Lava Escape', 'TR Pokey 2 Top', 'TR Pokey 2 Top - Crystal',
'TR Pokey 2 Bottom', 'TR Pokey 2 Bottom - Ranged Crystal', 'TR Twin Pokeys', 'TR Hallway', 'TR Dodgers',
'TR Big View', 'TR Big Chest', 'TR Big Chest Entrance', 'TR Lazy Eyes', 'TR Dash Room', 'TR Tongue Pull',
'TR Rupees', 'TR Crystaroller Bottom', 'TR Crystaroller Middle', 'TR Crystaroller Top',
'TR Crystaroller Top - Crystal', 'TR Crystaroller Chest', 'TR Crystaroller Middle - Ranged Crystal',
'TR Crystaroller Bottom - Ranged Crystal', 'TR Dark Ride North Platform', 'TR Dark Ride South Platform',
'TR Dark Ride Ledges', 'TR Dash Bridge', 'TR Eye Bridge',
'TR Crystal Maze Start', 'TR Crystal Maze Start - Crystal', 'TR Crystal Maze Interior', 'TR Crystal Maze End',
'TR Crystal Maze End - Ranged Crystal', 'TR Final Abyss Balcony', 'TR Final Abyss Ledge', 'TR Boss', 'TR Boss Spoils',
'Turtle Rock Main Portal', 'Turtle Rock Lazy Eyes Portal', 'Turtle Rock Chest Portal',
'Turtle Rock Eye Bridge Portal'
]
gt_regions = [
'GT Lobby', 'GT Bob\'s Torch', 'GT Hope Room', 'GT Big Chest', 'GT Blocked Stairs', 'GT Bob\'s Room',
'GT Tile Room', 'GT Speed Torch', 'GT Speed Torch Upper', 'GT Pots n Blocks', 'GT Crystal Conveyor',
'GT Crystal Conveyor Corner', 'GT Crystal Conveyor Left', 'GT Crystal Conveyor - Ranged Crystal',
'GT Crystal Conveyor Corner - Ranged Crystal', 'GT Compass Room', 'GT Invisible Bridges', 'GT Invisible Catwalk',
'GT Conveyor Cross', 'GT Conveyor Cross Across Pits', 'GT Hookshot East Platform', 'GT Hookshot Mid Platform',
'GT Hookshot North Platform', 'GT Hookshot South Platform', 'GT Hookshot South Entry',
'GT Hookshot South Entry - Ranged Crystal', 'GT Map Room', 'GT Double Switch Entry',
'GT Double Switch Pot Corners - Ranged Switches', 'GT Double Switch Pot Corners', 'GT Double Switch Left',
'GT Double Switch Left - Crystal', 'GT Double Switch Entry - Ranged Switches',
'GT Double Switch Exit', 'GT Spike Crystal Left',
'GT Spike Crystal Right', 'GT Warp Maze - Left Section', 'GT Warp Maze - Mid Section',
'GT Warp Maze - Right Section', 'GT Warp Maze - Pit Section', 'GT Warp Maze - Pit Exit Warp Spot',
'GT Warp Maze Exit Section', 'GT Firesnake Room', 'GT Firesnake Room Ledge', 'GT Warp Maze - Rail Choice',
'GT Warp Maze - Rando Rail', 'GT Warp Maze - Main Rails', 'GT Warp Maze - Pot Rail', 'GT Petting Zoo',
'GT Conveyor Star Pits', 'GT Hidden Star', 'GT DMs Room', 'GT Falling Bridge', 'GT Randomizer Room', 'GT Ice Armos',
'GT Big Key Room', 'GT Four Torches', 'GT Fairy Abyss', 'GT Crystal Paths', 'GT Mimics 1', 'GT Mimics 2',
'GT Dash Hall', 'GT Hidden Spikes', 'GT Cannonball Bridge', 'GT Refill', 'GT Gauntlet 1', 'GT Gauntlet 2',
'GT Gauntlet 3', 'GT Gauntlet 4', 'GT Gauntlet 5', 'GT Beam Dash', 'GT Lanmolas 2', 'GT Quad Pot', 'GT Wizzrobes 1',
'GT Dashing Bridge', 'GT Wizzrobes 2', 'GT Conveyor Bridge', 'GT Torch Cross', 'GT Staredown', 'GT Falling Torches',
'GT Mini Helmasaur Room', 'GT Bomb Conveyor', 'GT Crystal Circles', 'GT Crystal Inner Circle',
'GT Crystal Circles - Ranged Crystal', 'GT Left Moldorm Ledge', 'GT Right Moldorm Ledge', 'GT Moldorm',
'GT Moldorm Pit', 'GT Validation', 'GT Validation Door',
'GT Frozen Over', 'GT Brightly Lit Hall', 'GT Agahnim 2', 'Ganons Tower Portal'
]
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]
dungeon_regions = {
'Hyrule Castle': hyrule_castle_regions,
'Eastern Palace': eastern_regions,
'Desert Palace': desert_regions,
'Tower of Hera': hera_regions,
'Agahnims Tower': tower_regions,
'Palace of Darkness': pod_regions,
'Swamp Palace': swamp_regions,
'Skull Woods': skull_regions,
'Thieves Town': thieves_regions,
'Ice Palace': ice_regions,
'Misery Mire': mire_regions,
'Turtle Rock': tr_regions,
'Ganons Tower': gt_regions
}
def fill_dungeons_restrictive(world, shuffled_locations):
all_state_base = world.get_all_state()
region_starts = {
'Hyrule Castle': ['Hyrule Castle Lobby', 'Hyrule Castle West Lobby', 'Hyrule Castle East Lobby', 'Sewers Rat Path', 'Sanctuary'],
'Eastern Palace': ['Eastern Lobby'],
'Desert Palace': ['Desert Back Lobby', 'Desert Main Lobby', 'Desert West Lobby', 'Desert East Lobby'],
'Tower of Hera': ['Hera Lobby'],
'Agahnims Tower': ['Tower Lobby'],
'Palace of Darkness': ['PoD Lobby'],
'Swamp Palace': ['Swamp Lobby'],
'Skull Woods': ['Skull 1 Lobby', 'Skull 2 East Lobby', 'Skull 2 West Lobby', 'Skull 3 Lobby', 'Skull Pot Circle',
'Skull Pinball', 'Skull Left Drop', 'Skull Back Drop'],
'Thieves Town': ['Thieves Lobby'],
'Ice Palace': ['Ice Lobby'],
'Misery Mire': ['Mire Lobby'],
'Turtle Rock': ['TR Main Lobby', 'TR Lazy Eyes', 'TR Big Chest Entrance', 'TR Eye Bridge'],
'Ganons Tower': ['GT Lobby']
}
for player in range(1, world.players + 1):
pinball_room = world.get_location('Skull Woods - Pinball Room', player)
if world.retro:
world.push_item(pinball_room, ItemFactory('Small Key (Universal)', player), False)
else:
world.push_item(pinball_room, ItemFactory('Small Key (Skull Woods)', player), False)
pinball_room.event = True
pinball_room.locked = True
shuffled_locations.remove(pinball_room)
standard_starts = {
'Hyrule Castle': ['Hyrule Castle South']
}
if world.keysanity:
#in keysanity dungeon items are distributed as part of the normal item pool
for item in world.get_items():
if item.key:
item.advancement = True
elif item.map or item.compass:
item.priority = True
return
split_region_starts = {
'Desert Palace': {
'Back': ['Desert Back Lobby'],
'Main': ['Desert Main Lobby', 'Desert West Lobby', 'Desert East Lobby']
},
'Skull Woods': {
'1': ['Skull 1 Lobby', 'Skull Pot Circle'],
'2': ['Skull 2 West Lobby', 'Skull 2 East Lobby', 'Skull Back Drop'],
'3': ['Skull 3 Lobby']
}
}
dungeon_items = get_dungeon_item_pool(world)
# sort in the order Big Key, Small Key, Other before placing dungeon items
sort_order = {"BigKey": 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)
flexible_starts = {
'Skull Woods': ['Skull Left Drop', 'Skull Pinball']
}
class DungeonInfo:
def __init__(self, free, keys, bk, map, compass, bk_drop, drops, prize, dungeon_idx, extra_map_idx):
# todo reduce static maps ideas: prize, bk_name, sm_name, cmp_name, map_name):
self.free_items = free
self.key_num = keys
self.bk_present = bk
self.map_present = map
self.compass_present = compass
self.bk_drops = bk_drop
self.key_drops = drops
self.prize = prize
self.dungeon_index = dungeon_idx
self.extra_map_index = extra_map_idx
dungeon_table = {
'Hyrule Castle': DungeonInfo(6, 1, False, True, False, True, 3, None, 0x00, 0x00),
'Eastern Palace': DungeonInfo(3, 0, True, True, True, False, 2, [0x1209D, 0x53F3A, 0x53F3B, 0x180052, 0x180070, 0x186FE2], 0x04, None),
'Desert Palace': DungeonInfo(2, 1, True, True, True, False, 3, [0x1209E, 0x53F3C, 0x53F3D, 0x180053, 0x180072, 0x186FE3], 0x06, 0x12),
'Tower of Hera': DungeonInfo(2, 1, True, True, True, False, 0, [0x120A5, 0x53F4A, 0x53F4B, 0x18005A, 0x180071, 0x186FEA], 0x14, None),
'Agahnims Tower': DungeonInfo(0, 2, False, False, False, False, 2, None, 0x08, None),
'Palace of Darkness': DungeonInfo(5, 6, True, True, True, False, 0, [0x120A1, 0x53F42, 0x53F43, 0x180056, 0x180073, 0x186FE6], 0x0C, None),
'Swamp Palace': DungeonInfo(6, 1, True, True, True, False, 5, [0x120A0, 0x53F40, 0x53F41, 0x180055, 0x180079, 0x186FE5], 0x0A, None),
'Skull Woods': DungeonInfo(2, 3, True, True, True, False, 2, [0x120A3, 0x53F46, 0x53F47, 0x180058, 0x180074, 0x186FE8], 0x10, 0x20),
'Thieves Town': DungeonInfo(4, 1, True, True, True, False, 2, [0x120A6, 0x53F4C, 0x53F4D, 0x18005B, 0x180076, 0x186FEB], 0x16, None),
'Ice Palace': DungeonInfo(3, 2, True, True, True, False, 4, [0x120A4, 0x53F48, 0x53F49, 0x180059, 0x180078, 0x186FE9], 0x12, None),
'Misery Mire': DungeonInfo(2, 3, True, True, True, False, 3, [0x120A2, 0x53F44, 0x53F45, 0x180057, 0x180077, 0x186FE7], 0x0E, None),
'Turtle Rock': DungeonInfo(5, 4, True, True, True, False, 2, [0x120A7, 0x53F4E, 0x53F4F, 0x18005C, 0x180075, 0x186FEC], 0x18, 0x3E),
'Ganons Tower': DungeonInfo(20, 4, True, True, True, False, 4, None, 0x1A, None),
}
dungeon_keys = {
'Hyrule Castle': 'Small Key (Escape)',
'Eastern Palace': 'Small Key (Eastern Palace)',
'Desert Palace': 'Small Key (Desert Palace)',
'Tower of Hera': 'Small Key (Tower of Hera)',
'Agahnims Tower': 'Small Key (Agahnims Tower)',
'Palace of Darkness': 'Small Key (Palace of Darkness)',
'Swamp Palace': 'Small Key (Swamp Palace)',
'Skull Woods': 'Small Key (Skull Woods)',
'Thieves Town': 'Small Key (Thieves Town)',
'Ice Palace': 'Small Key (Ice Palace)',
'Misery Mire': 'Small Key (Misery Mire)',
'Turtle Rock': 'Small Key (Turtle Rock)',
'Ganons Tower': 'Small Key (Ganons Tower)'
}
dungeon_bigs = {
'Hyrule Castle': 'Big Key (Escape)',
'Eastern Palace': 'Big Key (Eastern Palace)',
'Desert Palace': 'Big Key (Desert Palace)',
'Tower of Hera': 'Big Key (Tower of Hera)',
'Agahnims Tower': 'Big Key (Agahnims Tower)',
'Palace of Darkness': 'Big Key (Palace of Darkness)',
'Swamp Palace': 'Big Key (Swamp Palace)',
'Skull Woods': 'Big Key (Skull Woods)',
'Thieves Town': 'Big Key (Thieves Town)',
'Ice Palace': 'Big Key (Ice Palace)',
'Misery Mire': 'Big Key (Misery Mire)',
'Turtle Rock': 'Big Key (Turtle Rock)',
'Ganons Tower': 'Big Key (Ganons Tower)'
}
dungeon_hints = {
'Hyrule Castle': 'in Hyrule Castle',
'Eastern Palace': 'in Eastern Palace',
'Desert Palace': 'in Desert Palace',
'Tower of Hera': 'in Tower of Hera',
'Agahnims Tower': 'in Castle Tower',
'Palace of Darkness': 'in Palace of Darkness',
'Swamp Palace': 'in Swamp Palace',
'Skull Woods': 'in Skull Woods',
'Thieves Town': 'in Thieves\' Town',
'Ice Palace': 'in Ice Palace',
'Misery Mire': 'in Misery Mire',
'Turtle Rock': 'in Turtle Rock',
'Ganons Tower': 'in Ganon\'s Tower'
}
dungeon_music_addresses = {'Eastern Palace - Prize': [0x1559A],
'Desert Palace - Prize': [0x1559B, 0x1559C, 0x1559D, 0x1559E],
'Tower of Hera - Prize': [0x155C5, 0x1107A, 0x10B8C],
'Palace of Darkness - Prize': [0x155B8],
'Swamp Palace - Prize': [0x155B7],
'Thieves\' Town - Prize': [0x155C6],
'Skull Woods - Prize': [0x155BA, 0x155BB, 0x155BC, 0x155BD, 0x15608, 0x15609, 0x1560A, 0x1560B],
'Ice Palace - Prize': [0x155BF],
'Misery Mire - Prize': [0x155B9],
'Turtle Rock - Prize': [0x155C7, 0x155A7, 0x155AA, 0x155AB]}
+360 -338
View File
@@ -1,339 +1,361 @@
Hint description:
Hints will appear in the following ratios across the 15 telepathic tiles that have hints and the five storyteller locations:
4 hints for inconvenient entrances.
4 hints for random entrances (this can by coincidence pick inconvenient entrances that aren't used for the first set of hints).
3 hints for inconvenient item locations.
5 hints for valuable items.
4 junk hints.
These hints will use the following format:
Entrance hints go "[Entrance on overworld] leads to [interior]".
Inconvenient item locations are a little more custom but amount to "[Location] has [item name]". The item name is literal and will specify which dungeon the dungeon specific items hail from (small key/big key/map/compass).
The valuable items are of the format "[item name] can be found [location]". The item name is again literal, and the location text is taken from Ganon's silver arrow hints. Note that the way it works is that every unique valuable item that exists is considered independently, and you won't get multiple hints for the EXACT same item (so you can only get one hint for Progressive Sword no matter how many swords exist in the seed, but if swords are not progressive, you could get hints for both Master Sword and Tempered Sword). More copies of an item existing does not increase the probability of getting a hint for that particular item (you are equally likely to get a hint for a Progressive Sword as for the Hammer). Unlike the IR, item names are never obfuscated by "something unique", and there is no special bias for hints for GT Big Key or Pegasus Boots.
Hint Locations:
Eastern Palace room before Big Chest
Desert Palace bonk torch room
Tower of Hera entrance room
Tower of Hera Big Chest room
Castle Tower after dark rooms
Palace of Darkness before Bow section
Swamp Palace entryway
Thieves' Town upstairs
Ice Palace entrance
Ice Palace after first drop
Ice Palace tall ice floor room
Misery Mire cutscene room
Turtle Rock entrance
Spectacle Rock cave
Spiky Hint cave
PoD Bdlg NPC
Near PoD Storyteller (bug near bomb wall)
Dark Sanctuary Storyteller (long room with tables)
Near Mire Storyteller (feather duster in winding cave)
SE DW Storyteller (owl in winding cave)
Inconvenient entrance list:
Skull Woods Final
Ice Palace
Misery Mire
Turtle Rock
Ganon's Tower
Mimic Ledge
SW DM Foothills Cave (mirror from upper Bumper ledge)
Hammer Pegs (near purple chest)
Super Bomb cracked wall
Inconvenient location list:
Swamp left (two chests)
Mire left (two chests)
Hera basement
Eastern Palace Big Key chest (protected by anti-fairies)
Thieves' Town Big Chest
Ice Palace Big Chest
Ganon's Tower Big Chest
Purple Chest
Spike Cave
Magic Bat
Sahasrahla (Green Pendant)
Valuable Items are simply all items that are shown on the pause subscreen (Y, B, or A sections) minus Silver Arrows and plus Triforce Pieces, Magic Upgrades (1/2 or 1/4), and the Single Arrow. If keysanity is being used, you can additionally get hints for Small Keys or Big Keys but not hints for Maps or Compasses.
While the exact verbage of location names and item names can be found in the source code, here's a copy for reference:
Overworld Entrance naming:
Turtle Rock: Turtle Rock Main
Misery Mire: Misery Mire
Ice Palace: Ice Palace
Skull Woods Final Section: The back of Skull Woods
Death Mountain Return Cave (West): The SW DM Foothills Cave
Mimic Cave: Mimic Ledge
Dark World Hammer Peg Cave: The rows of pegs
Pyramid Fairy: The crack on the pyramid
Eastern Palace: Eastern Palace
Elder House (East): Elder House
Elder House (West): Elder House
Two Brothers House (East): Eastern Quarreling Brothers' house
Old Man Cave (West): The lower DM entrance
Hyrule Castle Entrance (South): The ground level castle door
Thieves Town: Thieves' Town
Bumper Cave (Bottom): The lower Bumper Cave
Swamp Palace: Swamp Palace
Dark Death Mountain Ledge (West): The East dark DM connector ledge
Dark Death Mountain Ledge (East): The East dark DM connector ledge
Superbunny Cave (Top): The summit of dark DM cave
Superbunny Cave (Bottom): The base of east dark DM
Hookshot Cave: The rock on dark DM
Desert Palace Entrance (South): The book sealed passage
Tower of Hera: The Tower of Hera
Two Brothers House (West): The door near the race game
Old Man Cave (East): The SW-most cave on west DM
Old Man House (Bottom): A cave with a door on west DM
Old Man House (Top): The eastmost cave on west DM
Death Mountain Return Cave (East): The westmost cave on west DM
Spectacle Rock Cave Peak: The highest cave on west DM
Spectacle Rock Cave: The right ledge on west DM
Spectacle Rock Cave (Bottom): The left ledge on west DM
Paradox Cave (Bottom): The southmost cave on east DM
Paradox Cave (Middle): The right paired cave on east DM
Paradox Cave (Top): The east DM summit cave
Fairy Ascension Cave (Bottom): The east DM cave behind rocks
Fairy Ascension Cave (Top): The central ledge on east DM
Spiral Cave: The left ledge on east DM
Spiral Cave (Bottom): The SWmost cave on east DM
Palace of Darkness: Palace of Darkness
Hyrule Castle Entrance (West): The left castle door
Hyrule Castle Entrance (East): The right castle door
Agahnims Tower: The sealed castle door
Desert Palace Entrance (West): The westmost building in the desert
Desert Palace Entrance (North): The northmost cave in the desert
Blinds Hideout: Blind's old house
Lake Hylia Fairy: A cave NE of Lake Hylia
Light Hype Fairy: The cave south of your house
Desert Fairy: The cave near the desert
Chicken House: The chicken lady's house
Aginahs Cave: The open desert cave
Sahasrahlas Hut: The house near armos
Cave Shop (Lake Hylia): The cave NW Lake Hylia
Blacksmiths Hut: The old smithery
Sick Kids House: The central house in Kakariko
Lost Woods Gamble: A tree trunk door
Fortune Teller (Light): A building NE of Kakariko
Snitch Lady (East): A house guarded by a snitch
Snitch Lady (West): A house guarded by a snitch
Bush Covered House: A house with an uncut lawn
Tavern (Front): A building with a backdoor
Light World Bomb Hut: A Kakariko building with no door
Kakariko Shop: The old Kakariko shop
Mini Moldorm Cave: The cave south of Lake Hylia
Long Fairy Cave: The eastmost portal cave
Good Bee Cave: The open cave SE Lake Hylia
20 Rupee Cave: The rock SE Lake Hylia
50 Rupee Cave: The rock near the desert
Ice Rod Cave: The sealed cave SE Lake Hylia
Library: The old library
Potion Shop: The witch's building
Dam: The old dam
Lumberjack House: The lumberjack house
Lake Hylia Fortune Teller: The building NW Lake Hylia
Kakariko Gamble Game: The old Kakariko gambling den
Waterfall of Wishing: Going behind the waterfall
Capacity Upgrade: The cave on the island
Bonk Rock Cave: The rock pile near Sanctuary
Graveyard Cave: The graveyard ledge
Checkerboard Cave: The NE desert ledge
Cave 45: The ledge south of haunted grove
Kings Grave: The northeastmost grave
Bonk Fairy (Light): The rock pile near your home
Hookshot Fairy: A cave on east DM
Bonk Fairy (Dark): The rock pile near the old bomb shop
Dark Sanctuary Hint: The dark sanctuary cave
Dark Lake Hylia Fairy: The cave NE dark Lake Hylia
C-Shaped House: The NE house in Village of Outcasts
Big Bomb Shop: The old bomb shop
Dark Death Mountain Fairy: The SW cave on dark DM
Dark Lake Hylia Shop: The building NW dark Lake Hylia
Dark World Shop: The hammer sealed building
Red Shield Shop: The fenced in building
Mire Shed: The western hut in the mire
East Dark World Hint: The dark cave near the eastmost portal
Dark Desert Hint: The cave east of the mire
Spike Cave: The ledge cave on west dark DM
Palace of Darkness Hint: The building south of Kiki
Dark Lake Hylia Ledge Spike Cave: The rock SE dark Lake Hylia
Cave Shop (Dark Death Mountain): The base of east dark DM
Dark World Potion Shop: The building near the catfish
Archery Game: The old archery game
Dark World Lumberjack Shop: The northmost Dark World building
Hype Cave: The cave south of the old bomb shop
Brewery: The Village of Outcasts building with no door
Dark Lake Hylia Ledge Hint: The open cave SE dark Lake Hylia
Chest Game: The westmost building in the Village of Outcasts
Dark Desert Fairy: The eastern hut in the mire
Dark Lake Hylia Ledge Fairy: The sealed cave SE dark Lake Hylia
Fortune Teller (Dark): The building NE the Village of Outcasts
Sanctuary: Sanctuary
Lumberjack Tree Cave: The cave Behind Lumberjacks
Lost Woods Hideout Stump: The stump in Lost Woods
North Fairy Cave: The cave East of Graveyard
Bat Cave Cave: The cave in eastern Kakariko
Kakariko Well Cave: The cave in northern Kakariko
Hyrule Castle Secret Entrance Stairs: The tunnel near the castle
Skull Woods First Section Door: The southeastmost skull
Skull Woods Second Section Door (East): The central open skull
Skull Woods Second Section Door (West): The westmost open skull
Desert Palace Entrance (East): The eastern building in the desert
Turtle Rock Isolated Ledge Entrance: The isolated ledge on east dark DM
Bumper Cave (Top): The upper Bumper Cave
Hookshot Cave Back Entrance: The stairs on the floating island
Destination Entrance Naming:
Hyrule Castle: Hyrule Castle (all three entrances)
Eastern Palace: Eastern Palace
Desert Palace: Desert Palace (all four entrances, including final)
Tower of Hera: Tower of Hera
Palace of Darkness: Palace of Darkness
Swamp Palace: Swamp Palace
Skull Woods: Skull Woods (any entrance including final)
Thieves' Town: Thieves' Town
Ice Palace: Ice Palace
Misery Mire: Misery Mire
Turtle Rock: Turtle Rock (all four entrances)
Ganon's Tower: Ganon's Tower
Castle Tower: Agahnim's Tower
A connector: Paradox Cave, Spectacle Rock Cave, Hookshot Cave, Superbunny Cave, Spiral Cave, Old Man Fetch Cave, Old Man House, Elder House, Quarreling Brothers' House, Bumper Cave, DM Fairy Ascent Cave, DM Exit Cave
A bounty of five items: Mini-moldorm cave, Hype Cave, Blind's Hideout
Sahasrahla: Sahasrahla
A cave with two items: Mire hut, Waterfall Fairy, Pyramid Fairy
A fairy fountain: Any healer fairy cave, either bonk cave with four fairies, the "long fairy" cave
A common shop: Any shop that sells bombs by default
The rare shop: The shop that sells the Red Shield by default
The potion shop: Potion Shop
The bomb shop: Bomb Shop
A fortune teller: Any of the three fortune tellers
A house with a chest: Chicken Lady's house, C-House, Brewery
A cave with an item: Checkerboard cave, Hammer Pegs cave, Cave 45, Graveyard Ledge cave
A cave with a chest: Sanc Bonk Rock Cave, Cape Grave Cave, Ice Rod Cave, Aginah's Cave
The dam: Watergate
The sick kid: Sick Kid
The library: Library
Mimic Cave: Mimic Cave
Spike Cave: Spike Cave
A game of 16 chests: VoO chest game (for the item)
A storyteller: The four DW NPCs who charge 20 rupees for a hint as well as the PoD Bdlg guy who gives a free hint
A cave with some cash: 20 rupee cave, 50 rupee cave (both have thieves and some pots)
A game of chance: Gambling game (just for cash, no items)
A game of skill: Archery minigame
The queen of fairies: Capacity Upgrade Fairy
A drop's exit: Sanctuary, LW Thieves' Hideout, Kakariko Well, Magic Bat, Useless Fairy, Uncle Tunnel, Ganon drop exit
A restock room: The Kakariko bomb/arrow restock room
The tavern: The Kakariko tavern
The grass man: The Kakariko man with many beds
A cold bee: The "wrong side" of Ice Rod cave where you can get a Good Bee
Fairies deep in a cave: Hookshot Fairy
Location naming reference:
Mushroom: in the woods
Master Sword Pedestal: at the pedestal
Bottle Merchant: with a merchant
Stumpy: with tree boy
Flute Spot: underground
Digging Game: underground
Lake Hylia Island: on an island
Floating Island: on an island
Bumper Cave Ledge: on a ledge
Spectacle Rock: atop a rock
Maze Race: at the race
Desert Ledge: in the desert
Pyramid: on the pyramid
Catfish: with a catfish
Ether Tablet: at a monument
Bombos Tablet: at a monument
Hobo: with the hobo
Zora's Ledge: near Zora
King Zora: at a high price
Sunken Treasure: underwater
Floodgate Chest: in the dam
Blacksmith: with the smith
Purple Chest: from a box
Old Man: with the old man
Link's Uncle: with your uncle
Secret Passage: near your uncle
Kakariko Well (5 items): in a well
Lost Woods Hideout: near a thief
Lumberjack Tree: in a hole
Magic Bat: with the bat
Paradox Cave (7 items): in a cave with seven chests
Blind's Hideout (5 items): in a basement
Mini Moldorm Cave (5 items): near Moldorms
Hype Cave (4 back chests): near a bat-like man
Hype Cave - Generous Guy: with a bat-like man
Hookshot Cave (4 items): across pits
Sahasrahla's Hut (chests in back): near the elder
Sahasrahla: with the elder
Waterfall Fairy (2 items): near a fairy
Pyramid Fairy (2 items): near a fairy
Mire Shed (2 items): near sparks
Superbunny Cave (2 items): in a connection
Spiral Cave: in spiral cave
Kakariko Tavern: in the bar
Link's House: in your home
Sick Kid: with the sick
Library: near books
Potion Shop: near potions
Spike Cave: beyond spikes
Mimic Cave: in a cave of mimicry
Chest Game: as a prize
Chicken House: near poultry
Aginah's Cave: with Aginah
Ice Rod Cave: in a frozen cave
Brewery: alone in a home
C-Shaped House: alone in a home
Spectacle Rock Cave: alone in a cave
King's Tomb: alone in a cave
Cave 45: alone in a cave
Graveyard Cave: alone in a cave
Checkerboard Cave: alone in a cave
Bonk Rock Cave: alone in a cave
Peg Cave: alone in a cave
Sanctuary: in Sanctuary
Hyrule Castle - Boomerang Chest: in Hyrule Castle
Hyrule Castle - Map Chest: in Hyrule Castle
Hyrule Castle - Zelda's Chest: in Hyrule Castle
Sewers - Dark Cross: in the sewers
Sewers - Secret Room (3 items): in the sewers
Eastern Palace - Boss: with the Armos
Eastern Palace (otherwise, 5 items): in Eastern Palace
Desert Palace - Boss: with Lanmolas
Desert Palace (otherwise, 5 items): in Desert Palace
Tower of Hera - Boss: with Moldorm
Tower of Hera (otherwise, 5 items): in Tower of Hera
Castle Tower (2 items): in Castle Tower
Palace of Darkness - Boss: with Helmasaur King
Palace of Darkness (otherwise, 13 items): in Palace of Darkness
Swamp Palace - Boss: with Arrghus
Swamp Palace (otherwise, 9 items): in Swamp Palace
Skull Woods - Bridge Room: near Mothula
Skull Woods - Boss: with Mothula
Skull Woods (otherwise, 6 items): in Skull Woods
Thieves' Town - Boss: with Blind
Thieves' Town (otherwise, 7 items): in Thieves' Town
Ice Palace - Boss: with Kholdstare
Ice Palace (otherwise, 7 items): in Ice Palace
Misery Mire - Boss: with Vitreous
Misery Mire (otherwise, 7 items): in Misery Mire
Turtle Rock - Boss: with Trinexx
Turtle Rock (otherwise, 11 items): in Turtle Rock
Ganons Tower (after climb, 4 items): atop Ganon's Tower
Hint description:
Hints will appear in the following ratios across the 15 telepathic tiles that have hints and the five storyteller locations:
4 hints for inconvenient entrances.
4 hints for random entrances (this can by coincidence pick inconvenient entrances that aren't used for the first set of hints).
3 hints for inconvenient item locations.
5 hints for valuable items.
4 junk hints.
In the vanilla, dungeonssimple, and dungeonsfull shuffles, the following ratios will be used instead:
5 hints for inconvenient item locations.
8 hints for valuable items.
7 junk hints.
In the simple, restricted shuffles, these are the ratios:
2 hints for inconvenient entrances.
1 hint for an inconvenient dungeon entrance.
4 hints for random entrances (this can by coincidence pick inconvenient entrances that aren't used for the first set of hints).
3 hints for inconvenient item locations.
5 hints for valuable items.
5 junk hints.
These hints will use the following format:
Entrance hints go "[Entrance on overworld] leads to [interior]".
Inconvenient item locations are a little more custom but amount to "[Location] has [item name]". The item name is literal and will specify which dungeon the dungeon specific items hail from (small key/big key/map/compass).
The valuable items are of the format "[item name] can be found [location]". The item name is again literal, and the location text is taken from Ganon's silver arrow hints. Note that the way it works is that every unique valuable item that exists is considered independently, and you won't get multiple hints for the EXACT same item (so you can only get one hint for Progressive Sword no matter how many swords exist in the seed, but if swords are not progressive, you could get hints for both Master Sword and Tempered Sword). More copies of an item existing does not increase the probability of getting a hint for that particular item (you are equally likely to get a hint for a Progressive Sword as for the Hammer). Unlike the IR, item names are never obfuscated by "something unique", and there is no special bias for hints for GT Big Key or Pegasus Boots.
Hint Locations:
Eastern Palace room before Big Chest
Desert Palace bonk torch room
Tower of Hera entrance room
Tower of Hera Big Chest room
Castle Tower after dark rooms
Palace of Darkness before Bow section
Swamp Palace entryway
Thieves' Town upstairs
Ice Palace entrance
Ice Palace after first drop
Ice Palace tall ice floor room
Misery Mire cutscene room
Turtle Rock entrance
Spectacle Rock cave
Spiky Hint cave
PoD Bdlg NPC
Near PoD Storyteller (bug near bomb wall)
Dark Sanctuary Storyteller (long room with tables)
Near Mire Storyteller (feather duster in winding cave)
SE DW Storyteller (owl in winding cave)
Inconvenient entrance list:
Skull Woods Final
Ice Palace
Misery Mire
Turtle Rock
Ganon's Tower
Mimic Ledge
SW DM Foothills Cave (mirror from upper Bumper ledge)
Hammer Pegs (near purple chest)
Super Bomb cracked wall
Inconvenient location list:
Swamp left (two chests)
Mire left (two chests)
Hera basement
Eastern Palace Big Key chest (protected by anti-fairies)
Thieves' Town Big Chest
Ice Palace Big Chest
Ganon's Tower Big Chest
Purple Chest
Spike Cave
Magic Bat
Sahasrahla (Green Pendant)
In the vanilla, dungeonssimple, and dungeonsfull shuffles, the following two locations are added to the inconvenient locations list:
Graveyard Cave
Mimic Cave
Valuable Items are simply all items that are shown on the pause subscreen (Y, B, or A sections) minus Silver Arrows and plus Triforce Pieces, Magic Upgrades (1/2 or 1/4), and the Single Arrow. If key shuffle is being used, you can additionally get hints for Small Keys or Big Keys but not hints for Maps or Compasses.
While the exact verbage of location names and item names can be found in the source code, here's a copy for reference:
Overworld Entrance naming:
Links House: The hero's old residence
Turtle Rock: Turtle Rock Main
Misery Mire: Misery Mire
Ice Palace: Ice Palace
Skull Woods Final Section: The back of Skull Woods
Death Mountain Return Cave (West): The SW DM Foothills Cave
Mimic Cave: Mimic Ledge
Hammer Peg Cave: The rows of pegs
Pyramid Fairy: The crack on the pyramid
Eastern Palace: Eastern Palace
Elder House (East): Elder House
Elder House (West): Elder House
Two Brothers House (East): Eastern Quarreling Brothers' house
Old Man Cave (West): The lower DM entrance
Hyrule Castle Entrance (South): The ground level castle door
Thieves Town: Thieves' Town
Bumper Cave (Bottom): The lower Bumper Cave
Swamp Palace: Swamp Palace
Dark Death Mountain Ledge (West): The East dark DM connector ledge
Dark Death Mountain Ledge (East): The East dark DM connector ledge
Superbunny Cave (Top): The summit of dark DM cave
Superbunny Cave (Bottom): The base of east dark DM
Hookshot Cave: The rock on dark DM
Desert Palace Entrance (South): The book sealed passage
Tower of Hera: The Tower of Hera
Two Brothers House (West): The door near the race game
Old Man Cave (East): The SW-most cave on west DM
Old Man House (Bottom): A cave with a door on west DM
Old Man House (Top): The eastmost cave on west DM
Death Mountain Return Cave (East): The westmost cave on west DM
Spectacle Rock Cave Peak: The highest cave on west DM
Spectacle Rock Cave: The right ledge on west DM
Spectacle Rock Cave (Bottom): The left ledge on west DM
Paradox Cave (Bottom): The right paired cave on east DM
Paradox Cave (Middle): The southmost cave on east DM
Paradox Cave (Top): The east DM summit cave
Fairy Ascension Cave (Bottom): The east DM cave behind rocks
Fairy Ascension Cave (Top): The central ledge on east DM
Spiral Cave: The left ledge on east DM
Spiral Cave (Bottom): The SWmost cave on east DM
Palace of Darkness: Palace of Darkness
Hyrule Castle Entrance (West): The left castle door
Hyrule Castle Entrance (East): The right castle door
Agahnims Tower: The sealed castle door
Desert Palace Entrance (West): The westmost building in the desert
Desert Palace Entrance (North): The northmost cave in the desert
Blinds Hideout: Blind's old house
Lake Hylia Fairy: A cave NE of Lake Hylia
Light Hype Fairy: The cave south of your house
Desert Fairy: The cave near the desert
Chicken House: The chicken lady's house
Tavern North: A backdoor
Aginahs Cave: The open desert cave
Sahasrahlas Hut: The house near armos
Lake Hylia Shop: The cave NW Lake Hylia
Blacksmiths Hut: The old smithery
Sick Kids House: The central house in Kakariko
Lost Woods Gamble: A tree trunk door
Fortune Teller (Light): A building NE of Kakariko
Snitch Lady (East): A house guarded by a snitch
Snitch Lady (West): A house guarded by a snitch
Bush Covered House: A house with an uncut lawn
Tavern (Front): A building with a backdoor
Light World Bomb Hut: A Kakariko building with no door
Kakariko Shop: The old Kakariko shop
Mini Moldorm Cave: The cave south of Lake Hylia
Long Fairy Cave: The eastmost portal cave
Good Bee Cave: The open cave SE Lake Hylia
20 Rupee Cave: The rock SE Lake Hylia
50 Rupee Cave: The rock near the desert
Ice Rod Cave: The sealed cave SE Lake Hylia
Library: The old library
Potion Shop: The witch's building
Dam: The old dam
Lumberjack House: The lumberjack house
Lake Hylia Fortune Teller: The building NW Lake Hylia
Kakariko Gamble Game: The old Kakariko gambling den
Waterfall of Wishing: Going behind the waterfall
Capacity Upgrade: The cave on the island
Bonk Rock Cave: The rock pile near Sanctuary
Graveyard Cave: The graveyard ledge
Checkerboard Cave: The NE desert ledge
Cave 45: The ledge south of haunted grove
Kings Grave: The northeastmost grave
Bonk Fairy (Light): The rock pile near your home
Hookshot Fairy: A cave on east DM
Bonk Fairy (Dark): The rock pile near the old bomb shop
Dark Sanctuary Hint: The dark sanctuary cave
Dark Lake Hylia Fairy: The cave NE dark Lake Hylia
C-Shaped House: The NE house in Village of Outcasts
Big Bomb Shop: The old bomb shop
Dark Death Mountain Fairy: The SW cave on dark DM
Dark Lake Hylia Shop: The building NW dark Lake Hylia
Dark World Shop: The hammer sealed building
Red Shield Shop: The fenced in building
Mire Shed: The western hut in the mire
East Dark World Hint: The dark cave near the eastmost portal
Mire Hint: The cave east of the mire
Spike Cave: The ledge cave on west dark DM
Palace of Darkness Hint: The building south of Kiki
Dark Lake Hylia Ledge Spike Cave: The rock SE dark Lake Hylia
Dark Death Mountain Shop: The base of east dark DM
Dark Potion Shop: The building near the catfish
Archery Game: The old archery game
Dark Lumberjack Shop: The northmost Dark World building
Hype Cave: The cave south of the old bomb shop
Brewery: The Village of Outcasts building with no door
Dark Lake Hylia Ledge Hint: The open cave SE dark Lake Hylia
Chest Game: The westmost building in the Village of Outcasts
Mire Fairy: The eastern hut in the mire
Dark Lake Hylia Ledge Fairy: The sealed cave SE dark Lake Hylia
Fortune Teller (Dark): The building NE the Village of Outcasts
Sanctuary: Sanctuary
Lumberjack Tree Cave: The cave Behind Lumberjacks
Lost Woods Hideout Stump: The stump in Lost Woods
North Fairy Cave: The cave East of Graveyard
Bat Cave Cave: The cave in eastern Kakariko
Kakariko Well Cave: The cave in northern Kakariko
Hyrule Castle Secret Entrance Stairs: The tunnel near the castle
Skull Woods First Section Door: The southeastmost skull
Skull Woods Second Section Door (East): The central open skull
Skull Woods Second Section Door (West): The westmost open skull
Desert Palace Entrance (East): The eastern building in the desert
Turtle Rock Isolated Ledge Entrance: The isolated ledge on east dark DM
Bumper Cave (Top): The upper Bumper Cave
Hookshot Cave Back Entrance: The stairs on the floating island
Destination Entrance Naming:
Hyrule Castle: Hyrule Castle (all three entrances)
Eastern Palace: Eastern Palace
Desert Palace: Desert Palace (all four entrances, including final)
Tower of Hera: Tower of Hera
Palace of Darkness: Palace of Darkness
Swamp Palace: Swamp Palace
Skull Woods: Skull Woods (any entrance including final)
Thieves' Town: Thieves' Town
Ice Palace: Ice Palace
Misery Mire: Misery Mire
Turtle Rock: Turtle Rock (all four entrances)
Ganon's Tower: Ganon's Tower
Castle Tower: Agahnim's Tower
A connector: Paradox Cave, Spectacle Rock Cave, Hookshot Cave, Superbunny Cave, Spiral Cave, Old Man Fetch Cave, Old Man House, Elder House, Quarreling Brothers' House, Bumper Cave, DM Fairy Ascent Cave, DM Exit Cave
A bounty of five items: Mini-moldorm cave, Hype Cave, Blind's Hideout
Sahasrahla: Sahasrahla
A cave with two items: Mire hut, Waterfall Fairy, Pyramid Fairy
A fairy fountain: Any healer fairy cave, either bonk cave with four fairies, the "long fairy" cave
A common shop: Any shop that sells bombs by default
The rare shop: The shop that sells the Red Shield by default
The potion shop: Potion Shop
The bomb shop: Bomb Shop
A fortune teller: Any of the three fortune tellers
A house with a chest: Chicken Lady's house, C-House, Brewery
A cave with an item: Checkerboard cave, Hammer Pegs cave, Cave 45, Graveyard Ledge cave
A cave with a chest: Sanc Bonk Rock Cave, Cape Grave Cave, Ice Rod Cave, Aginah's Cave
The dam: Watergate
The sick kid: Sick Kid
The library: Library
Mimic Cave: Mimic Cave
Spike Cave: Spike Cave
A game of 16 chests: VoO chest game (for the item)
A storyteller: The four DW NPCs who charge 20 rupees for a hint as well as the PoD Bdlg guy who gives a free hint
A cave with some cash: 20 rupee cave, 50 rupee cave (both have thieves and some pots)
A game of chance: Gambling game (just for cash, no items)
A game of skill: Archery minigame
The queen of fairies: Capacity Upgrade Fairy
A drop's exit: Sanctuary, LW Thieves' Hideout, Kakariko Well, Magic Bat, Useless Fairy, Uncle Tunnel, Ganon drop exit
A restock room: The Kakariko bomb/arrow restock room
The tavern: The Kakariko tavern
The grass man: The Kakariko man with many beds
A cold bee: The "wrong side" of Ice Rod cave where you can get a Good Bee
Fairies deep in a cave: Hookshot Fairy
Location naming reference:
Mushroom: in the woods
Master Sword Pedestal: at the pedestal
Bottle Merchant: with a merchant
Stumpy: with tree boy
Flute Spot: underground
Digging Game: underground
Lake Hylia Island: on an island
Floating Island: on an island
Bumper Cave Ledge: on a ledge
Spectacle Rock: atop a rock
Maze Race: at the race
Desert Ledge: in the desert
Pyramid: on the pyramid
Catfish: with a catfish
Ether Tablet: at a monument
Bombos Tablet: at a monument
Hobo: with the hobo
Zora's Ledge: near Zora
King Zora: at a high price
Sunken Treasure: underwater
Floodgate Chest: in the dam
Blacksmith: with the smith
Purple Chest: from a box
Old Man: with the old man
Link's Uncle: with your uncle
Secret Passage: near your uncle
Kakariko Well (5 items): in a well
Lost Woods Hideout: near a thief
Lumberjack Tree: in a hole
Magic Bat: with the bat
Paradox Cave (7 items): in a cave with seven chests
Blind's Hideout (5 items): in a basement
Mini Moldorm Cave (5 items): near Moldorms
Hype Cave (4 back chests): near a bat-like man
Hype Cave - Generous Guy: with a bat-like man
Hookshot Cave (4 items): across pits
Sahasrahla's Hut (chests in back): near the elder
Sahasrahla: with the elder
Waterfall Fairy (2 items): near a fairy
Pyramid Fairy (2 items): near a fairy
Mire Shed (2 items): near sparks
Superbunny Cave (2 items): in a connection
Spiral Cave: in spiral cave
Kakariko Tavern: in the bar
Link's House: in your home
Sick Kid: with the sick
Library: near books
Potion Shop: near potions
Spike Cave: beyond spikes
Mimic Cave: in a cave of mimicry
Chest Game: as a game reward
Chicken House: near poultry
Aginah's Cave: with Aginah
Ice Rod Cave: in a frozen cave
Brewery: alone in a home
C-Shaped House: alone in a home
Spectacle Rock Cave: alone in a cave
King's Tomb: alone in a cave
Cave 45: alone in a cave
Graveyard Cave: alone in a cave
Checkerboard Cave: alone in a cave
Bonk Rock Cave: alone in a cave
Peg Cave: alone in a cave
Sanctuary: in Sanctuary
Hyrule Castle - Boomerang Chest: in Hyrule Castle
Hyrule Castle - Map Chest: in Hyrule Castle
Hyrule Castle - Zelda's Chest: in Hyrule Castle
Sewers - Dark Cross: in the sewers
Sewers - Secret Room (3 items): in the sewers
Eastern Palace - Boss: with the Armos
Eastern Palace (otherwise, 5 items): in Eastern Palace
Desert Palace - Boss: with Lanmolas
Desert Palace (otherwise, 5 items): in Desert Palace
Tower of Hera - Boss: with Moldorm
Tower of Hera (otherwise, 5 items): in Tower of Hera
Castle Tower (2 items): in Castle Tower
Palace of Darkness - Boss: with Helmasaur King
Palace of Darkness (otherwise, 13 items): in Palace of Darkness
Swamp Palace - Boss: with Arrghus
Swamp Palace (otherwise, 9 items): in Swamp Palace
Skull Woods - Bridge Room: near Mothula
Skull Woods - Boss: with Mothula
Skull Woods (otherwise, 6 items): in Skull Woods
Thieves' Town - Boss: with Blind
Thieves' Town (otherwise, 7 items): in Thieves' Town
Ice Palace - Boss: with Kholdstare
Ice Palace (otherwise, 7 items): in Ice Palace
Misery Mire - Boss: with Vitreous
Misery Mire (otherwise, 7 items): in Misery Mire
Turtle Rock - Boss: with Trinexx
Turtle Rock (otherwise, 11 items): in Turtle Rock
Ganons Tower (after climb, 4 items): atop Ganon's Tower
Ganon's Tower (otherwise, 23 items): in Ganon's Tower
-264
View File
@@ -1,264 +0,0 @@
#!/usr/bin/env python3
import argparse
import os
import logging
import RaceRandom as random
import textwrap
import sys
from Main import main
from Utils import is_bundled, close_console, output_path
class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
def _get_help_string(self, action):
return textwrap.dedent(action.help)
def start():
parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true')
parser.add_argument('--json_spoiler', help='Output a JSON Spoiler File', action='store_true')
parser.add_argument('--logic', default='noglitches', const='noglitches', nargs='?', choices=['noglitches', 'minorglitches', 'nologic'],
help='''\
Select Enforcement of Item Requirements. (default: %(default)s)
No Glitches:
Minor Glitches: May require Fake Flippers, Bunny Revival
and Dark Room Navigation.
No Logic: Distribute items without regard for
item requirements.
''')
parser.add_argument('--mode', default='open', const='open', nargs='?', choices=['standard', 'open', 'inverted'],
help='''\
Select game mode. (default: %(default)s)
Open: World starts with Zelda rescued.
Standard: Fixes Hyrule Castle Secret Entrance and Front Door
but may lead to weird rain state issues if you exit
through the Hyrule Castle side exits before rescuing
Zelda in a full shuffle.
Inverted: Starting locations are Dark Sanctuary in West Dark
World or at Link's House, which is shuffled freely.
Requires the moon pearl to be Link in the Light World
instead of a bunny.
''')
parser.add_argument('--swords', default='random', const='random', nargs='?', choices= ['random', 'assured', 'swordless', 'vanilla'],
help='''\
Select sword placement. (default: %(default)s)
Random: All swords placed randomly.
Assured: Start game with a sword already.
Swordless: No swords. Curtains in Skull Woods and Agahnim\'s
Tower are removed, Agahnim\'s Tower barrier can be
destroyed with hammer. Misery Mire and Turtle Rock
can be opened without a sword. Hammer damages Ganon.
Ether and Bombos Tablet can be activated with Hammer
(and Book). Bombos pads have been added in Ice
Palace, to allow for an alternative to firerod.
Vanilla: Swords are in vanilla locations.
''')
parser.add_argument('--goal', default='ganon', const='ganon', nargs='?', choices=['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'ganonhunt', 'crystals', 'all_items', 'completionist'],
help='''\
Select completion goal. (default: %(default)s)
Ganon: Collect all crystals, beat Agahnim 2 then
defeat Ganon.
Crystals: Collect all crystals then defeat Ganon.
Pedestal: Places the Triforce at the Master Sword Pedestal.
All Dungeons: Collect all crystals, pendants, beat both
Agahnim fights and then defeat Ganon.
All Items: Requires collecting 216 items to defeat Ganon.
Completionist: Same as above, plus All Dungeons
''')
parser.add_argument('--difficulty', default='normal', const='normal', nargs='?', choices=['normal', 'hard', 'expert'],
help='''\
Select game difficulty. Affects available itempool. (default: %(default)s)
Normal: Normal difficulty.
Hard: A harder setting with less equipment and reduced health.
Expert: A harder yet setting with minimum equipment and health.
''')
parser.add_argument('--item_functionality', default='normal', const='normal', nargs='?', choices=['normal', 'hard', 'expert'],
help='''\
Select limits on item functionality to increase difficulty. (default: %(default)s)
Normal: Normal functionality.
Hard: Reduced functionality.
Expert: Greatly reduced functionality.
''')
parser.add_argument('--timer', default='none', const='none', nargs='?', choices=['none', 'ohko'],
help='''\
Select One-Hit KO (OHKO) game setting. (default: %(default)s)
None: No timer.
OHKO: Link will always die in one hit.
''')
parser.add_argument('--progressive', default='on', const='on', nargs='?', choices=['on', 'off', 'random'],
help='''\
Select progressive bow setting. Affects available itempool. (default: %(default)s)
On: The first bow you find will give you access
to the bow item. The second will give you
Silver Arrows.
Off: Bow and Silver Arrows are separate items.
Random: Bows will randomly be progressive or not.
''')
parser.add_argument('--shuffle', default='vanilla', const='vanilla', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full', 'crossed', 'dungeonsfull', 'dungeonssimple'],
help='''\
Select Entrance Shuffling Algorithm. (default: %(default)s)
Full: Mix cave and dungeon entrances freely while limiting
multi-entrance caves to one world.
Simple: Shuffle Dungeon Entrances/Exits between each other
and keep all 4-entrance dungeons confined to one
location. All caves outside of death mountain are
shuffled in pairs and matched by original type.
Restricted: Use Dungeons shuffling from Simple but freely
connect remaining entrances.
Crossed: Mix cave and dungeon entrances freely while allowing
caves to cross between worlds.
Vanilla: All entrances are in the same locations they were
in the base game.
The dungeon variants only mix up dungeons and keep the rest of
the overworld vanilla.
''')
parser.add_argument('--crystals_ganon', default='7', const='7', nargs='?', choices=['random', '0', '1', '2', '3', '4', '5', '6', '7'],
help='''\
How many crystals are needed to defeat ganon. Any other
requirements for ganon for the selected goal still apply.
This setting does not apply when the all dungeons goal is
selected. (default: %(default)s)
Random: Picks a random value between 0 and 7 (inclusive).
0-7: Number of crystals needed
''')
parser.add_argument('--crystals_gt', default='7', const='7', nargs='?', choices=['random', '0', '1', '2', '3', '4', '5', '6', '7'],
help='''\
How many crystals are needed to open GT. For inverted mode
this applies to the castle tower door instead. (default: %(default)s)
Random: Picks a random value between 0 and 7 (inclusive).
0-7: Number of crystals needed
''')
parser.add_argument('--rom', default='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc', help='Path to an ALttP JAP(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('--fastmenu', default='normal', const='normal', nargs='?', choices=['normal', 'instant', 'double', 'triple', 'quadruple', 'half'],
help='''\
Select the rate at which the menu opens and closes.
(default: %(default)s)
''')
parser.add_argument('--quickswap', help='Enable quick item swapping with L and R.', action='store_true')
parser.add_argument('--pseudoboots', help='Enable pseduoboots (can dash but no logical checks).', action='store_true')
parser.add_argument('--disablemusic', help='Disables game music.', action='store_true')
parser.add_argument('--keysanity', help='''\
Keys (and other dungeon items) are no longer restricted to
their dungeons, but can be anywhere
''', action='store_true')
parser.add_argument('--retro', help='''\
Keys are universal, shooting arrows costs rupees,
and a few other little things make this more like Zelda-1.
''', 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('--accessibility', default='items', const='items', nargs='?', choices=['items', 'locations', 'none'], help='''\
Select Item/Location Accessibility. (default: %(default)s)
Items: You can reach all unique inventory items. No guarantees about
reaching all locations or all keys.
Locations: You will be able to reach every location in the game.
None: You will be able to reach enough locations to beat the game.
''')
parser.add_argument('--hints', help='''\
Make telepathic tiles and storytellers give helpful hints.
''', action='store_true')
# included for backwards compatibility
parser.add_argument('--shuffleganon', help=argparse.SUPPRESS, action='store_true', default=True)
parser.add_argument('--no-shuffleganon', help='''\
If set, the Pyramid Hole and Ganon's Tower are not
included entrance shuffle pool.
''', action='store_false', dest='shuffleganon')
parser.add_argument('--heartbeep', default='normal', const='normal', nargs='?', choices=['double', 'normal', 'half', 'quarter', 'off'],
help='''\
Select the rate at which the heart beep sound is played at
low health. (default: %(default)s)
''')
parser.add_argument('--heartcolor', default='red', const='red', nargs='?', choices=['red', 'blue', 'green', 'yellow', 'random'],
help='Select the color of Link\'s heart meter. (default: %(default)s)')
parser.add_argument('--sprite', help='''\
Path to a sprite sheet to use for Link. Needs to be in
binary format and have a length of 0x7000 (28672) bytes,
or 0x7078 (28792) bytes including palette data.
Alternatively, can be a ALttP Rom patched with a Link
sprite that will be extracted.
''')
parser.add_argument('--huditemcounter', default=False, help='''\
Displays a (number of items collected) / (total items available) counter
on the HUD.
''', action='store_true')
parser.add_argument('--nofastrom', default=False, help='''\
Displays a (number of items collected) / (total items available) counter
on the HUD.
''', action='store_true')
parser.add_argument('--suppress_rom', help='Do not create an output rom file.', action='store_true')
parser.add_argument('--gui', help='Launch the GUI', action='store_true')
parser.add_argument('--jsonout', action='store_true', help='''\
Output .json patch to stdout instead of a patched rom. Used
for VT site integration, do not use otherwise.
''')
parser.add_argument('--skip_playthrough', action='store_true', default=False)
parser.add_argument('--enemizercli', default='')
parser.add_argument('--shufflebosses', default='none', choices=['none', 'basic', 'normal', 'chaos'])
parser.add_argument('--shuffleenemies', default=False, action='store_true')
parser.add_argument('--enemy_health', default='default', choices=['default', 'easy', 'normal', 'hard', 'expert'])
parser.add_argument('--enemy_damage', default='default', choices=['default', 'shuffled', 'chaos'])
parser.add_argument('--shufflepalette', default=False, action='store_true')
parser.add_argument('--shufflepots', default=False, action='store_true')
parser.add_argument('--multi', default=1, type=lambda value: min(max(int(value), 1), 255))
parser.add_argument('--securerandom', default=False, action='store_true')
parser.add_argument('--outputpath')
parser.add_argument('--outputname')
args = parser.parse_args()
if args.outputpath and os.path.isdir(args.outputpath):
output_path.cached_path = args.outputpath
if is_bundled() and len(sys.argv) == 1:
# for the bundled builds, if we have no arguments, the user
# probably wants the gui. Users of the bundled build who want the command line
# interface shouuld specify at least one option, possibly setting a value to a
# default if they like all the defaults
from Gui import guiMain
close_console()
guiMain()
sys.exit(0)
# ToDo: Validate files further than mere existance
if not args.jsonout and 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)
sys.exit(1)
if args.sprite is not None and not os.path.isfile(args.sprite):
if not args.jsonout:
input('Could not find link sprite sheet at given location. \nPress Enter to exit.' % args.sprite)
sys.exit(1)
else:
raise IOError('Cannot find sprite file at %s' % args.sprite)
# set up logger
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:
from Gui import guiMain
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)
else:
main(seed=args.seed, args=args)
if __name__ == '__main__':
start()
-2440
View File
File diff suppressed because it is too large Load Diff
+1196 -282
View File
File diff suppressed because it is too large Load Diff
+183 -1412
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -1,13 +1,15 @@
import os
import queue
import threading
import tkinter as tk
from Utils import local_path
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=local_path(os.path.join("data","ER16.gif")))
er32 = tk.PhotoImage(file=local_path(os.path.join("data","ER32.gif")))
er48 = tk.PhotoImage(file=local_path(os.path.join("data","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
+72 -17
View File
@@ -1,4 +1,5 @@
from dataclasses import dataclass, field
from typing import List
from BaseClasses import CollectionState
from Utils import count_set_bits
@@ -18,7 +19,7 @@ def _new_default_sram():
@dataclass
class InitialSram:
_initial_sram_bytes: list[int] = field(default_factory=_new_default_sram)
_initial_sram_bytes: List[int] = field(default_factory=_new_default_sram)
def _set_value(self, idx: int, val:int):
if idx > SRAM_SIZE:
@@ -52,6 +53,9 @@ class InitialSram:
def pre_open_pyramid_hole(self):
self._or_value(OVERWORLD_DATA+0x5B, 0x20)
def pre_set_overworld_flag(self, owid, bitmask):
self._or_value(OVERWORLD_DATA+owid, bitmask)
def pre_open_tr_bomb_doors(self):
self._or_value(ROOM_DATA+0x47, 0x80)
self._or_value(ROOM_DATA+0x01AB, 0x80)
@@ -61,16 +65,23 @@ class InitialSram:
equip[0x36C] = 0x18
equip[0x36D] = 0x18
equip[0x379] = 0x68
starting_bomb_cap_upgrades = 10 if not world.bombbag[player] else 0
starting_arrow_cap_upgrades = 30
starting_bombs = 0
starting_arrows = 0
starting_magic = 0
starting_bomb_cap_upgrades = 0
starting_arrow_cap_upgrades = 0
if world.flute_mode[player] == 'pseudo':
self._initial_sram_bytes[0x3C2] = 0xFF
equip[0x34C] = 0x03
equip[0x38C] = 0x01
startingstate = CollectionState(world)
if startingstate.has('Bow', player):
equip[0x340] = 3 if startingstate.has('Silver Arrows', player) else 1
equip[0x38E] |= 0x20 # progressive flag to get the correct hint in all cases
if not world.retro[player]:
if not world.bow_mode[player].startswith('retro'):
equip[0x38E] |= 0x80
if startingstate.has('Silver Arrows', player):
equip[0x38E] |= 0x40
@@ -103,10 +114,43 @@ class InitialSram:
if startingstate.has('Magic Upgrade (1/4)', player):
equip[0x37B] = 2
equip[0x36E] = 0x80
starting_magic = 0x80
elif startingstate.has('Magic Upgrade (1/2)', player):
equip[0x37B] = 1
equip[0x36E] = 0x80
starting_magic = 0x80
if world.mode[player] == 'standard' and world.logic[player] not in ['noglitches', 'minorglitches']:
if startingstate.has('Ocarina (Activated)', player):
self.pre_set_overworld_flag(0x18, 0x20)
if startingstate.has('Return Old Man', player):
self._initial_sram_bytes[0x410] |= 0x01
if startingstate.has('Beat Agahnim 1', player):
self.pre_open_lumberjack()
if world.mode[player] == 'standard':
self.set_progress_indicator(0x80)
else:
self.set_progress_indicator(0x03)
if startingstate.has('Zelda Herself', player):
self._initial_sram_bytes[0x3CC] = 0x01
elif startingstate.has('Escort Old Man', player):
self._initial_sram_bytes[0x3CC] = 0x04
elif startingstate.has('Maiden Rescued', player):
self._initial_sram_bytes[0x3CC] = 0x06
elif startingstate.has('Get Frog', player):
self._initial_sram_bytes[0x3CC] = 0x07
elif startingstate.has('Sign Vandalized', player):
self._initial_sram_bytes[0x3CC] = 0x09
elif startingstate.has('Pick Up Kiki', player):
self._initial_sram_bytes[0x3CC] = 0x0A
elif startingstate.has('Pick Up Purple Chest', player):
self._initial_sram_bytes[0x3CC] = 0x0C
elif startingstate.has('Pick Up Big Bomb', player):
self._initial_sram_bytes[0x3CC] = 0x0D
if self._initial_sram_bytes[0x3CC] > 0x01 and world.mode[player] == 'standard':
self._initial_sram_bytes[0x3D3] = 0x80
for item in world.precollected_items:
if item.player != player:
@@ -117,7 +161,10 @@ class InitialSram:
'Golden Sword', 'Tempered Sword', 'Master Sword', 'Fighter Sword', 'Progressive Sword',
'Mirror Shield', 'Red Shield', 'Blue Shield', 'Progressive Shield',
'Red Mail', 'Blue Mail', 'Progressive Armor',
'Magic Upgrade (1/4)', 'Magic Upgrade (1/2)']:
'Magic Upgrade (1/4)', 'Magic Upgrade (1/2)',
'Return Old Man', 'Beat Agahnim 1', 'Zelda Herself', 'Escort Old Man',
'Maiden Rescued', 'Get Frog', 'Sign Vandalized', 'Pick Up Kiki',
'Pick Up Purple Chest', 'Pick Up Big Bomb']:
continue
set_table = {'Book of Mudora': (0x34E, 1), 'Hammer': (0x34B, 1), 'Bug Catching Net': (0x34D, 1), 'Hookshot': (0x342, 1), 'Magic Mirror': (0x353, 2),
@@ -139,8 +186,9 @@ class InitialSram:
'Big Key (Misery Mire)': (0x367, 0x01), 'Compass (Misery Mire)': (0x365, 0x01), 'Map (Misery Mire)': (0x369, 0x01),
'Big Key (Turtle Rock)': (0x366, 0x08), 'Compass (Turtle Rock)': (0x364, 0x08), 'Map (Turtle Rock)': (0x368, 0x08),
'Big Key (Ganons Tower)': (0x366, 0x04), 'Compass (Ganons Tower)': (0x364, 0x04), 'Map (Ganons Tower)': (0x368, 0x04)}
set_or_table = {'Flippers': (0x356, 1, 0x379, 0x02),'Pegasus Boots': (0x355, 1, 0x379, 0x04),
'Shovel': (0x34C, 1, 0x38C, 0x04), 'Ocarina': (0x34C, 3, 0x38C, 0x01),
set_or_table = {'Flippers': (0x356, 1, 0x379, 0x02), 'Pegasus Boots': (0x355, 1, 0x379, 0x04),
'Shovel': (0x34C, 1, 0x38C, 0x04), 'Ocarina': (0x34C, 2, 0x38C, 0x02),
'Ocarina (Activated)': (0x34C, 3, 0x38C, 0x01),
'Mushroom': (0x344, 1, 0x38C, 0x20 | 0x08), 'Magic Powder': (0x344, 2, 0x38C, 0x10),
'Blue Boomerang': (0x341, 1, 0x38C, 0x80), 'Red Boomerang': (0x341, 2, 0x38C, 0x40)}
keys = {'Small Key (Eastern Palace)': [0x37E], 'Small Key (Desert Palace)': [0x37F],
@@ -159,6 +207,7 @@ class InitialSram:
arrow_caps = {'Arrow Upgrade (+5)': 5, 'Arrow Upgrade (+10)': 10}
bombs = {'Single Bomb': 1, 'Bombs (3)': 3, 'Bombs (10)': 10}
arrows = {'Single Arrow': 1, 'Arrows (10)': 10}
magic = {'Big Magic': 0x80, 'Small Magic': 0x10}
if item.name in set_table:
equip[set_table[item.name][0]] = set_table[item.name][1]
@@ -182,27 +231,33 @@ class InitialSram:
elif item.name in arrow_caps:
starting_arrow_cap_upgrades += arrow_caps[item.name]
elif item.name in bombs:
equip[0x343] += bombs[item.name]
starting_bombs += bombs[item.name]
elif item.name in arrows:
if world.retro[player]:
if world.bow_mode[player].startswith('retro'):
equip[0x38E] |= 0x80
equip[0x377] = 1
starting_arrows = 1
else:
equip[0x377] += arrows[item.name]
starting_arrows += arrows[item.name]
elif item.name in ['Piece of Heart', 'Boss Heart Container', 'Sanctuary Heart Container']:
if item.name == 'Piece of Heart':
equip[0x36B] = (equip[0x36B] + 1) % 4
if item.name != 'Piece of Heart' or equip[0x36B] == 0:
equip[0x36C] = min(equip[0x36C] + 0x08, 0xA0)
equip[0x36D] = min(equip[0x36D] + 0x08, 0xA0)
elif item.name in magic:
starting_magic += magic[item.name]
else:
raise RuntimeError(f'Unsupported item in starting equipment: {item.name}')
equip[0x36E] = min(starting_magic, 0x80)
equip[0x370] = min(starting_bomb_cap_upgrades, 50)
equip[0x371] = min(starting_arrow_cap_upgrades, 70)
equip[0x343] = min(equip[0x343], 10)
equip[0x377] = min(equip[0x377], 30)
equip[0x343] = min(starting_bombs, equip[0x370])
equip[0x377] = min(starting_arrows, equip[0x371])
if not startingstate.has('Magic Mirror', player) and (world.doorShuffle[player] != 'vanilla' or world.mirrorscroll[player]):
equip[0x353] = 1
# Assertion and copy equip to initial_sram_bytes
assert equip[:0x340] == [0] * 0x340
self._initial_sram_bytes[0x340:0x38F] = equip[0x340:0x38F]
@@ -214,7 +269,7 @@ class InitialSram:
self._initial_sram_bytes[0x422] = self._initial_sram_bytes[0x35A]
self._initial_sram_bytes[0x46E] = self._initial_sram_bytes[0x35B]
if world.swords == "swordless":
if world.swords[player] == "swordless":
self._initial_sram_bytes[0x359] = 0xFF
self._initial_sram_bytes[0x417] = 0x00
-644
View File
@@ -1,644 +0,0 @@
import collections
from BaseClasses import Region, Location, Entrance, RegionType, Shop, ShopType
def create_inverted_regions(world, player):
world.regions += [
create_lw_region(player, 'Light World', ['Mushroom', 'Bottle Merchant', 'Flute Spot', 'Sunken Treasure', 'Purple Chest', 'Bombos Tablet'],
["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Kings Grave Outer Rocks', 'Dam',
'Inverted Big Bomb Shop', 'Tavern North', 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Kakariko Well Drop', 'Kakariko Well Cave',
'Blacksmiths Hut', 'Bat Cave Drop Ledge', 'Bat Cave Cave', 'Sick Kids House', 'Hobo Bridge', 'Lost Woods Hideout Drop', 'Lost Woods Hideout Stump',
'Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Mini Moldorm Cave', 'Ice Rod Cave', 'Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia Warp',
'Bonk Rock Cave', 'Library', 'Two Brothers House (East)', 'Desert Palace Stairs', 'Eastern Palace', 'Master Sword Meadow',
'Sanctuary', 'Sanctuary Grave', 'Death Mountain Entrance Rock', 'Light World River Drop',
'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)',
'Kakariko Shop', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', 'Cave Shop (Lake Hylia)',
'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game',
'East Dark World Mirror Spot', 'West Dark World Mirror Spot', 'South Dark World Mirror Spot', 'Cave 45', 'Checkerboard Cave', 'Mire Mirror Spot', 'Hammer Peg Area Mirror Spot',
'Shopping Mall Mirror Spot', 'Skull Woods Mirror Spot', 'Inverted Pyramid Entrance','Hyrule Castle Entrance (South)', 'Secret Passage Outer Bushes', 'Bush Covered Lawn Outer Bushes',
'Potion Shop Outer Bushes', 'Graveyard Cave Outer Bushes', 'Bomb Hut Outer Bushes']),
create_lw_region(player, 'Bush Covered Lawn', None, ['Bush Covered House', 'Bush Covered Lawn Inner Bushes', 'Bush Covered Lawn Mirror Spot']),
create_lw_region(player, 'Bomb Hut Area', None, ['Light World Bomb Hut', 'Bomb Hut Inner Bushes', 'Bomb Hut Mirror Spot']),
create_lw_region(player, 'Hyrule Castle Secret Entrance Area', None, ['Hyrule Castle Secret Entrance Stairs', 'Secret Passage Inner Bushes']),
create_lw_region(player, 'Death Mountain Entrance', None, ['Old Man Cave (West)', 'Death Mountain Entrance Drop', 'Bumper Cave Entrance Mirror Spot']),
create_lw_region(player, 'Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Mirror Spot']),
create_cave_region(player, 'Blinds Hideout', 'a bounty of five items', ["Blind\'s Hideout - Top",
"Blind\'s Hideout - Left",
"Blind\'s Hideout - Right",
"Blind\'s Hideout - Far Left",
"Blind\'s Hideout - Far Right"]),
create_lw_region(player, 'Northeast Light World', None, ['Zoras River', 'Waterfall Stoop', 'Potion Shop Outer Rock', 'Northeast Dark World Mirror Spot', 'Northeast Light World Warp']),
create_lw_region(player, 'Waterfall Stoop', None, ['Northeast Light World', 'Waterfall of Wishing']),
create_lw_region(player, 'Potion Shop Area', None, ['Potion Shop', 'Potion Shop Inner Bushes', 'Potion Shop Inner Rock', 'Potion Shop Mirror Spot', 'Potion Shop River Drop']),
create_lw_region(player, 'Graveyard Cave Area', None, ['Graveyard Cave', 'Graveyard Cave Inner Bushes', 'Graveyard Cave Mirror Spot']),
create_lw_region(player, 'River', None, ['Light World Pier', 'Potion Shop Pier']),
create_cave_region(player, 'Hyrule Castle Secret Entrance', 'a drop\'s exit', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']),
create_lw_region(player, 'Zoras River', ['King Zora', 'Zora\'s Ledge']),
create_cave_region(player, 'Waterfall of Wishing', 'a cave with two chests', ['Waterfall Fairy - Left', 'Waterfall Fairy - Right']),
create_lw_region(player, 'Kings Grave Area', None, ['Kings Grave', 'Kings Grave Inner Rocks']),
create_cave_region(player, 'Kings Grave', 'a cave with a chest', ['King\'s Tomb']),
create_cave_region(player, 'North Fairy Cave', 'a drop\'s exit', None, ['North Fairy Cave Exit']),
create_cave_region(player, 'Dam', 'the dam', ['Floodgate', 'Floodgate Chest']),
create_cave_region(player, 'Inverted Links House', 'your house', ['Link\'s House'], ['Inverted Links House Exit']),
create_cave_region(player, 'Chris Houlihan Room', 'I AM ERROR', None, ['Chris Houlihan Room Exit']),
create_cave_region(player, 'Tavern', 'the tavern', ['Kakariko Tavern']),
create_cave_region(player, 'Elder House', 'a connector', None, ['Elder House Exit (East)', 'Elder House Exit (West)']),
create_cave_region(player, 'Snitch Lady (East)', 'a boring house'),
create_cave_region(player, 'Snitch Lady (West)', 'a boring house'),
create_cave_region(player, 'Bush Covered House', 'the grass man'),
create_cave_region(player, 'Tavern (Front)', 'the tavern'),
create_cave_region(player, 'Light World Bomb Hut', 'a restock room'),
create_cave_region(player, 'Kakariko Shop', 'a common shop'),
create_cave_region(player, 'Fortune Teller (Light)', 'a fortune teller'),
create_cave_region(player, 'Lake Hylia Fortune Teller', 'a fortune teller'),
create_cave_region(player, 'Lumberjack House', 'a boring house'),
create_cave_region(player, 'Bonk Fairy (Light)', 'a fairy fountain'),
create_cave_region(player, 'Bonk Fairy (Dark)', 'a fairy fountain'),
create_cave_region(player, 'Lake Hylia Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'Swamp Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'Desert Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'Dark Lake Hylia Ledge Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'Dark Desert Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'Dark Death Mountain Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'Chicken House', 'a house with a chest', ['Chicken House']),
create_cave_region(player, 'Aginahs Cave', 'a cave with a chest', ['Aginah\'s Cave']),
create_cave_region(player, 'Sahasrahlas Hut', 'Sahasrahla', ['Sahasrahla\'s Hut - Left', 'Sahasrahla\'s Hut - Middle', 'Sahasrahla\'s Hut - Right', 'Sahasrahla']),
create_cave_region(player, 'Kakariko Well (top)', 'a drop\'s exit', ['Kakariko Well - Top', 'Kakariko Well - Left', 'Kakariko Well - Middle',
'Kakariko Well - Right', 'Kakariko Well - Bottom'], ['Kakariko Well (top to bottom)']),
create_cave_region(player, 'Kakariko Well (bottom)', 'a drop\'s exit', None, ['Kakariko Well Exit']),
create_cave_region(player, 'Blacksmiths Hut', 'the smith', ['Blacksmith', 'Missing Smith']),
create_lw_region(player, 'Bat Cave Drop Ledge', None, ['Bat Cave Drop']),
create_cave_region(player, 'Bat Cave (right)', 'a drop\'s exit', ['Magic Bat'], ['Bat Cave Door']),
create_cave_region(player, 'Bat Cave (left)', 'a drop\'s exit', None, ['Bat Cave Exit']),
create_cave_region(player, 'Sick Kids House', 'the sick kid', ['Sick Kid']),
create_lw_region(player, 'Hobo Bridge', ['Hobo']),
create_cave_region(player, 'Lost Woods Hideout (top)', 'a drop\'s exit', ['Lost Woods Hideout'], ['Lost Woods Hideout (top to bottom)']),
create_cave_region(player, 'Lost Woods Hideout (bottom)', 'a drop\'s exit', None, ['Lost Woods Hideout Exit']),
create_cave_region(player, 'Lumberjack Tree (top)', 'a drop\'s exit', ['Lumberjack Tree'], ['Lumberjack Tree (top to bottom)']),
create_cave_region(player, 'Lumberjack Tree (bottom)', 'a drop\'s exit', None, ['Lumberjack Tree Exit']),
create_cave_region(player, 'Cave 45', 'a cave with an item', ['Cave 45']),
create_cave_region(player, 'Graveyard Cave', 'a cave with an item', ['Graveyard Cave']),
create_cave_region(player, 'Checkerboard Cave', 'a cave with an item', ['Checkerboard Cave']),
create_cave_region(player, 'Long Fairy Cave', 'a fairy fountain'),
create_cave_region(player, 'Mini Moldorm Cave', 'a bounty of five items', ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right',
'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Generous Guy']),
create_cave_region(player, 'Ice Rod Cave', 'a cave with a chest', ['Ice Rod Cave']),
create_cave_region(player, 'Good Bee Cave', 'a cold bee'),
create_cave_region(player, '20 Rupee Cave', 'a cave with some cash'),
create_cave_region(player, 'Cave Shop (Lake Hylia)', 'a common shop'),
create_cave_region(player, 'Cave Shop (Dark Death Mountain)', 'a common shop'),
create_cave_region(player, 'Bonk Rock Cave', 'a cave with a chest', ['Bonk Rock Cave']),
create_cave_region(player, 'Library', 'the library', ['Library']),
create_cave_region(player, 'Kakariko Gamble Game', 'a game of chance'),
create_cave_region(player, 'Potion Shop', 'the potion shop', ['Potion Shop']),
create_lw_region(player, 'Lake Hylia Island', ['Lake Hylia Island']),
create_cave_region(player, 'Capacity Upgrade', 'the queen of fairies'),
create_cave_region(player, 'Two Brothers House', 'a connector', None, ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)']),
create_lw_region(player, 'Maze Race Ledge', ['Maze Race'], ['Two Brothers House (West)', 'Maze Race Mirror Spot']),
create_cave_region(player, '50 Rupee Cave', 'a cave with some cash'),
create_lw_region(player, 'Desert Ledge', ['Desert Ledge'], ['Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (West)', 'Desert Ledge Drop']),
create_lw_region(player, 'Desert Palace Stairs', None, ['Desert Palace Entrance (South)', 'Desert Palace Stairs Mirror Spot']),
create_lw_region(player, 'Desert Palace Lone Stairs', None, ['Desert Palace Stairs Drop', 'Desert Palace Entrance (East)']),
create_lw_region(player, 'Desert Palace Entrance (North) Spot', None, ['Desert Palace Entrance (North)', 'Desert Ledge Return Rocks', 'Desert Palace North Mirror Spot']),
create_dungeon_region(player, 'Desert Palace Main (Outer)', 'Desert Palace', ['Desert Palace - Big Chest', 'Desert Palace - Torch', 'Desert Palace - Map Chest'],
['Desert Palace Pots (Outer)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)', 'Desert Palace East Wing']),
create_dungeon_region(player, 'Desert Palace Main (Inner)', 'Desert Palace', None, ['Desert Palace Exit (South)', 'Desert Palace Pots (Inner)']),
create_dungeon_region(player, 'Desert Palace East', 'Desert Palace', ['Desert Palace - Compass Chest', 'Desert Palace - Big Key Chest']),
create_dungeon_region(player, 'Desert Palace North', 'Desert Palace', ['Desert Palace - Boss', 'Desert Palace - Prize'], ['Desert Palace Exit (North)']),
create_dungeon_region(player, 'Eastern Palace', 'Eastern Palace', ['Eastern Palace - Compass Chest', 'Eastern Palace - Big Chest', 'Eastern Palace - Cannonball Chest',
'Eastern Palace - Big Key Chest', 'Eastern Palace - Map Chest', 'Eastern Palace - Boss', 'Eastern Palace - Prize'], ['Eastern Palace Exit']),
create_lw_region(player, 'Master Sword Meadow', ['Master Sword Pedestal']),
create_cave_region(player, 'Lost Woods Gamble', 'a game of chance'),
create_lw_region(player, 'Hyrule Castle Ledge', None, ['Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)', 'Inverted Ganons Tower', 'Hyrule Castle Ledge Courtyard Drop', 'Inverted Pyramid Hole']),
create_dungeon_region(player, 'Hyrule Castle', 'Hyrule Castle', ['Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest'],
['Hyrule Castle Exit (East)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (South)', 'Throne Room']),
create_dungeon_region(player, 'Sewer Drop', 'a drop\'s exit', None, ['Sewer Drop']), # This exists only to be referenced for access checks
create_dungeon_region(player, 'Sewers (Dark)', 'a drop\'s exit', ['Sewers - Dark Cross'], ['Sewers Door']),
create_dungeon_region(player, 'Sewers', 'a drop\'s exit', ['Sewers - Secret Room - Left', 'Sewers - Secret Room - Middle',
'Sewers - Secret Room - Right'], ['Sanctuary Push Door', 'Sewers Back Door']),
create_dungeon_region(player, 'Sanctuary', 'a drop\'s exit', ['Sanctuary'], ['Sanctuary Exit']),
create_dungeon_region(player, 'Inverted Agahnims Tower', 'Castle Tower', ['Castle Tower - Room 03', 'Castle Tower - Dark Maze'], ['Agahnim 1', 'Inverted Agahnims Tower Exit']),
create_dungeon_region(player, 'Agahnim 1', 'Castle Tower', ['Agahnim 1'], None),
create_cave_region(player, 'Old Man Cave', 'a connector', ['Old Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']),
create_cave_region(player, 'Old Man House', 'a connector', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']),
create_cave_region(player, 'Old Man House Back', 'a connector', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']),
create_lw_region(player, 'Death Mountain', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave',
'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Mirror Spot']),
create_cave_region(player, 'Death Mountain Return Cave', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']),
create_lw_region(player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)', 'Bumper Cave Ledge Mirror Spot']),
create_cave_region(player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']),
create_cave_region(player, 'Spectacle Rock Cave (Bottom)', 'a connector', None, ['Spectacle Rock Cave Exit']),
create_cave_region(player, 'Spectacle Rock Cave (Peak)', 'a connector', None, ['Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave Exit (Peak)']),
create_lw_region(player, 'East Death Mountain (Bottom)', None, ['Broken Bridge (East)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'East Death Mountain Mirror Spot (Bottom)', 'Hookshot Fairy',
'Fairy Ascension Rocks', 'Spiral Cave (Bottom)']),
create_cave_region(player, 'Hookshot Fairy', 'fairies deep in a cave'),
create_cave_region(player, 'Paradox Cave Front', 'a connector', None, ['Paradox Cave Push Block Reverse', 'Paradox Cave Exit (Bottom)', 'Light World Death Mountain Shop']),
create_cave_region(player, 'Paradox Cave Chest Area', 'a connector', ['Paradox Cave Lower - Far Left',
'Paradox Cave Lower - Left',
'Paradox Cave Lower - Right',
'Paradox Cave Lower - Far Right',
'Paradox Cave Lower - Middle',
'Paradox Cave Upper - Left',
'Paradox Cave Upper - Right'],
['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']),
create_cave_region(player, 'Paradox Cave', 'a connector', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']),
create_cave_region(player, 'Light World Death Mountain Shop', 'a common shop'),
create_lw_region(player, 'East Death Mountain (Top)', ['Floating Island'], ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'East Death Mountain Mirror Spot (Top)', 'Fairy Ascension Ledge Access', 'Mimic Cave Ledge Access',
'Floating Island Mirror Spot']),
create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop', 'Dark Death Mountain Ledge Mirror Spot (West)']),
create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Cave', 'Mimic Cave Ledge Drop', 'Dark Death Mountain Ledge Mirror Spot (East)']),
create_cave_region(player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']),
create_cave_region(player, 'Spiral Cave (Bottom)', 'a connector', None, ['Spiral Cave Exit']),
create_lw_region(player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Drop', 'Fairy Ascension Cave (Bottom)']),
create_cave_region(player, 'Fairy Ascension Cave (Bottom)', 'a connector', None, ['Fairy Ascension Cave Climb', 'Fairy Ascension Cave Exit (Bottom)']),
create_cave_region(player, 'Fairy Ascension Cave (Drop)', 'a connector', None, ['Fairy Ascension Cave Pots']),
create_cave_region(player, 'Fairy Ascension Cave (Top)', 'a connector', None, ['Fairy Ascension Cave Exit (Top)', 'Fairy Ascension Cave Drop']),
create_lw_region(player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)', 'Laser Bridge Mirror Spot']),
create_lw_region(player, 'Death Mountain (Top)', ['Ether Tablet', 'Spectacle Rock'], ['East Death Mountain (Top)', 'Tower of Hera', 'Death Mountain Drop', 'Death Mountain (Top) Mirror Spot']),
create_dw_region(player, 'Bumper Cave Ledge', ['Bumper Cave Ledge'], ['Bumper Cave Ledge Drop', 'Bumper Cave (Top)']),
create_dungeon_region(player, 'Tower of Hera (Bottom)', 'Tower of Hera', ['Tower of Hera - Basement Cage', 'Tower of Hera - Map Chest'], ['Tower of Hera Small Key Door', 'Tower of Hera Big Key Door', 'Tower of Hera Exit']),
create_dungeon_region(player, 'Tower of Hera (Basement)', 'Tower of Hera', ['Tower of Hera - Big Key Chest']),
create_dungeon_region(player, 'Tower of Hera (Top)', 'Tower of Hera', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Boss', 'Tower of Hera - Prize']),
create_dw_region(player, 'East Dark World', ['Pyramid'], ['Pyramid Fairy', 'South Dark World Bridge', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)',
'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Northeast Dark World Broken Bridge Pass', 'East Dark World Teleporter', 'EDW Flute']),
create_dw_region(player, 'Northeast Dark World', ['Catfish'], ['West Dark World Gap', 'Dark World Potion Shop', 'East Dark World Broken Bridge Pass', 'NEDW Flute', 'Dark Lake Hylia Teleporter']),
create_cave_region(player, 'Palace of Darkness Hint', 'a storyteller'),
create_cave_region(player, 'East Dark World Hint', 'a storyteller'),
create_dw_region(player, 'South Dark World', ['Stumpy', 'Digging Game'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', 'East Dark World Bridge', 'Inverted Links House', 'Archery Game', 'Bonk Fairy (Dark)',
'Dark Lake Hylia Shop', 'South Dark World Teleporter', 'Post Aga Teleporter', 'SDW Flute']),
create_cave_region(player, 'Inverted Big Bomb Shop', 'the bomb shop'),
create_cave_region(player, 'Archery Game', 'a game of skill'),
create_dw_region(player, 'Dark Lake Hylia', None, ['East Dark World Pier', 'Dark Lake Hylia Ledge Pier', 'Ice Palace', 'Dark Lake Hylia Central Island Teleporter']),
create_dw_region(player, 'Dark Lake Hylia Ledge', None, ['Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'DLHL Flute']),
create_cave_region(player, 'Dark Lake Hylia Ledge Hint', 'a storyteller'),
create_cave_region(player, 'Dark Lake Hylia Ledge Spike Cave', 'a spiky hint'),
create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left',
'Hype Cave - Bottom', 'Hype Cave - Generous Guy']),
create_dw_region(player, 'West Dark World', ['Frog'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Bumper Cave Entrance Rock',
'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop',
'West Dark World Teleporter', 'WDW Flute']),
create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop', 'Dark Grassy Lawn Flute']),
create_dw_region(player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], ['Dark World Hammer Peg Cave', 'Peg Area Rocks', 'Hammer Peg Area Flute']),
create_dw_region(player, 'Bumper Cave Entrance', None, ['Bumper Cave (Bottom)', 'Bumper Cave Entrance Drop']),
create_cave_region(player, 'Fortune Teller (Dark)', 'a fortune teller'),
create_cave_region(player, 'Village of Outcasts Shop', 'a common shop'),
create_cave_region(player, 'Dark Lake Hylia Shop', 'a common shop'),
create_cave_region(player, 'Dark World Lumberjack Shop', 'a common shop'),
create_cave_region(player, 'Dark World Potion Shop', 'a common shop'),
create_cave_region(player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']),
create_cave_region(player, 'Pyramid Fairy', 'a cave with two chests', ['Pyramid Fairy - Left', 'Pyramid Fairy - Right']),
create_cave_region(player, 'Brewery', 'a house with a chest', ['Brewery']),
create_cave_region(player, 'C-Shaped House', 'a house with a chest', ['C-Shaped House']),
create_cave_region(player, 'Chest Game', 'a game of 16 chests', ['Chest Game']),
create_cave_region(player, 'Red Shield Shop', 'the rare shop'),
create_cave_region(player, 'Inverted Dark Sanctuary', 'a storyteller'),
create_cave_region(player, 'Bumper Cave', 'a connector', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Exit (Top)']),
create_dw_region(player, 'Skull Woods Forest', None, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)',
'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)']),
create_dw_region(player, 'Skull Woods Forest (West)', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section']),
create_dw_region(player, 'Dark Desert', None, ['Misery Mire', 'Mire Shed', 'Dark Desert Hint', 'Dark Desert Fairy', 'DD Flute']),
create_dw_region(player, 'Dark Desert Ledge', None, ['Dark Desert Drop', 'Dark Desert Teleporter']),
create_cave_region(player, 'Mire Shed', 'a cave with two chests', ['Mire Shed - Left', 'Mire Shed - Right']),
create_cave_region(player, 'Dark Desert Hint', 'a storyteller'),
create_dw_region(player, 'Dark Death Mountain', None, ['Dark Death Mountain Drop (East)', 'Inverted Agahnims Tower', 'Superbunny Cave (Top)', 'Hookshot Cave', 'Turtle Rock',
'Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Turtle Rock Tail Drop', 'DDM Flute']),
create_dw_region(player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)']),
create_dw_region(player, 'Turtle Rock (Top)', None, ['Dark Death Mountain Teleporter (East)', 'Turtle Rock Drop']),
create_dw_region(player, 'Dark Death Mountain Isolated Ledge', None, ['Turtle Rock Isolated Ledge Entrance']),
create_dw_region(player, 'Dark Death Mountain (East Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East Bottom)', 'EDDM Flute']),
create_cave_region(player, 'Superbunny Cave', 'a connector', ['Superbunny Cave - Top', 'Superbunny Cave - Bottom'],
['Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)']),
create_cave_region(player, 'Spike Cave', 'Spike Cave', ['Spike Cave']),
create_cave_region(player, 'Hookshot Cave', 'a connector', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'],
['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']),
create_dw_region(player, 'Death Mountain Floating Island (Dark World)', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance']),
create_cave_region(player, 'Mimic Cave', 'Mimic Cave', ['Mimic Cave']),
create_dungeon_region(player, 'Swamp Palace (Entrance)', 'Swamp Palace', None, ['Swamp Palace Moat', 'Swamp Palace Exit']),
create_dungeon_region(player, 'Swamp Palace (First Room)', 'Swamp Palace', ['Swamp Palace - Entrance'], ['Swamp Palace Small Key Door']),
create_dungeon_region(player, 'Swamp Palace (Starting Area)', 'Swamp Palace', ['Swamp Palace - Map Chest'], ['Swamp Palace (Center)']),
create_dungeon_region(player, 'Swamp Palace (Center)', 'Swamp Palace', ['Swamp Palace - Big Chest', 'Swamp Palace - Compass Chest',
'Swamp Palace - Big Key Chest', 'Swamp Palace - West Chest'], ['Swamp Palace (North)']),
create_dungeon_region(player, 'Swamp Palace (North)', 'Swamp Palace', ['Swamp Palace - Flooded Room - Left', 'Swamp Palace - Flooded Room - Right',
'Swamp Palace - Waterfall Room', 'Swamp Palace - Boss', 'Swamp Palace - Prize']),
create_dungeon_region(player, 'Thieves Town (Entrance)', 'Thieves\' Town', ['Thieves\' Town - Big Key Chest',
'Thieves\' Town - Map Chest',
'Thieves\' Town - Compass Chest',
'Thieves\' Town - Ambush Chest'], ['Thieves Town Big Key Door', 'Thieves Town Exit']),
create_dungeon_region(player, 'Thieves Town (Deep)', 'Thieves\' Town', ['Thieves\' Town - Attic',
'Thieves\' Town - Big Chest',
'Thieves\' Town - Blind\'s Cell'], ['Blind Fight']),
create_dungeon_region(player, 'Blind Fight', 'Thieves\' Town', ['Thieves\' Town - Boss', 'Thieves\' Town - Prize']),
create_dungeon_region(player, 'Skull Woods First Section', 'Skull Woods', ['Skull Woods - Map Chest'], ['Skull Woods First Section Exit', 'Skull Woods First Section Bomb Jump', 'Skull Woods First Section South Door', 'Skull Woods First Section West Door']),
create_dungeon_region(player, 'Skull Woods First Section (Right)', 'Skull Woods', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']),
create_dungeon_region(player, 'Skull Woods First Section (Left)', 'Skull Woods', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']),
create_dungeon_region(player, 'Skull Woods First Section (Top)', 'Skull Woods', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']),
create_dungeon_region(player, 'Skull Woods Second Section (Drop)', 'Skull Woods', None, ['Skull Woods Second Section (Drop)']),
create_dungeon_region(player, 'Skull Woods Second Section', 'Skull Woods', ['Skull Woods - Big Key Chest'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']),
create_dungeon_region(player, 'Skull Woods Final Section (Entrance)', 'Skull Woods', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']),
create_dungeon_region(player, 'Skull Woods Final Section (Mothula)', 'Skull Woods', ['Skull Woods - Boss', 'Skull Woods - Prize']),
create_dungeon_region(player, 'Ice Palace (Entrance)', 'Ice Palace', None, ['Ice Palace Entrance Room', 'Ice Palace Exit']),
create_dungeon_region(player, 'Ice Palace (Main)', 'Ice Palace', ['Ice Palace - Compass Chest', 'Ice Palace - Freezor Chest',
'Ice Palace - Big Chest', 'Ice Palace - Iced T Room'], ['Ice Palace (East)', 'Ice Palace (Kholdstare)']),
create_dungeon_region(player, 'Ice Palace (East)', 'Ice Palace', ['Ice Palace - Spike Room'], ['Ice Palace (East Top)']),
create_dungeon_region(player, 'Ice Palace (East Top)', 'Ice Palace', ['Ice Palace - Big Key Chest', 'Ice Palace - Map Chest']),
create_dungeon_region(player, 'Ice Palace (Kholdstare)', 'Ice Palace', ['Ice Palace - Boss', 'Ice Palace - Prize']),
create_dungeon_region(player, 'Misery Mire (Entrance)', 'Misery Mire', None, ['Misery Mire Entrance Gap', 'Misery Mire Exit']),
create_dungeon_region(player, 'Misery Mire (Main)', 'Misery Mire', ['Misery Mire - Big Chest', 'Misery Mire - Map Chest', 'Misery Mire - Main Lobby',
'Misery Mire - Bridge Chest', 'Misery Mire - Spike Chest'], ['Misery Mire (West)', 'Misery Mire Big Key Door']),
create_dungeon_region(player, 'Misery Mire (West)', 'Misery Mire', ['Misery Mire - Compass Chest', 'Misery Mire - Big Key Chest']),
create_dungeon_region(player, 'Misery Mire (Final Area)', 'Misery Mire', None, ['Misery Mire (Vitreous)']),
create_dungeon_region(player, 'Misery Mire (Vitreous)', 'Misery Mire', ['Misery Mire - Boss', 'Misery Mire - Prize']),
create_dungeon_region(player, 'Turtle Rock (Entrance)', 'Turtle Rock', None, ['Turtle Rock Entrance Gap', 'Turtle Rock Exit (Front)']),
create_dungeon_region(player, 'Turtle Rock (First Section)', 'Turtle Rock', ['Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left',
'Turtle Rock - Roller Room - Right'], ['Turtle Rock Pokey Room', 'Turtle Rock Entrance Gap Reverse']),
create_dungeon_region(player, 'Turtle Rock (Chain Chomp Room)', 'Turtle Rock', ['Turtle Rock - Chain Chomps'], ['Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)']),
create_dungeon_region(player, 'Turtle Rock (Second Section)', 'Turtle Rock', ['Turtle Rock - Big Key Chest'], ['Turtle Rock Ledge Exit (West)', 'Turtle Rock Chain Chomp Staircase', 'Turtle Rock Big Key Door']),
create_dungeon_region(player, 'Turtle Rock (Big Chest)', 'Turtle Rock', ['Turtle Rock - Big Chest'], ['Turtle Rock (Big Chest) (North)', 'Turtle Rock Ledge Exit (East)']),
create_dungeon_region(player, 'Turtle Rock (Crystaroller Room)', 'Turtle Rock', ['Turtle Rock - Crystaroller Room'], ['Turtle Rock Dark Room Staircase', 'Turtle Rock Big Key Door Reverse']),
create_dungeon_region(player, 'Turtle Rock (Dark Room)', 'Turtle Rock', None, ['Turtle Rock (Dark Room) (North)', 'Turtle Rock (Dark Room) (South)']),
create_dungeon_region(player, 'Turtle Rock (Eye Bridge)', 'Turtle Rock', ['Turtle Rock - Eye Bridge - Bottom Left', 'Turtle Rock - Eye Bridge - Bottom Right',
'Turtle Rock - Eye Bridge - Top Left', 'Turtle Rock - Eye Bridge - Top Right'],
['Turtle Rock Dark Room (South)', 'Turtle Rock (Trinexx)', 'Turtle Rock Isolated Ledge Exit']),
create_dungeon_region(player, 'Turtle Rock (Trinexx)', 'Turtle Rock', ['Turtle Rock - Boss', 'Turtle Rock - Prize']),
create_dungeon_region(player, 'Palace of Darkness (Entrance)', 'Palace of Darkness', ['Palace of Darkness - Shooter Room'], ['Palace of Darkness Bridge Room', 'Palace of Darkness Bonk Wall', 'Palace of Darkness Exit']),
create_dungeon_region(player, 'Palace of Darkness (Center)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Bridge', 'Palace of Darkness - Stalfos Basement'],
['Palace of Darkness Big Key Chest Staircase', 'Palace of Darkness (North)', 'Palace of Darkness Big Key Door']),
create_dungeon_region(player, 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness', ['Palace of Darkness - Big Key Chest']),
create_dungeon_region(player, 'Palace of Darkness (Bonk Section)', 'Palace of Darkness', ['Palace of Darkness - The Arena - Ledge', 'Palace of Darkness - Map Chest'], ['Palace of Darkness Hammer Peg Drop']),
create_dungeon_region(player, 'Palace of Darkness (North)', 'Palace of Darkness', ['Palace of Darkness - Compass Chest', 'Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'],
['Palace of Darkness Spike Statue Room Door', 'Palace of Darkness Maze Door']),
create_dungeon_region(player, 'Palace of Darkness (Maze)', 'Palace of Darkness', ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom', 'Palace of Darkness - Big Chest']),
create_dungeon_region(player, 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness', ['Palace of Darkness - Harmless Hellway']),
create_dungeon_region(player, 'Palace of Darkness (Final Section)', 'Palace of Darkness', ['Palace of Darkness - Boss', 'Palace of Darkness - Prize']),
create_dungeon_region(player, 'Inverted Ganons Tower (Entrance)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Torch', 'Ganons Tower - Hope Room - Left', 'Ganons Tower - Hope Room - Right'],
['Ganons Tower (Tile Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower Big Key Door', 'Inverted Ganons Tower Exit']),
create_dungeon_region(player, 'Ganons Tower (Tile Room)', 'Ganon\'s Tower', ['Ganons Tower - Tile Room'], ['Ganons Tower (Tile Room) Key Door']),
create_dungeon_region(player, 'Ganons Tower (Compass Room)', 'Ganon\'s Tower', ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right',
'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right'],
['Ganons Tower (Bottom) (East)']),
create_dungeon_region(player, 'Ganons Tower (Hookshot Room)', 'Ganon\'s Tower', ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right',
'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right'],
['Ganons Tower (Map Room)', 'Ganons Tower (Double Switch Room)']),
create_dungeon_region(player, 'Ganons Tower (Map Room)', 'Ganon\'s Tower', ['Ganons Tower - Map Chest']),
create_dungeon_region(player, 'Ganons Tower (Firesnake Room)', 'Ganon\'s Tower', ['Ganons Tower - Firesnake Room'], ['Ganons Tower (Firesnake Room)']),
create_dungeon_region(player, 'Ganons Tower (Teleport Room)', 'Ganon\'s Tower', ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right',
'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right'],
['Ganons Tower (Bottom) (West)']),
create_dungeon_region(player, 'Ganons Tower (Bottom)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Chest', 'Ganons Tower - Big Chest', 'Ganons Tower - Big Key Room - Left',
'Ganons Tower - Big Key Room - Right', 'Ganons Tower - Big Key Chest']),
create_dungeon_region(player, 'Ganons Tower (Top)', 'Ganon\'s Tower', None, ['Ganons Tower Torch Rooms']),
create_dungeon_region(player, 'Ganons Tower (Before Moldorm)', 'Ganon\'s Tower', ['Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right',
'Ganons Tower - Pre-Moldorm Chest'], ['Ganons Tower Moldorm Door']),
create_dungeon_region(player, 'Ganons Tower (Moldorm)', 'Ganon\'s Tower', None, ['Ganons Tower Moldorm Gap']),
create_dungeon_region(player, 'Agahnim 2', 'Ganon\'s Tower', ['Ganons Tower - Validation Chest', 'Agahnim 2'], None),
create_cave_region(player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']),
create_cave_region(player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']),
create_dw_region(player, 'Pyramid Ledge', None, ['Pyramid Drop']), # houlihan room exits here in inverted
# to simplify flute connections
create_cave_region(player, 'The Sky', 'A Dark Sky', None, ['DDM Landing','NEDW Landing', 'WDW Landing', 'SDW Landing', 'EDW Landing', 'DD Landing', 'DLHL Landing'])
]
for region_name, (room_id, shopkeeper, replaceable) in shop_table.items():
region = world.get_region(region_name, player)
shop = Shop(region, room_id, ShopType.Shop, shopkeeper, replaceable)
region.shop = shop
world.shops.append(shop)
for index, (item, price) in enumerate(default_shop_contents[region_name]):
shop.add_inventory(index, item, price)
region = world.get_region('Capacity Upgrade', player)
shop = Shop(region, 0x0115, ShopType.UpgradeShop, 0x04, True)
region.shop = shop
world.shops.append(shop)
shop.add_inventory(0, 'Bomb Upgrade (+5)', 100, 7)
if not world.retro:
shop.add_inventory(1, 'Arrow Upgrade (+5)', 100, 7)
world.intialize_regions()
def create_lw_region(player, name, locations=None, exits=None):
return _create_region(player, name, RegionType.LightWorld, 'Light World', locations, exits)
def create_dw_region(player, name, locations=None, exits=None):
return _create_region(player, name, RegionType.DarkWorld, 'Dark World', locations, exits)
def create_cave_region(player, name, hint='Hyrule', locations=None, exits=None):
return _create_region(player, name, RegionType.Cave, hint, locations, exits)
def create_dungeon_region(player, name, hint='Hyrule', locations=None, exits=None):
return _create_region(player, name, RegionType.Dungeon, hint, locations, exits)
def _create_region(player, name, type, hint='Hyrule', locations=None, exits=None):
ret = Region(name, type, hint, player)
if locations is None:
locations = []
if exits is None:
exits = []
for exit in exits:
ret.exits.append(Entrance(player, exit, ret))
for location in locations:
address, crystal, hint_text = location_table[location]
ret.locations.append(Location(player, location, address, crystal, hint_text, ret))
return ret
def mark_dark_world_regions(world):
# cross world caves may have some sections marked as both in_light_world, and in_dark_work.
# That is ok. the bunny logic will check for this case and incorporate special rules.
queue = collections.deque(region for region in world.regions if region.type == RegionType.DarkWorld)
seen = set(queue)
while queue:
current = queue.popleft()
current.is_dark_world = True
for exit in current.exits:
if exit.connected_region.type == RegionType.LightWorld:
# Don't venture into the dark world
continue
if exit.connected_region not in seen:
seen.add(exit.connected_region)
queue.append(exit.connected_region)
queue = collections.deque(region for region in world.regions if region.type == RegionType.LightWorld)
seen = set(queue)
while queue:
current = queue.popleft()
current.is_light_world = True
for exit in current.exits:
if exit.connected_region.type == RegionType.DarkWorld:
# Don't venture into the light world
continue
if exit.connected_region not in seen:
seen.add(exit.connected_region)
queue.append(exit.connected_region)
# (room_id, shopkeeper, replaceable)
shop_table = {
'Cave Shop (Dark Death Mountain)': (0x0112, 0xC1, True),
'Red Shield Shop': (0x0110, 0xC1, True),
'Dark Lake Hylia Shop': (0x010F, 0xC1, True),
'Dark World Lumberjack Shop': (0x010F, 0xC1, True),
'Village of Outcasts Shop': (0x010F, 0xC1, True),
'Dark World Potion Shop': (0x010F, 0xC1, True),
'Light World Death Mountain Shop': (0x00FF, 0xA0, True),
'Kakariko Shop': (0x011F, 0xA0, True),
'Cave Shop (Lake Hylia)': (0x0112, 0xA0, True),
'Potion Shop': (0x0109, 0xFF, False),
# Bomb Shop not currently modeled as a shop, due to special nature of items
}
# region, [item]
# slot, item, price, max=0, replacement=None, replacement_price=0
# item = (item, price)
_basic_shop_defaults = [('Red Potion', 150), ('Small Heart', 10), ('Bombs (10)', 50)]
_dark_world_shop_defaults = [('Red Potion', 150), ('Blue Shield', 50), ('Bombs (10)', 50)]
default_shop_contents = {
'Cave Shop (Dark Death Mountain)': _basic_shop_defaults,
'Red Shield Shop': [('Red Shield', 500), ('Bee', 10), ('Arrows (10)', 30)],
'Dark Lake Hylia Shop': _dark_world_shop_defaults,
'Dark World Lumberjack Shop': _dark_world_shop_defaults,
'Village of Outcasts Shop': _dark_world_shop_defaults,
'Dark World Potion Shop': _dark_world_shop_defaults,
'Light World Death Mountain Shop': _basic_shop_defaults,
'Kakariko Shop': _basic_shop_defaults,
'Cave Shop (Lake Hylia)': _basic_shop_defaults,
'Potion Shop': [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)],
}
location_table = {'Mushroom': (0x180013, False, 'in the woods'),
'Bottle Merchant': (0x2EB18, False, 'with a merchant'),
'Flute Spot': (0x18014A, False, 'underground'),
'Sunken Treasure': (0x180145, False, 'underwater'),
'Purple Chest': (0x33D68, False, 'from a box'),
'Blind\'s Hideout - Top': (0xEB0F, False, 'in a basement'),
'Blind\'s Hideout - Left': (0xEB12, False, 'in a basement'),
'Blind\'s Hideout - Right': (0xEB15, False, 'in a basement'),
'Blind\'s Hideout - Far Left': (0xEB18, False, 'in a basement'),
'Blind\'s Hideout - Far Right': (0xEB1B, False, 'in a basement'),
'Link\'s Uncle': (0x2DF45, False, 'with your uncle'),
'Secret Passage': (0xE971, False, 'near your uncle'),
'King Zora': (0xEE1C3, False, 'at a high price'),
'Zora\'s Ledge': (0x180149, False, 'near Zora'),
'Waterfall Fairy - Left': (0xE9B0, False, 'near a fairy'),
'Waterfall Fairy - Right': (0xE9D1, False, 'near a fairy'),
'King\'s Tomb': (0xE97A, False, 'alone in a cave'),
'Floodgate Chest': (0xE98C, False, 'in the dam'),
'Link\'s House': (0xE9BC, False, 'in your home'),
'Kakariko Tavern': (0xE9CE, False, 'in the bar'),
'Chicken House': (0xE9E9, False, 'near poultry'),
'Aginah\'s Cave': (0xE9F2, False, 'with Aginah'),
'Sahasrahla\'s Hut - Left': (0xEA82, False, 'near the elder'),
'Sahasrahla\'s Hut - Middle': (0xEA85, False, 'near the elder'),
'Sahasrahla\'s Hut - Right': (0xEA88, False, 'near the elder'),
'Sahasrahla': (0x2F1FC, False, 'with the elder'),
'Kakariko Well - Top': (0xEA8E, False, 'in a well'),
'Kakariko Well - Left': (0xEA91, False, 'in a well'),
'Kakariko Well - Middle': (0xEA94, False, 'in a well'),
'Kakariko Well - Right': (0xEA97, False, 'in a well'),
'Kakariko Well - Bottom': (0xEA9A, False, 'in a well'),
'Blacksmith': (0x18002A, False, 'with the smith'),
'Magic Bat': (0x180015, False, 'with the bat'),
'Sick Kid': (0x339CF, False, 'with the sick'),
'Hobo': (0x33E7D, False, 'with the hobo'),
'Lost Woods Hideout': (0x180000, False, 'near a thief'),
'Lumberjack Tree': (0x180001, False, 'in a hole'),
'Cave 45': (0x180003, False, 'alone in a cave'),
'Graveyard Cave': (0x180004, False, 'alone in a cave'),
'Checkerboard Cave': (0x180005, False, 'alone in a cave'),
'Mini Moldorm Cave - Far Left': (0xEB42, False, 'near Moldorms'),
'Mini Moldorm Cave - Left': (0xEB45, False, 'near Moldorms'),
'Mini Moldorm Cave - Right': (0xEB48, False, 'near Moldorms'),
'Mini Moldorm Cave - Far Right': (0xEB4B, False, 'near Moldorms'),
'Mini Moldorm Cave - Generous Guy': (0x180010, False, 'near Moldorms'),
'Ice Rod Cave': (0xEB4E, False, 'in a frozen cave'),
'Bonk Rock Cave': (0xEB3F, False, 'alone in a cave'),
'Library': (0x180012, False, 'near books'),
'Potion Shop': (0x180014, False, 'near potions'),
'Lake Hylia Island': (0x180144, False, 'on an island'),
'Maze Race': (0x180142, False, 'at the race'),
'Desert Ledge': (0x180143, False, 'in the desert'),
'Desert Palace - Big Chest': (0xE98F, False, 'in Desert Palace'),
'Desert Palace - Torch': (0x180160, False, 'in Desert Palace'),
'Desert Palace - Map Chest': (0xE9B6, False, 'in Desert Palace'),
'Desert Palace - Compass Chest': (0xE9CB, False, 'in Desert Palace'),
'Desert Palace - Big Key Chest': (0xE9C2, False, 'in Desert Palace'),
'Desert Palace - Boss': (0x180151, False, 'with Lanmolas'),
'Eastern Palace - Compass Chest': (0xE977, False, 'in Eastern Palace'),
'Eastern Palace - Big Chest': (0xE97D, False, 'in Eastern Palace'),
'Eastern Palace - Cannonball Chest': (0xE9B3, False, 'in Eastern Palace'),
'Eastern Palace - Big Key Chest': (0xE9B9, False, 'in Eastern Palace'),
'Eastern Palace - Map Chest': (0xE9F5, False, 'in Eastern Palace'),
'Eastern Palace - Boss': (0x180150, False, 'with the Armos'),
'Master Sword Pedestal': (0x289B0, False, 'at the pedestal'),
'Hyrule Castle - Boomerang Chest': (0xE974, False, 'in Hyrule Castle'),
'Hyrule Castle - Map Chest': (0xEB0C, False, 'in Hyrule Castle'),
'Hyrule Castle - Zelda\'s Chest': (0xEB09, False, 'in Hyrule Castle'),
'Sewers - Dark Cross': (0xE96E, False, 'in the sewers'),
'Sewers - Secret Room - Left': (0xEB5D, False, 'in the sewers'),
'Sewers - Secret Room - Middle': (0xEB60, False, 'in the sewers'),
'Sewers - Secret Room - Right': (0xEB63, False, 'in the sewers'),
'Sanctuary': (0xEA79, False, 'in Sanctuary'),
'Castle Tower - Room 03': (0xEAB5, False, 'in Castle Tower'),
'Castle Tower - Dark Maze': (0xEAB2, False, 'in Castle Tower'),
'Old Man': (0xF69FA, False, 'with the old man'),
'Spectacle Rock Cave': (0x180002, False, 'alone in a cave'),
'Paradox Cave Lower - Far Left': (0xEB2A, False, 'in a cave with seven chests'),
'Paradox Cave Lower - Left': (0xEB2D, False, 'in a cave with seven chests'),
'Paradox Cave Lower - Right': (0xEB30, False, 'in a cave with seven chests'),
'Paradox Cave Lower - Far Right': (0xEB33, False, 'in a cave with seven chests'),
'Paradox Cave Lower - Middle': (0xEB36, False, 'in a cave with seven chests'),
'Paradox Cave Upper - Left': (0xEB39, False, 'in a cave with seven chests'),
'Paradox Cave Upper - Right': (0xEB3C, False, 'in a cave with seven chests'),
'Spiral Cave': (0xE9BF, False, 'in spiral cave'),
'Ether Tablet': (0x180016, False, 'at a monolith'),
'Spectacle Rock': (0x180140, False, 'atop a rock'),
'Tower of Hera - Basement Cage': (0x180162, False, 'in Tower of Hera'),
'Tower of Hera - Map Chest': (0xE9AD, False, 'in Tower of Hera'),
'Tower of Hera - Big Key Chest': (0xE9E6, False, 'in Tower of Hera'),
'Tower of Hera - Compass Chest': (0xE9FB, False, 'in Tower of Hera'),
'Tower of Hera - Big Chest': (0xE9F8, False, 'in Tower of Hera'),
'Tower of Hera - Boss': (0x180152, False, 'with Moldorm'),
'Pyramid': (0x180147, False, 'on the pyramid'),
'Catfish': (0xEE185, False, 'with a catfish'),
'Stumpy': (0x330C7, False, 'with tree boy'),
'Digging Game': (0x180148, False, 'underground'),
'Bombos Tablet': (0x180017, False, 'at a monolith'),
'Hype Cave - Top': (0xEB1E, False, 'near a bat-like man'),
'Hype Cave - Middle Right': (0xEB21, False, 'near a bat-like man'),
'Hype Cave - Middle Left': (0xEB24, False, 'near a bat-like man'),
'Hype Cave - Bottom': (0xEB27, False, 'near a bat-like man'),
'Hype Cave - Generous Guy': (0x180011, False, 'with a bat-like man'),
'Peg Cave': (0x180006, False, 'alone in a cave'),
'Pyramid Fairy - Left': (0xE980, False, 'near a fairy'),
'Pyramid Fairy - Right': (0xE983, False, 'near a fairy'),
'Brewery': (0xE9EC, False, 'alone in a home'),
'C-Shaped House': (0xE9EF, False, 'alone in a home'),
'Chest Game': (0xEDA8, False, 'as a prize'),
'Bumper Cave Ledge': (0x180146, False, 'on a ledge'),
'Mire Shed - Left': (0xEA73, False, 'near sparks'),
'Mire Shed - Right': (0xEA76, False, 'near sparks'),
'Superbunny Cave - Top': (0xEA7C, False, 'in a connection'),
'Superbunny Cave - Bottom': (0xEA7F, False, 'in a connection'),
'Spike Cave': (0xEA8B, False, 'beyond spikes'),
'Hookshot Cave - Top Right': (0xEB51, False, 'across pits'),
'Hookshot Cave - Top Left': (0xEB54, False, 'across pits'),
'Hookshot Cave - Bottom Right': (0xEB5A, False, 'across pits'),
'Hookshot Cave - Bottom Left': (0xEB57, False, 'across pits'),
'Floating Island': (0x180141, False, 'on an island'),
'Mimic Cave': (0xE9C5, False, 'in a cave of mimicry'),
'Swamp Palace - Entrance': (0xEA9D, False, 'in Swamp Palace'),
'Swamp Palace - Map Chest': (0xE986, False, 'in Swamp Palace'),
'Swamp Palace - Big Chest': (0xE989, False, 'in Swamp Palace'),
'Swamp Palace - Compass Chest': (0xEAA0, False, 'in Swamp Palace'),
'Swamp Palace - Big Key Chest': (0xEAA6, False, 'in Swamp Palace'),
'Swamp Palace - West Chest': (0xEAA3, False, 'in Swamp Palace'),
'Swamp Palace - Flooded Room - Left': (0xEAA9, False, 'in Swamp Palace'),
'Swamp Palace - Flooded Room - Right': (0xEAAC, False, 'in Swamp Palace'),
'Swamp Palace - Waterfall Room': (0xEAAF, False, 'in Swamp Palace'),
'Swamp Palace - Boss': (0x180154, False, 'with Arrghus'),
'Thieves\' Town - Big Key Chest': (0xEA04, False, 'in Thieves\' Town'),
'Thieves\' Town - Map Chest': (0xEA01, False, 'in Thieves\' Town'),
'Thieves\' Town - Compass Chest': (0xEA07, False, 'in Thieves\' Town'),
'Thieves\' Town - Ambush Chest': (0xEA0A, False, 'in Thieves\' Town'),
'Thieves\' Town - Attic': (0xEA0D, False, 'in Thieves\' Town'),
'Thieves\' Town - Big Chest': (0xEA10, False, 'in Thieves\' Town'),
'Thieves\' Town - Blind\'s Cell': (0xEA13, False, 'in Thieves\' Town'),
'Thieves\' Town - Boss': (0x180156, False, 'with Blind'),
'Skull Woods - Compass Chest': (0xE992, False, 'in Skull Woods'),
'Skull Woods - Map Chest': (0xE99B, False, 'in Skull Woods'),
'Skull Woods - Big Chest': (0xE998, False, 'in Skull Woods'),
'Skull Woods - Pot Prison': (0xE9A1, False, 'in Skull Woods'),
'Skull Woods - Pinball Room': (0xE9C8, False, 'in Skull Woods'),
'Skull Woods - Big Key Chest': (0xE99E, False, 'in Skull Woods'),
'Skull Woods - Bridge Room': (0xE9FE, False, 'near Mothula'),
'Skull Woods - Boss': (0x180155, False, 'with Mothula'),
'Ice Palace - Compass Chest': (0xE9D4, False, 'in Ice Palace'),
'Ice Palace - Freezor Chest': (0xE995, False, 'in Ice Palace'),
'Ice Palace - Big Chest': (0xE9AA, False, 'in Ice Palace'),
'Ice Palace - Iced T Room': (0xE9E3, False, 'in Ice Palace'),
'Ice Palace - Spike Room': (0xE9E0, False, 'in Ice Palace'),
'Ice Palace - Big Key Chest': (0xE9A4, False, 'in Ice Palace'),
'Ice Palace - Map Chest': (0xE9DD, False, 'in Ice Palace'),
'Ice Palace - Boss': (0x180157, False, 'with Kholdstare'),
'Misery Mire - Big Chest': (0xEA67, False, 'in Misery Mire'),
'Misery Mire - Map Chest': (0xEA6A, False, 'in Misery Mire'),
'Misery Mire - Main Lobby': (0xEA5E, False, 'in Misery Mire'),
'Misery Mire - Bridge Chest': (0xEA61, False, 'in Misery Mire'),
'Misery Mire - Spike Chest': (0xE9DA, False, 'in Misery Mire'),
'Misery Mire - Compass Chest': (0xEA64, False, 'in Misery Mire'),
'Misery Mire - Big Key Chest': (0xEA6D, False, 'in Misery Mire'),
'Misery Mire - Boss': (0x180158, False, 'with Vitreous'),
'Turtle Rock - Compass Chest': (0xEA22, False, 'in Turtle Rock'),
'Turtle Rock - Roller Room - Left': (0xEA1C, False, 'in Turtle Rock'),
'Turtle Rock - Roller Room - Right': (0xEA1F, False, 'in Turtle Rock'),
'Turtle Rock - Chain Chomps': (0xEA16, False, 'in Turtle Rock'),
'Turtle Rock - Big Key Chest': (0xEA25, False, 'in Turtle Rock'),
'Turtle Rock - Big Chest': (0xEA19, False, 'in Turtle Rock'),
'Turtle Rock - Crystaroller Room': (0xEA34, False, 'in Turtle Rock'),
'Turtle Rock - Eye Bridge - Bottom Left': (0xEA31, False, 'in Turtle Rock'),
'Turtle Rock - Eye Bridge - Bottom Right': (0xEA2E, False, 'in Turtle Rock'),
'Turtle Rock - Eye Bridge - Top Left': (0xEA2B, False, 'in Turtle Rock'),
'Turtle Rock - Eye Bridge - Top Right': (0xEA28, False, 'in Turtle Rock'),
'Turtle Rock - Boss': (0x180159, False, 'with Trinexx'),
'Palace of Darkness - Shooter Room': (0xEA5B, False, 'in Palace of Darkness'),
'Palace of Darkness - The Arena - Bridge': (0xEA3D, False, 'in Palace of Darkness'),
'Palace of Darkness - Stalfos Basement': (0xEA49, False, 'in Palace of Darkness'),
'Palace of Darkness - Big Key Chest': (0xEA37, False, 'in Palace of Darkness'),
'Palace of Darkness - The Arena - Ledge': (0xEA3A, False, 'in Palace of Darkness'),
'Palace of Darkness - Map Chest': (0xEA52, False, 'in Palace of Darkness'),
'Palace of Darkness - Compass Chest': (0xEA43, False, 'in Palace of Darkness'),
'Palace of Darkness - Dark Basement - Left': (0xEA4C, False, 'in Palace of Darkness'),
'Palace of Darkness - Dark Basement - Right': (0xEA4F, False, 'in Palace of Darkness'),
'Palace of Darkness - Dark Maze - Top': (0xEA55, False, 'in Palace of Darkness'),
'Palace of Darkness - Dark Maze - Bottom': (0xEA58, False, 'in Palace of Darkness'),
'Palace of Darkness - Big Chest': (0xEA40, False, 'in Palace of Darkness'),
'Palace of Darkness - Harmless Hellway': (0xEA46, False, 'in Palace of Darkness'),
'Palace of Darkness - Boss': (0x180153, False, 'with Helmasaur King'),
'Ganons Tower - Bob\'s Torch': (0x180161, False, 'in Ganon\'s Tower'),
'Ganons Tower - Hope Room - Left': (0xEAD9, False, 'in Ganon\'s Tower'),
'Ganons Tower - Hope Room - Right': (0xEADC, False, 'in Ganon\'s Tower'),
'Ganons Tower - Tile Room': (0xEAE2, False, 'in Ganon\'s Tower'),
'Ganons Tower - Compass Room - Top Left': (0xEAE5, False, 'in Ganon\'s Tower'),
'Ganons Tower - Compass Room - Top Right': (0xEAE8, False, 'in Ganon\'s Tower'),
'Ganons Tower - Compass Room - Bottom Left': (0xEAEB, False, 'in Ganon\'s Tower'),
'Ganons Tower - Compass Room - Bottom Right': (0xEAEE, False, 'in Ganon\'s Tower'),
'Ganons Tower - DMs Room - Top Left': (0xEAB8, False, 'in Ganon\'s Tower'),
'Ganons Tower - DMs Room - Top Right': (0xEABB, False, 'in Ganon\'s Tower'),
'Ganons Tower - DMs Room - Bottom Left': (0xEABE, False, 'in Ganon\'s Tower'),
'Ganons Tower - DMs Room - Bottom Right': (0xEAC1, False, 'in Ganon\'s Tower'),
'Ganons Tower - Map Chest': (0xEAD3, False, 'in Ganon\'s Tower'),
'Ganons Tower - Firesnake Room': (0xEAD0, False, 'in Ganon\'s Tower'),
'Ganons Tower - Randomizer Room - Top Left': (0xEAC4, False, 'in Ganon\'s Tower'),
'Ganons Tower - Randomizer Room - Top Right': (0xEAC7, False, 'in Ganon\'s Tower'),
'Ganons Tower - Randomizer Room - Bottom Left': (0xEACA, False, 'in Ganon\'s Tower'),
'Ganons Tower - Randomizer Room - Bottom Right': (0xEACD, False, 'in Ganon\'s Tower'),
'Ganons Tower - Bob\'s Chest': (0xEADF, False, 'in Ganon\'s Tower'),
'Ganons Tower - Big Chest': (0xEAD6, False, 'in Ganon\'s Tower'),
'Ganons Tower - Big Key Room - Left': (0xEAF4, False, 'in Ganon\'s Tower'),
'Ganons Tower - Big Key Room - Right': (0xEAF7, False, 'in Ganon\'s Tower'),
'Ganons Tower - Big Key Chest': (0xEAF1, False, 'in Ganon\'s Tower'),
'Ganons Tower - Mini Helmasaur Room - Left': (0xEAFD, False, 'atop Ganon\'s Tower'),
'Ganons Tower - Mini Helmasaur Room - Right': (0xEB00, False, 'atop Ganon\'s Tower'),
'Ganons Tower - Pre-Moldorm Chest': (0xEB03, False, 'atop Ganon\'s Tower'),
'Ganons Tower - Validation Chest': (0xEB06, False, 'atop Ganon\'s Tower'),
'Ganon': (None, False, 'from me'),
'Agahnim 1': (None, False, 'from Ganon\'s wizardry form'),
'Agahnim 2': (None, False, 'from Ganon\'s wizardry form'),
'Floodgate': (None, False, None),
'Frog': (None, False, None),
'Missing Smith': (None, False, None),
'Dark Blacksmith Ruins': (None, False, None),
'Eastern Palace - Prize': ([0x1209D, 0x53E76, 0x53E77, 0x180052, 0x180070, 0xC6FE], True, 'Eastern Palace'),
'Desert Palace - Prize': ([0x1209E, 0x53E7A, 0x53E7B, 0x180053, 0x180072, 0xC6FF], True, 'Desert Palace'),
'Tower of Hera - Prize': ([0x120A5, 0x53E78, 0x53E79, 0x18005A, 0x180071, 0xC706], True, 'Tower of Hera'),
'Palace of Darkness - Prize': ([0x120A1, 0x53E7C, 0x53E7D, 0x180056, 0x180073, 0xC702], True, 'Palace of Darkness'),
'Swamp Palace - Prize': ([0x120A0, 0x53E88, 0x53E89, 0x180055, 0x180079, 0xC701], True, 'Swamp Palace'),
'Thieves\' Town - Prize': ([0x120A6, 0x53E82, 0x53E83, 0x18005B, 0x180076, 0xC707], True, 'Thieves\' Town'),
'Skull Woods - Prize': ([0x120A3, 0x53E7E, 0x53E7F, 0x180058, 0x180074, 0xC704], True, 'Skull Woods'),
'Ice Palace - Prize': ([0x120A4, 0x53E86, 0x53E87, 0x180059, 0x180078, 0xC705], True, 'Ice Palace'),
'Misery Mire - Prize': ([0x120A2, 0x53E84, 0x53E85, 0x180057, 0x180077, 0xC703], True, 'Misery Mire'),
'Turtle Rock - Prize': ([0x120A7, 0x53E80, 0x53E81, 0x18005C, 0x180075, 0xC708], True, 'Turtle Rock')}
+1622 -224
View File
File diff suppressed because it is too large Load Diff
+203 -161
View File
@@ -1,5 +1,3 @@
import logging
from BaseClasses import Item
@@ -11,169 +9,213 @@ def ItemFactory(items, player):
singleton = True
for item in items:
if item in item_table:
advancement, priority, type, code, pedestal_hint, pedestal_credit, sickkid_credit, zora_credit, witch_credit, fluteboy_credit, hint_text = item_table[item]
ret.append(Item(item, advancement, priority, type, code, pedestal_hint, pedestal_credit, sickkid_credit, zora_credit, witch_credit, fluteboy_credit, hint_text, player))
advancement, priority, type, code, price, pedestal_hint, pedestal_credit, sickkid_credit, zora_credit, witch_credit, fluteboy_credit, hint_text = item_table[item]
ret.append(Item(item, advancement, priority, type, code, price, pedestal_hint, pedestal_credit, sickkid_credit, zora_credit, witch_credit, fluteboy_credit, hint_text, player))
else:
logging.getLogger('').warning('Unknown Item: %s', item)
return None
raise RuntimeError(f'Unknown Item: {item}')
if singleton:
return ret[0]
return ret
# Format: Name: (Advancement, Priority, Type, ItemCode, Pedestal Hint Text, Pedestal Credit Text, Sick Kid Credit Text, Zora Credit Text, Witch Credit Text, Flute Boy Credit Text, Hint Text)
item_table = {'Bow': (True, False, None, 0x0B, 'Bow!\nJoin the archer class!', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'The Bow'),
'Progressive Bow': (True, False, None, 0x64, 'Bow!\nJoin the archer class!', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'A Bow'),
'Book of Mudora': (True, False, None, 0x1D, 'This is a\nparadox?!', 'and the story book', 'the scholarly kid', 'moon runes for sale', 'drugs for literacy', 'book-worm boy can read again', 'The Book'),
'Hammer': (True, False, None, 0x09, 'stop\nhammer time!', 'and m c hammer', 'hammer-smashing kid', 'm c hammer for sale', 'stop... hammer time', 'stop, hammer time', 'The Hammer'),
'Hookshot': (True, False, None, 0x0A, 'Hookshot!\nBOING! BOING!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'The Hookshot'),
'Magic Mirror': (True, False, None, 0x1A, 'Mirror!\nTake some time to\nreflect on this moment!', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'The Mirror'),
'Ocarina': (True, False, None, 0x14, 'Ocarina!\nA Flute by another name', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'The Flute'),
'Pegasus Boots': (True, False, None, 0x4B, 'Pegasus Boots!\nGotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'The Boots'),
'Power Glove': (True, False, None, 0x1B, 'Glove!\nNow you can\nlift weak stuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'The Glove'),
'Cape': (True, False, None, 0x19, 'Cape!\nInvisbility cloak activate!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'The Cape'),
'Mushroom': (True, False, None, 0x29, 'Mushroom!\nDon\'t eat it. Find a witch.', 'and the legal drugs', 'the drug-dealing kid', 'legal drugs for sale', 'shroom swap', 'shroom boy sells drugs again', 'The Mushroom'),
'Shovel': (True, False, None, 0x13, 'Shovel!\nCan you dig it?', 'and the spade', 'archaeologist kid', 'dirt spade for sale', 'can you dig it', 'shovel boy digs again', 'The Shovel'),
'Lamp': (True, False, None, 0x12, 'Lamp!\nYou can see in the dark,\nand light torches.', 'and the flashlight', 'light-shining kid', 'flashlight for sale', 'fungus for illumination', 'illuminated boy can see again', 'The Lamp'),
'Magic Powder': (True, False, None, 0x0D, 'Powder!\nSprinkle it on a dancing pickle!', 'and the magic sack', 'the sack-holding kid', 'magic sack for sale', 'the witch and assistant', 'magic boy plays marbles again', 'The Powder'),
'Moon Pearl': (True, False, None, 0x1F, 'Moon Pearl!\nRabbit Be Gone!', 'and the jaw breaker', 'fortune-telling kid', 'lunar orb for sale', 'shrooms for moon rock', 'moon boy plays ball again', 'The Moon Pearl'),
'Cane of Somaria': (True, False, None, 0x15, 'Cane of Somaria!\nMake blocks, throw blocks', 'and the red blocks', 'the block-making kid', 'block stick for sale', 'block stick for trade', 'cane boy makes blocks again', 'The Red Cane'),
'Fire Rod': (True, False, None, 0x07, 'Fire Rod!\nI\'m burning for you!', 'and the flamethrower', 'fire-starting kid', 'rage rod for sale', 'fungus for rage-rod', 'firestarter boy burns again', 'The Fire Rod'),
'Flippers': (True, False, None, 0x1E, 'Flippers!\nFancy a swim!', 'and the toewebs', 'the swimming kid', 'finger webs for sale', 'shrooms let you swim', 'swimming boy swims again', 'The Flippers'),
'Ice Rod': (True, False, None, 0x08, 'Ice Rod!\nActivate Freeze Ray!', 'and the freeze ray', 'the ice-bending kid', 'freeze ray for sale', 'fungus for ice-rod', 'ice-cube boy freezes again', 'The Ice Rod'),
'Titans Mitts': (True, False, None, 0x1C, 'Mitts!\nLift ALL the rocks!', 'and the golden glove', 'body-building kid', 'carry glove for sale', 'fungus for bling-gloves', 'body-building boy has gold again', 'The Mitts'),
'Ether': (True, False, None, 0x10, 'Ether!\nLet\'s cool things down!', 'and the bolt coin', 'coin-collecting kid', 'bolt coin for sale', 'shrooms for bolt-coin', 'medallion boy sees floor again', 'Ether'),
'Bombos': (True, False, None, 0x0F, 'Bombos!\nExplosions! Fire!\nBurn it all!', 'and the swirly coin', 'coin-collecting kid', 'swirly coin for sale', 'shrooms for swirly-coin', 'medallion boy melts room again', 'Bombos'),
'Quake': (True, False, None, 0x11, 'Quake!\nLet\'s shake the ground!', 'and the wavy coin', 'coin-collecting kid', 'wavy coin for sale', 'shrooms for wavy-coin', 'medallion boy shakes dirt again', 'Quake'),
'Bottle': (True, False, None, 0x16, 'Bottle!\nStore all manner of things!', 'and the terrarium', 'the terrarium kid', 'terrarium for sale', 'special promotion', 'bottle boy has terrarium again', 'A Bottle'),
'Bottle (Red Potion)': (True, False, None, 0x2B, 'Red Potion!\nFill your hearts!', 'and the red goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has red goo again', 'A Bottle'),
'Bottle (Green Potion)': (True, False, None, 0x2C, 'Green Potion!\nRestore your magic!', 'and the green goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has green goo again', 'A Bottle'),
'Bottle (Blue Potion)': (True, False, None, 0x2D, 'Blue Potion!\nHeal and restore!', 'and the blue goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has blue goo again', 'A Bottle'),
'Bottle (Fairy)': (True, False, None, 0x3D, 'Fairy Bottle\nI\'ll save your life!', 'and the captive', 'the tingle kid', 'hostage for sale', 'fairy dust and shrooms', 'bottle boy has friend again', 'A Bottle'),
'Bottle (Bee)': (True, False, None, 0x3C, 'Bee Bottle\nI\'ll sting your enemies a bit!', 'and the sting buddy', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has mad bee again', 'A Bottle'),
'Bottle (Good Bee)': (True, False, None, 0x48, 'Good Bee Bottle\nI\'ll sting your enemies\na whole lot!', 'and the sparkle sting', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has beetor again', 'A Bottle'),
'Master Sword': (True, False, 'Sword', 0x50, 'Master Sword!\nEvil\'s bane!', 'and the master sword', 'sword-wielding kid', 'glow sword for sale', 'fungus for blue slasher', 'sword boy fights again', 'The Master Sword'),
'Tempered Sword': (True, False, 'Sword', 0x02, 'Tempered Sword!\nMore slashy!', 'the tempered sword', 'sword-wielding kid', 'flame sword for sale', 'fungus for red slasher', 'sword boy fights again', 'The Tempered Sword'),
'Sword and Shield': (True, False, 'Sword', 0x00, 'Sword and Shield!\nUncle sword ahoy!', 'the sword and shield', 'sword and shield-wielding kid', 'training set for sale', 'fungus for training set', 'sword and shield boy fights again', 'The Sword and Shield'),
'Fighter Sword': (True, False, 'Sword', 0x49, 'Fighter Sword!\nStarter level slashy!', 'the tiny sword', 'sword-wielding kid', 'tiny sword for sale', 'fungus for tiny slasher', 'sword boy fights again', 'The Small Sword'),
'Golden Sword': (True, False, 'Sword', 0x03, 'Golden Sword!\nBest slashy!', 'and the butter sword', 'sword-wielding kid', 'butter for sale', 'cap churned to butter', 'sword boy fights again', 'The Golden Sword'),
'Progressive Sword': (True, False, 'Sword', 0x5E, 'Sword!\nA better sword for your time!', 'the unknown sword', 'sword-wielding kid', 'sword for sale', 'fungus for some slasher', 'sword boy fights again', 'A sword'),
'Progressive Glove': (True, False, None, 0x61, 'Glove!\nLift more than you can now!', 'and the lift upgrade', 'body-building kid', 'some glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'A Glove'),
'Silver Arrows': (True, False, None, 0x58, 'Silver Arrows!\nDefeat Ganon faster!', 'and the ganonsbane', 'ganon-killing kid', 'ganon doom for sale', 'fungus for pork', 'archer boy shines again', 'The Silver Arrows'),
'Green Pendant': (True, False, 'Crystal', [0x04, 0x38, 0x62, 0x00, 0x69, 0x37], None, None, None, None, None, None, None),
'Blue Pendant': (True, False, 'Crystal', [0x02, 0x34, 0x60, 0x00, 0x69, 0x39], None, None, None, None, None, None, None),
'Red Pendant': (True, False, 'Crystal', [0x01, 0x32, 0x60, 0x00, 0x69, 0x38], None, None, None, None, None, None, None),
'Triforce': (True, False, None, 0x6A, 'Triforce\nGrab me to win!', 'and the triforce', 'victorious kid', 'victory for sale', 'fungus for the win', 'greedy boy wins game again', 'The Triforce'),
'Power Star': (True, False, None, 0x6B, 'Power Star\nA small step\ntowards victory!', 'and the power star', 'star-struck kid', 'star for sale', 'see stars with shroom', 'mario powers up again', 'A Power Star'),
'Triforce Piece': (True, False, None, 0x6C, 'Triforce Piece\nA small step\ntowards victory!', 'and the thirdforce', 'triangular kid', 'triangle for sale', 'fungus for triangle', 'wise boy has triangle again', 'A Triforce Piece'),
'Crystal 1': (True, False, 'Crystal', [0x02, 0x34, 0x64, 0x40, 0x7F, 0x20], None, None, None, None, None, None, None),
'Crystal 2': (True, False, 'Crystal', [0x10, 0x34, 0x64, 0x40, 0x79, 0x20], None, None, None, None, None, None, None),
'Crystal 3': (True, False, 'Crystal', [0x40, 0x34, 0x64, 0x40, 0x6C, 0x20], None, None, None, None, None, None, None),
'Crystal 4': (True, False, 'Crystal', [0x20, 0x34, 0x64, 0x40, 0x6D, 0x20], None, None, None, None, None, None, None),
'Crystal 5': (True, False, 'Crystal', [0x04, 0x32, 0x64, 0x40, 0x6E, 0x20], None, None, None, None, None, None, None),
'Crystal 6': (True, False, 'Crystal', [0x01, 0x32, 0x64, 0x40, 0x6F, 0x20], None, None, None, None, None, None, None),
'Crystal 7': (True, False, 'Crystal', [0x08, 0x34, 0x64, 0x40, 0x7C, 0x20], None, None, None, None, None, None, None),
'Single Arrow': (False, False, None, 0x43, 'Single Arrow!\nDestiny awaits!', 'and the arrow', 'stick-collecting kid', 'sewing needle for sale', 'fungus for arrow', 'archer boy sews again', 'An arrow'),
'Arrows (10)': (False, False, None, 0x44, '10 Arrows\nAn archer\'s bailout!', 'and the arrow pack', 'stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again', 'Ten arrows'),
'Arrow Upgrade (+10)': (False, False, None, 0x54, '10 Arrow Upgrade\nGain 10 more arrow capacity!', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'An arrow capacity upgrade'),
'Arrow Upgrade (+5)': (False, False, None, 0x53, '5 Arrow Upgrade\nGain 5 more arrow capacity!', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'An arrow capacity upgrade'),
'Single Bomb': (False, False, None, 0x27, '1 Bomb\nBoom boom pow!', 'and the explosion', 'the bomb-holding kid', 'firecracker for sale', 'blend fungus into bomb', '\'splosion boy explodes again', 'A bomb'),
'Bombs (3)': (False, False, None, 0x28, '3 Bombs\nExplosions!\nIn a handy 3-pack', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'Three bombs'),
'Bombs (10)': (False, False, None, 0x31, '10 Bombs\nExplosions!\nIn a thrifty 10-pack', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'Ten bombs'),
'Bomb Upgrade (+10)': (False, False, None, 0x52, '10 Bomb Upgrade\nGain 10 more bomb capacity!', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'A bomb capacity upgrade'),
'Bomb Upgrade (+5)': (False, False, None, 0x51, '5 Bomb Upgrade\nGain 5 more bomb capacity!', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'A bomb capacity upgrade'),
'Blue Mail': (False, True, None, 0x22, 'Blue Mail!\nLess damage activate!', 'and the banana hat', 'the protected kid', 'banana hat for sale', 'the clothing store', 'tailor boy banana hatted again', 'The Blue Mail'),
'Red Mail': (False, True, None, 0x23, 'Red Mail!\nEven less damage!', 'and the eggplant hat', 'well-protected kid', 'purple hat for sale', 'the nice clothing store', 'tailor boy fears nothing again', 'The Red Mail'),
'Progressive Armor': (False, True, None, 0x60, 'Upgrade Mail!\nNot the kind you read!', 'and the unknown hat', 'the protected kid', 'new hat for sale', 'the clothing store', 'tailor boy has threads again', 'Some Armor'),
'Blue Boomerang': (True, False, None, 0x0C, 'Blue Boomerang!\nAlways comes back!', 'and the bluemarang', 'the bat-throwing kid', 'bent stick for sale', 'fungus for puma-stick', 'throwing boy plays fetch again', 'The Blue Boomerang'),
'Red Boomerang': (True, False, None, 0x2A, 'Red Boomerang!\nAlways comes back!', 'and the badmarang', 'the bat-throwing kid', 'air foil for sale', 'fungus for return-stick', 'magical boy plays fetch again', 'The Red Boomerang'),
'Blue Shield': (False, True, None, 0x04, 'Blue Shield\nBlock rocks!', 'and the stone blocker', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'The Blue Shield'),
'Red Shield': (False, True, None, 0x05, 'Red Shield\nBlock fireballs!', 'and the shot blocker', 'shield-wielding kid', 'fire shield for sale', 'fungus for fire shield', 'shield boy defends again', 'The Red Shield'),
'Mirror Shield': (True, False, None, 0x06, 'Mirror Shield\nBlock lasers!', 'and the laser blocker', 'shield-wielding kid', 'face shield for sale', 'fungus for face shield', 'shield boy defends again', 'The Mirror Shield'),
'Progressive Shield': (True, False, None, 0x5F, 'Shield\nA better shield for your time!', 'and the new shield', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'A Shield'),
'Bug Catching Net': (True, False, None, 0x21, 'Bug Net!\nCatch all manner\nof things!', 'and the bee catcher', 'the bug-catching kid', 'stick web for sale', 'fungus for butterflies', 'wrong boy catches bees again', 'The Bug Net'),
'Cane of Byrna': (True, False, None, 0x18, 'Cane of Byrna!\nSwirly protection!', 'and the bad cane', 'the spark-making kid', 'spark stick for sale', 'spark-stick for trade', 'cane boy encircles again', 'The Blue Cane'),
'Boss Heart Container': (False, False, None, 0x3E, 'Heart Container!\nHealth Increased!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'A Heart'),
'Sanctuary Heart Container': (False, False, None, 0x3F, 'Heart Container!\nHealth Increased!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'A Heart'),
'Piece of Heart': (False, False, None, 0x17, 'Heart Piece!\nOne step closer\nto more health!', 'and the broken heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'A Heart Piece'),
'Rupee (1)': (False, False, None, 0x34, 'Rupees!\nNeat I guess?', 'the pocket change', 'poverty-struck kid', 'life lesson for sale', 'buying cheap drugs', 'destitute boy has snack again', 'A green rupee'),
'Rupees (5)': (False, False, None, 0x35, 'Rupees!\nNeat I guess?', 'the pocket change', 'poverty-struck kid', 'life lesson for sale', 'buying cheap drugs', 'destitute boy has snack again', 'A blue rupee'),
'Rupees (20)': (False, False, None, 0x36, 'Rupees!\nThat\'s alright.', 'and the couch cash', 'the piggy-bank kid', 'life lesson for sale', 'the witch buying drugs', 'destitute boy has lunch again', 'A red rupee'),
'Rupees (50)': (False, False, None, 0x41, 'Rupees!\nThat\'s neat!', 'and the rupee pile', 'the well-off kid', 'life lesson for sale', 'buying okay drugs', 'destitute boy has dinner again', 'Fifty rupees'),
'Rupees (100)': (False, False, None, 0x40, 'Rupees!\nThat\'s awesome!', 'and the rupee stash', 'the kind-of-rich kid', 'life lesson for sale', 'buying good drugs', 'affluent boy goes drinking again', 'One hundred rupees'),
'Rupees (300)': (False, False, None, 0x46, 'Rupees!\nThat\'s fantastic!', 'and the rupee hoard', 'the really-rich kid', 'life lesson for sale', 'buying the best drugs', 'fat-cat boy is rich again', 'Three hundred rupees'),
'Rupoor': (False, False, None, 0x59, 'Rupoor!\nI\'ll take your rupees!', 'and the toll-booth', 'the toll-booth kid', 'double loss for sale', 'witch stole your rupees', 'affluent boy steals rupees', 'A rupoor'),
'Red Clock': (False, True, None, 0x5B, 'Red Clock!\nA waste of time.', 'the ruby clock', 'the ruby-time kid', 'red time for sale', 'for ruby time', 'moment boy travels time again', 'A red clock'),
'Blue Clock': (False, True, None, 0x5C, 'Blue Clock!\nA bit of time!', 'the sapphire clock', 'sapphire-time kid', 'blue time for sale', 'for sapphire time', 'moment boy time travels again', 'A blue clock'),
'Green Clock': (False, True, None, 0x5D, 'Green Clock!\nTons of time!', 'the emerald clock', 'the emerald-time kid', 'green time for sale', 'for emerald time', 'moment boy adjusts time again', 'A green clock'),
'Single RNG': (False, True, None, 0x62, 'something you don\'t yet have', None, None, None, None, 'unknown boy somethings again', 'A new mystery'),
'Multi RNG': (False, True, None, 0x63, 'something you may already have', None, None, None, None, 'unknown boy somethings again', 'A total mystery'),
'Magic Upgrade (1/2)': (True, False, None, 0x4E, 'Half Magic!\nDouble your magic power!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Half magic'), # can be required to beat mothula in an open seed in very very rare circumstance
'Magic Upgrade (1/4)': (True, False, None, 0x4F, 'Quarter Magic!\nMagic is basically free now!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Quarter magic'), # can be required to beat mothula in an open seed in very very rare circumstance
'Small Key (Eastern Palace)': (False, False, 'SmallKey', 0xA2, 'A Small Key for\nDesert Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Eastern Palace'),
'Big Key (Eastern Palace)': (False, False, 'BigKey', 0x9D, 'A Big Key for\nEastern Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Eastern Palace'),
'Compass (Eastern Palace)': (False, True, 'Compass', 0x8D, 'A Compass for\nEastern Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Eastern Palace'),
'Map (Eastern Palace)': (False, True, 'Map', 0x7D, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Eastern Palace'),
'Small Key (Desert Palace)': (False, False, 'SmallKey', 0xA3, 'A Small Key for\nDesert Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Desert Palace'),
'Big Key (Desert Palace)': (False, False, 'BigKey', 0x9C, 'A Big Key for\nDesert Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Desert Palace'),
'Compass (Desert Palace)': (False, True, 'Compass', 0x8C, 'A Compass for\nDesert Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Desert Palace'),
'Map (Desert Palace)': (False, True, 'Map', 0x7C, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Desert Palace'),
'Small Key (Tower of Hera)': (False, False, 'SmallKey', 0xAA, 'A Small Key for\nTower of Hera', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Tower of Hera'),
'Big Key (Tower of Hera)': (False, False, 'BigKey', 0x95, 'A Big Key for\nTower of Hera', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Tower of Hera'),
'Compass (Tower of Hera)': (False, True, 'Compass', 0x85, 'A Compass for\nTower of Hera', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Tower of Hera'),
'Map (Tower of Hera)': (False, True, 'Map', 0x75, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Tower of Hera'),
'Small Key (Escape)': (False, False, 'SmallKey', 0xA0, 'A Small Key for\nEscape', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Hyrule Castle'),
'Big Key (Escape)': (False, False, 'BigKey', 0x9F, 'A Big Key for\nEscape', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Hyrule Castle'),
'Compass (Escape)': (False, True, 'Compass', 0x8F, 'A Compass for\nEscape', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Hyrule Castle'),
'Map (Escape)': (False, True, 'Map', 0x7F, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Hyrule Castle'),
'Small Key (Agahnims Tower)': (False, False, 'SmallKey', 0xA4, 'A Small Key for\nAganim\'s Tower', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Castle Tower'),
'Small Key (Palace of Darkness)': (False, False, 'SmallKey', 0xA6, 'A Small Key for\nDark Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Palace of Darkness'),
'Big Key (Palace of Darkness)': (False, False, 'BigKey', 0x99, 'A Big Key for\nDark Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Palace of Darkness'),
'Compass (Palace of Darkness)': (False, True, 'Compass', 0x89, 'A Compass for\nDark Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Palace of Darkness'),
'Map (Palace of Darkness)': (False, True, 'Map', 0x79, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Palace of Darkness'),
'Small Key (Thieves Town)': (False, False, 'SmallKey', 0xAB, 'A Small Key for\nThieves Town', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Thieves\' Town'),
'Big Key (Thieves Town)': (False, False, 'BigKey', 0x94, 'A Big Key for\nThieves Town', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Thieves\' Town'),
'Compass (Thieves Town)': (False, True, 'Compass', 0x84, 'A Compass for\nThieves Town', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Thieves\' Town'),
'Map (Thieves Town)': (False, True, 'Map', 0x74, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Thieves\' Town'),
'Small Key (Skull Woods)': (False, False, 'SmallKey', 0xA8, 'A Small Key for\nSkull Woods', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Skull Woods'),
'Big Key (Skull Woods)': (False, False, 'BigKey', 0x97, 'A Big Key for\nSkull Woods', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Skull Woods'),
'Compass (Skull Woods)': (False, True, 'Compass', 0x87, 'A Compass for\nSkull Woods', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Skull Woods'),
'Map (Skull Woods)': (False, True, 'Map', 0x77, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Skull Woods'),
'Small Key (Swamp Palace)': (False, False, 'SmallKey', 0xA5, 'A Small Key for\nSwamp Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Swamp Palace'),
'Big Key (Swamp Palace)': (False, False, 'BigKey', 0x9A, 'A Big Key for\nSwamp Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Swamp Palace'),
'Compass (Swamp Palace)': (False, True, 'Compass', 0x8A, 'A compass for\nSwamp Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Swamp Palace'),
'Map (Swamp Palace)': (False, True, 'Map', 0x7A, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Swamp Palace'),
'Small Key (Ice Palace)': (False, False, 'SmallKey', 0xA9, 'A Small Key for\nIce Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Ice Palace'),
'Big Key (Ice Palace)': (False, False, 'BigKey', 0x96, 'A Big Key for\nIce Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Ice Palace'),
'Compass (Ice Palace)': (False, True, 'Compass', 0x86, 'A Compass for\nIce Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Ice Palace'),
'Map (Ice Palace)': (False, True, 'Map', 0x76, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Ice Palace'),
'Small Key (Misery Mire)': (False, False, 'SmallKey', 0xA7, 'A Small Key for\nMisery Mire', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Misery Mire'),
'Big Key (Misery Mire)': (False, False, 'BigKey', 0x98, 'A Big Key for\nMisery Mire', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Misery Mire'),
'Compass (Misery Mire)': (False, True, 'Compass', 0x88, 'A Compass for\nMisery Mire', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Misery Mire'),
'Map (Misery Mire)': (False, True, 'Map', 0x78, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Misery Mire'),
'Small Key (Turtle Rock)': (False, False, 'SmallKey', 0xAC, 'A Small Key for\nTurtle Rock', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Turtle Rock'),
'Big Key (Turtle Rock)': (False, False, 'BigKey', 0x93, 'A Big Key for\nTurtle Rock', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Turtle Rock'),
'Compass (Turtle Rock)': (False, True, 'Compass', 0x83, 'A Compass for\nTurtle Rock', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'A compass to Turtle Rock'),
'Map (Turtle Rock)': (False, True, 'Map', 0x73, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Turtle Rock'),
'Small Key (Ganons Tower)': (False, False, 'SmallKey', 0xAD, 'A Small Key for\nGanon\'s Tower', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key to Ganon\'s Tower'),
'Big Key (Ganons Tower)': (False, False, 'BigKey', 0x92, 'A Big Key for\nGanon\'s Tower', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'A big key to Ganon\'s Tower'),
'Compass (Ganons Tower)': (False, True, 'Compass', 0x82, 'A Compass for\nGanon\'s Tower', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a comapss to Ganon\'s Tower'),
'Map (Ganons Tower)': (False, True, 'Map', 0x72, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'A map to Ganon\'s Tower'),
'Small Key (Universal)': (False, True, None, 0xAF, 'A small key for any door', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key'),
'Small Key (Universal)': (False, True, None, 0xAF, 'A small key for any door', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'A small key'),
'Teleporter': (False, True, None, 0xB8, 'A teleporter', 'and the teleporter', 'the teleporting kid', 'teleportation for sale', 'teleporting fungus', 'teleporter boy warps again', 'A teleporter'),
'IFrames (10)': (False, False, None, 0xB9, 'More invincibility frames', 'and the i-frames', 'the invincible kid', 'invincibility for sale', 'invincible fungus', 'invincble boy damaged again', 'Some invincibility frames'),
'Nothing': (False, False, None, 0x5A, 'Some Hot Air', 'and the Nothing', 'the zen kid', 'outright theft', 'shroom theft', 'empty boy is bored again', 'Nothing'),
'Red Potion': (False, False, None, 0x2E, None, None, None, None, None, None, None),
'Green Potion': (False, False, None, 0x2F, None, None, None, None, None, None, None),
'Blue Potion': (False, False, None, 0x30, None, None, None, None, None, None, None),
'Bee': (False, False, None, 0x0E, None, None, None, None, None, None, None),
'Small Heart': (False, False, None, 0x42, None, None, None, None, None, None, None),
'Beat Agahnim 1': (True, False, 'Event', None, None, None, None, None, None, None, None),
'Beat Agahnim 2': (True, False, 'Event', None, None, None, None, None, None, None, None),
'Get Frog': (True, False, 'Event', None, None, None, None, None, None, None, None),
'Return Smith': (True, False, 'Event', None, None, None, None, None, None, None, None),
'Pick Up Purple Chest': (True, False, 'Event', None, None, None, None, None, None, None, None),
'Open Floodgate': (True, False, 'Event', None, None, None, None, None, None, None, None),
}
# Format: Name: (Advancement, Priority, Type, ItemCode, BasePrice, Pedestal Hint Text, Pedestal Credit Text, Sick Kid Credit Text, Zora Credit Text, Witch Credit Text, Flute Boy Credit Text, Hint Text)
item_table = {'Bow': (True, False, None, 0x0B, 200, 'Bow!\nJoin the archer class!', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'the Bow'),
'Progressive Bow': (True, False, None, 0x64, 150, 'Bow!\nJoin the archer class!', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'a Bow'),
'Progressive Bow (Alt)': (True, False, None, 0x65, 150, 'Bow!\nJoin the archer class!', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'a Bow'),
'Book of Mudora': (True, False, None, 0x1D, 150, 'This is a\nparadox?!', 'and the story book', 'the scholarly kid', 'moon runes for sale', 'drugs for literacy', 'book-worm boy can read again', 'the Book'),
'Hammer': (True, False, None, 0x09, 250, 'Stop\nhammer time!', 'and m c hammer', 'hammer-smashing kid', 'm c hammer for sale', 'stop... hammer time', 'stop, hammer time', 'the Hammer'),
'Hookshot': (True, False, None, 0x0A, 250, 'Hookshot!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'),
'Magic Mirror': (True, False, None, 0x1A, 250, 'Mirror!\nTake some time to\nreflect on this moment!', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the Mirror'),
'Ocarina': (True, False, None, 0x14, 250, 'Ocarina!\nA Flute by another name', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'),
'Ocarina (Activated)': (True, False, None, 0x4A, 250, 'Ocarina!\nA Flute by another name', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'),
'Pegasus Boots': (True, False, None, 0x4B, 250, 'Pegasus Boots!\nGotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the Boots'),
'Power Glove': (True, False, None, 0x1B, 100, 'Glove!\nNow you can\nlift weak stuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the Glove'),
'Cape': (True, False, None, 0x19, 50, 'Cape!\nInvisbility cloak activate!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the Cape'),
'Mushroom': (True, False, None, 0x29, 50, 'Mushroom!\nDon\'t eat it. Find a witch.', 'and the legal drugs', 'the drug-dealing kid', 'legal drugs for sale', 'shroom swap', 'shroom boy sells drugs again', 'the Mushroom'),
'Shovel': (True, False, None, 0x13, 50, 'Shovel!\nCan you dig it?', 'and the spade', 'archaeologist kid', 'dirt spade for sale', 'can you dig it', 'shovel boy digs again', 'the Shovel'),
'Lamp': (True, False, None, 0x12, 150, 'Lamp!\nYou can see in the dark,\nand light torches.', 'and the flashlight', 'light-shining kid', 'flashlight for sale', 'fungus for illumination', 'illuminated boy can see again', 'the Lamp'),
'Magic Powder': (True, False, None, 0x0D, 50, 'Powder!\nSprinkle it on a dancing pickle!', 'and the magic sack', 'the sack-holding kid', 'magic sack for sale', 'the witch and assistant', 'magic boy plays marbles again', 'the Powder'),
'Moon Pearl': (True, False, None, 0x1F, 200, 'Moon Pearl!\nRabbit Be Gone!', 'and the jaw breaker', 'fortune-telling kid', 'lunar orb for sale', 'shrooms for moon rock', 'moon boy plays ball again', 'the Moon Pearl'),
'Cane of Somaria': (True, False, None, 0x15, 250, 'Cane of Somaria!\nMake blocks, throw blocks', 'and the red blocks', 'the block-making kid', 'block stick for sale', 'block stick for trade', 'cane boy makes blocks again', 'the Red Cane'),
'Fire Rod': (True, False, None, 0x07, 250, 'Fire Rod!\nI\'m burning for you!', 'and the flamethrower', 'fire-starting kid', 'rage rod for sale', 'fungus for rage-rod', 'firestarter boy burns again', 'the Fire Rod'),
'Flippers': (True, False, None, 0x1E, 250, 'Flippers!\nFancy a swim?', 'and the toewebs', 'the swimming kid', 'finger webs for sale', 'shrooms let you swim', 'swimming boy swims again', 'the Flippers'),
'Ice Rod': (True, False, None, 0x08, 250, 'Ice Rod!\nActivate Freeze Ray!', 'and the freeze ray', 'the ice-bending kid', 'freeze ray for sale', 'fungus for ice-rod', 'ice-cube boy freezes again', 'the Ice Rod'),
'Titans Mitts': (True, False, None, 0x1C, 200, 'Mitts!\nLift ALL the rocks!', 'and the golden glove', 'body-building kid', 'carry glove for sale', 'fungus for bling-gloves', 'body-building boy has gold again', 'the Mitts'),
'Bombos': (True, False, None, 0x0F, 100, 'Bombos!\nExplosions! Fire!\nBurn it all!', 'and the swirly coin', 'coin-collecting kid', 'swirly coin for sale', 'shrooms for swirly-coin', 'medallion boy melts room again', 'Bombos'),
'Ether': (True, False, None, 0x10, 100, 'Ether!\nLet\'s cool things down!', 'and the bolt coin', 'coin-collecting kid', 'bolt coin for sale', 'shrooms for bolt-coin', 'medallion boy sees floor again', 'Ether'),
'Quake': (True, False, None, 0x11, 100, 'Quake!\nLet\'s shake the ground!', 'and the wavy coin', 'coin-collecting kid', 'wavy coin for sale', 'shrooms for wavy-coin', 'medallion boy shakes dirt again', 'Quake'),
'Bottle': (True, False, None, 0x16, 50, 'Bottle!\nStore all manner of things!', 'and the terrarium', 'the terrarium kid', 'terrarium for sale', 'special promotion', 'bottle boy has terrarium again', 'a bottle'),
'Bottle (Red Potion)': (True, False, None, 0x2B, 70, 'Red Potion!\nFill your hearts!', 'and the red goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has red goo again', 'a bottle'),
'Bottle (Green Potion)': (True, False, None, 0x2C, 60, 'Green Potion!\nRestore your magic!', 'and the green goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has green goo again', 'a bottle'),
'Bottle (Blue Potion)': (True, False, None, 0x2D, 80, 'Blue Potion!\nHeal and restore!', 'and the blue goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has blue goo again', 'a bottle'),
'Bottle (Fairy)': (True, False, None, 0x3D, 70, 'Fairy Bottle!\nI\'ll save your life!', 'and the captive', 'the tingle kid', 'hostage for sale', 'fairy dust and shrooms', 'bottle boy has friend again', 'a bottle'),
'Bottle (Bee)': (True, False, None, 0x3C, 50, 'Bee Bottle!\nI\'ll sting your enemies a bit!', 'and the sting buddy', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has mad bee again', 'a bottle'),
'Bottle (Good Bee)': (True, False, None, 0x48, 60, 'Good Bee Bottle!\nI\'ll sting your enemies\na whole lot!', 'and the sparkle sting', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has beetor again', 'a bottle'),
'Master Sword': (True, False, 'Sword', 0x50, 100, 'Master Sword!\nEvil\'s bane!', 'and the master sword', 'sword-wielding kid', 'glow sword for sale', 'fungus for blue slasher', 'sword boy fights again', 'the Master Sword'),
'Tempered Sword': (True, False, 'Sword', 0x02, 150, 'Tempered Sword!\nMore slashy!', 'the tempered sword', 'sword-wielding kid', 'flame sword for sale', 'fungus for red slasher', 'sword boy fights again', 'the Tempered Sword'),
'Fighter Sword': (True, False, 'Sword', 0x49, 50, 'Fighter Sword!\nStarter level slashy!', 'the tiny sword', 'sword-wielding kid', 'tiny sword for sale', 'fungus for tiny slasher', 'sword boy fights again', 'the Fighter Sword'),
'Sword and Shield': (True, False, 'Sword', 0x00, 'Sword and Shield!\nUncle sword ahoy!', 'the sword and shield', 'sword and shield-wielding kid', 'training set for sale', 'fungus for training set', 'sword and shield boy fights again', 'the small sword and shield'),
'Golden Sword': (True, False, 'Sword', 0x03, 200, 'Golden Sword!\nBest slashy!', 'and the butter sword', 'sword-wielding kid', 'butter for sale', 'cap churned to butter', 'sword boy fights again', 'the Golden Sword'),
'Progressive Sword': (True, False, 'Sword', 0x5E, 150, 'Sword!\nA better sword for your time!', 'the unknown sword', 'sword-wielding kid', 'sword for sale', 'fungus for some slasher', 'sword boy fights again', 'a Sword'),
'Progressive Glove': (True, False, None, 0x61, 150, 'Glove!\nLift more than you can now!', 'and the lift upgrade', 'body-building kid', 'some glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'a Glove'),
'Silver Arrows': (True, False, None, 0x58, 100, 'Silver Arrows!\nDefeat Ganon faster!', 'and the ganonsbane', 'ganon-killing kid', 'ganon doom for sale', 'fungus for pork', 'archer boy shines again', 'the Silver Arrows'),
'Green Pendant': (True, False, 'Prize', 0x37, 250, 'Green Pendant! Too\nbad Sahasrahla\nwill never see it!', 'and the green pendant', 'pendant kid', 'pendant for sale', 'fungus for pendant', 'pendant boy dabs again', 'a Prize'),
'Blue Pendant': (True, False, 'Prize', 0x39, 150, 'Blue Pendant!\nBut how?!', 'and the pendant', 'pendant kid', 'pendant for sale', 'fungus for pendant', 'pendant boy dabs again', 'a Prize'),
'Red Pendant': (True, False, 'Prize', 0x38, 150, 'Red Pendant!\nBut how?!', 'and the pendant', 'pendant kid', 'pendant for sale', 'fungus for pendant', 'pendant boy dabs again', 'a Prize'),
'Triforce': (True, False, None, 0x6A, 777, 'Triforce!\nGrab me to win!', 'and the triforce', 'victorious kid', 'victory for sale', 'fungus for the win', 'greedy boy wins game again', 'the Triforce'),
'Power Star': (True, False, None, 0x6B, 100, 'Power Star!\nA small step\ntowards victory!', 'and the power star', 'star-struck kid', 'star for sale', 'see stars with shroom', 'mario powers up again', 'a Power Star'),
'Triforce Piece': (True, False, None, 0x6C, 100, 'Triforce Piece!\nA small step\ntowards victory!', 'and the thirdforce', 'triangular kid', 'triangle for sale', 'fungus for triangle', 'wise boy has triangle again', 'a Triforce piece'),
'Crystal 1': (True, False, 'Prize', 0xB1, 200, 'Crystal 1! It\'s very shiny!', 'and the crystal', 'crystal kid', 'crystal for sale', 'fungus for crystal', 'crystal boy sparkles again', 'a Prize'),
'Crystal 2': (True, False, 'Prize', 0xB4, 200, 'Crystal 2! It\'s very shiny!', 'and the crystal', 'crystal kid', 'crystal for sale', 'fungus for crystal', 'crystal boy sparkles again', 'a Prize'),
'Crystal 3': (True, False, 'Prize', 0xB6, 200, 'Crystal 3! It\'s very shiny!', 'and the crystal', 'crystal kid', 'crystal for sale', 'fungus for crystal', 'crystal boy sparkles again', 'a Prize'),
'Crystal 4': (True, False, 'Prize', 0xB5, 200, 'Crystal 4! It\'s very shiny!', 'and the crystal', 'crystal kid', 'crystal for sale', 'fungus for crystal', 'crystal boy sparkles again', 'a Prize'),
'Crystal 5': (True, False, 'Prize', 0xB2, 250, 'Crystal 5! It unlocks a bomb!', 'and the red crystal', 'crystal kid', 'crystal for sale', 'fungus for crystal', 'crystal boy sparkles again', 'a Prize'),
'Crystal 6': (True, False, 'Prize', 0xB0, 250, 'Crystal 6! It unlocks a bomb!', 'and the red crystal', 'crystal kid', 'crystal for sale', 'fungus for crystal', 'crystal boy sparkles again', 'a Prize'),
'Crystal 7': (True, False, 'Prize', 0xB3, 200, 'Crystal 7! It\'s very shiny!', 'and the crystal', 'crystal kid', 'crystal for sale', 'fungus for crystal', 'crystal boy sparkles again', 'a Prize'),
'Single Arrow': (False, False, None, 0x43, 3, 'Single Arrow!\nDestiny awaits!', 'and the arrow', 'stick-collecting kid', 'sewing needle for sale', 'fungus for arrow', 'archer boy sews again', 'an arrow'),
'Arrows (10)': (False, False, None, 0x44, 30, '10 Arrows!\nAn archer\'s bailout!', 'and the arrow pack', 'stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again', 'ten arrows'),
'Arrow Upgrade (+10)': (False, False, None, 0x54, 100, '10 Arrow Upgrade!\nGain 10 more arrow capacity!', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'),
'Arrow Upgrade (+5)': (False, False, None, 0x53, 100, '5 Arrow Upgrade!\nGain 5 more arrow capacity!', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'),
'Single Bomb': (False, False, None, 0x27, 5, '1 Bomb!\nBoom boom pow!', 'and the explosion', 'the bomb-holding kid', 'firecracker for sale', 'blend fungus into bomb', '\'splosion boy explodes again', 'a bomb'),
'Arrows (5)': (False, False, None, 0xD5, 15, '5 Arrows!\nAn archer\'s bailout!', 'and the arrow pack', 'stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again', 'five arrows'),
'Small Magic': (False, False, None, 0x45, 5, 'Magic Decanter!\nJust a little one', 'and the bit of magic', 'bit-o-magic kid', 'magic bit for sale', 'fungus for magic', 'magic boy conjures again', 'a bit of magic'),
'Big Magic': (False, False, None, 0xD4, 40, 'Magic Decanter!\nFull refill', 'and lots of magic', 'lot-o-magic kid', 'magic refill for sale', 'fungus for magic', 'magic boy conjures again', 'a magic refill'),
'Chicken': (False, False, None, 0xD3, 5, 'Cucco of Legend', 'and the legendary cucco', 'chicken kid', 'fried chicken for sale', 'fungus for chicken', 'cucco boy clucks again', 'a cucco'),
'Bombs (3)': (False, False, None, 0x28, 15, '3 Bombs!\nExplosions!\nIn a handy 3-pack', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'three bombs'),
'Bombs (10)': (False, False, None, 0x31, 50, '10 Bombs!\nExplosions!\nIn a thrifty 10-pack', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'ten bombs'),
'Bomb Upgrade (+10)': (False, False, None, 0x52, 100, '10 Bomb Upgrade!\nGain 10 more bomb capacity!', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'),
'Bomb Upgrade (+5)': (False, False, None, 0x51, 100, '5 Bomb Upgrade!\nGain 5 more bomb capacity!', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'),
'Blue Mail': (False, True, None, 0x22, 50, 'Blue Mail!\nLess damage activate!', 'and the banana hat', 'the protected kid', 'banana hat for sale', 'the clothing store', 'tailor boy banana hatted again', 'the Blue Mail'),
'Red Mail': (False, True, None, 0x23, 100, 'Red Mail!\nEven less damage!', 'and the eggplant hat', 'well-protected kid', 'purple hat for sale', 'the nice clothing store', 'tailor boy fears nothing again', 'the Red Mail'),
'Progressive Armor': (False, True, None, 0x60, 50, 'Upgrade Mail!\nNot the kind you read!', 'and the unknown hat', 'the protected kid', 'new hat for sale', 'the clothing store', 'tailor boy has threads again', 'some armor'),
'Blue Boomerang': (True, False, None, 0x0C, 50, 'Blue Boomerang!\nAlways comes back!', 'and the bluemarang', 'the bat-throwing kid', 'bent stick for sale', 'fungus for puma-stick', 'throwing boy plays fetch again', 'the Blue Boomerang'),
'Red Boomerang': (True, False, None, 0x2A, 50, 'Red Boomerang!\nAlways comes back!', 'and the badmarang', 'the bat-throwing kid', 'air foil for sale', 'fungus for return-stick', 'magical boy plays fetch again', 'the Red Boomerang'),
'Blue Shield': (False, True, None, 0x04, 50, 'Blue Shield!\nBlock rocks!', 'and the stone blocker', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'a blue shield'),
'Red Shield': (False, True, None, 0x05, 500, 'Red Shield!\nBlock fireballs!', 'and the shot blocker', 'shield-wielding kid', 'fire shield for sale', 'fungus for fire shield', 'shield boy defends again', 'the Red Shield'),
'Mirror Shield': (True, False, None, 0x06, 200, 'Mirror Shield!\nBlock lasers!', 'and the laser blocker', 'shield-wielding kid', 'face shield for sale', 'fungus for face shield', 'shield boy defends again', 'the Mirror Shield'),
'Progressive Shield': (True, False, None, 0x5F, 50, 'Shield!\nA better shield for your time!', 'and the new shield', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'a shield'),
'Bug Catching Net': (True, False, None, 0x21, 50, 'Bug Net!\nCatch all manner\nof things!', 'and the bee catcher', 'the bug-catching kid', 'stick web for sale', 'fungus for butterflies', 'wrong boy catches bees again', 'the Bug Net'),
'Cane of Byrna': (True, False, None, 0x18, 50, 'Cane of Byrna!\nSwirly protection!', 'and the bad cane', 'the spark-making kid', 'spark stick for sale', 'spark-stick for trade', 'cane boy encircles again', 'the Blue Cane'),
'Boss Heart Container': (False, True, None, 0x3E, 40, 'Heart Container!\nHealth Increased!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'a heart'),
'Sanctuary Heart Container': (False, True, None, 0x3F, 50, 'Heart Container!\nHealth Increased!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'a heart'),
'Piece of Heart': (False, False, None, 0x17, 10, 'Heart Piece!\nOne step closer\nto more health!', 'and the broken heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'a heart piece'),
'Rupee (1)': (False, False, None, 0x34, 0, 'Rupees!\nJust pocket\nchange.', 'the pocket change', 'poverty-struck kid', 'life lesson for sale', 'buying cheap drugs', 'destitute boy has snack again', 'a green rupee'),
'Rupees (5)': (False, False, None, 0x35, 2, 'Rupees!\nJust pocket\nchange.', 'the pocket change', 'poverty-struck kid', 'life lesson for sale', 'buying cheap drugs', 'destitute boy has snack again', 'a blue rupee'),
'Rupees (20)': (False, False, None, 0x36, 10, 'Rupees!\nJust couch\ncash.', 'and the couch cash', 'the piggy-bank kid', 'life lesson for sale', 'the witch buying drugs', 'destitute boy has lunch again', 'a red rupee'),
'Rupees (50)': (False, False, None, 0x41, 25, 'Rupees!\nA big pile!', 'and the rupee pile', 'the well-off kid', 'life lesson for sale', 'buying okay drugs', 'destitute boy has dinner again', 'fifty rupees'),
'Rupees (100)': (False, False, None, 0x40, 50, 'Rupees!\nA big stash!', 'and the rupee stash', 'the kind-of-rich kid', 'life lesson for sale', 'buying good drugs', 'affluent boy goes drinking again', 'one hundred rupees'),
'Rupees (300)': (False, True, None, 0x46, 150, 'Rupees!\nA big hoard!', 'and the rupee hoard', 'the really-rich kid', 'life lesson for sale', 'buying the best drugs', 'fat-cat boy is rich again', 'three hundred rupees'),
'Rupoor': (False, False, None, 0x59, 0, 'Rupoor!\nI\'ll take your rupees!', 'and the toll-booth', 'the toll-booth kid', 'double loss for sale', 'witch stole your rupees', 'affluent boy steals rupees', 'a rupoor'),
'Red Clock': (False, True, None, 0x5B, 0, 'Red Clock!\nA waste of time.', 'the ruby clock', 'the ruby-time kid', 'red time for sale', 'for ruby time', 'moment boy travels time again', 'a red clock'),
'Blue Clock': (False, True, None, 0x5C, 50, 'Blue Clock!\nA bit of time!', 'the sapphire clock', 'sapphire-time kid', 'blue time for sale', 'for sapphire time', 'moment boy time travels again', 'a blue clock'),
'Green Clock': (False, True, None, 0x5D, 200, 'Green Clock!\nTons of time!', 'the emerald clock', 'the emerald-time kid', 'green time for sale', 'for emerald time', 'moment boy adjusts time again', 'a red clock'),
'Single RNG': (False, True, None, 0x62, 300, 'Something you don\'t yet have', None, None, None, None, 'unknown boy somethings again', 'a new mystery'),
'Multi RNG': (False, True, None, 0x63, 100, 'Something you may already have', None, None, None, None, 'unknown boy somethings again', 'a total mystery'),
'Magic Upgrade (1/2)': (True, False, None, 0x4E, 50, 'Half Magic!\nDouble your magic power!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Half Magic'), # can be required to beat mothula in an open seed in very very rare circumstance
'Magic Upgrade (1/4)': (True, False, None, 0x4F, 100, 'Quarter Magic!\nMagic is basically free now!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Quarter Magic'), # can be required to beat mothula in an open seed in very very rare circumstance
'Small Key (Eastern Palace)': (False, False, 'SmallKey', 0xA2, 40, 'A small key for\nEastern Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Eastern Palace'),
'Big Key (Eastern Palace)': (False, False, 'BigKey', 0x9D, 60, 'A big key for\nEastern Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Eastern Palace'),
'Compass (Eastern Palace)': (False, True, 'Compass', 0x8D, 10, 'A compass for\nEastern Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Eastern Palace'),
'Map (Eastern Palace)': (False, True, 'Map', 0x7D, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Eastern Palace'),
'Small Key (Desert Palace)': (False, False, 'SmallKey', 0xA3, 40, 'A small key for\nDesert Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Desert Palace'),
'Big Key (Desert Palace)': (False, False, 'BigKey', 0x9C, 60, 'A big key for\nDesert Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Desert Palace'),
'Compass (Desert Palace)': (False, True, 'Compass', 0x8C, 10, 'A compass for\nDesert Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Desert Palace'),
'Map (Desert Palace)': (False, True, 'Map', 0x7C, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Desert Palace'),
'Small Key (Tower of Hera)': (False, False, 'SmallKey', 0xAA, 40, 'A small key for\nTower of Hera', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Tower of Hera'),
'Big Key (Tower of Hera)': (False, False, 'BigKey', 0x95, 60, 'A big key for\nTower of Hera', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Tower of Hera'),
'Compass (Tower of Hera)': (False, True, 'Compass', 0x85, 10, 'A compass for\nTower of Hera', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Tower of Hera'),
'Map (Tower of Hera)': (False, True, 'Map', 0x75, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Tower of Hera'),
'Small Key (Escape)': (False, False, 'SmallKey', 0xA0, 40, 'A small key for\nHyrule Castle', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Hyrule Castle'),
'Big Key (Escape)': (False, False, 'BigKey', 0x9F, 60, 'A big key for\nHyrule Castle', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Hyrule Castle'),
'Compass (Escape)': (False, True, 'Compass', 0x8F, 10, 'A compass for\nHyrule Castle', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds null again', 'a compass to Hyrule Castle'),
'Map (Escape)': (False, True, 'Map', 0x7F, 10, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Hyrule Castle'),
'Small Key (Agahnims Tower)': (False, False, 'SmallKey', 0xA4, 40, 'A small key for\nAgahnim\'s Tower', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Castle Tower'),
'Big Key (Agahnims Tower)': (False, False, 'BigKey', 0x9B, 60, 'A big key for\nAgahnim\'s Tower', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Castle Tower'),
'Compass (Agahnims Tower)': (False, True, 'Compass', 0x8B, 10, 'A compass for\nAgahnim\'s Tower', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds null again', 'a compass to Castle Tower'),
'Map (Agahnims Tower)': (False, True, 'Map', 0x7B, 10, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Castle Tower'),
'Small Key (Palace of Darkness)': (False, False, 'SmallKey', 0xA6, 40, 'A small key for\nDark Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Palace of Darkness'),
'Big Key (Palace of Darkness)': (False, False, 'BigKey', 0x99, 60, 'A big key for\nDark Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Palace of Darkness'),
'Compass (Palace of Darkness)': (False, True, 'Compass', 0x89, 10, 'A compass for\nDark Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Palace of Darkness'),
'Map (Palace of Darkness)': (False, True, 'Map', 0x79, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Palace of Darkness'),
'Small Key (Thieves Town)': (False, False, 'SmallKey', 0xAB, 40, 'A small key for\nThieves Town', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Thieves\' Town'),
'Big Key (Thieves Town)': (False, False, 'BigKey', 0x94, 60, 'A big key for\nThieves Town', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Thieves\' Town'),
'Compass (Thieves Town)': (False, True, 'Compass', 0x84, 10, 'A compass for\nThieves Town', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Thieves\' Town'),
'Map (Thieves Town)': (False, True, 'Map', 0x74, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Thieves\' Town'),
'Small Key (Skull Woods)': (False, False, 'SmallKey', 0xA8, 40, 'A small key for\nSkull Woods', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Skull Woods'),
'Big Key (Skull Woods)': (False, False, 'BigKey', 0x97, 60, 'A big key for\nSkull Woods', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Skull Woods'),
'Compass (Skull Woods)': (False, True, 'Compass', 0x87, 10, 'A compass for\nSkull Woods', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Skull Woods'),
'Map (Skull Woods)': (False, True, 'Map', 0x77, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Skull Woods'),
'Small Key (Swamp Palace)': (False, False, 'SmallKey', 0xA5, 40, 'A small key for\nSwamp Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Swamp Palace'),
'Big Key (Swamp Palace)': (False, False, 'BigKey', 0x9A, 60, 'A big key for\nSwamp Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Swamp Palace'),
'Compass (Swamp Palace)': (False, True, 'Compass', 0x8A, 10, 'A compass for\nSwamp Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Swamp Palace'),
'Map (Swamp Palace)': (False, True, 'Map', 0x7A, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Swamp Palace'),
'Small Key (Ice Palace)': (False, False, 'SmallKey', 0xA9, 40, 'A small key for\nIce Palace', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Ice Palace'),
'Big Key (Ice Palace)': (False, False, 'BigKey', 0x96, 60, 'A big key for\nIce Palace', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Ice Palace'),
'Compass (Ice Palace)': (False, True, 'Compass', 0x86, 10, 'A compass for\nIce Palace', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Ice Palace'),
'Map (Ice Palace)': (False, True, 'Map', 0x76, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Ice Palace'),
'Small Key (Misery Mire)': (False, False, 'SmallKey', 0xA7, 40, 'A small key for\nMisery Mire', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Misery Mire'),
'Big Key (Misery Mire)': (False, False, 'BigKey', 0x98, 60, 'A big key for\nMisery Mire', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Misery Mire'),
'Compass (Misery Mire)': (False, True, 'Compass', 0x88, 10, 'A compass for\nMisery Mire', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Misery Mire'),
'Map (Misery Mire)': (False, True, 'Map', 0x78, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Misery Mire'),
'Small Key (Turtle Rock)': (False, False, 'SmallKey', 0xAC, 40, 'A small key for\nTurtle Rock', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Turtle Rock'),
'Big Key (Turtle Rock)': (False, False, 'BigKey', 0x93, 60, 'A big key for\nTurtle Rock', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Turtle Rock'),
'Compass (Turtle Rock)': (False, True, 'Compass', 0x83, 10, 'A compass for\nTurtle Rock', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Turtle Rock'),
'Map (Turtle Rock)': (False, True, 'Map', 0x73, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Turtle Rock'),
'Small Key (Ganons Tower)': (False, False, 'SmallKey', 0xAD, 40, 'A small key for\nGanon\'s Tower', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Ganon\'s Tower'),
'Big Key (Ganons Tower)': (False, False, 'BigKey', 0x92, 60, 'A big key for\nGanon\'s Tower', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Ganon\'s Tower'),
'Compass (Ganons Tower)': (False, True, 'Compass', 0x82, 10, 'A compass for\nGanon\'s Tower', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Ganon\'s Tower'),
'Map (Ganons Tower)': (False, True, 'Map', 0x72, 10, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a Map to Ganon\'s Tower'),
'Small Key (Universal)': (False, True, None, 0xAF, 100, 'A small key for any door', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a Small Key'),
'Nothing': (False, False, None, 0x5A, 1, 'Some Hot Air', 'and the Nothing', 'the zen kid', 'outright theft', 'shroom theft', 'empty boy is bored again', 'nothing'),
'Bee Trap': (False, False, None, 0xD0, 50, 'We will sting your face a whole lot!', 'and the sting buddies', 'the beekeeper kid', 'insects for sale', 'shroom pollenation', 'bottle boy has mad bees again', 'friendship'),
'Red Potion': (False, False, None, 0x2E, 150, 'Hearty red goop!', 'and the red goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has red goo again', 'a red potion'),
'Green Potion': (False, False, None, 0x2F, 60, 'Refreshing green goop!', 'and the green goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has green goo again', 'a green potion'),
'Blue Potion': (False, False, None, 0x30, 160, 'Delicious blue goop!', 'and the blue goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has blue goo again', 'a blue potion'),
'Bee': (False, False, None, 0x0E, 10, 'I will sting your foes a few times', 'and the sting buddy', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has mad bee again', 'a bee'),
'Good Bee': (False, False, None, 0xD6, 10, 'I will sting your foes a lot', 'and the cold buddy', 'the beekeeper kid', 'cold insect for sale', 'shroom pollenation', 'bottle boy has cold bee again', 'a good bee'),
'Small Heart': (False, False, None, 0x42, 10, 'Just a little\npiece of love!', 'and the heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'a heart'),
'Apples': (False, False, None, 0xD1, 30, 'Just a few pieces of fruit!', 'and the juicy fruit', 'the fruity kid', 'the fruit stand', 'expired fruit', 'bottle boy has fruit again', 'an apple hoard'),
'Fairy': (False, False, None, 0xD2, 50, 'Just a pixie!', 'and the pixie', 'the pixie kid', 'pixie for sale', 'pixie fungus', 'bottle boy has pixie again', 'a pixie'),
'Beat Boss': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Beat Agahnim 1': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Beat Agahnim 2': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Pick Up Kiki': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Dark Palace Opened': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Get Frog': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Return Smith': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Pick Up Purple Chest': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Deliver Purple Chest': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Open Floodgate': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Pick Up Big Bomb': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Detonate Big Bomb': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Trench 1 Filled': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Trench 2 Filled': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Drained Swamp': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Turtle Opened': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Shining Light': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Maiden Rescued': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Maiden Unmasked': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Convenient Block': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Hidden Pits': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Zelda Herself': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Zelda Delivered': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Sign Vandalized': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Escort Old Man': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Return Old Man': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Farmable Bombs': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
'Farmable Rupees': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
}
prize_item_table = {
'Green Pendant': [0x04, 0x38, 0x60, 0x00, 0x69, 0x08],
'Blue Pendant': [0x02, 0x34, 0x60, 0x00, 0x69, 0x09],
'Red Pendant': [0x01, 0x32, 0x60, 0x00, 0x69, 0x0a],
'Crystal 1': [0x02, 0x34, 0x64, 0x40, 0x7F, 0x01],
'Crystal 2': [0x10, 0x34, 0x64, 0x40, 0x79, 0x02],
'Crystal 3': [0x40, 0x34, 0x64, 0x40, 0x6C, 0x03],
'Crystal 4': [0x20, 0x34, 0x64, 0x40, 0x6D, 0x04],
'Crystal 5': [0x04, 0x32, 0x64, 0x40, 0x6E, 0x05],
'Crystal 6': [0x01, 0x32, 0x64, 0x40, 0x6F, 0x06],
'Crystal 7': [0x08, 0x34, 0x64, 0x40, 0x7C, 0x07]
}
+2186
View File
File diff suppressed because it is too large Load Diff
+1148 -170
View File
File diff suppressed because it is too large Load Diff
+1148
View File
File diff suppressed because it is too large Load Diff
+458
View File
@@ -0,0 +1,458 @@
import argparse
import asyncio
import functools
import json
import logging
import re
import shlex
import ssl
import urllib.request
import zlib
import aioconsole
import websockets
import Items
import PotShuffle
import Regions
import source.dungeon.EnemyList as EnemyList
import source.rom.DataTables as DataTables
from BaseClasses import PotFlags, PotItem
from MultiClient import (
ReceivedItem,
get_item_name_from_id,
get_location_name_from_address,
)
class Client:
def __init__(self, socket):
self.socket = socket
self.auth = False
self.name = None
self.team = None
self.slot = None
self.send_index = 0
class Context:
def __init__(self, host, port, password):
self.data_filename = None
self.save_filename = None
self.disable_save = False
self.player_names = {}
self.rom_names = {}
self.remote_items = set()
self.locations = {}
self.host = host
self.port = port
self.password = password
self.server = None
self.countdown_timer = 0
self.clients = []
self.received_items = {}
self.lookup_name_to_id = {}
self.lookup_id_to_name = {}
self.disable_client_forfeit = False
async def send_msgs(websocket, msgs):
if not websocket or not websocket.open or websocket.closed:
return
try:
await websocket.send(json.dumps(msgs))
except websockets.ConnectionClosed:
pass
def broadcast_all(ctx : Context, msgs):
for client in ctx.clients:
if client.auth:
asyncio.create_task(send_msgs(client.socket, msgs))
def broadcast_team(ctx : Context, team, msgs):
for client in ctx.clients:
if client.auth and client.team == team:
asyncio.create_task(send_msgs(client.socket, msgs))
def notify_all(ctx : Context, text):
logging.info("Notice (all): %s" % text)
broadcast_all(ctx, [['Print', text]])
def notify_team(ctx : Context, team : int, text : str):
logging.info("Notice (Team #%d): %s" % (team+1, text))
broadcast_team(ctx, team, [['Print', text]])
def notify_client(client : Client, text : str):
if not client.auth:
return
logging.info("Notice (Player %s in team %d): %s" % (client.name, client.team+1, text))
asyncio.create_task(send_msgs(client.socket, [['Print', text]]))
async def server(websocket, ctx : Context):
client = Client(websocket)
ctx.clients.append(client)
try:
await on_client_connected(ctx, client)
async for data in websocket:
for msg in json.loads(data):
if len(msg) == 1:
cmd = msg
args = None
else:
cmd = msg[0]
args = msg[1]
await process_client_cmd(ctx, client, cmd, args)
except Exception as e:
if not isinstance(e, websockets.WebSocketException):
logging.exception(e)
finally:
await on_client_disconnected(ctx, client)
ctx.clients.remove(client)
async def on_client_connected(ctx : Context, client : Client):
await send_msgs(client.socket, [['RoomInfo', {
'password': ctx.password is not None,
'players': [(client.team, client.slot, client.name) for client in ctx.clients if client.auth]
}]])
async def on_client_disconnected(ctx : Context, client : Client):
if client.auth:
await on_client_left(ctx, client)
async def on_client_joined(ctx : Context, client : Client):
notify_all(ctx, "%s (Team #%d) has joined the game" % (client.name, client.team + 1))
async def on_client_left(ctx : Context, client : Client):
notify_all(ctx, "%s (Team #%d) has left the game" % (client.name, client.team + 1))
async def countdown(ctx : Context, timer):
notify_all(ctx, f'[Server]: Starting countdown of {timer}s')
if ctx.countdown_timer:
ctx.countdown_timer = timer
return
ctx.countdown_timer = timer
while ctx.countdown_timer > 0:
notify_all(ctx, f'[Server]: {ctx.countdown_timer}')
ctx.countdown_timer -= 1
await asyncio.sleep(1)
notify_all(ctx, f'[Server]: GO')
def get_connected_players_string(ctx : Context):
auth_clients = [c for c in ctx.clients if c.auth]
if not auth_clients:
return 'No player connected'
auth_clients.sort(key=lambda c: (c.team, c.slot))
current_team = 0
text = 'Team #1: '
for c in auth_clients:
if c.team != current_team:
text += f':: Team #{c.team + 1}: '
current_team = c.team
text += f'{c.name} '
return 'Connected players: ' + text[:-1]
def get_received_items(ctx : Context, team, player):
return ctx.received_items.setdefault((team, player), [])
def tuplize_received_items(items):
return [(item.item, item.location, item.player) for item in items]
def send_new_items(ctx : Context):
for client in ctx.clients:
if not client.auth:
continue
items = get_received_items(ctx, client.team, client.slot)
if len(items) > client.send_index:
asyncio.create_task(send_msgs(client.socket, [['ReceivedItems', (client.send_index, tuplize_received_items(items)[client.send_index:])]]))
client.send_index = len(items)
def forfeit_player(ctx : Context, team, slot):
all_locations = set(ctx.lookup_id_to_name.keys())
notify_all(ctx, "%s (Team #%d) has forfeited" % (ctx.player_names[(team, slot)], team + 1))
register_location_checks(ctx, team, slot, all_locations)
def register_location_checks(ctx : Context, team, slot, locations):
found_items = False
for location in locations:
if (location, slot) in ctx.locations:
target_item, target_player = ctx.locations[(location, slot)]
if target_player != slot or slot in ctx.remote_items:
found = False
recvd_items = get_received_items(ctx, team, target_player)
for recvd_item in recvd_items:
if recvd_item.location == location and recvd_item.player == slot:
found = True
break
if not found:
new_item = ReceivedItem(target_item, location, slot)
recvd_items.append(new_item)
if slot != target_player:
broadcast_team(ctx, team, [['ItemSent', (slot, location, target_player, target_item)]])
loc_name = get_location_name_from_address(ctx, location)
logging.info('(Team #%d) %s sent %s to %s (%s)' % (team+1, ctx.player_names[(team, slot)], get_item_name_from_id(target_item), ctx.player_names[(team, target_player)], loc_name))
found_items = True
send_new_items(ctx)
if found_items and not ctx.disable_save:
try:
with open(ctx.save_filename, "wb") as f:
jsonstr = json.dumps((list(ctx.rom_names.items()),
[(k, [i.__dict__ for i in v]) for k, v in ctx.received_items.items()]))
f.write(zlib.compress(jsonstr.encode("utf-8")))
except Exception as e:
logging.exception(e)
async def process_client_cmd(ctx : Context, client : Client, cmd, args):
if type(cmd) is not str:
await send_msgs(client.socket, [['InvalidCmd']])
return
if cmd == 'Connect':
if not args or type(args) is not dict or \
'password' not in args or type(args['password']) not in [str, type(None)] or \
'rom' not in args or type(args['rom']) is not list:
await send_msgs(client.socket, [['InvalidArguments', 'Connect']])
return
errors = set()
if ctx.password is not None and args['password'] != ctx.password:
errors.add('InvalidPassword')
if tuple(args['rom']) not in ctx.rom_names:
errors.add('InvalidRom')
else:
team, slot = ctx.rom_names[tuple(args['rom'])]
if any([c.slot == slot and c.team == team for c in ctx.clients if c.auth]):
errors.add('SlotAlreadyTaken')
else:
client.name = ctx.player_names[(team, slot)]
client.team = team
client.slot = slot
if errors:
await send_msgs(client.socket, [['ConnectionRefused', list(errors)]])
else:
client.auth = True
reply = [['Connected', [(client.team, client.slot), [(p, n) for (t, p), n in ctx.player_names.items() if t == client.team]]]]
items = get_received_items(ctx, client.team, client.slot)
if items:
reply.append(['ReceivedItems', (0, tuplize_received_items(items))])
client.send_index = len(items)
await send_msgs(client.socket, reply)
await on_client_joined(ctx, client)
if not client.auth:
return
if cmd == 'Sync':
items = get_received_items(ctx, client.team, client.slot)
if items:
client.send_index = len(items)
await send_msgs(client.socket, [['ReceivedItems', (0, tuplize_received_items(items))]])
if cmd == 'LocationChecks':
if type(args) is not list:
await send_msgs(client.socket, [['InvalidArguments', 'LocationChecks']])
return
register_location_checks(ctx, client.team, client.slot, args)
if cmd == 'LocationScouts':
if type(args) is not list:
await send_msgs(client.socket, [['InvalidArguments', 'LocationScouts']])
return
locs = []
for location in args:
if type(location) is not int or 0 >= location > len(ctx.lookup_id_to_name.keys()):
await send_msgs(client.socket, [['InvalidArguments', 'LocationScouts']])
return
loc_name = list(ctx.lookup_id_to_name.keys())[location - 1]
target_item, target_player = ctx.locations[(ctx.lookup_name_to_id[loc_name], client.slot)]
replacements = {'SmallKey': 0xA2, 'BigKey': 0x9D, 'Compass': 0x8D, 'Map': 0x7D}
item_type = [i[2] for i in Items.item_table.values() if type(i[3]) is int and i[3] == target_item]
if item_type:
target_item = replacements.get(item_type[0], target_item)
locs.append([loc_name, location, target_item, target_player])
logging.info(f"{client.name} in team {client.team+1} scouted {', '.join([l[0] for l in locs])}")
await send_msgs(client.socket, [['LocationInfo', [l[1:] for l in locs]]])
if cmd == 'Say':
if type(args) is not str or not args.isprintable():
await send_msgs(client.socket, [['InvalidArguments', 'Say']])
return
notify_all(ctx, client.name + ': ' + args)
if args.startswith('!players'):
notify_all(ctx, get_connected_players_string(ctx))
if args.startswith('!forfeit'):
if ctx.disable_client_forfeit:
notify_client(client, 'Client-initiated forfeits are disabled. Please ask the host of this game to forfeit on your behalf.')
else:
forfeit_player(ctx, client.team, client.slot)
if args.startswith('!countdown'):
try:
timer = int(args.split()[1])
except (IndexError, ValueError):
timer = 10
asyncio.create_task(countdown(ctx, timer))
def set_password(ctx : Context, password):
ctx.password = password
logging.warning('Password set to ' + password if password is not None else 'Password disabled')
async def console(ctx : Context):
while True:
input = await aioconsole.ainput()
command = shlex.split(input)
if not command:
continue
if command[0] == '/exit':
ctx.server.ws_server.close()
break
if command[0] == '/players':
logging.info(get_connected_players_string(ctx))
if command[0] == '/password':
set_password(ctx, command[1] if len(command) > 1 else None)
if command[0] == '/kick' and len(command) > 1:
team = int(command[2]) - 1 if len(command) > 2 and command[2].isdigit() else None
for client in ctx.clients:
if client.auth and client.name.lower() == command[1].lower() and (team is None or team == client.team):
if client.socket and not client.socket.closed:
await client.socket.close()
if command[0] == '/forfeitslot' and len(command) > 1 and command[1].isdigit():
if len(command) > 2 and command[2].isdigit():
team = int(command[1]) - 1
slot = int(command[2])
else:
team = 0
slot = int(command[1])
forfeit_player(ctx, team, slot)
if command[0] == '/forfeitplayer' and len(command) > 1:
team = int(command[2]) - 1 if len(command) > 2 and command[2].isdigit() else None
for client in ctx.clients:
if client.auth and client.name.lower() == command[1].lower() and (team is None or team == client.team):
if client.socket and not client.socket.closed:
forfeit_player(ctx, client.team, client.slot)
if command[0] == '/senditem' and len(command) > 2:
[(player, item)] = re.findall(r'\S* (\S*) (.*)', input)
if item in Items.item_table:
for client in ctx.clients:
if client.auth and client.name.lower() == player.lower():
new_item = ReceivedItem(Items.item_table[item][3], "cheat console", client.slot)
get_received_items(ctx, client.team, client.slot).append(new_item)
notify_all(ctx, 'Cheat console: sending "' + item + '" to ' + client.name)
send_new_items(ctx)
else:
logging.warning("Unknown item: " + item)
if command[0][0] != '/':
notify_all(ctx, '[Server]: ' + input)
def init_lookups(ctx):
ctx.lookup_id_to_name = {x: y for x, y in Regions.lookup_id_to_name.items()}
ctx.lookup_name_to_id = {x: y for x, y in Regions.lookup_name_to_id.items()}
for super_tile, pot_list in PotShuffle.vanilla_pots.items():
for pot_index, pot in enumerate(pot_list):
if pot.item != PotItem.Hole:
if pot.item == PotItem.Key:
loc_name = next(loc for loc, datum in PotShuffle.key_drop_data.items()
if datum[1] == super_tile)
else:
descriptor = 'Large Block' if pot.flags & PotFlags.Block else f'Pot #{pot_index+1}'
loc_name = f'{pot.room} {descriptor}'
location_id = Regions.pot_address(pot_index, super_tile)
ctx.lookup_name_to_id[loc_name] = location_id
ctx.lookup_id_to_name[location_id] = loc_name
uw_table = DataTables.get_uw_enemy_table()
key_drop_data = {(v[1][1], v[1][2]): k for k, v in PotShuffle.key_drop_data.items() if v[0] == 'Drop'}
for super_tile, enemy_list in uw_table.room_map.items():
for index, sprite in enumerate(enemy_list):
if (super_tile, index) in key_drop_data:
loc_name = key_drop_data[(super_tile, index)]
location_id = PotShuffle.key_drop_data[loc_name][1][0]
else:
loc_name = f'{sprite.region} Enemy #{index+1}'
location_id = EnemyList.drop_address(index, super_tile)
ctx.lookup_name_to_id[loc_name] = location_id
ctx.lookup_id_to_name[location_id] = loc_name
async def main():
parser = argparse.ArgumentParser()
parser.add_argument('--host', default=None)
parser.add_argument('--port', default=38281, type=int)
parser.add_argument('--password', default=None)
parser.add_argument('--multidata', default=None)
parser.add_argument('--savefile', default=None)
parser.add_argument('--disable_save', default=False, action='store_true')
parser.add_argument('--loglevel', default='info', choices=['debug', 'info', 'warning', 'error', 'critical'])
args = parser.parse_args()
logging.basicConfig(format='[%(asctime)s] %(message)s', level=getattr(logging, args.loglevel.upper(), logging.INFO))
ctx = Context(args.host, args.port, args.password)
init_lookups(ctx)
ctx.data_filename = args.multidata
try:
if not ctx.data_filename:
import tkinter
import tkinter.filedialog
root = tkinter.Tk()
root.withdraw()
ctx.data_filename = tkinter.filedialog.askopenfilename(filetypes=(("Multiworld data","*multidata"),))
with open(ctx.data_filename, 'rb') as f:
jsonobj = json.loads(zlib.decompress(f.read()).decode("utf-8"))
for team, names in enumerate(jsonobj['names']):
for player, name in enumerate(names, 1):
ctx.player_names[(team, player)] = name
ctx.rom_names = {tuple(rom): (team, slot) for slot, team, rom in jsonobj['roms']}
ctx.remote_items = set(jsonobj['remote_items'])
ctx.locations = {tuple(k): tuple(v) for k, v in jsonobj['locations']}
except Exception as e:
logging.error('Failed to read multiworld data (%s)' % e)
return
ip = urllib.request.urlopen('https://v4.ident.me', context=ssl._create_unverified_context()).read().decode('utf8') if not ctx.host else ctx.host
logging.info('Hosting game at %s:%d (%s)' % (ip, ctx.port, 'No password' if not ctx.password else 'Password: %s' % ctx.password))
ctx.disable_save = args.disable_save
if not ctx.disable_save:
if not ctx.save_filename:
ctx.save_filename = (ctx.data_filename[:-9] if ctx.data_filename[-9:] == 'multidata' else (ctx.data_filename + '_')) + 'multisave'
try:
with open(ctx.save_filename, 'rb') as f:
jsonobj = json.loads(zlib.decompress(f.read()).decode("utf-8"))
rom_names = jsonobj[0]
received_items = {tuple(k): [ReceivedItem(**i) for i in v] for k, v in jsonobj[1]}
if not all([ctx.rom_names[tuple(rom)] == (team, slot) for rom, (team, slot) in rom_names]):
raise Exception('Save file mismatch, will start a new game')
ctx.received_items = received_items
logging.info('Loaded save file with %d received items for %d players' % (sum([len(p) for p in received_items.values()]), len(received_items)))
except FileNotFoundError:
logging.error('No save data found, starting a new game')
except Exception as e:
logging.info(e)
ctx.server = websockets.serve(functools.partial(server,ctx=ctx), ctx.host, ctx.port, ping_timeout=None, ping_interval=None)
await ctx.server
await console(ctx)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.run_until_complete(asyncio.gather(*asyncio.Task.all_tasks()))
loop.close()
+110
View File
@@ -0,0 +1,110 @@
import argparse
import logging
from yaml.constructor import SafeConstructor
import RaceRandom as random
from DungeonRandomizer import parse_cli
from Main import main as DRMain
from source.classes.BabelFish import BabelFish
from source.tools.MysteryUtils import get_weights, roll_settings
def add_bool(self, node):
return self.construct_scalar(node)
SafeConstructor.add_constructor(u'tag:yaml.org,2002:bool', add_bool)
def main():
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--multi', default=1, type=lambda value: min(max(int(value), 1), 255))
multiargs, _ = parser.parse_known_args()
parser = argparse.ArgumentParser()
parser.add_argument('--weights', help='Path to the weights file to use for rolling game settings, urls are also valid')
parser.add_argument('--samesettings', help='Rolls settings per weights file rather than per player', action='store_true')
parser.add_argument('--seed', help='Define seed number to generate.', type=int)
parser.add_argument('--multi', default=1, type=lambda value: min(max(int(value), 1), 255))
parser.add_argument('--names', default='')
parser.add_argument('--teams', default=1, type=lambda value: max(int(value), 1))
parser.add_argument('--spoiler', default='none', choices=['none', 'settings', 'semi', 'full', 'debug'])
parser.add_argument('--no_race', action='store_true')
parser.add_argument('--print_template_yaml', action='store_true')
parser.add_argument('--suppress_rom', action='store_true')
parser.add_argument('--suppress_meta', action='store_true')
parser.add_argument('--bps', action='store_true')
parser.add_argument('--rom')
parser.add_argument('--outputpath')
parser.add_argument('--loglevel', default='info', choices=['debug', 'info', 'warning', 'error', 'critical'])
for player in range(1, multiargs.multi + 1):
parser.add_argument(f'--p{player}', help=argparse.SUPPRESS)
args = parser.parse_args()
if args.seed is None:
random.seed(None)
seed = random.randint(0, 999999999)
else:
seed = args.seed
random.seed(seed)
seedname = f'M{random.randint(0, 999999999)}'
print(f"Generating mystery for {args.multi} player{'s' if args.multi > 1 else ''}, {seedname} Seed {seed}")
weights_cache = {}
if args.weights:
weights_cache[args.weights] = get_weights(args.weights)
print(f"Weights: {args.weights} >> {weights_cache[args.weights]['description']}")
for player in range(1, args.multi + 1):
path = getattr(args, f'p{player}')
if path:
if path not in weights_cache:
weights_cache[path] = get_weights(path)
print(f"P{player} Weights: {path} >> {weights_cache[path]['description']}")
erargs = parse_cli(['--multi', str(args.multi)])
erargs.seed = seed
erargs.names = args.names
erargs.spoiler = args.spoiler
erargs.suppress_rom = args.suppress_rom
erargs.suppress_meta = args.suppress_meta
erargs.print_template_yaml = args.print_template_yaml
erargs.bps = args.bps
erargs.race = not args.no_race
erargs.outputname = seedname
if args.outputpath:
erargs.outputpath = args.outputpath
erargs.loglevel = args.loglevel
erargs.mystery = True
if args.rom:
erargs.rom = args.rom
mw_settings = {'algorithm': False}
settings_cache = {k: (roll_settings(v) if args.samesettings else None) for k, v in weights_cache.items()}
for player in range(1, args.multi + 1):
path = getattr(args, f'p{player}') if getattr(args, f'p{player}') else args.weights
if path:
settings = settings_cache[path] if settings_cache[path] else roll_settings(weights_cache[path])
for k, v in vars(settings).items():
if v is not None:
if k == 'algorithm': # multiworld wide parameters
if not mw_settings[k]: # only use the first roll
setattr(erargs, k, v)
mw_settings[k] = True
else:
getattr(erargs, k)[player] = v
else:
raise RuntimeError(f'No weights specified for player {player}')
# set up logger
loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[erargs.loglevel]
logging.basicConfig(format='%(message)s', level=loglevel)
DRMain(erargs, seed, BabelFish())
if __name__ == '__main__':
main()
+1807
View File
File diff suppressed because it is too large Load Diff
+523
View File
@@ -0,0 +1,523 @@
"""
Helper functions to deliver entrance/exit/region sets to OWG rules.
"""
from BaseClasses import Entrance, Region
from OWEdges import OWTileRegions
# Cave regions that superbunny can get through - but only with a sword.
sword_required_superbunny_mirror_regions = ["Spiral Cave (Top)"]
# Cave regions that superbunny can get through - but only with boots.
boots_required_superbunny_mirror_regions = ["Two Brothers House"]
# Cave locations that superbunny can access - but only with boots.
boots_required_superbunny_mirror_locations = [
"Sahasrahla's Hut - Left",
"Sahasrahla's Hut - Middle",
"Sahasrahla's Hut - Right",
]
# Entrances that can't be superbunny-mirrored into.
invalid_mirror_bunny_entrances = [
"Hype Cave",
"Bonk Fairy (Dark)",
"Thieves Town",
"Hammer Peg Cave",
"Brewery",
"Hookshot Cave",
"Dark Lake Hylia Ledge Fairy",
"Dark Lake Hylia Ledge Spike Cave",
"Palace of Darkness",
"Misery Mire",
"Turtle Rock",
"Bonk Rock Cave",
"Bonk Fairy (Light)",
"50 Rupee Cave",
"20 Rupee Cave",
"Checkerboard Cave",
"Light Hype Fairy",
"Waterfall of Wishing",
"Light World Bomb Hut",
"Mini Moldorm Cave",
"Ice Rod Cave",
"Sanctuary Grave",
"Kings Grave",
"Sanctuary Grave",
"Hyrule Castle Secret Entrance Drop",
"Skull Woods Second Section Hole",
"Skull Woods First Section Hole (North)",
]
# Interior locations that can be accessed with superbunny state.
superbunny_accessible_locations = [
"Waterfall of Wishing - Left",
"Waterfall of Wishing - Right",
"King's Tomb",
"Floodgate",
"Floodgate Chest",
"Cave 45",
"Bonk Rock Cave",
"Brewery",
"C-Shaped House",
"Chest Game",
"Mire Shed - Left",
"Mire Shed - Right",
"Secret Passage",
"Ice Rod Cave",
"Pyramid Fairy - Left",
"Pyramid Fairy - Right",
"Superbunny Cave - Top",
"Superbunny Cave - Bottom",
"Blind's Hideout - Left",
"Blind's Hideout - Right",
"Blind's Hideout - Far Left",
"Blind's Hideout - Far Right",
"Kakariko Well - Left",
"Kakariko Well - Middle",
"Kakariko Well - Right",
"Kakariko Well - Bottom",
"Kakariko Tavern",
"Library",
"Spiral Cave",
] + boots_required_superbunny_mirror_locations
# TODO: Add pottery locations
def get_non_mandatory_exits(world, player):
"""
Entrances that can be reached with full equipment using overworld glitches and don't need to be an exit.
The following are still be mandatory exits:
Open:
Turtle Rock Isolated Ledge Entrance
Skull Woods Second Section Door (West) (or Skull Woods Final Section)
Inverted:
Two Brothers House (West)
Desert Palace Entrance (East)
"""
yield 'Bumper Cave (Top)'
yield 'Death Mountain Return Cave (West)'
yield 'Hookshot Cave Back Entrance'
if world.is_tile_swapped(0x30, player):
yield 'Desert Palace Entrance (North)'
yield 'Desert Palace Entrance (West)'
else:
yield 'Desert Palace Entrance (East)'
if world.is_tile_swapped(0x1b, player):
yield 'Agahnims Tower'
yield 'Hyrule Castle Entrance (West)'
yield 'Hyrule Castle Entrance (East)'
if not world.is_tile_swapped(0x05, player):
yield 'Dark Death Mountain Ledge (West)'
yield 'Dark Death Mountain Ledge (East)'
#yield 'Mimic Cave' #TODO: This was here, I don't think this is true
def get_boots_clip_exits_lw(world, player):
"""
Special Light World region exits that require boots clips.
"""
for name, parent_region, target_region in boots_clips_local:
if world.is_tile_lw_like(OWTileRegions[parent_region], player):
yield(name, parent_region, target_region)
for names, parent_regions, target_regions in boots_clips:
region_pair = get_world_pair(world, player, get_region_pairs(world, player, names, parent_regions, target_regions), True)
if region_pair and region_pair[2]:
assert region_pair[0], f'Exit name missing in OWG pairing from {region_pair[1]} to {region_pair[2]}'
yield(region_pair[0], region_pair[1], region_pair[2])
def get_boots_clip_exits_dw(world, player):
"""
Special Dark World region exits that require boots clips.
"""
for name, parent_region, target_region in boots_clips_local:
if not world.is_tile_lw_like(OWTileRegions[parent_region], player):
yield(name, parent_region, target_region)
for names, parent_regions, target_regions in boots_clips:
region_pair = get_world_pair(world, player, get_region_pairs(world, player, names, parent_regions, target_regions), False)
if region_pair and region_pair[2]:
assert region_pair[0], f'Exit name missing in OWG pairing from {region_pair[1]} to {region_pair[2]}'
yield(region_pair[0], region_pair[1], region_pair[2])
def get_glitched_speed_drops_lw(world, player):
"""
Light World drop-down ledges that require glitched speed.
"""
def get_glitched_speed_drops_dw(world, player):
"""
Dark World drop-down ledges that require glitched speed.
"""
def get_mirror_clip_spots(world, player):
"""
Out of bounds transitions using the mirror
"""
for name, parent_region, target_region in mirror_clips_local:
if not world.is_tile_lw_like(OWTileRegions[parent_region], player):
yield(name, parent_region, target_region)
for names, parent_regions, target_regions in mirror_clips:
region_pair = get_world_pair(world, player, get_region_pairs(world, player, names, parent_regions, target_regions), False)
if region_pair and region_pair[2] and not world.is_tile_lw_like(OWTileRegions[region_pair[1]], player):
assert region_pair[0], f'Exit name missing in OWG pairing from {region_pair[1]} to {region_pair[2]}'
yield(region_pair[0], region_pair[1], region_pair[2])
def get_mirror_offset_spots(world, player):
"""
Mirror shenanigans placing a mirror portal with a broken camera
"""
# TODO: These really should check to see if there is a mirrorless path to the mirror portal
# but being that OWG is very very open, it's very unlikely there isn't a path, but possible
for names, parent_regions, target_regions, path_to in mirror_offsets:
region_pair = get_world_pair(world, player, get_region_pairs(world, player, names, parent_regions, target_regions, path_to), False)
if region_pair and region_pair[2] and not world.is_tile_lw_like(OWTileRegions[region_pair[1]], player):
assert region_pair[0], f'Exit name missing in OWG pairing from {region_pair[1]} to {region_pair[2]}'
yield(region_pair[0], region_pair[1], region_pair[2], region_pair[3])
def get_swapped_status(world, player, parents, targets):
if parents[0]:
parent_swapped = world.is_tile_swapped(OWTileRegions[parents[0]], player)
else:
parent_swapped = world.is_tile_swapped(OWTileRegions[parents[1]], player)
if targets[0] and targets[0] in (glitch_regions[0] + glitch_regions[1]):
target_swapped = targets[0] in glitch_regions[1]
else:
if targets[0]:
target_swapped = world.is_tile_swapped(OWTileRegions[targets[0]], player)
else:
target_swapped = world.is_tile_swapped(OWTileRegions[targets[1]], player)
return parent_swapped, target_swapped
def get_region_pairs(world, player, names, parent_regions, target_regions, path_regions=None):
# this pairs the source region to the proper destination
region_pairs = [None, None]
parent_swapped, target_swapped = get_swapped_status(world, player, parent_regions, target_regions)
if parent_regions[0]:
region_pairs[0] = [names[0], parent_regions[0]]
if parent_swapped == target_swapped:
region_pairs[0].append(target_regions[0])
if path_regions:
region_pairs[0].append(path_regions[0])
else:
region_pairs[0].append(target_regions[1])
if path_regions:
region_pairs[0].append(path_regions[1])
if parent_regions[1]:
region_pairs[1] = [names[1], parent_regions[1]]
if parent_swapped == target_swapped:
region_pairs[1].append(target_regions[1])
if path_regions:
region_pairs[1].append(path_regions[1])
else:
region_pairs[1].append(target_regions[0])
if path_regions:
region_pairs[1].append(path_regions[0])
return region_pairs
def get_world_pair(world, player, region_pairs, get_light_world):
# this chooses the region pair that is in the right world
if region_pairs[0]:
is_lw = world.is_tile_lw_like(OWTileRegions[region_pairs[0][1]], player)
else:
is_lw = not world.is_tile_lw_like(OWTileRegions[region_pairs[1][1]], player)
if is_lw == get_light_world:
return region_pairs[0]
else:
return region_pairs[1]
def create_owg_connections(world, player):
"""
Add OWG transitions to player's world without logic
"""
create_no_logic_connections(player, world, get_boots_clip_exits_lw(world, player))
create_no_logic_connections(player, world, get_boots_clip_exits_dw(world, player))
# Glitched speed drops.
#create_no_logic_connections(player, world, get_glitched_speed_drops_lw(world, player))
#create_no_logic_connections(player, world, get_glitched_speed_drops_dw(world, player))
# Mirror clip spots.
create_no_logic_connections(player, world, get_mirror_clip_spots(world, player))
# Mirror offset spots.
for data in get_mirror_offset_spots(world, player):
create_no_logic_connections(player, world, [data[0:3]])
def overworld_glitches_rules(world, player):
# Boots-accessible locations.
set_owg_rules(player, world, get_boots_clip_exits_lw(world, player), lambda state: state.can_boots_clip_lw(player))
set_owg_rules(player, world, get_boots_clip_exits_dw(world, player), lambda state: state.can_boots_clip_dw(player))
# Glitched speed drops.
#set_owg_rules(player, world, get_glitched_speed_drops_lw(world, player), lambda state: state.can_get_glitched_speed_lw(player))
#set_owg_rules(player, world, get_glitched_speed_drops_dw(world, player), lambda state: state.can_get_glitched_speed_dw(player))
# Mirror clip spots.
# TODO: Should this also require can_boots_clip
set_owg_rules(player, world, get_mirror_clip_spots(world, player), lambda state: state.has_Mirror(player))
# Mirror offset spots.
for data in get_mirror_offset_spots(world, player):
set_owg_rules(player, world, [data[0:3]], lambda state: state.has_Mirror(player) and state.can_boots_clip_lw(player) and state.can_reach(data[3], None, player))
# Regions that require the boots and some other stuff.
# TODO: Revisit below when we can guarantee water walk
# if world.mode[player] != 'inverted':
# add_alternate_rule(world.get_entrance('Waterfall of Wishing Cave Entry', player), lambda state: state.has_Pearl(player) or state.has_Boots(player))
# else:
# add_alternate_rule(world.get_entrance('Waterfall of Wishing Cave Entry', player), lambda state: state.has_Pearl(player))
# Zora's Ledge via waterwalk setup.
#add_alternate_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has_Boots(player)) #revisit when we can guarantee water walk
# Adding additional item requirements to OWG Clips
if world.is_tile_swapped(0x18, player) != world.is_tile_swapped(0x28, player):
add_additional_rule(world.get_entrance('Kakariko To Dig Game Hook Clip', player), lambda state: state.has('Hookshot', player))
else:
add_additional_rule(world.get_entrance('VoO To Dig Game Hook Clip', player), lambda state: state.has('Hookshot', player))
add_additional_rule(world.get_entrance('Tree Line Water Clip', player), lambda state: state.has('Flippers', player))
add_additional_rule(world.get_entrance('Dark Tree Line Water Clip', player), lambda state: state.has('Flippers', player))
# Bunny pocket
if not world.is_tile_swapped(0x00, player):
add_alternate_rule(world.get_entrance("Skull Woods Final Section", player), lambda state: state.can_bunny_pocket(player) and state.has("Fire Rod", player))
if world.is_tile_swapped(0x05, player):
add_alternate_rule(world.get_entrance("DM Hammer Bridge (West)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
add_alternate_rule(world.get_entrance("DM Hammer Bridge (East)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
if not world.is_tile_swapped(0x18, player):
add_alternate_rule(world.get_entrance("Bush Yard Pegs (Inner)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
add_alternate_rule(world.get_entrance("Bush Yard Pegs (Outer)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
if world.is_tile_swapped(0x22, player):
add_alternate_rule(world.get_entrance("Blacksmith Ledge Peg (West)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
def add_alternate_rule(entrance, rule):
old_rule = entrance.access_rule
entrance.access_rule = lambda state: old_rule(state) or rule(state)
def add_additional_rule(entrance, rule):
old_rule = entrance.access_rule
entrance.access_rule = lambda state: old_rule(state) and rule(state)
def create_no_logic_connections(player, world, connections, connect_external=False):
for entrance, parent_region, target_region, *_ in connections:
parent = world.get_region(parent_region, player)
if isinstance(target_region, Region):
target_region = target_region.name
if connect_external and target_region.endswith(" Portal"):
target = world.get_portal(target_region[:-7], player).find_portal_entrance().parent_region
else:
target = world.get_region(target_region, player)
connection = Entrance(player, entrance, parent)
connection.spot_type = 'OWG'
parent.exits.append(connection)
connection.connect(target)
def set_owg_rules(player, world, connections, default_rule):
for entrance, _, _, *rule_override in connections:
connection = world.get_entrance(entrance, player)
rule = rule_override[0] if len(rule_override) > 0 else default_rule
connection.access_rule = rule
glitch_regions = (['Central Cliffs', 'Eastern Cliff', 'Desert Northern Cliffs'],
['Dark Central Cliffs', 'Darkness Cliff', 'Mire Northern Cliffs'])
# same screen clips, no Tile Flip OWR implications
boots_clips_local = [ # (name, from_region, to_region)
('Hera Ascent Clip', 'West Death Mountain (Bottom)', 'West Death Mountain (Top)'), #cannot guarantee camera correction, but a bomb clip exists
('WDDM Bomb Clip', 'West Dark Death Mountain (Bottom)', 'West Dark Death Mountain (Top)'), #cannot guarantee camera correction, but a bomb clip exists
('Ganons Tower Screen Wrap Clip', 'West Dark Death Mountain (Bottom)', 'GT Stairs'), # This only gets you to the GT entrance
('Spectacle Rock Ledge Clip', 'West Death Mountain (Top)', 'Spectacle Rock Ledge'),
('Floating Island Clip', 'East Death Mountain (Top East)', 'Death Mountain Floating Island'),
('Floating Island Return Clip', 'Death Mountain Floating Island', 'East Death Mountain (Top East)'),
#('DW Floating Island Clip', 'East Dark Death Mountain (Bottom)', 'Death Mountain Floating Island'), #cannot guarantee camera correction
('EDM East Dropdown Clip', 'East Death Mountain (Top East)', 'East Death Mountain (Bottom Left)'),
('EDM Hammer Bypass Teleport', 'East Death Mountain (Top West)', 'East Death Mountain (Top East)'),
('EDDM West Dropdown Clip', 'East Dark Death Mountain (Top)', 'East Dark Death Mountain (Bottom Left)'),
('WDM To EDM Bottom Clip', 'East Death Mountain (Bottom Left)', 'East Death Mountain (Bottom)'),
('WDDM To EDDM Bottom Clip', 'East Dark Death Mountain (Bottom Left)', 'East Dark Death Mountain (Bottom)'),
('TR Bridge Clip', 'East Dark Death Mountain (Top)', 'Dark Death Mountain Ledge'),
('TR Pegs Ledge Clip', 'Death Mountain TR Pegs Area', 'Death Mountain TR Pegs Ledge'),
('TR Pegs Ledge Descent Clip', 'Death Mountain TR Pegs Ledge', 'Death Mountain TR Pegs Area'), # inverted only, but doesn't hurt to exist always
('Turtle Rock Ledge Clip', 'Turtle Rock Area', 'Turtle Rock Ledge'),
('Mountain Pass To Ledge Clip', 'Mountain Pass Area', 'Mountain Pass Ledge'),
('Bumper Cave Ledge Clip', 'Bumper Cave Area', 'Bumper Cave Ledge'),
('Mountain Ledge Drop Clip', 'Mountain Pass Ledge', 'Mountain Pass Entry'),
('Bumper Cave Ledge Drop Clip', 'Bumper Cave Ledge', 'Bumper Cave Entry'),
('Potion Shop Northbound Rock Bypass Clip', 'Potion Shop Area', 'Potion Shop Northeast'),
('Potion Shop Southbound Rock Bypass Clip', 'Potion Shop Northeast', 'Potion Shop Area'),
('Dark Witch Northbound Rock Bypass Clip', 'Dark Witch Area', 'Dark Witch Northeast'),
('Dark Witch Southbound Rock Bypass Clip', 'Dark Witch Northeast', 'Dark Witch Area'),
('Hyrule Castle To Water Clip', 'Hyrule Castle Area', 'Hyrule Castle Water'), #fake flipper
#('Bat Cave River Clip Spot', 'Blacksmith Area', 'Blacksmith Ledge'), #TODO: This should be added in MG (screenwrap transition)
('Maze Race Item Get Ledge Clip', 'Maze Race Area', 'Maze Race Prize'),
#('Hobo Water Clip', 'Stone Bridge South Area', 'Stone Bridge Water'), # TODO: Doesn't work with OW Free Terrain
('Tree Line Water Clip', 'Tree Line Area', 'Tree Line Water'), #requires flippers
('Dark Tree Line Water Clip', 'Dark Tree Line Area', 'Dark Tree Line Water'), #requires flippers
('Desert To Teleporter Clip', 'Desert Area', 'Desert Teleporter Ledge'),
('Mire To Teleporter Clip', 'Mire Area', 'Mire Teleporter Ledge'),
('Desert To Bombos Tablet Clip', 'Desert Area', 'Bombos Tablet Ledge'),
('Lake Hylia To Shore Clip', 'Lake Hylia Northwest Bank', 'Lake Hylia South Shore'),
('Ice Lake To Shore Clip', 'Ice Lake Northwest Bank', 'Ice Lake Southwest Ledge')
#('Desert Pass To Zora Clip', 'Desert Pass Area', 'Zoras Domain', ) #revisit when Zora is shuffled
]
# Common structure for cross-screen connections:
# (name, from_region, to_region) <- each three consists of [LW, DW]
# This is so Tile Flip OWR can properly connect both connections, and simultaneously be aware of which one requires pearl
# Note: Some clips have no way to reach the OOB area, and others have no way to get from the OOB area
# to a proper destination, these are marked with 'None'; these connections will not be made
boots_clips = [
(['Lumberjack DMA Clip', 'Dark Lumberjack DMA Clip'], ['Lumberjack Area', 'Dark Lumberjack Area'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)']),
(['Lumberjack DMD Clip', None], ['West Death Mountain (Top)', None], ['Lumberjack Area', 'Dark Lumberjack Area']),
(['DM Glitched Bridge Clip', 'DDM Glitched Bridge Clip'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['East Death Mountain (Top East)', 'East Dark Death Mountain (Top)']),
(['WDM to EDM Top Clip', 'WDDM to EDDM Top Clip'], ['West Death Mountain (Top)', 'West Dark Death Mountain (Top)'], ['East Death Mountain (Top West)', None]),
(['Sanctuary DMD Clip', 'Chapel DMD Clip'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Sanctuary Area', 'Dark Chapel Area']),
(['Graveyard Ledge DMD Clip', 'Dark Graveyard DMD Clip', ], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Graveyard Ledge', 'Dark Graveyard North']),
(['Kings Grave DMD Clip', 'Dark Kings Grave DMD Clip'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Kings Grave Area', None]),
(['EDM to WDM Top Clip', 'EDDM To WDDM Clip'], ['East Death Mountain (Top West)', 'East Dark Death Mountain (Top)'], ['West Death Mountain (Top)', 'West Dark Death Mountain (Top)']),
(['EDM To TR Pegs Clip', 'EDDM To TR Clip'], ['East Death Mountain (Top East)', 'East Dark Death Mountain (Top)'], ['Death Mountain TR Pegs Area', None]),
(['EDM DMD FAWT Clip', 'Dark Witch DMD FAWT Clip'], ['East Death Mountain (Bottom)', 'East Dark Death Mountain (Bottom)'], ['Potion Shop Area', 'Dark Witch Area']),
(['WDM DMD To River Bend Clip', 'WDDM DMD To Qirn Jump Clip'], ['East Death Mountain (Bottom Left)', 'East Dark Death Mountain (Bottom Left)'], ['River Bend Area', 'Qirn Jump Area']),
(['EDM DMD To River Bend Clip', 'EDDM DMD To Qirn Jump Clip'], ['East Death Mountain (Bottom)', 'East Dark Death Mountain (Bottom)'], ['River Bend Area', 'Qirn Jump Area']),
(['TR Pegs To EDM Clip', 'TR To EDDM Clip'], ['Death Mountain TR Pegs Area', 'Turtle Rock Area'], ['East Death Mountain (Top East)', 'East Dark Death Mountain (Top)']),
(['Zora DMD Clip', 'Catfish DMD Clip'], ['Death Mountain TR Pegs Area', 'Turtle Rock Area'], ['Zora Waterfall Area', 'Catfish Area']),
(['Mountain Pass To Pond Clip', 'Bumper Cave To Pond Clip'], ['Mountain Pass Area', 'Bumper Cave Area'], ['Kakariko Pond Area', 'Outcast Pond Area']),
(['Zora Waterfall Ledge Clip', 'Catfish Ledge Clip'], ['Zora Waterfall Area', 'Catfish Area'], ['Zora Approach Area', 'Catfish Approach Area']),
#(['Pond DMA Clip', 'Dark Pond DMA Clip'], ['Kakariko Pond Area', 'Outcast Pond Area'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)']), #cannot guarantee camera correction
(['Pond To Mountain Pass Clip', 'Pond To Bumper Cave Clip'], ['Kakariko Pond Area', 'Outcast Pond Area'], ['Mountain Pass Area', 'Bumper Cave Area']),
(['Pond To Bonk Rocks Clip', 'Pond To Chapel Clip'], ['Kakariko Pond Area', 'Outcast Pond Area'], ['Bonk Rock Ledge', 'Dark Chapel Area']),
(['River Bend To Potion Shop Clip', 'Qirn Jump To Dark Witch Clip'], ['River Bend East Bank', 'Qirn Jump East Bank'], ['Potion Shop Area', 'Dark Witch Area']),
(['River Bend To Wooden Bridge Clip', 'Qirn Jump To Broken Bridge North Clip'], ['River Bend East Bank', 'Qirn Jump East Bank'], ['Wooden Bridge Area', 'Broken Bridge Northeast']),
(['River Bend To Broken Bridge Clip', 'Qirn Jump To Broken Bridge Clip'], ['River Bend East Bank', 'Qirn Jump East Bank'], [None, 'Broken Bridge Area']),
(['Potion Shop To EP Clip', 'Dark Witch To PoD Clip'], ['Potion Shop Area', 'Dark Witch Area'], ['Eastern Palace Area', 'Palace of Darkness Area']),
(['Potion Shop To River Bend Clip', 'Dark Witch To Qirn Jump Clip'], ['Potion Shop Area', 'Dark Witch Area'], ['River Bend East Bank', 'Qirn Jump East Bank']),
(['Potion Shop To Zora Approach Clip', 'Dark Witch To Catfish Approach Clip'], ['Potion Shop Northeast', 'Dark Witch Northeast'], ['Zora Approach Area', 'Catfish Approach Area']),
(['Zora Approach To Potion Shop Clip', 'Catfish Approach To Dark Witch Clip'], ['Zora Approach Area', 'Catfish Approach Area'], ['Potion Shop Area', 'Dark Witch Area']),
(['Zora Approach To PoD Clip', 'Catfish Approach To PoD Clip'], ['Zora Approach Area', 'Catfish Approach Area'], [None, 'Palace of Darkness Area']),
(['Kakariko Bomb Hut Clip', 'VoO To Dig Game Clip'], ['Kakariko Southwest', 'Village of Outcasts'], ['Maze Race Area', 'Dig Game Area']),
(['Kakariko To Dig Game Hook Clip', 'VoO To Dig Game Hook Clip'], ['Kakariko Southwest', 'Village of Outcasts'], [None, 'Dig Game Ledge']), #requires hookshot
(['Forgotten Forest To Blacksmith Clip', None], ['Forgotten Forest Area', None], ['Hyrule Castle Water', 'Pyramid Water']), #fake flipper
(['Wooden Bridge To Dunes Clip', 'Broken Bridge To Dunes Clip'], ['Wooden Bridge Area', 'Broken Bridge West'], ['Sand Dunes Area', 'Dark Dunes Area']),
(['Wooden Bridge To Water Clip', 'Broken Bridge To Water Clip'], ['Wooden Bridge Area', 'Broken Bridge West'], [None, 'Pyramid Water']), #fake flipper
(['Eastern Palace To Zora Approach Clip', None], ['Eastern Palace Area', None], ['Zora Approach Area', 'Catfish Approach Area']),
(['Eastern Palace To Nook Clip', None], ['Eastern Palace Area', None], ['Eastern Nook Area', 'Darkness Nook Area']),
(['Eastern Palace To Cliff Clip', 'PoD To Cliff Clip'], ['Eastern Palace Area', 'Palace of Darkness Area'], ['Eastern Cliff', 'Darkness Cliff']),
(['Sand Dunes To Cliff Clip', 'Dark Dunes To Cliff Clip'], ['Sand Dunes Area', 'Dark Dunes Area'], ['Eastern Cliff', 'Darkness Cliff']),
(['Sand Dunes To Water Clip', 'Dark Dunes To Water Clip'], ['Sand Dunes Area', 'Dark Dunes Area'], [None, 'Pyramid Water']), #fake flipper
(['Maze Race To Desert Ledge Clip', 'Dig Game To Mire Clip'], ['Maze Race Area', 'Dig Game Area'], ['Desert Ledge', 'Mire Area']),
(['Maze Race To Desert Boss Clip', 'Dig Game To Desert Boss Clip'], ['Maze Race Area', 'Dig Game Area'], ['Desert Ledge Keep', None]),
(['Suburb To Cliff Clip', 'Archery Game To Cliff Clip'], ['Kakariko Suburb Area', 'Archery Game Area'], ['Desert Northern Cliffs', 'Mire Northern Cliffs']),
(['Central Bonk Rocks To Cliff Clip', 'Dark Bonk Rocks To Cliff Clip'], ['Central Bonk Rocks Area', 'Dark Bonk Rocks Area'], ['Central Cliffs', 'Dark Central Cliffs']),
(['Links House To Cliff Clip', 'Bomb Shop To Cliff Clip'], ['Links House Area', 'Big Bomb Shop Area'], ['Central Cliffs', 'Dark Central Cliffs']),
(['Stone Bridge To Cliff Clip', 'Hammer Bridge To Cliff Clip'], ['Stone Bridge South Area', 'Hammer Bridge South Area'], ['Central Cliffs', 'Dark Central Cliffs']),
(['Eastern Nook To Eastern Clip', None], ['Eastern Nook Area', None], ['Eastern Palace Area', 'Palace of Darkness Area']),
(['Eastern Nook To Ice Cave FAWT Clip', 'PoD Nook To Shopping Mall FAWT Clip'], ['Eastern Nook Area', 'Darkness Nook Area'], ['Ice Cave Area', 'Shopping Mall Area']),
(['Links To Bridge FAWT Clip', 'Bomb Shop To Hammer Bridge FAWT Clip'], ['Links House Area', 'Big Bomb Shop Area'], ['Stone Bridge North Area', 'Hammer Bridge North Area']), #fake flipper
(['Stone Bridge To Water Clip', 'Hammer Bridge To Water Clip'], ['Stone Bridge North Area', 'Hammer Bridge North Area'], [None, 'Pyramid Water']), #fake flipper
(['Desert To Maze Race Clip', None], ['Desert Ledge', None], ['Maze Race Area', 'Dig Game Area']),
(['Desert To Cliff Clip', 'Mire To Cliff Clip'], ['Desert Area', 'Mire Area'], ['Desert Northern Cliffs', 'Mire Northern Cliffs']),
(['Flute Boy To Cliff Clip', 'Stumpy To Cliff Clip'], ['Flute Boy Approach Area', 'Stumpy Approach Area'], ['Desert Northern Cliffs', 'Mire Northern Cliffs']),
(['Cave 45 To Cliff Clip', None], ['Cave 45 Ledge', None], ['Desert Northern Cliffs', 'Mire Northern Cliffs']),
(['C Whirlpool To Cliff Clip', 'Dark C Whirlpool To Cliff Clip'], ['C Whirlpool Area', 'Dark C Whirlpool Area'], ['Central Cliffs', 'Dark Central Cliffs']),
(['C Whirlpool Outer To Cliff Clip', 'Dark C Whirlpool Outer To Cliff Clip'], ['C Whirlpool Outer Area', 'Dark C Whirlpool Outer Area'], ['Central Cliffs', 'Dark Central Cliffs']),
(['C Whirlpool Portal Bomb Clip', 'Dark C Whirlpool Portal Bomb Clip'], ['C Whirlpool Portal Area', 'Dark C Whirlpool Portal Area'], ['Central Cliffs', 'Dark Central Cliffs']), # bomb TODO: bombbag not considered
(['Statues To Cliff Clip', 'Hype To Cliff Clip'], ['Statues Area', 'Hype Cave Area'], ['Central Cliffs', 'Dark Central Cliffs']),
(['Lake Hylia To Statues Clip', 'Ice Lake To Hype Clip'], ['Lake Hylia Northwest Bank', 'Ice Lake Northwest Bank'], ['Statues Area', 'Hype Cave Area']),
(['Lake Hylia To South Pass Clip', 'Ice Lake To South Pass Clip'], ['Lake Hylia Northwest Bank', 'Ice Lake Northwest Bank'], ['South Pass Area', 'Dark South Pass Area']),
(['Desert Pass To Cliff Clip', 'Swamp Nook To Cliff Clip'], ['Desert Pass Area', 'Swamp Nook Area'], ['Desert Northern Cliffs', 'Mire Northern Cliffs']),
(['Desert Pass Southeast To Cliff Clip', None], ['Desert Pass Southeast', None], ['Desert Northern Cliffs', 'Mire Northern Cliffs']),
(['Dam To Cliff Clip', 'Swamp To Cliff Clip'], ['Dam Area', 'Swamp Area'], ['Desert Northern Cliffs', 'Mire Northern Cliffs']),
(['Dam To Desert Pass Southeast Clip', 'Swamp To Desert Pass Southeast Clip'], ['Dam Area', 'Swamp Area'], ['Desert Pass Southeast', None]),
(['South Pass To Lake Hylia Clip', 'South Pass To Ice Lake Clip'], ['South Pass Area', 'Dark South Pass Area'], ['Lake Hylia Northwest Bank', 'Ice Lake Northwest Bank']),
(['South Pass To Shore Clip', 'South Pass To Dark Shore Clip'], ['South Pass Area', 'Dark South Pass Area'], ['Lake Hylia South Shore', 'Ice Lake Southwest Ledge']),
#(['Octoballoon To Shore Clip', 'Bomber Corner To Shore Clip'], ['Octoballoon Area', 'Bomber Corner Area'], ['Lake Hylia South Shore', 'Ice Lake Southeast Ledge']), #map wrap hardlock risk
(['HC Water To Blacksmith Clip', 'Pyramid Water To Hammerpegs Clip'], ['Hyrule Castle Water', 'Pyramid Water'], ['Blacksmith Area', 'Hammer Pegs Area']), #TODO: THIS IS NOT A BOOTS CLIP, this is a normal connection that needs to occur somewhere
([None, 'Pyramid Water To Bomb Shop Clip'], [None, 'Pyramid Water'], ['Links House Area', 'Big Bomb Shop Area']) #TODO: THIS IS NOT A BOOTS CLIP, this is a normal connection that needs to occur somewhere
]
mirror_clips_local = [
('Desert East Mirror Clip', 'Mire Area', 'Desert Mouth'),
('EDDM Mirror Clip', 'East Dark Death Mountain (Bottom Left)', 'East Dark Death Mountain (Bottom)'),
('EDDM Mirror Clip', 'East Dark Death Mountain (Top)', 'Dark Death Mountain Ledge')
]
mirror_clips = [
([None, 'Qirn Jump Bunny DMD Clip'], [None, 'East Dark Death Mountain (Bottom Left)'], ['River Bend Area', 'Qirn Jump Area'])
]
mirror_offsets = [
(['DM Offset Mirror', 'DDM Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Courtyard Northeast', 'Pyramid Crack'], ['Pyramid Area', 'Hyrule Castle Courtyard']),
(['DM To HC Ledge Offset Mirror', 'DDM To Pyramid Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Ledge', 'Pyramid Area'], ['Pyramid Area', 'Hyrule Castle Area'])
]
+2533
View File
File diff suppressed because it is too large Load Diff
+471
View File
@@ -0,0 +1,471 @@
# Past Feature Notes
1.5.0
* Enemy Drop: Added "spies" and shadows for hidden enemies when enemy drop shuffled is enabled
* Pottery: Pots will uncolor when the item inside is collected next time the room is loaded
1.4.3
* File Select/End Game screen: Mirror Scroll and Pseudoboots added (Thanks Hiimcody!)
# Patch Notes
Changelog archive
* 1.5.5
* Logic: Fixed an issue where PoD Bridge lead to Arena Main instead of Arena Landing Area. (Potentially unnecessarily requiring bombs or Somaria to progress)
* HUD: Key counters are correct even when door shuffle is off
* 1.5.4
* Documentation: New AI-assisted documentation [Site](https://aerinon.github.io/ALttPDoorRandomizer)
* Generation Error: Fixed Issue with Shop Code and Take Any Caves (thanks Codemann for assistance)
* 1.5.3
* Logic: Key logic fix for part of a dungeon located at Skull 3 (or other similar restricted entrancs). Appropriate key logic was not being applied, causing progression issues. This mostly affect crosskey style seeds.
* Standard: Rupee balancing algorithm can no longer switch out the weapon on uncle for money.
* Dungeon Counters: Some fixes for inconsistent tracking and display of dungeon counters on the keysanity menu.
* Text: Updated main tournament winner (Thanks clearmouse!)
* 1.5.1
* Bugfix: Fixed an issue with keys not counting correctly
* 1.5.0
* Logic: Fixed vanilla key logic for GT basement
* Logic (Playthrough): Fixed an issue where enemy kill rules were not applied during playthrough calculation. (Thanks Catobat for the catch)
* Keysanity/Keydrop Menu for DR:
* Map key information is now controlled by the Dungeon Chest Counts setting. If set to always on, this information will be available right away in the menu and will be on the HUD even when the map is not obtained.
* The key counter on the HUD for the current dungeon now accounts for keys from enemies or pots that are from vanilla key locations.
* The first number on the HUD represents all keys collected either in that dungeon or elsewhere.
* The second number on the HUD is the total keys that can be collected either in that dungeon or elsewhere.
* The key counter on inside the Menu is unchanged. (At the bottom near A button items)
* The first number in the Menu is the current number of keys in your inventory
* The second number is how many keys left to find in chests (not those from pots/enemies unless those item pools are enabled)
* Customizer: free_lamp_cone option added. The logic will account for this, and place the lamp without regard to dark rooms.
* Customizer: force_enemy option added that makes all enemies the specified type if possible. There are known gfx glitches in the overworld.
* Optimization: Improved generation performance (Thanks Catobat!)
* 1.4.11
* Rom fixes (all thanks to Codemann, I believe)
* Pot bug when at sprite limit
* Kodongo AI vanilla in vanilla rooms
* Issue with music silencing across certain room transitions
* Glitched: Some HMG logic fixed. Thanks Muffins! (Sorry it took me forever to get this PR in)
* Glitched: Blind fight VRAM fix. Thanks Mufffins!
* Text: Updated tourney winners. Thanks clearmouse!
* Enemizer: Banned Swamola enemy everywhere as they may be causing crashes
* Enemizer: Enemy bans from Q2 and Q3. Thank you for all the reports.
* 1.4.10
* Logic: Changed the rule surrounding the Bumper Cave Ledge Drop (the murderdactyl) to only require Pearl AND (Cape OR Byrna OR a Sword) in OHKO mode for now. This is a temporary solution until a better way to prevent needing to use a framerule to get past the bird is invented.
* Helmacopter Fix.
* Fixed a bug in shopsanity that caused the generation to fail with certain prices.
* Enemizer: fairies were invalid on the overworld (unless a bonk occurred nearby), so they will no longer be randomized there.
* 1.4.9
* Attempted fix for Moth conveyor room timing. Thanks for many people's input. Unsure if Helmacopter is still acceptable.
* Mirror scroll will show up on file start screen if enabled (thanks Clearmouse!)
* Fixes for HMG by Muffins
* Various fixes for Enemizer by Codemann (gfx fixes, more randomization options)
* Vanilla door shuffle prevents big key doors changes from door_type_mode
* Couple of minor fixes to custom generation. Deals with a complete specification of all dungeons
* Various enemizer bans for blocked paths (thanks to all the reports, Q1 2025)
* 1.4.8.1
- Fixed broken doors generation
- Fixed bomb/arrow upgrade ignoring custom pricing
- Extended `money_balance` to apply to price balancing for non-custom shops.
* 1.4.8
- New option: Mirror Scroll - to add the item to the starting inventory in non-doors modes (Thanks Telethar!)
- Customizer: Ability to customize shop prices and control money balancing. `money_balance` is a percentage betwen 0 and 100 that attempts to ensure you have that much percentage of money available for purchases. (100 is default, 0 essentially ignores money considerations)
- Fixed a key logic bug with decoupled doors when a big key door leads to a small key door (the small key door was missing appropriate logic)
- Fixed an ER bug where Bonk Fairy could be used for a mandatory connector in standard mode (boots could allow escape to be skipped)
- Fixed an issue with flute activation in rain mode. (thanks Codemann!)
- Fixed an issue with enemies in TR Dark Ride room not requiring Somaria. (Refactored the room for decoupled logic better)
- More HMG fixes by Muffins
- Fixed an issue with multi-player HMG
- Fixed an issue limiting number of items specified in the item pool on the GUI
- Minor documentation fixes (thanks Codemann!)
* 1.4.7.2
- Fixed an issue with shuffle_ganon/fix_gtower_exit causing a generation failure
- More HMG fixes by Muffins
* 1.4.7.1
- Fixed an issue with the repaired "beemizer" setting not being backwards compatible
* 1.4.7
- Fixed generation error with Big Key in starting inventory (thanks Cody!)
- HMG/NL logic fixes by Muffins
- Enemizer: Disabled Walking Zora in the UW due to crash with Swamola (they ignore a lot of collison anyway)
- Enemizer: Fixed an issue with enemizer bush sprites
- Enemizer: Banned new Mimics from being the randomized bush sprite due to crash
- "Beatable" or "accessibility: none" can now use randomized trap doors to seal off entire parts of dungeons (was intended, bug prevented the logic skip)
- Logic error with enemizer and standard should use new enemy logic rules
- Fixed a bug with the inconsistent treatment of the beemizer setting
- Fixed an issue with returning Blacksmith in Simple shuffle (when blacksmith is at Link's House)
- Fixed an issue with dark sanctuary spawn at tavern north door (thanks Codemann!)
- Various enemy bans for the last few months
* 1.4.6
- Restores original Sanc & Quit behavior, if Aga1 is not dead, then no quick pyramid warp
- Fixed problem with Lite/Lean shuffling some fairy caves unnecessarily
- The 300 Rupees item is now marked as priority, so it will not be used as GT junk fill (this matches a change in the VT randomizer)
- Murahdahla is now logically accessible in inverted mode as a bunny. May affect some beatable-only TFH seeds by allowing Moon Pearl to be inaccessible.
- Fixed an issue around PreferredLocationGroups in customizer which would not work with pre-activated Ocraina or priority items.
- Minor fix on triforce text
- Enemy bans for poor placements
* 1.4.5
- Logic: Added appropriate enemy logic to GT Mimics 1 and 2 rooms
- Logic: Added appropriate enemy logic to Mire 2 room. Note this does change the default logical strats, due to how enemy kill logic works.
- Ice Rod + 1 Bomb is now out of logic
- Fire Rod + 1 Bomb is now out of logic
- Fire Rod + 1 magic extension is still in logic
- Byrna + 1 magic extension is newly in logic
(One magic extension is either half magic or a bottle with the ability to purchase a blue or green potion) In general, making up for a lack of magic extension with a few bombs is something that could be added to the logic. Using the ice rod to freeze an enemy and then using that enemy to deal blunt damage and then using bombs to clear the frozen enemy is another strategy that could be added to the logic someday. If these are important to you, let me know.
- Generation: Fixed an issue with dungeonsfull shuffle
* 1.4.4
- Fixed a crash near the end of the credits when total collection rate was over 1000
* 1.4.3
* Key Logic Algorithm: Renamed "Default" to "Dangerous" to indicate the potential soft-lock issues
* Hera Basement Cage: Fix for small key counting multiple times (again)
* Generation: Fixed several generation problems with ER and intensity 3
* Customizer: Generation bug when attempting to place small keys
* Hints: Updated pedestal/tablet text to be more clear
* Enemizer: Various enemy bans
* 1.4.2
* New ER Options:
* [Skull Woods shuffle options](#skull-woods-shuffle)
* [New option](#linked-drops-override) to override linked drop down behavior
* Customizer: You can now start with a "RandomWeapon" in the start inventory section
* Customizer: You may now start with "Big Magic" or "Small Magic" items
* Customizer: Suppress warning for missing items if they are in start inventory
* MultiClient: change default port to 23074 for newer SNI versions
* Generation: Fixed typo causing ER gen failure with Bomb Shop at Graveyard Ledge
* 1.4.1.12u
* New Entrance Shuffle Algorithm no longer experimental
* Back of Tavern Shuffle now on by default
* Enemizer: Wallmasters banned from tiles where spiral staircases are. (Softlock issue)
* Packaged build of unstable now available
* Customizer: New PreferredLocationGroup for putting a set of items in a set of locations. See customizer docs.
* Customizer: Fixed an issue with starting with `Ocarina` and flute_mode is active
* Spoiler: Some reformatting. Crystal req. for GT/Ganon moved to requirements section so randomized requirements don't show up in the meta section
* Algorithm: Major_Only. Supports up to 16 extra locations (the visible heart pieces) for when major item count exceeds major location count. Examples: Triforce Hunt, Trinity (Triforce on Ped), Bombbag shuffle
* Fix: HC Big Key drop doesn't count on Basic Doors
* Fix: Small Key for this dungeon in Hera Basement doesn't count twice for the key counter
* Fix: All cross-dungeon modes with restrict boss items should require map/compass for the boss
* Fixed a small bug with traversal algorithm
* Enemizer: Enemy bans+
* 1.4.1.11u
* New Feature: Several spoiler levels added: None, Settings-only, Semi, Full, Debug
* Semi includes only entrances, prizes, and medallions (potential new spoiler mode being worked on, definition may change)
* Entrance: Lite/Lean support enemy drop shuffle
* Standard: Re-added tutorial guard near large rock
* Enemizer
* Fixed the overwriting of bonk fairies
* Fixed broken graphics on hyrule castle
* Enemy bans
* Customizer: Fixed bug with customizing prize packs
* 1.4.1.10u
* Vanilla key logic: Fix for vanilla layout Misery Mire which allows more complex key logic. Locations blocked by crystal switch access are only locked by 2 keys thanks to that being the minimum in Mire to reach one of two crystal switches.
* Autotracking: Fix for chest turn counter with chest containing multiworld items (Thanks Hiimcody)
* Enemizer: Enemy bans
* Rom: Code prettification and fixing byte designations by Codemann
* Support added for BPS patches via jsonout setting (Thanks Veetorp!)
* 1.4.1.9u
* Enemy Drop Underworld: Changed enemy drop indicator to not require compass
* Experimental: Moved dark world bunny spawns out of experimental. (It is now always on)
* Fix: Red/Blue pendants were swapped for autotracking. (Thanks Muffins!)
* Fix: Red square sometimes wasn't blinking
* Updated tournament winners
* Enemizer: Enemy bans
* 1.4.1.8u
* HUD: New dungeon indicators based on common abbreviations
* OWG+HMG: EG is allowed to be armed
* Drop Shuffle: Fixed an issue with minor drops counting for the wrong dungeon
* Enemizer: Trinexx ice breath should be properly disabled if Trinexx is located outside of Turtle Rock
* Enemizer: Enemy bans
* 1.4.1.7u
* Some bugs around Triforce Pieces smoothed out
* Enemizer: No exception for mimics/eyegores in vanilla rooms if enemy logic is turned to off
* Enemizer: Various enemy bans
* 1.4.1.6u
* Difficulty: Fixed some issues around item caps not being respected
* Enemezier: Tutorial guards remove from South Kakariko
* Map: Pendant colors fixed
* Minor rom code cleanup
* Enemizer: Hovers added to problematic pool near pits. Some other bans
* 1.4.1.5u
* Major Fix: Problem with Ganon's Room sprites
* HMG: Remove extra Swamp Smalls in the pool due to pottery settings
* Enemizer: Couple enemy bans
* 1.4.1.4u
* Logic: Fixed logic bugs surrounding dynammic doors missing logic from big keys and other door types
* Inverted: Castle warp should not appear after defeating Aga 1
* Enemzier: Fixed a crash with cached sprites Zora/Swamola
* 1.4.1.3v
* Enemizer: Raven/Murderdactyls using the correct damage table
* Enemzier: Boss drops only center when boss shuffle is on
* 1.4.1.2v
* Expert/Hard Item Pool: Capacity fairy no longer gives out free crystal
* Vanilla door + Universal Keys: Generation fixed
* Boss Shuffle: Generation fixed (thanks Codemann for easy solution)
* Vanilla ER: No need for ability to check prizes on keysanity menu
* Swapped ER: Possible generation issue fixed (thanks Codemann)
* Enemizer: Roller ban
* Performance: Faster text boxes. Thanks Kan!
* 1.4.1.1v
* Logic: Moon pearl logic respects blocked doors
* 1.4.1.0v
* World Model Refactor: The overworld has been split up by screen, brings OR and DR a bit closer together in the model sense. A few OWG clips have been rewritten to fit into this new logic better.
* Logic: New logic for some bosses on ice
* Helmasaur on Ice: Bombs for mask, sword or arrows for 2nd phase
* Blind on Ice: Beam sword, Somaria, or Byrna plus magic extension for damage. Red shield or Byrna for protection.
* Kholdstare on Ice: Three options (after cracking the shell)
* Beam sword
* Fire Rod with 1.5 magic extensions
* Fire Rod & Bombos & any Sword & 1 Magic Extension
* Vitreous on Ice: Arrows and Bombs or a Beam Sword
* Trinexx on Ice: Boots always required for dodging. Damage options:
* Gold sword
* Tempered sword with magic extension
* Hammer or Master sword with 3 magic extensions (Rod spam for elemental heads, non-ideal weapon for last phase)
* Trinexx on Ice forbidden in doors seeds until we can model some health requirements. Low health Trinexx still isn't realistically feasible (bascially playing OHKO)
* Logic: Added silver arrows as Arrghus damage option when item functionality is not set to hard or expert
* Logic: Byrna not in logic for laser bridge when item functionality is set to hard or expert
* Enemizer Damage Rework:
* Shuffled: Actually shuffles the damage groups in the table instead of picking random numbers and reducing for mails from there. Enemies will still be assigned to a damage group randomly.
* There will always be at least one group which does no damage. The thief will always be in that group. Ganon always has his own group.
* Glitched modes: Aga 1 should be vulnerable in rain state for glitched modes
* Generation: Trinexx and Lanmolas room allowed as lobbies in intensity 3 (works with enemizer now)
* Enemy AI: Terrorpin AI code removed. May help with unusual enemy behavior?
* 1.4.0.1v
* Key logic: Vanilla key logic fixes. Statically set some HC logic and PoD front door
* Generation: Fix a broken tile pattern
* Inverted: Castle warp should not appear after defeating Aga 1
* Murahdahla: Should not disappear after Aga 1. May fix other subtle issues.
* Shopsanity: Buying multiple of an item in the potion shop should no longer increase item count.
* 1.4.0.0v
* Initial support for HMG (Thanks Muffins!)
* Generation: fix for bunny walk logic taking up too much memory
* Key Logic: Partial is now the new default
* Enemizer: enemy bans
* 1.3.0.9v
* ER: New Swapped ER mode borrowed from OWR
* ER: fixed a generation error where TR chooses all "must-exits"
* Ganonhunt: playthrough no longer collects crystals
* Vanilla Fill: Uncle weapon is always a sword, medallions for Mire/TR will be vanilla
* Customizer: support shufflebosses/shuffleenemies as well as boss_shuffle/enemy_shuffle
* Enemizer: enemy bans
* 1.3.0.8v
* Enemizer: Red Mimics correctly banned from challenge rooms in appropriate logic setting
* No Logic Standard ER: Rain doors aren't blocked if no logic is enabled.
* Trinexx: attempt to fix early start
* MW Progression Balancing: Change to be percentage based instead of raw count. (80% threshold)
* Take anys: Good Bee cave chosen as take any should no longer prevent generation
* Money balancing: Fixed generation issue
* Enemizer: various enemy bans
* 1.3.0.7v
* Fix for Mimic Cave enemy drops
* Fix for Spectacle Rock Cave enemy drops (the mini-moldorms)
* Fix for multiworld lamps with incorrect graphics
* No longer shuffles fairy bonks (from trees) as part of Enemizer
* 1.3.0.6v
* Flute can't be activated in rain state (except glitched modes) (Thanks codemann!)
* Enemizer
* Arrghus at Lanmo 2 no longer prevents pot pickups
* Trinexx at Lanmo 2 requires the Cape go backwards to face him
* Lift-able Blocks require a sprite slot (should help reduce problems)
* Fixed logic issues:
* Self-locking key not allowed in Sanctuary in standard (typo fixed)
* More advanced bunny-walking logic in dungeons (multiple paths considered)
* ER: Minor fix for Link's House on DM in Insanity (escape cave should not be re-used)
* MSU: GTBK song fix for DR (Thanks codemann!)
* District Algorithm: Fails if no available location outside chosen districts
* Various enemy bans
* More Gibos near kiki and Old Man
* Bumper/AntiFairy obstacles
* Damaging roller
* Statue + Pots don't mix
* Statues on Skull Big Key Chest tile
* Toppo in challenge rooms
* Misc others
* 1.3.0.5v
* Hud/Map Counter: Collecting a keys for this dungeon of a bonk torch no longer increments the counter twice and immediately updates the hud.
* Enemizer: Hera basement item counting twice fixed by banning wallmasters on the tile.
* Enemizer: Statues banned offscreen for pull switches
* Enemizer: Several sprite producing enemies have been limited on crowded tiles. Offenders: Hinox, Sluggula, Bomb Guard, Beamos, Gibo, Wall Cannons, Probe using Guards. Others do not spam as many projectiles.
* Enemizer: More enemy bans (mostly Wizzrobes near walls where they won't spawn, couple missed firebar spots)
* 1.3.0.4v
* Enemizer: The bunny beam near Lanmo 2 and the 4 fairies near Ice Armos are not shuffled anymore. This is due to how bosses shuffle works and since it cannot be guaranteed to work within the current system, they are vanilla. (Vitreous still overwrites the fairies and Arrghus only lets two spawn, etc.)
* Dropshuffle: Pokey 1 has been fixed to drop his item
* Mystery/Customizer: true/false and on/off in yaml files should behave the same.
* More enemy bans as have been reported
* 1.3.0.3v
* Faeries now part of the enemy shuffle pool. Take note, this will increase enemy drop locations to include fairy pools both in dungeons and in caves.
* Enemy drop indicator (blue square) now works in caves based on entrance used
* Fixes:
* Collection rate counter is properly hidden in mystery seeds
* Sprite limit lowered where possible to allow for lifting of pots
* Hovers in Swamp Waterway properly do not drop items anymore
* Lots more bans (thanks to jsd in particular but also thanks to all the reports)
* Minor issue with customizer/mystery files not allowing "true" for booleans
* 1.3.0.2v
* Fix for multiworld received keys not counting correctly
* Fix for multiworld lamps incorrect graphics
* Fix for collection rate decreasing on item "pickup"
* Fix for pendants as prizes counting as items
* Fix for castle barrier gfx in rain state
* Enemizer fixes and bans:
* Fixed a generation issue where ChainChomp placement would cause a failure. (Invincible enemies banned in Sprial Cave for early game traversal for now)
* Skull Pot Prison should not be blocked by "impassable" enemies
* Bumpers banned in Ice Hookshot room
* Fixed issue in GT Spike Crystal room
* Fixed blockage issues in TT Ambush and Compass rooms
* Forbid Bumper in Fairy Ascension cave; needed to clip into wall weirdly to pass.
* Enemy Drop bans
* Forbid Stals in many places where they cannot be woken up. Behind rails and on top of blocks, for example.
* A couple minor wizzrobes bans because of despawns.
* Enemies over pits and on conveyors near pits have been issued standard bans for falling enemies. Mimics join the ranks here as they don't work well on pits or on conveyors.
* Mimics banned where conveyors touch walls and could clip out unintentionally
* 1.3.0.1v
* Fixed bugs with item duping and disappearing drops
* Fixed multiworld crash
* Fixed assured sword missing when using start inventory (via GUI/CLI)
* Forbid extra statues in Swamp Push Statue room
* Forbid bumpers on OW water
* Forbid Stal on pits
* Text fix on sprite author (thanks Synack)
* 1.2.0.23u
* Generation: fix for bunny walk logic taking up too much memory
* Key Logic: Partial is now the new default
* 1.2.0.22u
* Flute can't be activated in rain state (except glitched modes) (Thanks codemann!)
* ER: Minor fix for Link's House on DM in Insanity (escape cave should not be re-used)
* Logic issues:
* Self-locking key not allowed in Sanctuary in standard (typo fixed)
* More advanced bunny-walking logic in dungeons (multiple paths considred)
* MSU: GTBK song fix for DR (Thanks codemann!)
* 1.2.0.21u
* Fix that should force items needed for leaving Zelda's cell to before the throne room, so S&Q isn't mandatory
* Small fix for Tavern Shuffle (thanks Catobat)
* Several small generation fixes
* 1.2.0.20u
* New generation feature that allows Spiral Stair to link to themselves (thank Catobat)
* Added logic for trap doors that could be opened using existing room triggers
* Fixed a problem with inverted generation and the experimental flag
* Added a notes field for user added notes either via CLI or Customizer (thanks Hiimcody and Codemann)
* Fixed a typo for a specific pot hint
* Fix for Hera Boss music (thanks Codemann)
* 1.1.6 (from Stable)
* Minor issue with dungeon counter hud interfering with timer
* 1.2.0.19u
* Added min/max for triforce pool, goal, and difference for CLI and Customizer. (Thanks Catobat)
* Fixed a bug with dungeon generation
* Multiworld: Fixed /missing command to not list all the pots
* Changed the "Ganonhunt" goal to use open pyramid on the Auto setting
* Customizer: Fixed the example yaml for shopsanity
* 1.2.0.18u
* Fixed an issue with pyramid hole being in logic when it is not opened.
* Crystal cutscene at GT use new symmetrical layouts (thanks Codemann)
* Fix for Hera Boss music (thanks Codemann)
* Fixed an issue where certain vanilla door types would not allow other types to be placed.
* Customizer: fixed an issue where last ditch placements would move customized items. Those are now locked and the generation will fail instead if no alternatives are found.
* Customizer: fixed an issue with assured sword and start_inventory
* Customizer: warns when trying to specifically place an item that's not in the item pool
* Fixed "accessibility: none" displaying a spoiling message
* Fixed warning message about custom item pool when it is fine
* 1.2.0.17u
* Fixed logic bug that allowed Pearl to be behind Graveyard Cave or King's Tomb entrances with only Mirror and West Dark World access (cross world shuffles only)
* Removed backup locations for Dungeon Only and Major Only algorithms. If item cannot be placed in the appropriate location, the seed will fail to generate instead
* Fix for Non-ER Inverted Experimental (Aga and GT weren't logically swapped)
* Fix for customizer setting crystals to 0 for either GT/Ganon
* 1.2.0.16u
* Fix for partial key logic on vanilla Mire
* Fix for Kholdstare Shell collision when at Lanmo 2
* Fix for Mire Attic Hint door (direction was swapped)
* Dungeon at Chest Game displays correctly on OW map option
* 1.2.0.15u
* GUI reorganization
* Logic fix for pots in GT conveyor cross
* Auto option for pyramid open (trinity or ER + crystals goal)
* World model refactor (combining inverted and normal world models)
* Partitioned fix for lamp logic and links house
* Fix starting flute logic
* Reduced universal keys in pool slightly for non-vanilla dungeons
* Fake world fix finally
* Some extra restrictions on links house placement for lite/lean
* Collection_rate works in customizer files
* 1.2.0.14u
* Small fix for key logic validation (got rid of a false negative)
* Customized doors in ice cross work properly now
* 1.2.0.13u
* Allow green/blue potion refills to be customized
* OW Map showing dungeon entrance at Snitch Lady (West) fixed (instead of @ HC Courtyard)
* Standing item data is cleared on transition to overworld (enemy drops won't bleed to overworld sprites)
* Escape assist won't give you a free quiver in retro bow mode
* Fixed an issue where a door would be opened magically (due to original pairing)
* MultiServer can now disable forfeits if desired
* 1.2.0.12u
* Fix for mirror portal in inverted
* Yet another fix for blocked door in Standard ER
* 1.2.0.11u
* Fixed an issue with lower layer doors in Standard
* Fix for doors in cave state (will no longer be vanilla)
* Added a logic rule for th murderdactyl near bumper ledge for OHKO purposes
* Enemizer alteration for Hovers and normal enemies in shallow water
* Fix for beemizer including modes with an increased item pool
* Fix for district algorithm
* 1.2.0.10u
* Fixed overrun issues with edge transitions
* Better support for customized start_inventory with dungeon items
* Colorized pots now available with lottery. Default is on.
* Dungeon_only support pottery
* Fix AllowAccidentalGlitches flag in OWG
* Potential fix for mirror portal and entering cave on same frame
* A few other minor issues, generation and graphical
* 1.2.0.9-u
* Disallowed standard exits (due to ER) are now graphically half blocked instead of missing
* Graphical issues with Sanctuary and Swamp Hub lobbies are fixed
* Fixes an issue surrounding door state and decoupled doors leading to blocked doors
* Customizer improvements:
* Better logic around customized lobbies
* Better logic around customized door types
* Fix to key doors that was causing extra key doors
* Generation improvement around crystal switches
* Fix bug in dungeon_only that wasn't using pot key locations (known issue still exists in pottery modes)
* Fixes for multiworld:
* Fixes an issue when keys are found in own dungeon for another player when using the bizhawk plugin.
* Fixes an issue with absorbables for another player also being received by the player picking it up.
* 1.2.0.8-u
* New Features: trap_door_mode and key_logic_algorithm
* Change S&Q in door shuffle + standard during escape to spawn as Uncle
* Fix for vanilla doors + certain ER modes
* Fix for unintentional decoupled door in standard
* Fix a problem with BK doors being one-sided
* Change to how wilds keys are placed in standard, better randomization
* Removed a Triforce text
* Fix for Desert Tiles 1 key door
* 1.2.0.7-u
* Fix for some misery mire key logic
* Minor standard generation fix
* Fix for inactive flute start
* Settingsfile for multiworld generation support
* Fix for duped HC/AT Maps/Compasses
* 1.2.0.6-u
* Fix for light cone in Escape when entering from Dark World post-zelda
* Fix for light cone in Escape when lighting a torch with fire rod
* 1.2.0.5.u
* Logic fix for Sanctuary mirror (it wasn't resetting the crystal state)
* Minor bugfixes for customizer
* 1.2.0.4-u
* Starting inventory fixes if item not present in the item pool.
* Support for Assured sword setting and OWG Boots when using a custom item pool. (Customizer or GUI)
* Logic fix for the skull woods star tile that lets you into the X pot room. Now accounts for small key or big key door there blocking the way from the star tile. A trap door is not allowed there.
* Standard logic improvement that requires a path from Zelda to the start so that you cannot get softlocked by rescuing Zelda. Standard mirror scroll change may need to be reverted if impossible seed are still generated.
* 1.2.0.3-u
* Starting inventory taken into account with default item pool. (Custom pools must do this themselves)
* Fast ROM update
* Fix for restricted boss item counting maps & compasses as vital
* Bug fix for vanilla ER + inverted + experimental
* 1.2.0.2-u
* Fixed a bug with certain trap doors missing
* Added a hint reference for district hints
* 1.2.0.1-u
* Added new ganonhunt and completionist goals
* Fixed the issue when defeating Agahnim and standing in the doorway can cause door state to linger.
* Fix for Inverted Lean/Lite ER
* Fix for vanilla Doors + Standard + ER
* Added a limit per dungeon on small key doors to ensure reasonable generation
* Fixed many small bugs
# Known Issues
* Decoupled doors can lead to situations where you aren't logically supposed to go back through a door without a big key or small key, but you can if you press the correct direction back through the door first. There are some transitions where you may get stuck without a bomb. These problems are planned to be fixed.
* Logic getting to Skull X room may be wrong if a trap door, big key door, or bombable wall is shuffled there. A bomb jump to get to those pot may be required if you don't have boots to bonk across.
+136 -95
View File
@@ -3,27 +3,40 @@ import argparse
import hashlib
import logging
import os
import RaceRandom as random
import time
import sys
import time
import RaceRandom as random
from BaseClasses import World
from Regions import create_regions
from EntranceShuffle import link_entrances, connect_entrance, connect_two_way, connect_exit
from Rom import patch_rom, LocalRom, Sprite, write_string_to_rom
from Rules import set_rules
from Dungeons import create_dungeons
from Items import ItemFactory
from ItemList import difficulties
from Items import ItemFactory
from Main import create_playthrough
from OverworldShuffle import link_overworld
from Regions import create_regions
from Rom import (
LocalRom,
apply_rom_settings,
get_sprite_from_name,
patch_rom,
write_string_to_rom,
)
from Rules import set_rules
from source.overworld.EntranceShuffle2 import (
connect_entrance,
connect_exit,
connect_two_way,
link_entrances_new,
)
__version__ = '0.2-dev'
PlandoVersion = '0.2-dev'
def main(args):
start_time = time.perf_counter()
start_time = time.process_time()
# initialize the world
world = World(1, 'vanilla', 'noglitches', 'standard', 'normal', 'none', 'on', 'ganon', 'freshness', False, False, False, args.quickswap, args.fastmenu, args.disablemusic, False, False, False, None, 'none', False)
world = World(1, 'vanilla', True, 'vanilla', 'vanilla', 'vanilla', 'noglitches', 'standard', 'normal', 'none', 'on', 'ganon', 'freshness', False, False, False, False, False, False, None, False)
world.player_names[1].append("Player 1")
logger = logging.getLogger('')
hasher = hashlib.md5()
@@ -34,14 +47,19 @@ def main(args):
random.seed(world.seed)
logger.info('ALttP Plandomizer Version %s - Seed: %s\n\n', __version__, args.plando)
logger.info('ALttP Plandomizer Version %s - Seed: %s\n\n', PlandoVersion, args.plando)
world.difficulty_requirements = difficulties[world.difficulty]
world.difficulty_requirements[1] = difficulties[world.difficulty[1]]
create_regions(world, 1)
create_dungeons(world, 1)
link_entrances(world, 1)
text_patches = []
prefill_world(world, args.plando, text_patches)
link_overworld(world, 1)
link_entrances_new(world, 1)
logger.info('Calculating Access Rules.')
@@ -49,11 +67,9 @@ def main(args):
logger.info('Fill the world.')
text_patches = []
fill_world(world, args.plando)
fill_world(world, args.plando, text_patches)
if world.get_entrance('Dam', 1).connected_region.name != 'Dam' or world.get_entrance('Swamp Palace', 1).connected_region.name != 'Swamp Palace (Entrance)':
if not (world.get_entrance('Dam', 1).connected_region.name in ['Dam', 'Swamp Portal'] and world.get_entrance('Swamp Palace', 1).connected_region.name in ['Swamp Portal', 'Dam']):
world.swamp_patch_required[1] = True
logger.info('Calculating playthrough.')
@@ -68,13 +84,10 @@ def main(args):
logger.info('Patching ROM.')
if args.sprite is not None:
sprite = Sprite(args.sprite)
else:
sprite = None
rom = LocalRom(args.rom)
patch_rom(world, 1, rom, args.heartbeep, args.heartcolor, sprite)
patch_rom(world, rom, 1, 1, False, str(args.rom_header) if args.rom_header else None)
apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic, args.sprite, args.triforce_gfx, args.ow_palettes, args.uw_palettes)
for textname, texttype, text in text_patches:
if texttype == 'text':
@@ -85,84 +98,23 @@ def main(args):
outfilebase = 'Plando_%s_%s' % (os.path.splitext(os.path.basename(args.plando))[0], world.seed)
rom.write_to_file('%s.sfc' % outfilebase)
if args.create_spoiler:
if args.spoiler != 'none':
world.spoiler.to_file('%s_Spoiler.txt' % outfilebase)
logger.info('Done. Enjoy.')
logger.debug('Total Time: %s', time.perf_counter() - start_time)
logger.debug('Total Time: %s', time.process_time() - start_time)
return world
def fill_world(world, plando, text_patches):
mm_medallion = 'Ether'
tr_medallion = 'Quake'
def fill_world(world, plando):
logger = logging.getLogger('')
with open(plando, 'r') as plandofile:
for line in plandofile.readlines():
line = line.lstrip()
if line.startswith('#'):
continue
if ':' in line:
line = line.lstrip()
if line.startswith('!'):
if line.startswith('!mm_medallion'):
_, medallionstr = line.split(':', 1)
mm_medallion = medallionstr.strip()
elif line.startswith('!tr_medallion'):
_, medallionstr = line.split(':', 1)
tr_medallion = medallionstr.strip()
elif line.startswith('!mode'):
_, modestr = line.split(':', 1)
world.mode = modestr.strip()
elif line.startswith('!logic'):
_, logicstr = line.split(':', 1)
world.logic = logicstr.strip()
elif line.startswith('!goal'):
_, goalstr = line.split(':', 1)
world.goal = goalstr.strip()
elif line.startswith('!light_cone_sewers'):
_, sewerstr = line.split(':', 1)
world.sewer_light_cone = sewerstr.strip().lower() == 'true'
elif line.startswith('!light_cone_lw'):
_, lwconestr = line.split(':', 1)
world.light_world_light_cone = lwconestr.strip().lower() == 'true'
elif line.startswith('!light_cone_dw'):
_, dwconestr = line.split(':', 1)
world.dark_world_light_cone = dwconestr.strip().lower() == 'true'
elif line.startswith('!fix_trock_doors'):
_, trdstr = line.split(':', 1)
world.fix_trock_doors = trdstr.strip().lower() == 'true'
elif line.startswith('!fix_trock_exit'):
_, trfstr = line.split(':', 1)
world.fix_trock_exit = trfstr.strip().lower() == 'true'
elif line.startswith('!fix_gtower_exit'):
_, gtfstr = line.split(':', 1)
world.fix_gtower_exit = gtfstr.strip().lower() == 'true'
elif line.startswith('!fix_pod_exit'):
_, podestr = line.split(':', 1)
world.fix_palaceofdarkness_exit = podestr.strip().lower() == 'true'
elif line.startswith('!fix_skullwoods_exit'):
_, swestr = line.split(':', 1)
world.fix_skullwoods_exit = swestr.strip().lower() == 'true'
elif line.startswith('!check_beatable_only'):
_, chkbtstr = line.split(':', 1)
world.check_beatable_only = chkbtstr.strip().lower() == 'true'
elif line.startswith('!ganon_death_pyramid_respawn'):
_, gnpstr = line.split(':', 1)
world.ganon_at_pyramid = gnpstr.strip().lower() == 'true'
elif line.startswith('!save_quit_boss'):
_, sqbstr = line.split(':', 1)
world.save_and_quite_from_boss = sqbstr.strip().lower() == 'true'
elif line.startswith('!text_'):
textname, text = line.split(':', 1)
text_patches.append([textname.lstrip('!text_').strip(), 'text', text.strip()])
#temporarilly removed. New credits system not ready to handle this.
#elif line.startswith('!credits_'):
# textname, text = line.split(':', 1)
# text_patches.append([textname.lstrip('!credits_').strip(), 'credits', text.strip()])
continue
elif ':' in line:
locationstr, itemstr = line.split(':', 1)
location = world.get_location(locationstr.strip(), 1)
if location is None:
@@ -172,8 +124,9 @@ def fill_world(world, plando, text_patches):
item = ItemFactory(itemstr.strip(), 1)
if item is not None:
world.push_item(location, item)
if item.key:
if item.smallkey or item.bigkey:
location.event = True
#TODO: move entrance stuff to prefill_world to work like OW stuff
elif '<=>' in line:
entrance, exit = line.split('<=>', 1)
connect_two_way(world, entrance.strip(), exit.strip(), 1)
@@ -184,18 +137,104 @@ def fill_world(world, plando, text_patches):
entrance, exit = line.split('<=', 1)
connect_exit(world, exit.strip(), entrance.strip(), 1)
world.required_medallions[1] = (mm_medallion, tr_medallion)
# set up Agahnim Events
world.get_location('Agahnim 1', 1).event = True
world.get_location('Agahnim 1', 1).item = ItemFactory('Beat Agahnim 1', 1)
world.get_location('Agahnim 2', 1).event = True
world.get_location('Agahnim 2', 1).item = ItemFactory('Beat Agahnim 2', 1)
def prefill_world(world, plando, text_patches):
mm_medallion = 'Ether'
tr_medallion = 'Quake'
logger = logging.getLogger('')
with open(plando, 'r') as plandofile:
for line in plandofile.readlines():
line = line.lstrip()
if line.startswith('#'):
continue
elif line.startswith('!'):
if line.startswith('!mm_medallion'):
_, medallionstr = line.split(':', 1)
mm_medallion = medallionstr.strip()
elif line.startswith('!tr_medallion'):
_, medallionstr = line.split(':', 1)
tr_medallion = medallionstr.strip()
elif line.startswith('!mode'):
_, modestr = line.split(':', 1)
world.mode = {1: modestr.strip()}
elif line.startswith('!logic'):
_, logicstr = line.split(':', 1)
world.logic = {1: logicstr.strip()}
elif line.startswith('!goal'):
_, goalstr = line.split(':', 1)
world.goal = {1: goalstr.strip()}
elif line.startswith('!owLayout'):
_, modestr = line.split(':', 1)
world.owLayout = {1: modestr.strip()}
elif line.startswith('!owCrossed'):
_, modestr = line.split(':', 1)
world.owCrossed = {1: modestr.strip()}
elif line.startswith('!owKeepSimilar'):
_, modestr = line.split(':', 1)
modestr = modestr.strip().lower()
world.owKeepSimilar = {1: True if modestr in ('true', 'yes', 'on', 'enabled') else False}
elif line.startswith('!light_cone_sewers'):
_, sewerstr = line.split(':', 1)
world.sewer_light_cone = {1: sewerstr.strip().lower() == 'true'}
elif line.startswith('!fix_trock_doors'):
_, trdstr = line.split(':', 1)
world.fix_trock_doors = {1: trdstr.strip().lower() == 'true'}
elif line.startswith('!fix_trock_exit'):
_, trfstr = line.split(':', 1)
world.fix_trock_exit = {1: trfstr.strip().lower() == 'true'}
elif line.startswith('!fix_gtower_exit'):
_, gtfstr = line.split(':', 1)
world.fix_gtower_exit = {1: gtfstr.strip().lower() == 'true'}
elif line.startswith('!fix_pod_exit'):
_, podestr = line.split(':', 1)
world.fix_palaceofdarkness_exit = {1: podestr.strip().lower() == 'true'}
elif line.startswith('!fix_skullwoods_exit'):
_, swestr = line.split(':', 1)
world.fix_skullwoods_exit = {1: swestr.strip().lower() == 'true'}
elif line.startswith('!check_beatable_only'):
_, chkbtstr = line.split(':', 1)
world.check_beatable_only = chkbtstr.strip().lower() == 'true'
elif line.startswith('!ganon_death_pyramid_respawn'):
_, gnpstr = line.split(':', 1)
world.ganon_at_pyramid = gnpstr.strip().lower() == 'true'
elif line.startswith('!save_quit_boss'):
_, sqbstr = line.split(':', 1)
world.save_and_quite_from_boss = sqbstr.strip().lower() == 'true'
elif line.startswith('!text_'):
textname, text = line.split(':', 1)
text_patches.append([textname.lstrip('!text_').strip(), 'text', text.strip()])
#temporarilly removed. New credits system not ready to handle this.
#elif line.startswith('!credits_'):
# textname, text = line.split(':', 1)
# text_patches.append([textname.lstrip('!credits_').strip(), 'credits', text.strip()])
continue
elif line.startswith('$'):
edge1, edge2 = line.split('=', 1)
if world.custom_overworld is None:
world.custom_overworld = {1: []}
world.custom_overworld[1].append(edge1.strip(), edge2.strip())
#TODO: Do entrances similar to OW
elif '<=>' in line:
entrance, exit = line.split('<=>', 1)
#connect_two_way(world, entrance.strip(), exit.strip(), 1)
elif '=>' in line:
entrance, exit = line.split('=>', 1)
#connect_entrance(world, entrance.strip(), exit.strip(), 1)
elif '<=' in line:
entrance, exit = line.split('<=', 1)
#connect_exit(world, exit.strip(), entrance.strip(), 1)
world.required_medallions[1] = (mm_medallion, tr_medallion)
def start():
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true')
parser.add_argument('--spoiler', default='none', help='Output a Spoiler File')
parser.add_argument('--ignore_unsolvable', help='Do not abort if seed is deemed unsolvable.', action='store_true')
parser.add_argument('--rom', default='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc', help='Path to an ALttP JAP(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.')
@@ -211,6 +250,8 @@ def start():
help='Select the rate at which the heart beep sound is played at low health.')
parser.add_argument('--heartcolor', default='red', const='red', nargs='?', choices=['red', 'blue', 'green', 'yellow'],
help='Select the color of Link\'s heart meter. (default: %(default)s)')
parser.add_argument('--ow_palettes', default='default', choices=['default', 'random', 'blackout'])
parser.add_argument('--uw_palettes', default='default', choices=['default', 'random', 'blackout'])
parser.add_argument('--sprite', help='Path to a sprite sheet to use for Link. Needs to be in binary format and have a length of 0x7000 (28672) bytes.')
parser.add_argument('--plando', help='Filled out template to use for setting up the rom.')
args = parser.parse_args()
@@ -222,8 +263,8 @@ def start():
if not os.path.isfile(args.plando):
input('Could not find Plandomizer distribution at expected path %s. Please run with -h to see help for further information. \nPress Enter to exit.' % args.plando)
sys.exit(1)
if args.sprite is not None and not os.path.isfile(args.rom):
input('Could not find link sprite sheet at given location. \nPress Enter to exit.' % args.sprite)
if args.sprite is not None and not os.path.isfile(args.sprite) and not get_sprite_from_name(args.sprite):
input('Could not find link sprite sheet at given location. \nPress Enter to exit.')
sys.exit(1)
# set up logger
+7
View File
@@ -242,3 +242,10 @@ Ganons Tower - Mini Helmasaur Room - Right: Nothing
Ganons Tower - Pre-Moldorm Chest: Small Key (Ganons Tower)
Ganons Tower - Validation Chest: Nothing
Ganon: Triforce
# set Overworld connections (lines starting with $, separate edges with =)
!owLayout: wild
#!owMixed: true # Mixed OW not supported yet
!owCrossed: none
!owKeepSimilar: true
$Links House NE = Kakariko Village SE
+1082
View File
File diff suppressed because it is too large Load Diff
+353 -383
View File
@@ -1,489 +1,459 @@
# ALttPEntranceRandomizer
# Overworld Randomizer
This is a entrance randomizer for _The Legend of Zelda: A Link to the Past_ for the SNES.
This is a overworld randomizer for _The Legend of Zelda: A Link to the Past_ for the SNES
based on the Door Randomizer found at [Aerinon's Github Project.](https://github.com/Aerinon/ALttPDoorRandomizer)
See https://alttpr.com/ for more details on the normal randomizer.
# Installation
### Trackers & Guides
Clone this repository and then run ```EntranceRandomizer.py``` (requires Python 3).
This is a very new mode of LTTPR so the tools and info is very limited.
- There is an [OW Rando Cheat Sheet](https://zelda.codemann8.com/images/shared/ow-rando-reference-sheet.png) that shows all the transitions that exist and are candidates for shuffle.
- There is OW tracking capability within the following trackers:
- [Community Tracker](https://alttptracker.dunka.net/)
- CodeTracker, an [EmoTracker](https://emotracker.net) package for LTTPR
- There is an [OW OWG Reference Sheet](https://zelda.codemann8.com/images/shared/ow-owg-reference-sheet.png) that shows all the in-logic places where boots/mirror clips and fake flippers are expected from the player.
Alternatively, run ```Gui.py``` for a simple graphical user interface.
### If you want to playtest this, know these things:
- If you fake flipper, beware of transitioning south. You could end up at the top of the waterfall in the southeast of either world. If you mistakenly drop down, it is important to know that altho the game may appear as frozen for a bit of time, the game is simply scrolling Link back to the original point of water entry. Upon "landing", you'll be able to S+Q properly. Falling from the waterfall is avoidable but it is super easy to do as it is super close to the transition.
For releases, a Windows standalone executable is available for users without Python 3.
# Feedback and Bug Reports
All feedback and dev conversation happens in the #ow-rando channel on the [ALTTP Randomizer discord](https://discordapp.com/invite/alttprandomizer).
# Installation from Source
1. Download the source code from the repository directly and put it in a folder of your choosing. Any method of grabbing the source code is fine, but due to some changes on GitHub's site, some of the other alternatives might be better options for some people.
- Use [GitHub Desktop](https://desktop.github.com) to clone this repository to a folder on your computer. Once a repository is established, you can click `Fetch origin` or `Pull` to re-download whenever you want to grab the latest version. This is the best option for a simple one-click solution.
- Download the [source code](https://github.com/codemann8/ALttPDoorRandomizer/archive/refs/heads/OverworldShuffle.zip) from GitHub manually.
2. You must have [Python](https://www.python.org/downloads) installed (version 3.7 - 3.10 supported), and ensure PATH is included during the installation.
- A common issue with users is that there are multiple instances of Python installed on the same computer. This causes the computer to be confused with which Python instance it uses. Ensure that any older Python installations have been removed.
3. This program requires all python dependencies that are necessary to run OW Randomizer. There are multiple ways to install them:
- Try running ```pip install missingdependency``` or ```python -m pip install missingdependency``` on the command line (replace ```missingdependency``` with the specific package that is missing) to install the dependency.
- The simpler method, run (double-click) ```resources/ci/common/local_install.py``` to install all the missing dependencies as well.
4. Once installed, you should be able to run (double-click) ```Gui.py``` and the OWR program will appear, where you can select your desired settings.
See the following link if you have additional trouble: https://github.com/codemann8/ALttPDoorRandomizer/blob/OverworldShuffle/docs/BUILDING.md
# Running the Program
- Run (or double-click) ```Gui.py``` for a simple graphical user interface.
- Alternatively, you can generate thru the CLI, run ```DungeonRandomizer.py```.
# Getting Started
## "I heard about OWR and want to give it a try, what do I do?"
This is a common sentiment among those who are unfamiliar with OWR's offerings. One might be tempted to simply turn on a bunch of the options and give it a go. I cannot express this enough:
**^ DO NOT do this! ^**
OWR definitely has a lot of options, and all of them by themselves are pretty simple to grasp, but combining multiple OWR options together increases the complexity and confusion in exponential fashion. Now, of course, some OWR options like Flute Shuffle can safely be combined at any level and isn't gonna make anything more complicated. But specifically, avoid combining these 3 options, at least when going for your first seed:
- OW Layout Shuffle
- OW Tile Flip (Mixed)
- Crossed OW
## "Any recommendations for a first-timer?"
For a first (and second) seed... *and I say "second" because I feel like both of these recommendations I'm about to make have VERY different vibes, have different levels of challenge, but are both, of their own right, worthy of being tried at least once.* Your first OWR experience can be combined with any mode combination that you are already familiar with and have a lot of experience in playing. If you like Crosskeys and feel very comfortable running that, feel free to turn on all those settings in addition to ONE of these two options:
1. `OW Tile Flip (Mixed)` - Overly, a pretty easy-breezy mode, it doesn't require too much big brain, and is pretty managable even without proper logic tracking, as long as you at least have a standard map tracker. This is actually my favorite way to run OWR today
- DO NOT turn on Layout or Whirlpool Shuffle, leave this on `Vanilla`
- DO NOT turn on Crossed OWR
- `Flute Shuffle` or `Bonk Drops` could be enabled if desired, altho I'd recommend against it, at least for a fresh viewpoint of Mixed OWR
2. `OW Layout Shuffle` - Set to `Parallel`. This is the original spirit and vision of OWR from the time of its own founding. It's definitely much more complicated to run than OW Tile Flip, so keep that in mind.
- `Starting Boots` - Either actual boots or pseudoboots, you will be spending a lot of time navigating the OW, so it's best to do it with the ability to run fast.
- DO NOT turn on OW Tile Flip (Mixed)
- DO NOT turn on Crossed OWR
- Enable `Whirlpool Shuffle` - Recommended to always be enabled with Layout Shuffle
- Enable `Keep Similar Edges Together` - This just helps keep some of your sanity for a first experience
- Enable `Flute Shuffle` - I recommend setting this to `Balanced`, this helps space out the flute spots across the world. Being that the world itself is shuffled, the vanilla flute spots are likely NOT as conveniently located as they normally are.
- `Free Terrain` - Recommend to NOT turn this on for a first run, but definitely on a second run.
- `Bonk Drops` - Recommend to NOT turn this on, especially if you don't have starting boots, but you could enable this in future seeds if you've become more familiar with OWR, as you'll be visiting these screens anyways, you might as well grab the items on the way :)
## "What tracker should I use?"
I personally use 2 trackers together, at least if Layout Shuffle is enabled. Currently, DunkaTracker is the ONLY tracker that is useful for tracking Layout Shuffle, highly recommended. However, I personally don't like the main portion of the tracker and ignore the main window completely. For tracking everything else, I use `CodeTracker`, a tracker pack that is installable within `EmoTracker`, this handles ALL OWR modes EXCEPT Layout Shuffle (and generally Crossed OW, but missing that doesn't make much of a difference). I am unaware of ANY trackers outside of these 2 that handle OWR modes, so my advice would be to familiarize yourself with both trackers and pick and choose the parts you find most useful for yourself.
# Terminology
### OW / OWR
OW is shorthand for Overworld, referring to anywhere that is "outside" in the game: ie. not caves or dungeons, which are considered Underworld.
OWR is shorthand for Overworld Rando/Shuffle, the concept of randomizing certain elements present in the Overworld.
### LW / DW (**IMPORTANT TO READ**)
Light World and Dark World. Some of the references to LW and DW can be a bit ambiguous. Sometimes, if a LW tile is being referenced, it's usually referring to the normal LW tile that you already know of. Other times, I might be referring to a DW tile that has now become part of the LW, due to a certain way that the game can be shuffled. This can be particularly confusing when trying to understand these modes, and what they do, based on the text description of them, but it's important to keep in mind the context of which is being described.
Things get extra confusing when adding Crossed OWR into the mix, due to the fluidity of navigating between LW and DW freely. It's often best to think of Crossed OWR like this: You've been used to a two-part Light and Dark World, but Crossed works more close to a Starting Plane and Other Plane, ie. You can walk around and never be able to reach the "other" plane until you have the items to enter portals, including using mirror. Both of these planes consist of Light and Dark World tiles.
During gameplay and in the OW, there is an L or D in the upper left corner, indicating which *world* you are in. As complicated as all the rules can be, this L or D is the simplest way to digest it all. Whenever it says you are in DW, this means you are subject to being transformed to a bunny, cannot use the flute, and you will be able to use the mirror to gain access to the LW. When in LW, you are transformed to Link (if not already), and you're able to use the flute.
### Tile
This refers to one OW screen, containing one or more transitions (or edges) that lead to another tile. Most tiles have a "other world" version of it, linked by either a portal or mirror; some do not like Zora's Domain or Master Sword Pedestal.
### Edge / Transition
This refers to the sides/edges of the screen, where you walk into them and causes another tile to load, the camera pans over, and Link continues movement that destination tile.
### Parallel (as a concept)
Various things in this readme are referred to as parallel or non-parallel. Parallel refers to elements that exist in similar orientation in the opposite world. For instance, Kakariko Village and Village of Outcasts each have 5 transitions, all in the same geographical area and all leading in the same direction, that makes all those transitions parallel. In another instance, The Purple Chest screen (where you turn it in) has transitions on the West side of the screen, but in the DW, those transitions do not exist, therefore, these West transitions are non-parallel, and the tile itself is not parallel. Determining whether something is parallel or not dictates whether something can be shuffled or not, or whether it requires something else to be grouped with it and shuffled together.
### Tile Groups
These are groups of tiles that must be shuffled (or not shuffled) as a group. For instance, if Standard World State is enabled, Link's House, Hyrule Castle, and Sanctuary must be kept together, to ensure that the opening sequence can commence. There are a number of scenarios that can cause various tiles to be grouped, this is largely determined by the specific combination of OWR settings and is necessary to ensure correct logic.
### Similar Edge
These refer to groups of edges that are near each other. For instance, at Link's House, there are 3 different edges on the West side of the screen, separated by the cliffside terrain. All 3 of these can potentially lead to 3 different places. But conversely, these 3 edges are also considered similar edges and can be made to all lead to the same area.
Similar edges on the larger OW tiles are a bit harder to intuitively determine. For instance, in Kakariko Village, there are 3 North edges, but all 3 are NOT part of the same Similar Edge group. Instead, the 2 on the West End are deemed Similar, while the one to the far East is its own edge. The most definitive way to figure out which edges are actually grouped, look at a world map image with gridlines (one is linked above in `Trackers & Guides` labeled OW Rando Cheat Sheet), if you draw imaginary lines, splitting up large tiles into 2x2 parts (continuing the small tiles' patterns), all edges within these bounds are considered Similar Edges.
Similar edges are used when `Keep Similar Edges Together` is enabled and have meaning when used with `Layout Shuffle` (with and without `Free Terrain`) and `Crossed` settings.
# Overworld Map Changes
The overworld map check screen has been completely overhauled in this OWR fork. In other LTTP forks, there are numbered icons to indicate the crystal number of the crystal and those are shown alongside crystal prizes. OWR has changed this so the numbers instead correspond to dungeon numbers. In the LW, you have the 3 pendant dungeons, these are indicated by a blue 1, 2, and 3. In the DW, you have the 7 crystal dungeon, these are indicated by red numbers (1-7). In addition, there may be some mode combinations where HC, AT, and GT may be visible via icon, indicated by a white H, a white A, and a skull. An example of what you can expect to see on a map check can be found [here](https://zelda.codemann8.com/images/shared/newmapcheck.gif).
# Inverted Changes
The version of Inverted included in OWR varies quite a bit compared to the Door Rando and VT (main rando) forks. This is often referred to as Inverted 2.0, as this is a plan to shift it to a newer/updated concept, intended to either enhance/improve the Inverted experience or to restore some behaviors more closer to vanilla. Some of these changes are likely going to be added to all rando forks/branches and subject to change, but this will be based on user feedback.
- Links House start now spawns inside the Big Bomb Shop, where there is now a bed
- Old Man Cave/Bumper Cave entrances are restored to their original state
- Mountain Cave S+Q now spawns in his usual Cave
- Removed the ladder that leads from West Dark Death Mountain up to the top near the GT entrance
- Flute Spot 1 is moved to the very Top of Dark Death Mountain, next to the GT entrance
- When finding Flute, it comes pre-activated (will hear SFX on collecting)
- Spiral and Mimic Cave are now bridged together
- TR Peg Puzzle is restored but instead reveals a ladder
- Houlihan now exits same place as the Link's House start does
- Ganon Hole Exit now exits out a new door on top of HC
- Ice Palace has been re-sealed to vanilla, portal moved to outer edge of moat (makes IP mirror locked)
- Glitched modes will now use vanilla terrain except where necessary
Note: These changes do impact the logic. If you use `CodeTracker`, these Inverted 2.0 logic rules are automatically detected if using autotracker, indicated by a 2 in the corner of the World State mode icon. This can also be manually applied if you right-click the World State mode icon.
# Settings
## Game Mode
Only settings specifically added by this Overworld Shuffle fork are found here. All door and entrance randomizer settings are supported. See their [readme](https://github.com/Aerinon/ALttPDoorRandomizer/blob/master/README.md)
### Standard
Fixes Hyrule Castle Secret Entrance and Front Door, but may lead to weird rain state issues if you exit through the Hyrule Castle side exits before rescuing Zelda in a full shuffle.
Gives lightcone in Hyrule Castle Sewers even without the Lamp.
### Open
This mode starts with the option to start in your house or the sanctuary, you are free to explore.
Special notes:
- Uncle already in sewers and most likely does not have a sword.
- Sewers do not get a free light cone.
- It may be a while before you find a sword, think of other ways to do damage to enemies. (bombs are a great tool, as well as picking up bushes in over world).
### Swordless
This mode removes all swords from the itempool. Otherwise just like open.
Special notes:
- The Medallions to open Misery Mire and Turtle Rock can be used without a sword if you stand on the symbol.
- The curtains in Skull Woods and Hyrule Castle Tower that normally require a sword to cut have been removed.
- Ganon takes damage from the Hammer.
- The magic barrier to Hyrule Castle Tower can be broken with a Hammer.
- The Hammer can be used to activate the Ether and Bombos tablets.
### Inverted
This mode is similar to Open but requires the Moon Pearl in order to not transform into a bunny in the Light World and the Sanctuary spawn point is moved to the Dark Sanctuary
Special Notes:
- Link's House is shuffled freely. The Dark Sanctuary is shuffled within West Dark World.
- There are a number of overworld changes to account for the inability to mirror from the Light World to the Dark World.
- Legacy shuffles are not implemente for this mode.
## Game Logic
This determines the Item Requirements for each location.
### No Glitches
The game can be completed without knowing how to perform glitches of any kind.
### Minor Glitches
May require Fake Flippers, Bunny Revival.
### No Logic
Items are placed without regard for progression or the seed being possible. Major glitches are likely required.
## Game Goal
### Ganon
Standard game completion requiring you to collect the 7 crystals, defeat Agahnim 2 and then beat Ganon.
### Pedestal
Places the Triforce at the Master Sword Pedestal. Ganon cannot be damaged.
### All Dungeons
Ganon cannot be damaged until all dungeons (including Hyrule Castle Tower and Ganons Tower) are cleared.
### Triforce Hunt
Triforce Pieces are added to the item pool, and some number of them being found will trigger game completion. Ganon cannot be damaged.
By default 30 Triforce Pieces are placed while 20 are needed to beat the game. Both values can be adjusted with the custom item pool feature.
### Crystals
Standard game completion requiring you to collect the 7 crystals and then beat Ganon.
This is only noticeably different if the the Ganon shuffle option is enabled.
## Game Difficulty
### Normal
This is the default setting that has an item pool most similar to the original
The Legend of Zelda: A Link to the Past.
### Hard
This setting reduces the availability of a variety of minor helpful items, most notably
limiting the player to two bottles, a Tempered Sword, and Blue Mail. Several minor game
mechanics are adjusted to increase difficulty, most notably weakening potions and preventing
the player from having fairies in bottles.
### Expert
This setting is a more extreme version of the Hard setting. Potions are further nerfed, the item
pool is less helpful, and the player can find no armor, only a Master Sword, and only a single bottle.
## Timer Setting
### None
Does not invoke a timer.
### Display
Displays a timer on-screen but does not alter the item pool.
This will prevent the dungeon item count feature in Easy and Keysanity from working.
### Timed
Displays a count-up timer on screen that can be reduced with Green Clocks and Blue Clocks or
increased with Red Clocks found in chests that will be added to the itempool.
### Timed-OHKO
Displays a countdown timer on screen that, when it hits zero, will put the player into a one hit
knockout state until more time is added to the clock via some of the Green Clocks that will be added
to the itempool.
### OHKO
The player will be in a one hit knockout state the entire game. This is the same as Timed-OHKO except
without the Clock items and the timer permanently at zero.
### Timed-countdown
Displays a countdown timer on screen that can be increased with Green Clocks and Blue Clocks or
decreased with Red Clocks found in chests that will be added to the itempool. The goal of this mode
is to finish the game without the timer reaching zero, but the game will continue uninterrupted if
the player runs out of time.
## Progressive equipment
Determines if Sword, Shield, and gloves are progressive (upgrading in sequence) or not.
### On (Default)
This setting makes swords, shields, armor, and gloves progressive. The first of any type of equipment found
by the player will be the lowest level item, and each subsequent find of a category will upgrade that type of
equipment.
### Off
This setting makes swords, shields, armor, and gloves non-progressive. All of the items of these types will be
randomly placed in chests, and the player could find them in any order and thus instantly receive high level equipment.
Downgrades are not possible; finding a lower level piece of equipment than what is already in the player's possession
will simply do nothing.
### Random
This setting makes swords, shields, armor, and gloves randomly either progressive or not. Each category is independently
randomized.
## Item Distribution Algorithm
Determines how the items are shuffled.
### Balanced
This is a variation of VT26 that aims to strike a balance between the overworld heavy VT25 and the dungeon heavy VT26 algorithm.
It does this by reshuffling the remaining locations after placing dungeon items.
### VT26
Items and locations are shuffled like in VT25, and dungeon items are now placed using the same algorithm. When Ganon is not
shuffled it includes a slight deliberate bias against having too many desireable items in Ganon's Tower to help counterbalance
the sheer number of chests in that single location.
### VT25
Items and locations are shuffled and placed from the top of the lists. The only thing preventing an item from being placed into a spot
is if is absolutely impossible to be there given the previous made placement choices. Leads to very uniform but guaranteed solvable distributions.
### VT22
The ordinary VT v8.22 algorithm. Fixes issues in placement in VT21 by discarding all previously skipped and unfilled locations
after 2/3 of the progression items were placed to prevent stale late game locations from soaking up the same items all the time.
### VT21
The ordinary VT v8.21 algorithm. Unbiased placement of items into unlocked locations, placing items that unlock new locations first.
May lead to distributions that seem a bit wonky (high likelyhood of ice rod in Turtle Rock, for instance)
### Flood
Pushes out items starting from Link's House and is slightly biased to placing progression items with less restrictions. Use for relatively simple distributions.
### Freshness
Alternative approach to VT22 to improve on VT21 flaws. Locations that are skipped because they are currently unreachable increase in
staleness, decreasing the likelihood of receiving a progress item.
## Entrance Shuffle Algorithm
Determines how locations are shuffled. In all modes other than Insanity and the similar legacy versions, holes shuffle as a pair with the connecting cave and the front
two sections of Skull Woods remain confined to the general Skull Woods area. Link's house is never shuffled as a design decision.
## Overworld Layout Shuffle (--ow_layout)
OW Edge Transitions are shuffled to create new world layouts. A brief visual representation of this can be viewed [here](https://zelda.codemann8.com/images/shared/ow-modes.gif). (This graphic also includes combinations of Crossed and Tile Flip)
### Vanilla
Places entrances in the same locations they were in the original The Legend of Zelda: A Link to the Past.
OW Transitions are not shuffled.
### Simple
### Grid
Shuffles dungeon entrances between each other and keeps all 4-entrance dungeons confined to one location such that dungeons will one to one swap with each other.
Other than on Light World Death Mountain, interiors are shuffled but still connect the same points on the overworld. On Death Mountain, entrances are connected more freely.
OW Screens are shuffled in such a way that they are still arranged on an 8x8 grid for each world like vanilla, and the OW Transitions are based on that arrangement.
### Restricted
### Wild
Uses dungeon shuffling from Simple but freely connects remaining entrances. Caves and dungeons with multiple entrances will be confined to one world.
OW Transitions are shuffled with no respect to geometric coherence.
### Full
## Parallel (--ow_unparallel to disable)
Mixes cave and dungeon entrances freely. Caves and dungeons with multiple entrances will be confined to one world.
With OW Layout Shuffle, this forces both worlds to have a matching layout.
### Crossed
## Free Terrain (--ow_terrain)
Mixes cave and dungeon entrances freely, but now connector caves and dungeons can link Light World and Dark World.
With OW Layout Shuffle, this allows land and water edges to be connected.
### Insanity
## Crossed Options (--ow_crossed)
Decouples entrances and exits from each other and shuffles them freely. Caves that were single entrance in vanilla still can only exit to the same location from which they were entered.
This allows OW connections to be shuffled cross-world. There are 2 main methodologies of Crossed OWR:
### Legacy Variants
- `Grouped` and `Polar` both are guaranteed to result in two separated planes of tiles, similar to that of vanilla. This means you cannot simply walk around and be able to visit all the tiles. To navigate to the other plane, you have the following methods: 1) Normal portals 2) Mirroring on DW tiles 3) Fluting to a tile that was previously unreachable
Similar to the base shuffles, but the distinction between single entrance and multi-entrance caves from older versions of the randomizer is maintained.
Madness_Legacy is the more similar to the modern Insanity. Insanity_Legacy has fake worlds and guaranteed Moon Pearl and Magic Mirror for a very different experience.
- `Unrestricted` is not bound to follow a two-plane framework. This means that it could be possible to travel on foot to every tile without entering a normal portal.
### Dungeon Variants
See each option to get more details on the differences.
The dungeon variants only mix up dungeons and keep the rest of the overworld vanilla.
### None
## Heartbeep Sound Rate
Transitions will remain same-world.
Select frequency of beeps when on low health. Can completely disable them.
### Grouped
## Heart Color
This option shuffles connections cross-world in the same manner as Tile Flip (Mixed), the connections coming in and going out of a Tile Group (see `Terminology` section above) are crossed (ie. meaning it is impossible to take a different path to a tile and end up in the opposite world, unlike `Unrestricted`). This is considered the simplest way to play Crossed OWR.
Select the color of Link's hearts.
### Polar
## Menu Speed
Only effective if Tile Flip (Mixed) is enabled. Polar follows the same principle as Grouped, except that it preserves the original/vanilla connections even when tiles are flipped/mixed. This results in a completely vanilla overworld, except that some tiles will transform Link to a Bunny. Even though these tiles give the appearance of your normal LW tile, due to how Tile Flip works, those LW tiles give DW properties (such as bunnying, ability to mirror, and prevents flute usage). This offers an interesting twist on Mixed where you have a pre-conditioned knowledge of the terrain you will encounter, but not necessarily be able to do what you need to do there, due to bunny state. (see `Tile Flip / Mixed` section for more details)
A setting that lets the player set the rate at which the menu opens and closes.
### Unrestricted
## Create Spoiler Log
Every transition is independently a candidate to be chosen as a cross-world connection. This option abides by the `Keep Similar Edges Together` option and will guarantee same effect on all edges in a Similar Edge group if enabled. If a Similar Edge group is chosen from the pool of candidates, it only counts as one portal, not multiple. Each transition has an equal 50/50 chance of being a crossed connection.
Output a Spoiler File.
Note: If Whirlpool Shuffle is enabled, those connections can be cross-world.
## Do not Create Patched Rom
## Keep Similar Edges Together (--ow_keepsimilar)
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 keeps similar edge transitions together. ie. The 2 west land edges of Potion Shop will be paired to another set of two similar edges, unless Free Terrain is also enabled, in which case these 2 edges together with the west water edge form a group of 3 similar edges. See `Terminology` section above for a more detailed explanation of Similar Edges.
## Enable L/R button quickswapping
Note: This affects OW Layout Shuffle mostly, but also affects `Unrestricted` mode in Crossed OW.
Use to enable quick item swap with L/R buttons. Press L and R together to switch the state of items like the Mushroom/Powder pair.
## Tile Flip / Mixed Overworld (--ow_mixed)
## Keysanity
Tile Flip (often referred to as Mixed OWR) can be thought of as a hybrid of Open and Inverted, where OW tiles are randomly chosen to be flipped to become a part of the opposite world. When this occurs, that tile will use the Inverted version of that tile. For instance, if the Cave 45 tile becomes flipped, that means while walking around in the LW, you will find the screen that's south of Stumpy instead, and Cave 45 will instead be found in the DW; but like Inverted, the Cave 45 tile is modified to not have a ledge, this ensures that it will be possible to access it.
This setting allows dungeon specific items (Small Key, Big Key, Map, Compass) to be distributed anywhere in the world and not just
in their native dungeon. Small Keys dropped by enemies or found in pots are not affected. The chest in southeast Skull Woods that
is traditionally a guaranteed Small Key still is. These items will be distributed according to the v26/balanced algorithm, but
the rest of the itempool will respect the algorithm setting. Music for dungeons is randomized so it cannot be used as a tell
for which dungeons contain pendants and crystals; finding a Map for a dungeon will allow the overworld map to display its prize.
Being that this uses concepts from Inverted, it will be important to review the OWR-exclusive changes that have been made to Inverted (often referred to as Inverted 2.0). See `Inverted Changes` for more details.
## Retro
During gameplay:
- When on the OW, there will be an L or D in the upper left corner, indicating which world you are currently in. Mirroring still works the same, you must be in the DW to mirror to the LW.
- When doing a map check (pressing X while on the OW), the tiles shown will reflect the flipped tiles. This means that dungeon prizes will show the prizes for the dungeons that are now part of that world. Here is an image showing the difference of appearance when tiles are flipped on the [map check](https://zelda.codemann8.com/images/shared/lttp-lw-mapcheck.gif) screen.
This setting turns all Small Keys into universal Small Keys that can be used in any dungeon and are distributed across the world.
The Bow now consumed rupees to shoot; the cost is 10 rupees per Wood Arrow and 50 per Silver Arrow. Shooting Wood Arrows requires
the purchase of an arrow item from shops, and to account for this and the dynamic use of keys, both Wood Arrows and Small Keys will
be added to several shops around the world. Four "take any" caves are added that allow the player to choose between an extra Heart
Container and a Bottle being filled with Blue Potion, and one of the four swords from the item pool is placed into a special cave as
well. The five caves that are removed for these will be randomly selected single entrance caves that did not contain any items or any shops.
In further concert with the Bow changes, all arrows under pots, in chests, and elsewhere in the seed will be replaced with rupees.
Note: Tiles are put into Tile Groups (see `Terminology`) that must be shuffled together when certain settings are enabled. For instance, if ER is disabled, then any tiles that have a connector cave that leads to a different tile, then those tiles must flip together.
## Place Dungeon Items
## Tile Flip vs Crossed Explained
The above OWR options are very difficult to describe. The above descriptions are written in a way that is most correct even when these options are combined with more complicated modes. But, this section aims to simplify the explanation by assuming the user chooses a normal 'Open 7/7 Defeat Ganon' seed but with just one OWR setting enabled.
If not set, Compasses and Maps are removed from the dungeon item pools and replaced by empty 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.
Both of these options are very similar and often confused from each other.
- Tile Flip is a mode where some DW tiles are moved and BECOME part of the LW (and the LW counterparts become part of the DW). What does it mean to "become" part of a world? It means that it will inherit (NOT bring over) the properties of that world it is moving to (such as being able to flute, ability to use the mirror, or being susceptible to bunnying).
- Crossed on the other hand doesn't change the properties of tiles, instead it transports Link *physically?* across worlds upon transitioning. This also means that Link can be transformed into a bunny moving from tile to tile.
tldr: Tile Flip moves the tiles, Crossed moves Link
## Include Ganon's Tower and Pyramid Hole in Shuffle pool
So, let's run an example of 2 tiles, Link's House and the screen to the right of it. Transitioning right from Link's House: In vanilla, you get the Stone Bridge screen and Link stays his normal self and is just normal LW behavior. Now, let's assume Links House screen stays vanilla, but the tile to the right is getting Flipped or Crossed.
- In Tile Flip, you'd get the Hammer Bridge screen and Link would stay as Link and you'd be able to flute away from this screen if you had a flute.
- In Crossed, you'd get the same Hammer Bridge Screen, but this time Link would be transformed into a bunny, just like he'd normally be when on that tile.
- In Polar Crossed (when both Tile Flip and Crossed effects are applied together), you get the normal Stone Bridge screen, but Link is transformed to a bunny (because the Stone Bridge screen has moved to the DW AND Link is also moving across worlds).
If set, Ganon's Tower is included in the dungeon shuffle pool and the Pyramid Hole/Exit pair is included in the Holes shuffle pool. Ganon can not be defeated until the primary goal is fulfilled.
This setting removes any bias against Ganon's Tower that some algorithms may have.
As you can see, things get pretty complicated when mixing modes together. Doing this can definitely create a very unique and interesting experience, but one that is very hard to grasp. And then beyond that there is OW Layout Shuffle, which is where transition destinations are shuffled, so Link will get transported to a different tile entirely, but the same rules apply when you eventually find the Stone/Hammer Bridge screen, you just likely won't find that screen thru a transition on Link's House screen.
## Include Helpful Hints
## Whirlpool Shuffle (--ow_whirlpool)
If set, the 15 telepathic tiles and 5 storytellers scattered about Hyrule will give helpful hints about various items and entrances. An exact breakdown of the hint
distribution is provided as an included text file.
When enabled, the whirlpool connections are shuffled. If Crossed OW is enabled, the whirlpools can also be cross-world as well. When the number of crossed edges are limited thru Customizer, this doesn't count towards the limited number of crossed edge transitions.
## Use Custom Item Pool
## Flute Shuffle (--ow_fluteshuffle)
If set, the item pool normally associated with your difficulty setting is replaced by the item pool specified in the custom tab. This feature is only supported when the randomizer is run
via the GUI; attempting to set this via the command line does nothing.
When enabled, new flute spots are generated and gives the player the option to cancel out of the flute menu by pressing X.
## Seed
Note: Desert Teleporter Ledge is always guaranteed to be chosen. One of the three Mountain tiles are guaranteed if OW Layout Shuffle is set to Vanilla.
Can be used to set a seed number to generate. Using the same seed with same settings on the same version of the entrance randomizer will always yield an identical output.
### Vanilla
## Count
Flute spots remain unchanged.
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).
### Balanced
New flute spots are chosen at random, with restrictions that limit the promixity between other chosen flute spots.
### Random
New flute spots are chosen at random with minimum bias.
## Follower Shuffle (--shuffle_followers)
This shuffles the follower companions throughout the world. Here is a full list of followers in the game:
- Princess Zelda
- Old Man
- Blind Maiden
- Frog/Blacksmith
- Locksmith (Guy who unlocks Purple Chest)
- Kiki the Monkey
- Purple Chest
- Super Bomb
When followers are shuffled, you must still fulfill the original requirements of the follower location. For example, if the Super Bomb Shop now contains the Frog, you must have crystals 5 and 6 and 100 rupees to unlock the Frog. It is also important to note that Purple Chest still needs to be delivered to the usual spot. Also, since it isn't useful normally, many people might not know that the Locksmith (the Purple Chest unlocking guy) can follow you, you must remove his sign to get him to follow.
Most of the limitations of followers in the vanilla game have been lifted for this shuffle to work. For instance, you are able to mirror, flute, die, collect a crystal, and save/quit in most situations and still retain the follower. You are also able to enter caves/dungeons and complete dig game while you have a follower.
In the scenario where you are forced down a narrow path and a follower is in your way and you already have a different follower. Running into that follower will switch the followers rather than overwriting, this gives you the opportunity to proceed with either one of the followers. Note that if you leave the screen, you lose this option to switch and you will need to go back to the original place you found the first follower.
Optionally, thru the customizer, you can add a follower to your starting inventory, and you will be given that follower and it will stay with you until you complete their quest.
## Bonk Drop Shuffle (--bonk_drops)
This adds 42 new item locations to the game. These bonk locations are limited to the ones that drop a static item in the vanilla game.
- Bonk Locations consist of some trees, rocks, and statues
- 33 Trees
- 8 of the tree locations require Agahnim to be defeated to access the item
- 6 Rocks
- 1 of the rocks drops 2 items
- 2 Statues
- 1 of them is the Cold Fairy Statue next to Ice Rod Cave
- Bonk locations can be collected by bonking into them with the Pegasus Boots or using the Quake Medallion
- One of the bonk locations are guaranteed to have a full magic decanter
- Some of the drops can be farmed repeatedly, but only increments the collection rate once
- All of the bonk trees have been given an alternate color (and all non-bonk trees are reverted to normal tree color)
- Some screens are coded to change the "alternate tree color", some of them are strange (just how the vanilla game does it)
- Rocks and statues are unable to be made to have a different color
Here is a map that shows all the [Bonk Locations](https://zelda.codemann8.com/images/shared/bonkdrops.png). FYI, the numbers indicate how many bonk items there. The stars with a green square are all Bonk Locations that are unlocked after you kill Aga 1.
As far as map trackers, Bonk Locations are supported on `CodeTracker` when the Bonk Drops option is enabled.
#### Items Added To Pool:
- 15 Fairies
- 8 Apples
- 6 Bee Traps
- 3 Red Rupees
- 3 Blue Rupees
- 2 Single Bombs
- 2 Small Hearts
- 1 Large Magic Decanter
- 1 8x Bomb Pack
- 1 Good Bee
## Nearby Dungeon Items
This is a new option in addition to the traditional wild vs non-wild (keysanity/non-keysanity) options for all the dungeon item types (maps, compasses, small keys, big keys, prizes). This new option shuffles dungeon items into locations somewhere either within the dungeon that it is assigned to or within the surrounding district of that dungeon.
## Prize Shuffle (--prizeshuffle)
A new option has been added to shuffle the 10 dungeon prizes in ways that they haven't been shuffled before. This means that dungeon prizes can be found in other item locations, such as chests or free-standing item locations. This also means that bosses are able to drop a 2nd item in place of the shuffled prize.
### On Boss
This is the normal prize behavior that has been a part of rando up until now. The dungeon prizes are shuffled amongst themselves in their own pool and aren't considered part of the main collection total.
### In Dungeon
This option shuffles the prize into a location somewhere within the dungeon that it is assigned to.
### Nearby
This option shuffles the prize into a location somewhere either within the dungeon that it is assigned to or within the surrounding district of that dungeon.
### Randomized
This option freely shuffles the prizes throughout the world. While the dungeon prizes can end up anywhere, they still are assigned to a specific dungeon. When you defeat the boss of a certain dungeon, checking the map on the overworld will reveal the location WHERE you can find the prize, an example shown [here](https://zelda.codemann8.com/images/shared/prizemap-all.gif). Finding the map will still reveal WHAT the prize is. If you defeated a boss but haven't collected the map for that dungeon, the prize will be indicated by a red X, example shown [here](https://zelda.codemann8.com/images/shared/prizemap-boss.gif). If you collected a map but haven't defeated the boss yet, the icon indicator on the map will be shown on the top edge (for LW dungeons) or the bottom edge (for DW dungeons), but it will show you WHAT the prize is for that dungeon, an example of that is shown [here](https://zelda.codemann8.com/images/shared/prizemap-map.gif).
- It is important to note that the overworld map check has changed: the numbered icons that are displayed are NO LONGER indicating the crystal number like they have in the past. They are now indicating the dungeon that it belongs to; a blue E/D/T indicates the 3 LW dungeons (EP, DP, and ToH) and a red 1-7 indicate the 7 DW dungeons
## New Goal Options (--goal)
### Trinity
This goal gives you the choice between 3 goals, only one of which the player needs to complete: Fast Ganon (no Aga2), pulling Pedestal, or turn in TF pieces to Murahdahla. By default, you need to find 8 of 10 total TF pieces but this can be changed with a Custom Item Pool. It is recommended to set GT Entry to 7 crystals and Ganon to 4 or 5 crystals or Random crystals, although the player can flexibly change these settings as they see fit.
## New Entrance Shuffle Options (--shuffle)
### Lite
This mode is intended to be a beginner-friendly introduction to playing ER, unlike that of Simple ER. It focuses on reducing Low% world traversal in late-game dungeons while reducing the number of entrances needing to be checked.
This mode groups entrances into types and shuffles them freely within those groups.
- Dungeons and Connectors (Multi-Entrance Caves)
- Item Locations (Single-Entrance Caves with an item, includes Potion Shop and Red Bomb Shop)
- Includes Shops only if Shopsanity is enabled
- Includes caves with pots only if Pottery settings have them shuffled)
- Dropdowns and their associated exits (Skull Woods dropdowns are handled the same as in Crossed)
- Non-item locations (junk locations) all remain vanilla
Lite ER shuffles all connectors same-world, to limit bunny traversal. And to prevent Low% enemy and boss combat, some dungeons are confined to specific worlds.
The following dungeons are guaranteed to be in the Light World:
- Hyrule Castle
- Eastern Palace
- Desert Palace
- Tower of Hera
- Agahnim's Tower
The following are guaranteed to be in the Dark World:
- Ice Palace
- Misery Mire
- Turtle Rock
- Ganon's Tower
Both Lite and Lean ER modes are supported in `CodeTracker`, showing only the entrances that are shuffled.
### Lean
This mode is intended to be a more refined and more competitive format to Crossed ER. It focuses on reducing the number of entrances needing to be checked, while giving the player unique routing options based on the entrance pools defined below, as opposed to mindlessly checking all the remaining entrances. The Dungeons/Connectors can connect cross-world.
This mode groups entrances into types and shuffles them freely within those groups.
- Dungeons and Connectors (Multi-Entrance Caves)
- Item Locations (Single-Entrance Caves with an item, includes Potion Shop and Red Bomb Shop)
- Includes Shops only if Shopsanity is enabled
- Includes caves with pots only if Pottery settings have them shuffled)
- Dropdowns and their associated exits (Skull Woods dropdowns are handled the same as in Crossed)
- Non-item locations (junk locations) all remain vanilla
Both Lite and Lean ER modes are supported in `CodeTracker`, showing only the entrances that are shuffled.
### Swapped
This mostly follows the rules of Crossed ER, but instead of entrances being randomly placed individually, random pairs of two entrances are chosen to swap with each other. This creates a unique experience where checking one entrance gives you information about another entrance, which can influence your future routing.
If there is an odd amount of entrances being shuffled in the pool, the last remaining entrance will be vanilla. All other entrances are guaranteed to be non-vanilla.
Here is a [Swapped ER Reference Sheet](http://zelda.codemann8.com/images/shared/swapped-reference-sheet.png) that shows some of the caves/houses that are less familiar to most people.
### District
This is an entrance shuffle that only shuffles entrances within their respective `Districts` (See Below). Also, dropdowns and the entrance that a dropdown normally exits are NOT kept together; this also means that the Skull Woods entrances are no longer guaranteed to lead to Skull Woods. Also, since there is no district that can span multiple worlds, this is NOT a cross-world entrance mode.
Districts are a concept originally conceived by Aerinon in the Door Randomizer, where parts of the OW are split into areas and given a name. Here is a [District Map](https://zelda.codemann8.com/images/shared/ow-districts-reference-sheet.png) showing how they are split up.
# Command Line Options
```
-h, --help
-h, --help
```
Show the help message and exit.
```
--create_spoiler
--ow_layout <mode>
```
Output a Spoiler File (default: False)
For specifying the overworld layout shuffle you want as above. (default: vanilla)
```
--logic [{noglitches,minorglitches,nologic}]
--ow_unparallel
```
Select the game logic (default: noglitches)
With OW Layout Shuffle, this no longer forces both worlds to have a matching layout.
```
--mode [{standard,open,swordless,inverted}]
--ow_terrain
```
Select the game mode. (default: open)
With OW Layout Shuffle, this allows land and water edges to be connected.
```
--goal [{ganon,pedestal,dungeons,triforcehunt,crystals}]
--ow_crossed <mode>
```
Select the game completion goal. (default: ganon)
For specifying the type of cross-world connections you want on the overworld
```
--difficulty [{normal,hard,expert}]
--ow_keepsimilar
```
Select the game difficulty. Affects available itempool. (default: normal)
This keeps similar edge transitions paired together with other pairs of transitions
```
--item_functionality [{normal,hard,expert}]
--ow_mixed
```
Select limits on item functionality to increase difficulty. (default: normal)
This gives each OW tile a random chance to be flipped to the opposite world
```
--timer [{none,display,timed,timed-ohko,ohko,timed-countdown}]
--ow_fluteshuffle <mode>
```
Select the timer setting. (default: none)
For randomizing the flute spots around the overworld
```
--progressive [{on,off,random}]
--ow_no_fog
```
Select the setting for progressive equipment. (default: on)
With OW Grid Layout Shuffle or Mixed, this disables the fog that prevents you from seeing unvisited screens on the overworld map.
```
--algorithm [{freshness,flood,vt21,vt22,vt25,vt26,balanced}]
--shuffle_followers
```
Select item distribution algorithm. (default: balanced)
This shuffles the follower companion locations, ie. Purple Chest, Old Man, etc.
```
--shuffle [{default,simple,restricted,full,crossed,insanity,restricted_legacy,full_legacy,madness_legacy,insanity_legacy,dungeonsfull,dungeonssimple}]
--bonk_drops
```
Select entrance shuffle algorithm. (default: full)
This extends the item pool to bonk locations and makes them additional item locations
```
--rom ROM
--prizeshuffle <mode>
```
Path to a Japanese 1.0 A Link to the Past Rom. (default: Zelda no Densetsu - Kamigami no Triforce (Japan).sfc)
```
--loglevel [{error,info,warning,debug}]
```
Select level of logging for output. (default: info)
```
--seed SEED
```
Define seed number to generate. (default: None)
```
--count COUNT
```
Set the count option (default: None)
```
--quickswap
```
Use to enable quick item swap with L/R buttons. (default: False)
```
--fastmenu [{normal,instant,double,triple,quadruple,half}]
```
Alters the rate at which the menu opens and closes. (default: normal)
```
--disablemusic
```
Disables game music, resulting in the game sound being just the SFX. (default: False)
```
--keysanity
```
Enable Keysanity (default: False)
```
--retro
```
Enable Retro mode (default: False)
```
--nodungeonitems
```
If set, Compasses and Maps are removed from the dungeon item pools and replaced by empty 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)
```
--heartbeep [{normal,half,quarter,off}]
```
Select frequency of beeps when on low health. (default: normal)
```
--heartcolor [{red,blue,green,yellow,random}]
```
Select the color of Link\'s heart meter. (default: red)
```
--sprite SPRITE
```
Use to select a different sprite sheet to use for Link. Path to a binary file of length 0x7000 containing the sprite data stored at address 0x80000 in the rom. (default: None)
```
--accessibility [{items,locations,none}]
```
Sets the item/location accessibility rules. (default: items)
```
--hints
```
Enables helpful hints from storytellers and telepathic tiles (default: False)
```
--no-shuffleganon
```
Disables the "Include Ganon's Tower and Pyramid Hole in Shuffle pool" option. (default: Enabled)
```
--suppress_rom
```
Enables the "Do not Create Patched Rom" option. (default: False)
```
--gui
```
Open the graphical user interface. Preloads selections with set command line parameters.
This allows prizes (crystals/pendants) to shuffle outside their usual boss location.
+150
View File
@@ -0,0 +1,150 @@
# New Features
FastROM changes have been included now.
## Enemizer Features
Please see this document for extensive details. [Enemizer in DR](https://docs.google.com/document/d/1iwY7Gy50DR3SsdXVaLFIbx4xRBqo9a-e1_jAl5LMCX8/edit?usp=sharing)
Key points:
* Enemizer no longer uses a third party program. It is now built-in.
* New option under Enemy Drops: Underworld. Any underworld enemy can drop items.
* New option under Enemizer tab: Enemy Logic
Please read the entire document above for extensive details about enemizer and enemy drop shuffle systems.
Enemizer main changes:
* Several sprites added to the pool. Most notable is how enemies behave on shallow water. They work now.
* Clearing rooms, spawnable chests, and enemy keys drops can now have enemies with specific logic in the room. This logic is controlled by the new Enemy Logic option
* New system for banning enemies that cause issue is place. If you see an enemy in a place that would cause issue, please report it and it can be banned to never happen again. Initial bans can be found [in the code](source/enemizer/enemy_deny.yaml) for the curious
* Thieves are always unkillable, but banned from the entire underworld. We can selectively ban them from problematic places in the overworld, and if someone wants to figure out where they could be safe in the underworld, I'll allow them there once the major problems have been banned.
* THe old "random" and "legacy" options have been discarded for enemy shuffle. Tile room patterns are currently shuffled with enemies.
Underworld drops:
* A flashing blue square added to help locate enemies that have remaining drops on the supertile. (Dungeons and caves without a compass get this for free.)
* Flying enemies, spawned enemies, and enemies with special death routines will not drop items.
* Pikits do not drop their item if they have eaten a shield.
* Hovers in swamp waterway do no drop items due to a layer issue that's not been solved.
* Enemies that are over pits require boomerang or hookshot to collect the item
* Enemies behind rails require the boomerang (hookshot can sequence break in certain cases)
* Enemies that spawn on walls do not drop items. (Keese normally don't, but in enemizer these can be valid drops otherwise. The document has a visual guide.)
(Older notes below)
One major change with this update is that big key doors and certain trap doors are no longer guaranteed to be vanilla in Dungeon Door Shuffle modes even if you choose not to shuffle those types. A newer algorithm for putting dungeons together has been written and it will remove big key doors and trap doors when necessary to ensure progress can be made.
Please note that retro features are now independently customizable as referenced below. Selecting Retro mode or World State: Retro will change Bow Mode to Retro (Progressive). Take Anys to Random, and Small Keys to Universal.
## Flute Mode
Normal mode for flute means you need to activate it at the village statue after finding it like usual.
Activated flute mode mean you can use it immediately upon finding it. the flute SFX plays to let you know this is the case.
## Bow Mode
Four options here:
* Progressive. Standard progressive bows.
* Silvers separate. One bow in the pool and silvers are a separate item.
* Retro (progressive). Arrows cost rupees. You need to purchase the single arrow item at a shop and there are two progressive bows places.
* Retro + Silvers. Arrows cost rupees. You need to purchase the single arrow item or find the silvers, there is only one bow, and silvers are a separate item (but count for the quiver if found).
## Dungeon Shuffle Features
### Small Keys
There are three options now available:
* In Dungeon: The small key will be in their own dungeon
* Randomized: Small keys can be shuffled outside their own dungeon
* Universal: Retro keys without the other options
### Dungeon Door Shuffle
New mode: Partitioned. Partly between basic and crossed, dungeons are shuffled in 3 pools:
* Light World dungeons, Hyrule Castle and Aga Tower are mixed together
* Palace of Darkness, Swamp Palace, Skull Woods, and Thieves Town are mixed together
* The other dark world dungeons including Ganons Tower are mixed together
### Door Types to Shuffle
Four options here, and all of them only take effect if Dungeon Door Shuffle is not Vanilla:
* Small Key Doors, Bomb Doors, Dash Doors: This is what was normally shuffled previously
* Adds Big Keys Doors: Big key doors are now shuffled in addition to those above, and Big Key doors are enabled to be on in both vertical directions thanks to a graphic that ended up on the cutting room floor. This does change
* Adds Trap Doors: All trap doors that are permanently shut in vanilla are shuffled.
* Increases all Door Types: This is a chaos mode where each door type per dungeon is randomized between 1 less and 4 more.
Note: Boss Trap doors are removed currently and not added into the trap door pool as extra trap doors. This may not be a permanent change
### Decouple Doors
This is similar to insanity mode in ER where door entrances and exits are not paired anymore. Tends to remove more logic from dungeons as many rooms will not be required to traverse to explore. Hope you like transitions.
## Customizer
Please see [Customizer documentation](docs/Customizer.md) on how to create custom seeds.
## New Goals
### Ganonhunt
Collect the requisite triforce pieces, then defeat Ganon. (Aga2 not required). Use `ganonhunt` on CLI
### Completionist
All dungeons not enough for you? You have to obtain every item in the game too. This option turns on the collection rate counter and forces accessibility to be 100% locations. Finish by defeating Ganon.
## Standard Generation Change
Hyrule Castle in standard mode is generated a little differently now. The throne room is guaranteed to be in Hyrule Castle and the Sanctuary is guaranteed to be beyond that. Additionally, the Mirror Scroll will bring you back to Zelda's Cell or the Throne Room depending on what save point you last obtained, this is to make it consistent with where you end up if you die. If you are lucky enough to find the Mirror, it behaves differently and brings you the last entrance used - giving you more options for exploration in Hyrule Castle.
## ER Features
### New Experimental Algorithm
To accommodate future flexibility the ER algorithm was rewritten for easy of use. This allows future modes to be added more easily. This new algorithm is only used when the experimental flag is turned on.
### Lite/Lean ER (Experimental required)
Designed by Codemann, these are available now (only with experimental turned on - they otherwise fail)
#### Lite
- Dungeon and multi-entrance caves can only lead to dungeon and multi-entrance caves
- Dropdowns can only lead to dropdowns, with them staying coupled to their appropriate exits
- Cave entrances that normally lead to items can only lead to caves that have items (this includes Potion Shop and Big Bomb Shop)
- All remaining entrances remain vanilla
- Multi-entrance caves are connected same-world only
- LW is guaranteed to have HC/EP/DP/ToH/AT and DW: IP/MM/TR/GT
- Shop locations are included in the Item Cave pool if Shopsanity is enabled
- Houses with pots are included in the Item Cave pool if Pottery is enabled
#### Lean
- Same grouping/pooling mechanism as in Lite ER
- Both dungeons and connectors can be cross-world connections
- No dungeon guarantees like in Lite ER
### Back of Tavern Shuffle (Experimental required)
Thanks goes to Catobat which now allows the back of tavern to be shuffled anywhere and any valid cave can be at the back of tavern with this option checked. Available in experimental only for now as it requires the new algorithm to be shuffled properly.
#### Take Any Caves
These are now independent of retro mode and have three options: None, Random, and Fixed. None disables the caves. Random works as take-any caves did before. Fixed means that the take any caves replace specific fairy caves in the pool and will be at those entrances unless ER is turned on (then they can be shuffled wherever). The fixed entrances are:
* Desert Healer Fairy
* Swamp Healer Fairy (aka Light Hype Cave)
* Dark Death Mountain Healer Fairy
* Dark Lake Hylia Ledge Healer Fairy (aka Shopping Mall Bomb)
* Bonk Fairy (Dark)
# Patch Notes
* 1.5.6
* Enemy Drops: Pikit are no longer eligible for dropped items due to a vanilla bug where a failed steal can overwrite the assigned drop.
* Standard Mode: Reworked spawn refills to be more generous for enemy drop modes.
* Customizer: Added `item_pool_adjust` section to apply additive/subtractive deltas to the base item pool rather than replacing it entirely.
* Multiworld: Fixed a generation crash when beemizer is active and pottery is enabled. Pot locations are now properly filled with same-player items when the MW limit is hit even when beemizer has replaced native pot items.
+1
View File
@@ -22,6 +22,7 @@ def _wrap(name):
# These are for intellisense purposes only, and will be overwritten below
choice = _prng_inst.choice
choices = _prng_inst.choices
gauss = _prng_inst.gauss
getrandbits = _prng_inst.getrandbits
randint = _prng_inst.randint
+1689 -562
View File
File diff suppressed because it is too large Load Diff
+2585 -963
View File
File diff suppressed because it is too large Load Diff
+528
View File
@@ -0,0 +1,528 @@
from enum import Enum, unique
from Tables import door_pair_offset_table
def create_rooms(world, player):
world.rooms += [
Room(player, 0x01, 0x51168).door(Position.WestN2, DoorKind.Warp).door(Position.EastN2, DoorKind.Warp),
Room(player, 0x02, 0x50b97).door(Position.South2, DoorKind.TrapTriggerableLow).door(Position.InteriorV2, DoorKind.NormalLow2).door(Position.South2, DoorKind.ToggleFlag),
# Room(player, 0x03, 0x509cf).door(Position.SouthW, DoorKind.CaveEntrance),
Room(player, 0x04, 0xfe25c).door(Position.NorthW, DoorKind.StairKey2).door(Position.InteriorW, DoorKind.Dashable).door(Position.InteriorS, DoorKind.Dashable).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.Normal),
Room(player, 0x06, 0xfa192).door(Position.SouthW, DoorKind.Trap),
Room(player, 0x07, None),
# Room(player, 0x08, 0x5064f).door(Position.InteriorS2, DoorKind.CaveEntranceLow08).door(Position.SouthE, DoorKind.CaveEntrance).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.SouthW2, DoorKind.ToggleFlag),
Room(player, 0x09, None),
Room(player, 0x0a, 0xfa734).door(Position.North, DoorKind.StairKey),
Room(player, 0x0b, 0xfabf0).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.Trap2).door(Position.InteriorN, DoorKind.SmallKey),
Room(player, 0x0c, 0xfef53).door(Position.South, DoorKind.DungeonEntrance),
Room(player, 0x0d, 0xf918b).door(Position.SouthW, DoorKind.Trap),
Room(player, 0x0e, 0xfc279).door(Position.InteriorW, DoorKind.StairKey2).door(Position.InteriorS, DoorKind.Trap).door(Position.SouthE, DoorKind.DungeonEntrance),
# Room(player, 0x10, 0x50596).door(Position.SouthW, DoorKind.DungeonEntrance).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x11, 0x50c52).door(Position.InteriorN, DoorKind.Dashable).door(Position.InteriorS, DoorKind.Dashable).door(Position.SouthE, DoorKind.SmallKey),
Room(player, 0x12, 0x50a9b).door(Position.North2, DoorKind.NormalLow).door(Position.North2, DoorKind.ToggleFlag).door(Position.South2, DoorKind.NormalLow).door(Position.South2, DoorKind.IncognitoEntrance),
Room(player, 0x13, 0xfe29d).door(Position.EastS, DoorKind.SmallKey).door(Position.EastN, DoorKind.Normal),
Room(player, 0x14, 0xfe464).door(Position.SouthE, DoorKind.SmallKey).door(Position.WestS, DoorKind.SmallKey).door(Position.NorthW, DoorKind.Normal).door(Position.WestN, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.EastN, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x15, 0xfe63e).door(Position.WestS, DoorKind.Trap).door(Position.WestN, DoorKind.Normal),
Room(player, 0x16, 0xfa150).door(Position.InteriorV, DoorKind.Bombable).door(Position.InteriorW, DoorKind.SmallKey).door(Position.InteriorE, DoorKind.Normal).door(Position.NorthW, DoorKind.Normal),
Room(player, 0x17, None),
# Room(player, 0x18, 0x506e5).door(Position.NorthW2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.ToggleFlag),
Room(player, 0x19, 0xfacc6).door(Position.East, DoorKind.Bombable).door(Position.EastN, DoorKind.SmallKey),
Room(player, 0x1a, 0xfa670).door(Position.InteriorE, DoorKind.SmallKey).door(Position.WestN, DoorKind.SmallKey).door(Position.West, DoorKind.Bombable).door(Position.SouthW, DoorKind.SmallKey).door(Position.InteriorN, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal),
Room(player, 0x1b, 0xfab31).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.Normal),
Room(player, 0x1c, 0xff784).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.Trap).door(Position.InteriorW, DoorKind.Dashable),
Room(player, 0x1d, 0xfff19).door(Position.NorthW, DoorKind.BigKey),
Room(player, 0x1e, 0xfc35e).door(Position.EastS, DoorKind.Trap).door(Position.InteriorS, DoorKind.Trap).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.SouthE, DoorKind.Normal),
Room(player, 0x1f, 0xfc3af).door(Position.WestS, DoorKind.Trap).door(Position.InteriorS, DoorKind.Trap2),
Room(player, 0x20, 0xf918b).door(Position.SouthW, DoorKind.Trap),
Room(player, 0x21, 0x50d2e).door(Position.NorthE, DoorKind.SmallKey).door(Position.InteriorV, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x22, 0x50dd1).door(Position.South, DoorKind.SmallKey).door(Position.WestS, DoorKind.Normal),
Room(player, 0x23, 0xfed30).door(Position.SouthE, DoorKind.BombableEntrance).door(Position.EastS, DoorKind.Normal),
Room(player, 0x24, 0xfe6ee).door(Position.NorthE, DoorKind.BigKey).door(Position.InteriorN, DoorKind.Trap2).door(Position.InteriorW, DoorKind.Trap2).door(Position.InteriorE, DoorKind.Trap2).door(Position.SouthE, DoorKind.DungeonEntrance).door(Position.NorthW, DoorKind.Normal).door(Position.WestS, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x26, 0xf9cbb).door(Position.South, DoorKind.SmallKey).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.InteriorN, DoorKind.Normal),
Room(player, 0x27, None),
Room(player, 0x28, 0xf92a8).door(Position.NorthW, DoorKind.StairKey2).door(Position.South, DoorKind.DungeonEntrance),
Room(player, 0x2a, 0xfa594).door(Position.NorthE, DoorKind.Trap).door(Position.NorthW, DoorKind.SmallKey).door(Position.EastS, DoorKind.Bombable).door(Position.East2, DoorKind.NormalLow).door(Position.SouthW, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal),
Room(player, 0x2b, 0xfaaa7).door(Position.InteriorS, DoorKind.Bombable).door(Position.WestS, DoorKind.Bombable).door(Position.NorthW, DoorKind.Trap).door(Position.West2, DoorKind.NormalLow),
# Room(player, 0x2c, 0x508cf).door(Position.InteriorW, DoorKind.Bombable).door(Position.InteriorE, DoorKind.Bombable).door(Position.InteriorS, DoorKind.Bombable).door(Position.SouthE, DoorKind.Bombable).door(Position.SouthW, DoorKind.CaveEntrance),
Room(player, 0x2e, 0xfc3d8).door(Position.NorthE, DoorKind.Normal),
# Room(player, 0x2f, 0x507d1).door(Position.InteriorW, DoorKind.Bombable).door(Position.SouthE, DoorKind.CaveEntrance),
Room(player, 0x30, 0xf8de3).door(Position.NorthW, DoorKind.Hidden).door(Position.InteriorW, DoorKind.Trap2),
Room(player, 0x31, 0xfcf4f).door(Position.InteriorW, DoorKind.BigKey).door(Position.InteriorS, DoorKind.TrapTriggerable),
Room(player, 0x32, 0x50e4b).door(Position.North, DoorKind.SmallKey),
Room(player, 0x33, 0xf8792).door(Position.SouthW, DoorKind.Trap),
Room(player, 0x34, 0xf993c).door(Position.EastN, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x35, 0xf97f1).door(Position.EastN, DoorKind.SmallKey).door(Position.WestN, DoorKind.Normal).door(Position.WestS, DoorKind.Normal).door(Position.InteriorE, DoorKind.Normal)
.door(Position.EastS, DoorKind.Normal).door(Position.InteriorV2, DoorKind.NormalLow),
Room(player, 0x36, 0xf9685).door(Position.EastN, DoorKind.Bombable).door(Position.North, DoorKind.SmallKey).door(Position.WestN, DoorKind.SmallKey).door(Position.WestS, DoorKind.Normal)
.door(Position.EastS, DoorKind.Normal).door(Position.South2, DoorKind.NormalLow),
Room(player, 0x37, 0xf9492).door(Position.WestN, DoorKind.Bombable).door(Position.EastN, DoorKind.Bombable).door(Position.InteriorW, DoorKind.SmallKey).door(Position.EastS, DoorKind.SmallKey).door(Position.WestS, DoorKind.Normal).door(Position.InteriorV2, DoorKind.NormalLow),
Room(player, 0x38, 0xf935b).door(Position.WestN, DoorKind.Bombable).door(Position.WestS, DoorKind.SmallKey),
Room(player, 0x39, 0xfc180).door(Position.SouthW, DoorKind.Trap).door(Position.InteriorS, DoorKind.SmallKey),
Room(player, 0x3a, 0xfa3f5).door(Position.South, DoorKind.SmallKey).door(Position.NorthW, DoorKind.Normal).door(Position.NorthE, DoorKind.Normal),
Room(player, 0x3b, 0xfa9de).door(Position.SouthW, DoorKind.Normal),
# Room(player, 0x3c, 0x509a3).door(Position.NorthE, DoorKind.Bombable).door(Position.SouthE, DoorKind.CaveEntrance),
Room(player, 0x3d, 0xffd37).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.InteriorN, DoorKind.SmallKey).door(Position.SouthW, DoorKind.SmallKey).door(Position.InteriorW, DoorKind.Bombable),
Room(player, 0x3e, 0xfc486).door(Position.InteriorE, DoorKind.Trap).door(Position.SouthW, DoorKind.SmallKey),
Room(player, 0x3f, 0xfc51b).door(Position.InteriorS, DoorKind.Trap),
Room(player, 0x40, 0xf8eea).door(Position.InteriorS2, DoorKind.NormalLow2),
Room(player, 0x41, 0x50f15).door(Position.South, DoorKind.Trap),
Room(player, 0x42, None),
Room(player, 0x43, 0xf87f8).door(Position.NorthW, DoorKind.BigKey).door(Position.InteriorE, DoorKind.SmallKey).door(Position.SouthE, DoorKind.SmallKey),
Room(player, 0x44, 0xfdbcd).door(Position.InteriorN, DoorKind.Trap2).door(Position.InteriorS, DoorKind.SmallKey).door(Position.EastN, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x45, 0xfdcae).door(Position.WestN, DoorKind.Trap).door(Position.InteriorW, DoorKind.Normal).door(Position.WestS, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x46, 0xf9bbb).door(Position.North2, DoorKind.NormalLow).door(Position.InteriorW2, DoorKind.NormalLow).door(Position.InteriorE2, DoorKind.NormalLow),
Room(player, 0x49, 0xfc12c).door(Position.NorthW, DoorKind.Hidden).door(Position.InteriorN, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.SmallKey).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x4a, 0xfa267).door(Position.InteriorW, DoorKind.Trap).door(Position.InteriorE, DoorKind.Trap).door(Position.North, DoorKind.SmallKey).door(Position.InteriorV, DoorKind.Normal).door(Position.South, DoorKind.DungeonEntrance),
Room(player, 0x4b, 0xfa8c9).door(Position.NorthW, DoorKind.Trap).door(Position.InteriorW, DoorKind.Dashable).door(Position.InteriorE, DoorKind.Dashable),
Room(player, 0x4c, 0xffece).door(Position.EastS, DoorKind.Trap),
Room(player, 0x4d, 0xffe5a).door(Position.NorthW, DoorKind.SmallKey).door(Position.WestS, DoorKind.Normal),
Room(player, 0x4e, 0xfc5ba).door(Position.InteriorN, DoorKind.Trap).door(Position.NorthW, DoorKind.SmallKey),
Room(player, 0x4f, 0xfca89).door(Position.WestS, DoorKind.SmallKey),
Room(player, 0x50, 0x510dc).door(Position.EastN2, DoorKind.Warp).door(Position.SouthE2, DoorKind.NormalLow2),
Room(player, 0x51, 0x51029).door(Position.North, DoorKind.Normal).door(Position.North, DoorKind.DungeonChanger),
Room(player, 0x52, 0x51230).door(Position.WestN2, DoorKind.Warp).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.South, DoorKind.Normal),
Room(player, 0x53, 0xf88ad).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.Trap2).door(Position.NorthE, DoorKind.SmallKey),
Room(player, 0x54, None),
# Room(player, 0x55, 0x50166).door(Position.InteriorW2, DoorKind.NormalLow).door(Position.SouthW, DoorKind.Normal).door(Position.SouthW, DoorKind.IncognitoEntrance),
Room(player, 0x56, 0xfbb4e).door(Position.InteriorW, DoorKind.SmallKey).door(Position.SouthW, DoorKind.DungeonEntrance).door(Position.InteriorS, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x57, 0xfbbd2).door(Position.InteriorN, DoorKind.Bombable).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.EastS, DoorKind.SmallKey).door(Position.SouthW, DoorKind.DungeonEntrance).door(Position.WestS, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal),
Room(player, 0x58, 0xfbcf6).door(Position.NorthW, DoorKind.BlastWall).door(Position.WestS, DoorKind.SmallKey).door(Position.SouthE, DoorKind.SmallKey).door(Position.InteriorN, DoorKind.Bombable).door(Position.SouthW, DoorKind.DungeonEntrance).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x59, 0xfbff7).door(Position.NorthW, DoorKind.SmallKey).door(Position.SouthW, DoorKind.DungeonEntrance).door(Position.InteriorN2, DoorKind.NormalLow2).door(Position.InteriorS2, DoorKind.NormalLow2),
Room(player, 0x5a, 0xfa7e5).door(Position.SouthE, DoorKind.Trap),
Room(player, 0x5b, 0xff8cc).door(Position.SouthE, DoorKind.SmallKey).door(Position.EastN, DoorKind.Trap),
Room(player, 0x5c, 0xff976).door(Position.InteriorE, DoorKind.Bombable).door(Position.WestN, DoorKind.Normal),
Room(player, 0x5d, 0xff9e1).door(Position.InteriorW, DoorKind.Trap).door(Position.SouthW, DoorKind.Trap).door(Position.InteriorN, DoorKind.Trap),
Room(player, 0x5e, 0xfc6b8).door(Position.EastS, DoorKind.SmallKey).door(Position.InteriorE, DoorKind.Trap2).door(Position.SouthE, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x5f, 0xfc6fa).door(Position.WestS, DoorKind.SmallKey),
Room(player, 0x60, 0x51309).door(Position.NorthE2, DoorKind.NormalLow2).door(Position.East2, DoorKind.NormalLow2).door(Position.East2, DoorKind.ToggleFlag).door(Position.EastN, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal).door(Position.SouthE, DoorKind.IncognitoEntrance),
Room(player, 0x61, 0x51454).door(Position.West2, DoorKind.NormalLow).door(Position.West2, DoorKind.ToggleFlag).door(Position.East2, DoorKind.NormalLow).door(Position.East2, DoorKind.ToggleFlag).door(Position.South2, DoorKind.NormalLow).door(Position.South2, DoorKind.IncognitoEntrance).door(Position.WestN, DoorKind.Normal),
Room(player, 0x62, 0x51577).door(Position.West2, DoorKind.NormalLow2).door(Position.West2, DoorKind.ToggleFlag).door(Position.NorthW2, DoorKind.NormalLow2).door(Position.North, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthW, DoorKind.IncognitoEntrance),
Room(player, 0x63, 0xf88ed).door(Position.NorthW, DoorKind.StairKey).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.DungeonEntrance), # looked like a huge typo - I had to guess on StairKey
Room(player, 0x64, 0xfda53).door(Position.InteriorS, DoorKind.Trap2),
Room(player, 0x65, 0xfdac5).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x66, 0xfa01b).door(Position.InteriorE2, DoorKind.Waterfall).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.SouthW2, DoorKind.ToggleFlag).door(Position.InteriorW2, DoorKind.NormalLow2),
Room(player, 0x67, 0xfbe17).door(Position.NorthE, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x68, 0xfbf02).door(Position.WestS, DoorKind.Trap).door(Position.NorthE, DoorKind.SmallKey),
Room(player, 0x6a, 0xfa7c7).door(Position.NorthE, DoorKind.BigKey),
Room(player, 0x6b, 0xff821).door(Position.NorthE, DoorKind.BigKey).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.Trap).door(Position.InteriorW, DoorKind.Trap),
Room(player, 0x6c, 0xffaa0).door(Position.InteriorS, DoorKind.Trap2).door(Position.InteriorW, DoorKind.Trap).door(Position.EastS, DoorKind.Normal),
Room(player, 0x6d, 0xffa4e).door(Position.NorthW, DoorKind.Trap).door(Position.InteriorW, DoorKind.Trap).door(Position.WestS, DoorKind.Trap),
Room(player, 0x6e, 0xfc74b).door(Position.NorthE, DoorKind.Trap),
Room(player, 0x70, None),
Room(player, 0x71, 0x52341).door(Position.InteriorW, DoorKind.SmallKey).door(Position.SouthW2, DoorKind.TrapTriggerableLow).door(Position.InteriorS2, DoorKind.TrapTriggerableLow),
Room(player, 0x72, 0x51fda).door(Position.InteriorV, DoorKind.SmallKey),
Room(player, 0x73, 0xf8972).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.Trap2).door(Position.InteriorE, DoorKind.Normal),
Room(player, 0x74, 0xf8a66).door(Position.InteriorE, DoorKind.Normal).door(Position.InteriorW, DoorKind.Normal),
Room(player, 0x75, 0xf8ab9).door(Position.InteriorW, DoorKind.Trap2).door(Position.SouthE, DoorKind.Normal),
Room(player, 0x76, 0xf9e35).door(Position.InteriorN2, DoorKind.NormalLow).door(Position.InteriorS2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.ToggleFlag),
Room(player, 0x77, 0xfd0e6).door(Position.NorthW2, DoorKind.StairKeyLow).door(Position.South2, DoorKind.DungeonEntranceLow),
Room(player, 0x7b, 0xff02b).door(Position.SouthW, DoorKind.Trap).door(Position.EastN, DoorKind.SmallKey).door(Position.EastS, DoorKind.Normal),
Room(player, 0x7c, 0xff0ef).door(Position.NorthE, DoorKind.BlastWall).door(Position.EastS, DoorKind.Bombable).door(Position.WestN, DoorKind.SmallKey).door(Position.WestS, DoorKind.Normal),
Room(player, 0x7d, 0xff20c).door(Position.SouthE, DoorKind.Trap).door(Position.WestS, DoorKind.Bombable).door(Position.InteriorW, DoorKind.SmallKey),
Room(player, 0x7e, 0xfc7c6).door(Position.SouthE, DoorKind.SmallKey).door(Position.InteriorS, DoorKind.TrapTriggerable).door(Position.EastN, DoorKind.Normal),
Room(player, 0x7f, 0xfc827).door(Position.WestN, DoorKind.Trap).door(Position.InteriorW, DoorKind.Normal),
Room(player, 0x80, None),
Room(player, 0x81, 0x5224b).door(Position.NorthW2, DoorKind.NormalLow2),
Room(player, 0x82, None),
Room(player, 0x83, 0xf8bba).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.DungeonEntrance).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x84, 0xf8cb7).door(Position.South, DoorKind.DungeonEntrance),
Room(player, 0x85, 0xf8d7d).door(Position.NorthE, DoorKind.Trap).door(Position.InteriorN, DoorKind.SmallKey).door(Position.SouthE, DoorKind.DungeonEntrance).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x87, 0xfd1b7).door(Position.InteriorN, DoorKind.Trap2).door(Position.InteriorE, DoorKind.Normal),
Room(player, 0x89, None),
Room(player, 0x8b, 0xff33f).door(Position.InteriorN, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.SmallKey).door(Position.EastN, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.NorthW, DoorKind.Normal),
Room(player, 0x8c, 0xff3ef).door(Position.EastN, DoorKind.Trap).door(Position.InteriorW, DoorKind.Trap2).door(Position.InteriorN, DoorKind.SmallKey).door(Position.WestN, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal),
Room(player, 0x8d, 0xff4e0).door(Position.SouthE, DoorKind.Trap).door(Position.InteriorN, DoorKind.SmallKey).door(Position.WestN, DoorKind.Normal).door(Position.NorthE, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0x8e, 0xfc84d).door(Position.NorthE, DoorKind.SmallKey),
Room(player, 0x90, 0xfbab2).door(Position.SouthW, DoorKind.Trap),
Room(player, 0x91, 0xfb9e6).door(Position.EastS, DoorKind.Normal),
Room(player, 0x92, 0xfb97b).door(Position.InteriorN, DoorKind.Bombable).door(Position.InteriorW, DoorKind.Bombable).door(Position.WestS, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x93, 0xfb8e1).door(Position.InteriorW, DoorKind.Trap2).door(Position.InteriorE, DoorKind.SmallKey).door(Position.WestS, DoorKind.Normal),
Room(player, 0x95, 0xffc04).door(Position.SouthE, DoorKind.Normal).door(Position.EastN, DoorKind.Normal),
Room(player, 0x96, 0xffc78).door(Position.InteriorS, DoorKind.Trap2).door(Position.WestN, DoorKind.Normal),
Room(player, 0x97, 0xfb30a).door(Position.InteriorS, DoorKind.Normal).door(Position.InteriorW, DoorKind.Normal),
Room(player, 0x98, 0xfaf5b).door(Position.SouthW, DoorKind.DungeonEntrance),
Room(player, 0x99, 0x5172a).door(Position.InteriorW, DoorKind.StairKey).door(Position.South, DoorKind.SmallKey).door(Position.InteriorE, DoorKind.Normal),
Room(player, 0x9b, 0xff5a2).door(Position.InteriorN, DoorKind.SmallKey).door(Position.NorthW, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x9c, 0xff6c9).door(Position.EastS, DoorKind.Trap).door(Position.NorthW, DoorKind.Normal).door(Position.NorthE, DoorKind.Normal).door(Position.WestS, DoorKind.Normal),
Room(player, 0x9d, 0xff741).door(Position.NorthE, DoorKind.Normal).door(Position.WestS, DoorKind.Normal).door(Position.InteriorN, DoorKind.Normal),
Room(player, 0x9e, 0xfc8c8).door(Position.NorthE, DoorKind.StairKey2).door(Position.InteriorE, DoorKind.BigKey).door(Position.InteriorS, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0x9f, 0xfc937).door(Position.WestS, DoorKind.Trap).door(Position.SouthW, DoorKind.Trap),
Room(player, 0xa0, 0xfba9a).door(Position.NorthW, DoorKind.BigKey),
Room(player, 0xa1, 0xfb83d).door(Position.SouthE, DoorKind.SmallKey).door(Position.East, DoorKind.Normal),
Room(player, 0xa2, 0xfb759).door(Position.South, DoorKind.SmallKey).door(Position.West, DoorKind.Normal).door(Position.East, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal),
Room(player, 0xa3, 0xfb667).door(Position.West, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal),
Room(player, 0xa4, 0xfe741).door(Position.SouthW, DoorKind.Trap),
Room(player, 0xa5, 0xffb7f).door(Position.NorthE, DoorKind.Trap).door(Position.InteriorE, DoorKind.Trap2).door(Position.InteriorW, DoorKind.Trap2),
Room(player, 0xa6, None),
Room(player, 0xa8, 0x51887).door(Position.InteriorS, DoorKind.Trap2).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthE, DoorKind.SmallKey).door(Position.InteriorN2, DoorKind.NormalLow2).door(Position.EastN2, DoorKind.NormalLow2).door(Position.East, DoorKind.Normal),
Room(player, 0xa9, 0x519c9).door(Position.West, DoorKind.Trap).door(Position.East, DoorKind.Trap).door(Position.North, DoorKind.BigKey).door(Position.WestN2, DoorKind.NormalLow2).door(Position.EastN2, DoorKind.NormalLow2).door(Position.South, DoorKind.Normal),
Room(player, 0xaa, 0x51b29).door(Position.InteriorE, DoorKind.Trap2).door(Position.WestN2, DoorKind.NormalLow2).door(Position.InteriorN, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal).door(Position.West, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal),
Room(player, 0xab, 0xfd9a9).door(Position.InteriorW, DoorKind.StairKey).door(Position.SouthW, DoorKind.Normal),
Room(player, 0xac, 0xfd9d8).door(Position.SouthE, DoorKind.Trap),
Room(player, 0xae, 0xfc975).door(Position.EastN, DoorKind.Normal),
Room(player, 0xaf, 0xfc9e1).door(Position.NorthW, DoorKind.Normal).door(Position.WestN, DoorKind.Normal),
Room(player, 0xb0, 0xf8f6b).door(Position.InteriorW, DoorKind.Trap).door(Position.InteriorN, DoorKind.Trap).door(Position.InteriorS, DoorKind.SmallKey),
Room(player, 0xb1, 0xfb3b7).door(Position.InteriorW, DoorKind.BigKey).door(Position.NorthE, DoorKind.SmallKey).door(Position.SouthE, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal),
Room(player, 0xb2, 0xfb4ad).door(Position.North, DoorKind.BigKey).door(Position.InteriorS, DoorKind.Trap2).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.EastN2, DoorKind.NormalLow2).door(Position.NorthE, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0xb3, 0xfb5e4).door(Position.InteriorW, DoorKind.SmallKey).door(Position.WestN2, DoorKind.NormalLow2).door(Position.NorthW, DoorKind.Normal).door(Position.WestS, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal),
Room(player, 0xb4, 0xfe807).door(Position.NorthW, DoorKind.BigKey),
Room(player, 0xb5, 0xfeb07).door(Position.SouthW, DoorKind.Trap),
Room(player, 0xb6, 0xfdd50).door(Position.NorthW, DoorKind.StairKey2).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.SmallKey).door(Position.InteriorW, DoorKind.SmallKey).door(Position.SouthE, DoorKind.Normal),
Room(player, 0xb7, 0xfddcd).door(Position.SouthW, DoorKind.Normal),
Room(player, 0xb8, 0x51b75).door(Position.NorthE, DoorKind.BigKey).door(Position.EastN, DoorKind.Normal),
Room(player, 0xb9, 0x51d09).door(Position.EastN, DoorKind.SmallKey).door(Position.North, DoorKind.Normal).door(Position.South, DoorKind.Normal).door(Position.WestN, DoorKind.Normal),
Room(player, 0xba, 0x51d57).door(Position.WestN, DoorKind.SmallKey).door(Position.NorthW, DoorKind.Trap).door(Position.InteriorN, DoorKind.Trap2),
Room(player, 0xbb, 0xfd86b).door(Position.NorthW, DoorKind.Normal).door(Position.InteriorN, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal).door(Position.InteriorE, DoorKind.Normal).door(Position.EastN, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
Room(player, 0xbc, 0xfd974).door(Position.InteriorS, DoorKind.SmallKey).door(Position.SouthE, DoorKind.SmallKey).door(Position.InteriorN, DoorKind.Trap).door(Position.SouthW, DoorKind.Bombable).door(Position.WestN, DoorKind.Normal).door(Position.WestS, DoorKind.Normal).door(Position.InteriorW, DoorKind.Normal).door(Position.NorthE, DoorKind.Normal),
Room(player, 0xbe, 0xfca28).door(Position.SouthE, DoorKind.Trap).door(Position.EastS, DoorKind.SmallKey).door(Position.InteriorE, DoorKind.Normal),
Room(player, 0xbf, 0xfca89).door(Position.WestS, DoorKind.SmallKey),
Room(player, 0xc0, 0xf9026).door(Position.InteriorN, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.Trap2).door(Position.NorthE, DoorKind.StairKey),
Room(player, 0xc1, 0xfb176).door(Position.InteriorS, DoorKind.SmallKey).door(Position.EastS, DoorKind.SmallKey).door(Position.InteriorN, DoorKind.TrapTriggerable).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.Normal).door(Position.EastN, DoorKind.Normal).door(Position.NorthE, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal),
Room(player, 0xc2, 0xfb0e7).door(Position.EastN, DoorKind.SmallKey).door(Position.WestS, DoorKind.SmallKey).door(Position.NorthW, DoorKind.Normal).door(Position.WestN, DoorKind.Normal).door(Position.East, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal).door(Position.EastS, DoorKind.Normal).door(Position.NorthE, DoorKind.Normal),
Room(player, 0xc3, 0xfb56c).door(Position.WestN, DoorKind.SmallKey).door(Position.InteriorN, DoorKind.Trap2).door(Position.InteriorH, DoorKind.Trap2).door(Position.InteriorS, DoorKind.TrapTriggerable).door(Position.NorthW, DoorKind.Normal).door(Position.West, DoorKind.Normal).door(Position.WestS, DoorKind.Normal),
Room(player, 0xc4, 0xfec3f).door(Position.EastS, DoorKind.SmallKey),
Room(player, 0xc5, 0xfece1).door(Position.WestS, DoorKind.SmallKey).door(Position.NorthW, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal),
Room(player, 0xc6, 0xfdf5c).door(Position.NorthW, DoorKind.SmallKey).door(Position.NorthE, DoorKind.Normal).door(Position.EastN, DoorKind.Normal).door(Position.EastS, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal),
Room(player, 0xc7, 0xfe0a1).door(Position.NorthW, DoorKind.Trap).door(Position.WestN, DoorKind.Normal).door(Position.WestS, DoorKind.Normal),
Room(player, 0xc8, 0x51596).door(Position.SouthE, DoorKind.Trap),
Room(player, 0xc9, 0x51e5a).door(Position.InteriorV, DoorKind.Trap).door(Position.North, DoorKind.Trap).door(Position.InteriorW, DoorKind.Normal).door(Position.InteriorE, DoorKind.Normal).door(Position.South, DoorKind.DungeonEntrance),
Room(player, 0xcb, 0xfd630).door(Position.East, DoorKind.Dashable),
Room(player, 0xcc, 0xfd783).door(Position.NorthE, DoorKind.BigKey).door(Position.NorthW, DoorKind.Bombable).door(Position.West, DoorKind.Dashable),
Room(player, 0xce, 0xfcadd).door(Position.NorthE, DoorKind.Trap),
Room(player, 0xd0, 0xf90de).door(Position.InteriorS, DoorKind.SmallKey).door(Position.InteriorN, DoorKind.Trap2),
Room(player, 0xd1, 0xfb259).door(Position.InteriorS, DoorKind.Trap2).door(Position.NorthW, DoorKind.Normal).door(Position.NorthE, DoorKind.Normal).door(Position.InteriorE, DoorKind.Normal),
Room(player, 0xd2, 0xfafd6).door(Position.NorthE, DoorKind.Trap),
Room(player, 0xd5, 0xfee40).door(Position.SouthW, DoorKind.BombableEntrance).door(Position.NorthW, DoorKind.Normal),
Room(player, 0xd6, 0xfe1cb).door(Position.NorthW, DoorKind.UnknownD6).door(Position.SouthE, DoorKind.DungeonEntrance).door(Position.NorthE, DoorKind.Normal),
Room(player, 0xd8, 0x515ed).door(Position.NorthE, DoorKind.Trap).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.EastS, DoorKind.Normal),
Room(player, 0xd9, 0x5166f).door(Position.WestS, DoorKind.Trap).door(Position.InteriorS, DoorKind.Trap).door(Position.EastS, DoorKind.Trap),
Room(player, 0xda, 0x5169d).door(Position.WestS, DoorKind.Trap),
Room(player, 0xdb, 0xfd370).door(Position.East, DoorKind.Trap).door(Position.South, DoorKind.DungeonEntrance),
Room(player, 0xdc, 0xfd4d1).door(Position.West, DoorKind.Normal),
# Room(player, 0xdf, 0x52db4).door(Position.South, DoorKind.CaveEntrance),
Room(player, 0xe0, 0xf9149).door(Position.InteriorN, DoorKind.Trap2).door(Position.InteriorW, DoorKind.Trap2).door(Position.NorthE, DoorKind.StairKey).door(Position.SouthW, DoorKind.DungeonEntrance),
# Room(player, 0xe1, 0x5023c).door(Position.InteriorH2, DoorKind.NormalLow2).door(Position.SouthW, DoorKind.CaveEntrance),
# Room(player, 0xe2, 0x50464).door(Position.InteriorH, DoorKind.Normal).door(Position.SouthE, DoorKind.CaveEntrance),
# Room(player, 0xe3, 0x5032b).door(Position.InteriorS2, DoorKind.TrapLowE3).door(Position.InteriorE2, DoorKind.NormalLow2).door(Position.SouthW, DoorKind.CaveEntrance),
# Room(player, 0xe4, 0x534b1).door(Position.SouthW2, DoorKind.CaveEntranceLow).door(Position.InteriorN, DoorKind.Normal).door(Position.East, DoorKind.Normal),
# Room(player, 0xe5, 0x535ba).door(Position.West, DoorKind.Normal).door(Position.South, DoorKind.CaveEntrance),
# Room(player, 0xe6, 0x532ee).door(Position.SouthW2, DoorKind.CaveEntranceLow).door(Position.EastN2, DoorKind.NormalLow),
# Room(player, 0xe7, 0x533ce).door(Position.SouthE2, DoorKind.CaveEntranceLow).door(Position.WestN2, DoorKind.NormalLow),
# Room(player, 0xe8, 0x529d3).door(Position.SouthE, DoorKind.CaveEntrance),
# Room(player, 0xea, 0x531f5).door(Position.SouthW, DoorKind.CaveEntrance),
# Room(player, 0xeb, 0x52e1a).door(Position.SouthE, DoorKind.CaveEntrance),
# Room(player, 0xed, 0x52bec).door(Position.SouthE, DoorKind.CaveEntrance),
# Room(player, 0xee, 0x52f76).door(Position.SouthE, DoorKind.CaveEntrance),
# Room(player, 0xef, 0x52d37).door(Position.InteriorE, DoorKind.Trap2).door(Position.South, DoorKind.CaveEntrance),
# Room(player, 0xf0, 0x5258a).door(Position.SouthW, DoorKind.CaveEntrance).door(Position.East2, DoorKind.NormalLow),
# Room(player, 0xf1, 0x52703).door(Position.SouthE2, DoorKind.CaveEntranceLow).door(Position.West2, DoorKind.NormalLow),
# Room(player, 0xf2, 0x5274a).door(Position.EastS, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal).door(Position.SouthE, DoorKind.IncognitoEntrance),
# Room(player, 0xf3, 0x52799).door(Position.WestS, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthW, DoorKind.IncognitoEntrance),
# Room(player, 0xf4, 0x527d3).door(Position.EastS, DoorKind.Dashable).door(Position.SouthE, DoorKind.Normal).door(Position.SouthE, DoorKind.IncognitoEntrance),
# Room(player, 0xf5, 0x52813).door(Position.WestS, DoorKind.Dashable).door(Position.SouthW, DoorKind.Normal).door(Position.SouthW, DoorKind.IncognitoEntrance),
# Room(player, 0xf8, 0x528fe).door(Position.South, DoorKind.CaveEntrance),
# Room(player, 0xf9, 0x5305a).door(Position.SouthW, DoorKind.CaveEntrance),
# Room(player, 0xfa, 0x53165).door(Position.SouthW2, DoorKind.EntranceLow),
# Room(player, 0xfb, 0x52ea4).door(Position.South, DoorKind.CaveEntrance),
# Room(player, 0xfd, 0x52ab1).door(Position.South2, DoorKind.CaveEntranceLow),
# Room(player, 0xfe, 0x52ff1).door(Position.SouthE2, DoorKind.CaveEntranceLow),
# Room(player, 0xff, 0x52c9a).door(Position.InteriorW, DoorKind.Bombable).door(Position.InteriorE, DoorKind.Bombable).door(Position.SouthE, DoorKind.CaveEntrance),
]
# fix some wonky things
# should I put back the dungeon changer for certain logic - like no logic? maybe in basic
if world.doorShuffle[player] != 'vanilla':
world.get_room(0x51, player).delete(1) # remove the dungeon changer
world.get_room(0x60, player).swap(2, 4) # puts the exit at pos 2 - enables pos 3
world.get_room(0x61, player).swap(1, 6) # puts the WN door at pos 1 - enables it
world.get_room(0x61, player).swap(5, 6) # puts the Incognito Entrance at the end, so it can be deleted
world.get_room(0x62, player).swap(1, 4) # puts the exit at pos 1 - enables pos 3
world.get_room(0x77, player).swap(0, 1) # fixes Hera Lobby Key Stairs - entrance now at pos 0
if world.enemy_shuffle[player] != 'none':
world.get_room(0xc0, player).change(0, DoorKind.Normal) # fix this kill room if enemizer is on
world.get_room(0x0e, player).change(1, DoorKind.TrapTriggerable) # fix this kill room if enemizer is on
def reset_rooms(world, player):
world.rooms = [x for x in world.rooms if x.player != player]
world._room_cache.clear()
create_rooms(world, player)
class Room(object):
def __init__(self, player, index, address):
self.player = player
self.index = index
self.doorListAddress = address
self.doorList = []
self.modified = False
self.palette = None
def position(self, door):
return self.doorList[door.doorListPos][0]
def kind(self, door):
return self.doorList[door.doorListPos][1]
def door(self, pos, kind):
self.doorList.append((pos, kind))
return self
def change(self, list_idx, kind):
prev = self.doorList[list_idx]
self.doorList[list_idx] = (prev[0], kind)
self.modified = True
def mirror(self, list_idx):
prev = self.doorList[list_idx]
mirror_door = None
for door in self.doorList:
if door != prev:
mirror_door = door
break
self.doorList[list_idx] = (mirror_door[0], mirror_door[1])
self.modified = True
def swap(self, idx1, idx2):
item1 = self.doorList[idx1]
item2 = self.doorList[idx2]
self.doorList[idx1] = item2
self.doorList[idx2] = item1
self.modified = True
def delete(self, list_idx):
self.doorList[list_idx] = (Position.FF, DoorKind.FF)
self.modified = True
def address(self):
return self.doorListAddress
def rom_data(self):
byte_array = []
for pos, kind in self.doorList:
byte_array.append(pos.value)
byte_array.append(kind.value)
return byte_array
def next_free(self, pos=4):
for i, door in enumerate(self.doorList):
if i >= pos:
return None
position, kind = door
if kind not in [DoorKind.SmallKey, DoorKind.Dashable, DoorKind.Bombable, DoorKind.TrapTriggerable,
DoorKind.Trap, DoorKind.Trap2, DoorKind.TrapTriggerableLow, DoorKind.TrapLowE3,
DoorKind.BigKey, DoorKind.StairKey, DoorKind.StairKey2, DoorKind.StairKeyLow,
DoorKind.BlastWall, DoorKind.BombableEntrance]:
return i
return None
def __str__(self):
return str(self.__unicode__())
def __unicode__(self):
return '%s' % self.index
class PairedDoor(object):
def __init__(self, door_a, door_b, original=False):
self.door_a = door_a
self.door_b = door_b
self.pair = True
self.original = original
def address_a(self, world, player):
d = world.check_for_door(self.door_a, player)
return 0x13C000 + (door_pair_offset_table[d.roomIndex]+d.doorListPos)*2
def address_b(self, world, player):
d = world.check_for_door(self.door_b, player)
return 0x13C000 + (door_pair_offset_table[d.roomIndex]+d.doorListPos)*2
def rom_data_a(self, world, player):
if not self.pair:
return [0x00, 0x00]
d = world.check_for_door(self.door_b, player)
return [d.roomIndex, pos_map[d.doorListPos]]
def rom_data_b(self, world, player):
if not self.pair:
return [0x00, 0x00]
d = world.check_for_door(self.door_a, player)
return [d.roomIndex, pos_map[d.doorListPos]]
pos_map = {
0: 0x80, 1: 0x40, 2: 0x20, 3: 0x10
# indices 4-7 not supported yet
}
@unique
class DoorKind(Enum):
Normal = 0x00
NormalLow = 0x02
EntranceLow = 0x04
Waterfall = 0x08
DungeonEntrance = 0x0A
DungeonEntranceLow = 0x0C
CaveEntrance = 0x0E
CaveEntranceLow = 0x10
IncognitoEntrance = 0x12
DungeonChanger = 0x14
ToggleFlag = 0x16
Trap = 0x18 # both sides trapped
UnknownD6 = 0x1A
SmallKey = 0x1C
BigKey = 0x1E
StairKey = 0x20
StairKey2 = 0x22
HauntedStairKey = 0x24 # not a real door, can see it in dark rooms when facing left
StairKeyLow = 0x26
Dashable = 0x28
BombableEntrance = 0x2A
Bombable = 0x2E
BlastWall = 0x30
Hidden = 0x32
TrapTriggerable = 0x36 # right side trap or bottom side trap (door directions: West, North)
Trap2 = 0x38 # left side trap or top side trap (door directions: East, South)
NormalLow2 = 0x40
TrapTriggerableLow = 0x44
Warp = 0x46
CaveEntranceLow08 = 0x48
TrapLowE3 = 0x4A # Maybe this is a toggle flag too?
FF = 0xFF
@unique
class Position(Enum):
NorthW = 0x00
North = 0x10
NorthE = 0x20
NorthW2 = 0x30
North2 = 0x40
NorthE2 = 0x50
InteriorW = 0x60
InteriorV = 0x70
InteriorE = 0x80
InteriorW2 = 0x90
InteriorV2 = 0xA0
InteriorE2 = 0xB0
SouthW = 0x61
South = 0x71
SouthE = 0x81
SouthW2 = 0x91
South2 = 0xA1
SouthE2 = 0xB1
WestN = 0x02
West = 0x12
WestS = 0x22
WestN2 = 0x32
West2 = 0x42
# WestS2 = 0x52
InteriorN = 0x62
InteriorH = 0x72
InteriorS = 0x82
InteriorN2 = 0x92
InteriorH2 = 0xA2
InteriorS2 = 0xB2
EastN = 0x63
East = 0x73
EastS = 0x83
EastN2 = 0x93
East2 = 0xA3
# EastS2 = 0xB3
FF = 0xFF
class TestWorld(object):
def __init__(self):
self.rooms = []
# python3 -c "from RoomData import offset_utility; offset_utility()"
# This utility was used to calculate the distance offsets
def offset_utility():
world = TestWorld()
create_rooms(world, 1)
map = {}
cntr = 1
for room in world.rooms:
map[room.index] = cntr
cntr = cntr + len(room.doorList)
string = ''
for i in range(225):
if i % 16 == 0:
string = string + 'dw '
if i not in map:
string = string + '$0000,'
else:
string = string + hex(map[i]) + ','
print(string)
# python3 -c "from RoomData import key_door_template_generator; key_door_template_generator()"
# This utility was used to help initialize the pairing data
def key_door_template_generator():
world = TestWorld()
create_rooms(world, 1)
map = {}
cntr = 1
for room in world.rooms:
string = 'dw '
for door in room.doorList:
if door[1] in [DoorKind.SmallKey, DoorKind.BigKey, DoorKind.SmallKey, DoorKind.Dashable, DoorKind.Bombable]:
string = string + '$xxxx,'
else:
string = string + '$0000,'
print(string[0:-1])
# python3 -c "from RoomData import door_address_list; door_address_list('/home/randall/kwyn/orig/z3.sfc')"
# python3 -c "from RoomData import door_address_list; door_address_list('path/to/rom.sfc')"
def door_address_list(rom):
with open(rom, 'rb') as stream:
rom_data = bytearray(stream.read())
room_index = 0
while room_index < 256:
offset = room_index * 3
address = rom_data[0x0F8000 + offset]
address = address + 0x100 * rom_data[0x0F8000 + offset + 1]
byte3 = rom_data[0x0F8000 + offset + 2]
address = address + (byte3 << 16)
if byte3 == 0x03:
address = address - 0x020000
elif byte3 == 0x0A:
address = address - 0x058000
elif byte3 == 0x1f:
address = address - 0x100000
else:
print('Byte3 ' + hex(byte3))
print('Address ' + hex(address))
raise Exception('Bad address?')
terminated = False
while not terminated:
marker = rom_data[address] + (rom_data[address+1] << 8)
# if marker == 0xFFFF:
# print('Room '+ hex(room_index)+ ' terminated at '+ hex(address))
# terminated = True
if marker == 0xFFF0:
print(hex(room_index) + ': ' + hex(address+2))
# print('Room ' + hex(room_index) + ' address: ' + hex(address+2))
terminated = True
else:
address = address + 3
room_index = room_index + 1
+2198 -848
View File
File diff suppressed because it is too large Load Diff
+286
View File
@@ -0,0 +1,286 @@
## Door Tables ##
normal_offset_table = {
0x01: 0x01, 0x02: 0x02, 0x04: 0x03, 0x06: 0x04, 0x0d: 0x05, 0x11: 0x06, 0x12: 0x07, 0x13: 0x08,
0x14: 0x09, 0x15: 0x0A, 0x16: 0x0B, 0x19: 0x0C, 0x1a: 0x0D, 0x1b: 0x0E, 0x1d: 0x0F, 0x1e: 0x10,
0x1f: 0x11, 0x20: 0x12, 0x21: 0x13, 0x22: 0x14, 0x23: 0x15, 0x24: 0x16, 0x26: 0x17, 0x2a: 0x18,
0x2b: 0x19, 0x2e: 0x1A, 0x30: 0x1B, 0x32: 0x1C, 0x33: 0x1D, 0x34: 0x1E, 0x35: 0x1F, 0x36: 0x20,
0x37: 0x21, 0x38: 0x22, 0x39: 0x23, 0x3a: 0x24, 0x3b: 0x25, 0x3d: 0x26, 0x3e: 0x27, 0x41: 0x28,
0x43: 0x29, 0x44: 0x2A, 0x45: 0x2B, 0x46: 0x2C, 0x49: 0x2D, 0x4a: 0x2E, 0x4b: 0x2F, 0x4c: 0x30,
0x4d: 0x31, 0x4e: 0x32, 0x50: 0x33, 0x51: 0x34, 0x52: 0x35, 0x53: 0x36, 0x56: 0x37, 0x57: 0x38,
0x58: 0x39, 0x59: 0x3A, 0x5a: 0x3B, 0x5b: 0x3C, 0x5c: 0x3D, 0x5d: 0x3E, 0x5e: 0x3F, 0x5f: 0x40,
0x60: 0x41, 0x61: 0x42, 0x62: 0x43, 0x66: 0x44, 0x67: 0x45, 0x68: 0x46, 0x6a: 0x47, 0x6b: 0x48,
0x6c: 0x49, 0x6d: 0x4A, 0x6e: 0x4B, 0x71: 0x4C, 0x75: 0x4D, 0x76: 0x4E, 0x7b: 0x4F, 0x7c: 0x50,
0x7d: 0x51, 0x7e: 0x52, 0x7f: 0x53, 0x81: 0x54, 0x85: 0x55, 0x8b: 0x56, 0x8c: 0x57, 0x8d: 0x58,
0x8e: 0x59, 0x90: 0x5A, 0x91: 0x5B, 0x92: 0x5C, 0x93: 0x5D, 0x95: 0x5E, 0x96: 0x5F, 0x99: 0x60,
0x9b: 0x61, 0x9c: 0x62, 0x9d: 0x63, 0x9e: 0x64, 0x9f: 0x65, 0xa0: 0x66, 0xa1: 0x67, 0xa2: 0x68,
0xa3: 0x69, 0xa4: 0x6A, 0xa5: 0x6B, 0xa8: 0x6C, 0xa9: 0x6D, 0xaa: 0x6E, 0xab: 0x6F, 0xac: 0x70,
0xae: 0x71, 0xaf: 0x72, 0xb1: 0x73, 0xb2: 0x74, 0xb3: 0x75, 0xb4: 0x76, 0xb5: 0x77, 0xb6: 0x78,
0xb7: 0x79, 0xb8: 0x7A, 0xb9: 0x7B, 0xba: 0x7C, 0xbb: 0x7D, 0xbc: 0x7E, 0xbe: 0x7F, 0xbf: 0x80,
0xc1: 0x81, 0xc2: 0x82, 0xc3: 0x83, 0xc4: 0x84, 0xc5: 0x85, 0xc6: 0x86, 0xc7: 0x87, 0xc8: 0x88,
0xc9: 0x89, 0xcb: 0x8A, 0xcc: 0x8B, 0xce: 0x8C, 0xd1: 0x8D, 0xd2: 0x8E, 0xd5: 0x8F, 0xd6: 0x90,
0xd8: 0x91, 0xd9: 0x92, 0xda: 0x93, 0xdb: 0x94, 0xdc: 0x95,
0x40: 0x96, 0x42: 0x97, # newcomers for str stairs
# newcomers for entrances
0x28: 0x98, 0x0e: 0x99, 0x0c: 0x9a, 0x98: 0x9b, 0x83: 0x9c, 0x84: 0x9d, 0x77: 0x9e, 0xe0: 0x9f,
0x63: 0xa0
}
spiral_offset_table = {
0x01: 0x01, 0x02: 0x02, 0x04: 0x03, 0x07: 0x04, 0x09: 0x05, 0x0a: 0x07, 0x0c: 0x08, 0x0e: 0x0b,
0x11: 0x0c, 0x15: 0x0d, 0x16: 0x0e, 0x17: 0x0f, 0x1a: 0x11, 0x1c: 0x13, 0x1d: 0x14, 0x1e: 0x15,
0x26: 0x16, 0x27: 0x19, 0x28: 0x1b, 0x31: 0x1c, 0x34: 0x1f, 0x38: 0x20, 0x3a: 0x21, 0x3f: 0x22,
0x40: 0x23, 0x41: 0x24, 0x42: 0x25, 0x45: 0x26, 0x4a: 0x27, 0x4c: 0x29, 0x4d: 0x2a, 0x4e: 0x2b,
0x53: 0x2c, 0x54: 0x2d, 0x5c: 0x2e, 0x5d: 0x2f, 0x5f: 0x30, 0x63: 0x35, 0x64: 0x36, 0x66: 0x37,
0x6a: 0x38, 0x6b: 0x3a, 0x6c: 0x3b, 0x6e: 0x3c, 0x70: 0x3d, 0x71: 0x40, 0x72: 0x41, 0x76: 0x42,
0x77: 0x45, 0x7f: 0x49, 0x80: 0x4a, 0x87: 0x4b, 0x8c: 0x4f, 0x8e: 0x53, 0x91: 0x54, 0x93: 0x55,
0x97: 0x56, 0x98: 0x57, 0x99: 0x58, 0x9e: 0x59, 0xa0: 0x5a, 0xa2: 0x5b, 0xa5: 0x5c, 0xa6: 0x5d,
0xab: 0x5e, 0xae: 0x5f, 0xb0: 0x60, 0xb5: 0x63, 0xb6: 0x64, 0xbc: 0x65, 0xbe: 0x66, 0xc0: 0x67,
0xd0: 0x6a, 0xd1: 0x6d, 0xd2: 0x6e, 0xda: 0x6f, 0xe0: 0x70
}
door_pair_offset_table = {
0x01: 0x0001, 0x02: 0x0003, 0x04: 0x0006, 0x06: 0x000b, 0x0a: 0x000c, 0x0b: 0x000d, 0x0c: 0x0010, 0x0d: 0x0011,
0x0e: 0x0012, 0x11: 0x0015, 0x12: 0x0018, 0x13: 0x001c, 0x14: 0x001e, 0x15: 0x0025, 0x16: 0x0027, 0x19: 0x002b,
0x1a: 0x002d, 0x1b: 0x0033, 0x1c: 0x0035, 0x1d: 0x0038, 0x1e: 0x0039, 0x1f: 0x003d, 0x20: 0x003f, 0x21: 0x0040,
0x22: 0x0043, 0x23: 0x0045, 0x24: 0x0047, 0x26: 0x004f, 0x28: 0x0053, 0x2a: 0x0055, 0x2b: 0x005b, 0x2e: 0x005f,
0x30: 0x0060, 0x31: 0x0062, 0x32: 0x0064, 0x33: 0x0065, 0x34: 0x0066, 0x35: 0x0068, 0x36: 0x006e, 0x37: 0x0074,
0x38: 0x007a, 0x39: 0x007c, 0x3a: 0x007e, 0x3b: 0x0081, 0x3d: 0x0082, 0x3e: 0x0086, 0x3f: 0x0088, 0x40: 0x0089,
0x41: 0x008a, 0x43: 0x008b, 0x44: 0x008e, 0x45: 0x0092, 0x46: 0x0096, 0x49: 0x0099, 0x4a: 0x009d, 0x4b: 0x00a2,
0x4c: 0x00a5, 0x4d: 0x00a6, 0x4e: 0x00a8, 0x4f: 0x00aa, 0x50: 0x00ab, 0x51: 0x00ad, 0x52: 0x00af, 0x53: 0x00b2,
0x56: 0x00b5, 0x57: 0x00b9, 0x58: 0x00bf, 0x59: 0x00c5, 0x5a: 0x00c9, 0x5b: 0x00ca, 0x5c: 0x00cc, 0x5d: 0x00ce,
0x5e: 0x00d1, 0x5f: 0x00d5, 0x60: 0x00d6, 0x61: 0x00dc, 0x62: 0x00e3, 0x63: 0x00e9, 0x64: 0x00ec, 0x65: 0x00ed,
0x66: 0x00ee, 0x67: 0x00f2, 0x68: 0x00f5, 0x6a: 0x00f7, 0x6b: 0x00f8, 0x6c: 0x00fc, 0x6d: 0x00ff, 0x6e: 0x0102,
0x71: 0x0103, 0x72: 0x0106, 0x73: 0x0107, 0x74: 0x010a, 0x75: 0x010c, 0x76: 0x010e, 0x77: 0x0112, 0x7b: 0x0114,
0x7c: 0x0117, 0x7d: 0x011b, 0x7e: 0x011e, 0x7f: 0x0121, 0x81: 0x0123, 0x83: 0x0124, 0x84: 0x0127, 0x85: 0x0128,
0x87: 0x012c, 0x8b: 0x012e, 0x8c: 0x0133, 0x8d: 0x0139, 0x8e: 0x013e, 0x90: 0x013f, 0x91: 0x0140, 0x92: 0x0141,
0x93: 0x0146, 0x95: 0x0149, 0x96: 0x014b, 0x97: 0x014d, 0x98: 0x014f, 0x99: 0x0150, 0x9b: 0x0153, 0x9c: 0x0156,
0x9d: 0x015a, 0x9e: 0x015d, 0x9f: 0x0161, 0xa0: 0x0163, 0xa1: 0x0164, 0xa2: 0x0166, 0xa3: 0x016a, 0xa4: 0x016c,
0xa5: 0x016d, 0xa8: 0x0170, 0xa9: 0x0176, 0xaa: 0x017c, 0xab: 0x0182, 0xac: 0x0184, 0xae: 0x0185, 0xaf: 0x0186,
0xb0: 0x0188, 0xb1: 0x018b, 0xb2: 0x018f, 0xb3: 0x0197, 0xb4: 0x019c, 0xb5: 0x019d, 0xb6: 0x019e, 0xb7: 0x01a3,
0xb8: 0x01a4, 0xb9: 0x01a6, 0xba: 0x01aa, 0xbb: 0x01ad, 0xbc: 0x01b3, 0xbe: 0x01bb, 0xbf: 0x01be, 0xc0: 0x01bf,
0xc1: 0x01c2, 0xc2: 0x01ca, 0xc3: 0x01d2, 0xc4: 0x01d9, 0xc5: 0x01da, 0xc6: 0x01dd, 0xc7: 0x01e3, 0xc8: 0x01e6,
0xc9: 0x01e7, 0xcb: 0x01ec, 0xcc: 0x01ed, 0xce: 0x01f0, 0xd0: 0x01f1, 0xd1: 0x01f3, 0xd2: 0x01f7, 0xd5: 0x01f8,
0xd6: 0x01fa, 0xd8: 0x01fd, 0xd9: 0x0200, 0xda: 0x0203, 0xdb: 0x0204, 0xdc: 0x0206, 0xe0: 0x0207
}
# Note: 0-7 correspond to 1,2,3,4,5,6,a,14 respectively, see doortables.asm : MultDivInfo
multiply_lookup = {
0x08: {0x8: 0, 0x10: 1, 0x18: 2, 0x20: 3, 0x30: 5, 0x50: 6, 0xa0: 7},
0x10: {0x8: 0, 0x10: 0, 0x18: 2, 0x20: 1, 0x30: 2, 0x50: 3, 0xa0: 6},
0x18: {0x8: 0, 0x10: 1, 0x18: 0, 0x20: 3, 0x30: 1, 0x50: 6, 0xa0: 7},
0x20: {0x8: 0, 0x10: 0, 0x18: 2, 0x20: 0, 0x30: 2, 0x50: 4, 0xa0: 4},
0x30: {0x8: 0, 0x10: 0, 0x18: 0, 0x20: 1, 0x30: 0, 0x50: 4, 0xa0: 6},
0x50: {0x8: 0, 0x10: 0, 0x18: 2, 0x20: 1, 0x30: 2, 0x50: 0, 0xa0: 1},
0xa0: {0x8: 0, 0x10: 0, 0x18: 2, 0x20: 0, 0x30: 2, 0x50: 0, 0xa0: 0},
}
divisor_lookup = {
0x08: {0x8: 0, 0x10: 0, 0x18: 0, 0x20: 0, 0x30: 0, 0x50: 0, 0xa0: 0},
0x10: {0x8: 1, 0x10: 0, 0x18: 1, 0x20: 0, 0x30: 0, 0x50: 0, 0xa0: 0},
0x18: {0x8: 2, 0x10: 2, 0x18: 0, 0x20: 2, 0x30: 0, 0x50: 2, 0xa0: 2},
0x20: {0x8: 3, 0x10: 1, 0x18: 3, 0x20: 0, 0x30: 1, 0x50: 1, 0xa0: 0},
0x30: {0x8: 5, 0x10: 2, 0x18: 1, 0x20: 2, 0x30: 0, 0x50: 2, 0xa0: 2},
0x50: {0x8: 6, 0x10: 3, 0x18: 6, 0x20: 4, 0x30: 4, 0x50: 0, 0xa0: 0},
0xa0: {0x8: 7, 0x10: 6, 0x18: 7, 0x20: 4, 0x30: 6, 0x50: 1, 0xa0: 0},
}
# I don't need this right now, but I don't want to throw it away either
# Note: this value + 0x028000 is where the header is for the room (PC not SNES addressing)
# room_header_lookup = {
# 0x0: 0x462, 0x1: 0x46c, 0x2: 0x47a, 0x3: 0x5dd, 0x4: 0x485, 0x5: 0x490, 0x6: 0x490, 0x7: 0x497,
# 0x8: 0x4a2, 0x9: 0x4a9, 0xa: 0x4b5, 0xb: 0x4c0, 0xc: 0x4cb, 0xd: 0x4d8, 0xe: 0x4df, 0xf: 0x4ea,
# 0x10: 0x4ea, 0x11: 0x4f1, 0x12: 0x4fc, 0x13: 0x503, 0x14: 0x511, 0x15: 0x518, 0x16: 0x523, 0x17: 0x52e,
# 0x18: 0xc73, 0x19: 0x53a, 0x1a: 0x541, 0x1b: 0x54d, 0x1c: 0x558, 0x1d: 0x563, 0x1e: 0x56e, 0x1f: 0x579,
# 0x20: 0x584, 0x21: 0x58b, 0x22: 0x58b, 0x23: 0x503, 0x24: 0x592, 0x25: 0x599, 0x26: 0x599, 0x27: 0x5a6,
# 0x28: 0x5b2, 0x29: 0x5bd, 0x2a: 0x5c4, 0x2b: 0x5cb, 0x2c: 0xc73, 0x2d: 0x5d6, 0x2e: 0x5d6, 0x2f: 0x5dd,
# 0x30: 0x5e4, 0x31: 0x5ef, 0x32: 0x5fb, 0x33: 0x606, 0x34: 0x60d, 0x35: 0x618, 0x36: 0x61f, 0x37: 0x618,
# 0x38: 0x626, 0x39: 0x631, 0x3a: 0x63b, 0x3b: 0x646, 0x3c: 0x651, 0x3d: 0x658, 0x3e: 0x663, 0x3f: 0x66e,
# 0x40: 0x67a, 0x41: 0x686, 0x42: 0x691, 0x43: 0x69d, 0x44: 0x6a4, 0x45: 0x6ab, 0x46: 0x6b6, 0x47: 0x6bd,
# 0x48: 0x6bd, 0x49: 0x6bd, 0x4a: 0x6c4, 0x4b: 0x6d0, 0x4c: 0x6da, 0x4d: 0x6e5, 0x4e: 0x6f0, 0x4f: 0x6fb,
# 0x50: 0x705, 0x51: 0x713, 0x52: 0x71e, 0x53: 0x72c, 0x54: 0x737, 0x55: 0x742, 0x56: 0x749, 0x57: 0x750,
# 0x58: 0x757, 0x59: 0x75e, 0x5a: 0x765, 0x5b: 0x76c, 0x5c: 0x773, 0x5d: 0x77e, 0x5e: 0x789, 0x5f: 0x794,
# 0x60: 0x7a0, 0x61: 0x7a7, 0x62: 0x7a0, 0x63: 0x7b2, 0x64: 0x7bd, 0x65: 0x7c8, 0x66: 0x7d2, 0x67: 0x7dd,
# 0x68: 0x7e4, 0x69: 0x7eb, 0x6a: 0x7eb, 0x6b: 0x7f7, 0x6c: 0x802, 0x6d: 0x80d, 0x6e: 0x814, 0x6f: 0x81f,
# 0x70: 0x81f, 0x71: 0x82b, 0x72: 0x836, 0x73: 0x841, 0x74: 0x848, 0x75: 0x84f, 0x76: 0x856, 0x77: 0x863,
# 0x78: 0x870, 0x79: 0x870, 0x7a: 0x870, 0x7b: 0x870, 0x7c: 0x87a, 0x7d: 0x881, 0x7e: 0x88b, 0x7f: 0x896,
# 0x80: 0x8a1, 0x81: 0x8ac, 0x82: 0x8ac, 0x83: 0x8b3, 0x84: 0x8ba, 0x85: 0x8c1, 0x86: 0x8c8, 0x87: 0x8c8,
# 0x88: 0x8d4, 0x89: 0x8d4, 0x8a: 0x8de, 0x8b: 0x8de, 0x8c: 0x8e5, 0x8d: 0x8f2, 0x8e: 0x8f9, 0x8f: 0x904,
# 0x90: 0x904, 0x91: 0x90b, 0x92: 0x916, 0x93: 0x91d, 0x94: 0x928, 0x95: 0x928, 0x96: 0x92f, 0x97: 0x93a,
# 0x98: 0x945, 0x99: 0x950, 0x9a: 0x95b, 0x9b: 0x95b, 0x9c: 0x965, 0x9d: 0x96c, 0x9e: 0x976, 0x9f: 0x981,
# 0xa0: 0x988, 0xa1: 0x993, 0xa2: 0x99a, 0xa3: 0x993, 0xa4: 0x9a5, 0xa5: 0x9ac, 0xa6: 0x9b7, 0xa7: 0x9c2,
# 0xa8: 0x9cc, 0xa9: 0x9d3, 0xaa: 0x9dd, 0xab: 0x9e4, 0xac: 0x9ef, 0xad: 0x9f6, 0xae: 0x9f6, 0xaf: 0xa01,
# 0xb0: 0xa08, 0xb1: 0xa14, 0xb2: 0xa1e, 0xb3: 0xa25, 0xb4: 0xa2c, 0xb5: 0xa37, 0xb6: 0xa42, 0xb7: 0x50a,
# 0xb8: 0xa4d, 0xb9: 0xa54, 0xba: 0xa5b, 0xbb: 0xa62, 0xbc: 0xa69, 0xbd: 0xa74, 0xbe: 0xa74, 0xbf: 0xa7f,
# 0xc0: 0xa86, 0xc1: 0xa92, 0xc2: 0xa99, 0xc3: 0xaa0, 0xc4: 0xaa7, 0xc5: 0xab2, 0xc6: 0x50a, 0xc7: 0xab9,
# 0xc8: 0xac0, 0xc9: 0xac7, 0xca: 0xace, 0xcb: 0xace, 0xcc: 0xace, 0xcd: 0xad5, 0xce: 0xad5, 0xcf: 0xadf,
# 0xd0: 0xadf, 0xd1: 0xaeb, 0xd2: 0xaf6, 0xd3: 0xb01, 0xd4: 0xb01, 0xd5: 0xab2, 0xd6: 0x50a, 0xd7: 0xb01,
# 0xd8: 0xb01, 0xd9: 0xb08, 0xda: 0xb0f, 0xdb: 0xace, 0xdc: 0xace, 0xdd: 0xb1a, 0xde: 0xb1a, 0xdf: 0xb21,
# 0xe0: 0xb2c, 0xe1: 0xb37, 0xe2: 0xb3e, 0xe3: 0xb45, 0xe4: 0xb4c, 0xe5: 0xb4c, 0xe6: 0xb53, 0xe7: 0xb53,
# 0xe8: 0xb5a, 0xe9: 0xb68, 0xea: 0xb68, 0xeb: 0xb73, 0xec: 0xb7e, 0xed: 0xb7e, 0xee: 0xb8a, 0xef: 0xb94,
# 0xf0: 0xb53, 0xf1: 0xb53, 0xf2: 0xba0, 0xf3: 0xba0, 0xf4: 0xba5, 0xf5: 0xba5, 0xf6: 0xbac, 0xf7: 0xbac,
# 0xf8: 0xbac, 0xf9: 0xbba, 0xfa: 0xbc1, 0xfb: 0xbcc, 0xfc: 0xbd7, 0xfd: 0xbd7, 0xfe: 0xbba, 0xff: 0xbe3
# }
# item name: (spriteID, pool count, replacement item)
bonk_prize_lookup = {
'Chicken': (0x0b, 0, None),
'Bee Trap': (0x79, 6, None),
'Apples': (0xac, 8, None),
'Good Bee': (0xb2, 1, None),
'Small Heart': (0xd8, 2, None),
'Rupee (1)': (0xd9, 0, None),
'Rupees (5)': (0xda, 3, None), # TODO: add in murahdahla tree rupee
'Rupees (20)': (0xdb, 3, None),
'Single Bomb': (0xdc, 2, None),
'Bombs (3)': (None, 0, 'Bombs (4)'),
'Bombs (4)': (0xdd, 0, 'Bombs (3)'),
'Bombs (8)': (0xde, 1, 'Bombs (10)'),
'Bombs (10)': (None, 0, 'Bombs (8)'),
'Small Magic': (0xdf, 0, None),
'Big Magic': (0xe0, 1, None),
'Arrows (5)': (0xe1, 0, None),
'Arrows (10)': (0xe2, 0, None),
'Fairy': (0xe3, 15, None)
}
# item name: (custom gfx, address offset, palette, palette address, size)
# decompressed gfx loaded at $7F8000
# custom gfx loaded at $228000
item_gfx_table = {
'Green Rupees (20)': (False, 0x0000, 0x04, 0x0000, 2),
'Pegasus Boots': (False, 0x0040, 0x01, 0x0000, 2),
'Psuedoboots': (False, 0x0040, 0x02, 0x0000, 2),
'Blue Pendant': (False, 0x0080, 0x02, 0x0000, 2),
'Red Pendant': (False, 0x0080, 0x01, 0x0000, 2),
'Warp Tile': (False, 0x00C0, 0x04, 0x0000, 2),
'Open Chest': (False, 0x0100, 0x02, 0x0000, 2),
'Chicken': (False, 0x0140, 0x04, 0x0000, 2),
'Duck': (False, 0x0180, 0x01, 0x0000, 2),
'Chest': (False, 0x0400, 0x02, 0x0000, 2),
'Frog': (False, 0x0440, 0x04, 0x0000, 2),
'Kiki (Head)': (False, 0x0480, 0x04, 0x0000, 2),
'Purple Chest': (False, 0x0500, 0x04, 0x0000, 2),
'Super Bomb': (False, 0x0540, 0x04, 0x0000, 2),
'Blacksmith': (False, 0x0580, 0x04, 0x0000, 2),
'Bug Net': (False, 0x0860, 0x01, 0x0000, 2),
'Crystal': (False, 0x08A0, 0x86, 0xB240, 2),
'Silver Arrows': (False, 0x08E0, 0x01, 0x0000, 2),
'Progressive Bow': (False, 0x0920, 0x02, 0x0000, 2),
'Bottle (Fairy)': (False, 0x0960, 0x02, 0x0000, 2),
'Bottle (Bee)': (False, 0x09A0, 0x02, 0x0000, 2),
'Piece of Heart': (False, 0x0C00, 0x01, 0x0000, 2),
'Ocarina': (False, 0x0C40, 0x02, 0x0000, 2),
'Mirror Shield': (False, 0x0C80, 0x80, 0xB230, 2),
'Rupees (100)': (False, 0x0D20, 0x04, 0x0000, 2),
'Rupees (50)': (False, 0x0D60, 0x04, 0x0000, 2),
'Rupees (300)': (False, 0x0DA0, 0x04, 0x0000, 2),
'Flippers': (False, 0x1000, 0x02, 0x0000, 2),
'Magic Mirror': (False, 0x1040, 0x02, 0x0000, 2),
'Bomb': (False, 0x1080, 0x02, 0x0000, 2),
'Lamp': (False, 0x10C0, 0x01, 0x0000, 2),
'Psuedolamp': (False, 0x10C0, 0x02, 0x0000, 2),
'Magic Cape': (False, 0x1100, 0x01, 0x0000, 2),
'Compass': (False, 0x1140, 0x02, 0x0000, 2),
'Moon Pearl': (False, 0x1180, 0x01, 0x0000, 2),
'Ether': (False, 0x1400, 0x04, 0x0000, 2),
'Bombos': (False, 0x1440, 0x04, 0x0000, 2),
'Quake': (False, 0x1480, 0x04, 0x0000, 2),
'Bottle': (False, 0x14C0, 0x01, 0x0000, 2),
'Bottle (Red Potion)': (False, 0x1500, 0x01, 0x0000, 2),
'Bottle (Green Potion)': (False, 0x1500, 0x04, 0x0000, 2),
'Bottle (Blue Potion)': (False, 0x1500, 0x02, 0x0000, 2),
'Mushroom': (False, 0x1540, 0x04, 0x0000, 2),
'Map': (False, 0x1580, 0x04, 0x0000, 2),
'Big Key': (False, 0x15C0, 0x04, 0x0000, 2),
'Green Potion': (False, 0x1800, 0x04, 0x0000, 2),
'Blue Potion': (False, 0x1800, 0x02, 0x0000, 2),
'Red Potion': (False, 0x1800, 0x01, 0x0000, 2),
'Bombs (3)': (False, 0x1840, 0x02, 0x0000, 2),
'Arrows (10)': (False, 0x1880, 0x02, 0x0000, 2),
'Heart Container': (False, 0x18C0, 0x01, 0x0000, 2),
'Heart Container (Green)': (False, 0x18C0, 0x04, 0x0000, 2),
'Heart Container (Blue)': (False, 0x18C0, 0x02, 0x0000, 2),
'Green Mail': (False, 0x1900, 0x04, 0x0000, 2),
'Blue Mail': (False, 0x1900, 0x02, 0x0000, 2),
'Red Mail': (False, 0x1900, 0x01, 0x0000, 2),
'Fire Shield': (False, 0x1940, 0x80, 0xB220, 2),
'Blue Shield': (False, 0x19C0, 0x02, 0x0000, 2),
'Magic Powder': (False, 0x1CC0, 0x02, 0x0000, 2),
'Bombs (10)': (False, 0x1D00, 0x02, 0x0000, 2),
'Power Glove': (False, 0x1D40, 0x01, 0x0000, 2),
'Titans Mitt': (False, 0x1D40, 0x04, 0x0000, 2),
'Book of Mudora': (False, 0x1D80, 0x04, 0x0000, 2),
'Maiden (Head)': (False, 0x2000, 0x04, 0x0000, 2),
'Zelda (Head)': (False, 0x2080, 0x04, 0x0000, 2),
'Old Man (Head)': (False, 0x2140, 0x04, 0x0000, 2),
'Locksmith (Head)': (False, 0x2180, 0x04, 0x0000, 2),
'Fire': (False, 0x25C0, 0x04, 0x0000, 2),
'Apples': (False, 0x30A0, 0x04, 0x0000, 2),
'Fairy': (False, 0x3140, 0x01, 0x0000, 2),
'Whirlpool': (False, 0x31C0, 0x02, 0x0000, 2),
'Nothing': (True, 0x0020, 0x01, 0x0000, 2),
'Triforce': (True, 0x0060, 0x04, 0x0000, 2),
'Fighter Sword': (True, 0x00A0, 0x02, 0x0000, 2),
'Master Sword': (True, 0x00E0, 0x02, 0x0000, 2),
'Tempered Sword': (True, 0x0120, 0x01, 0x0000, 2),
'Golden Sword': (True, 0x0160, 0x04, 0x0000, 2),
'Half Magic': (True, 0x01A0, 0x04, 0x0000, 2),
'Quarter Magic': (True, 0x01E0, 0x04, 0x0000, 2),
'Bomb Upgrade (+5)': (True, 0x0420, 0x04, 0x0000, 2),
'Bomb Upgrade (+10)': (True, 0x0460, 0x04, 0x0000, 2),
'Bomb Upgrade (50)': (True, 0x04A0, 0x04, 0x0000, 2),
'Bombbag': (True, 0x04E0, 0x02, 0x0000, 2),
'Arrow Upgrade (+5)': (True, 0x0520, 0x02, 0x0000, 2),
'Arrow Upgrade (+10)': (True, 0x0560, 0x02, 0x0000, 2),
'Arrow Upgrade (70)': (True, 0x05A0, 0x02, 0x0000, 2),
'Silver Arrows (Ag)': (True, 0x05E0, 0x01, 0x0000, 2),
'Green Pendant': (True, 0x0820, 0x04, 0x0000, 2),
'Sword and Shield': (True, 0x0860, 0x02, 0xD244, 2),
'Green Potion (G)': (True, 0x08A0, 0x04, 0x0000, 2),
'Blue Potion (B)': (True, 0x08E0, 0x02, 0x0000, 2),
'Red Potion (R)': (True, 0x0920, 0x01, 0x0000, 2),
'Bee Trap': (True, 0x0960, 0x02, 0x0000, 2),
'Red Crystal': (True, 0x0C60, 0x01, 0x0000, 2),
'Green Clock': (True, 0x0DE0, 0x04, 0x0000, 2),
'Blue Clock': (True, 0x0DE0, 0x02, 0x0000, 2),
'Red Clock': (True, 0x0DE0, 0x01, 0x0000, 2),
'Egg': (True, 0x1020, 0x02, 0x0000, 2),
'Master Key': (True, 0x1060, 0x02, 0x0000, 2),
'Lumberjack (Head)': (True, 0x11A0, 0x02, 0x0000, 2),
'Power Star': (True, 0x11E0, 0x04, 0x0000, 2),
# Thin GFX
'Rupee (1)': (False, 0x0800, 0x04, 0x0000, 0),
'Rupees (5)': (False, 0x0800, 0x02, 0x0000, 0),
'Rupees (20)': (False, 0x0800, 0x01, 0x0000, 0),
'Blue Shield (Thin)': (False, 0x09E0, 0x02, 0x0000, 0),
'Heart': (False, 0x0CC0, 0x01, 0x0000, 0),
'Heart (Green)': (False, 0x0CC0, 0x04, 0x0000, 0),
'Heart (Blue)': (False, 0x0CC0, 0x02, 0x0000, 0),
'Small Magic': (False, 0x0CE0, 0x04, 0x0000, 0),
'Arrow': (False, 0x0D00, 0x02, 0x0000, 0),
'Nothing (Thin)': (False, 0x0DE0, 0x01, 0x0000, 0),
'Master Sword (Thin)': (False, 0x11C0, 0x05, 0x0000, 0),
'Tempered Sword (Thin)': (False, 0x11C0, 0x01, 0x0000, 0),
'Golden Sword (Thin)': (False, 0x11C0, 0x04, 0x0000, 0),
'Shovel': (False, 0x11E0, 0x01, 0x0000, 0),
'Bow': (False, 0x1C00, 0x01, 0x0000, 0),
'Fighter Sword (Thin)': (False, 0x1C20, 0x02, 0x0000, 0),
'Somaria': (False, 0x1C40, 0x01, 0x0000, 0),
'Byrna': (False, 0x1C40, 0x02, 0x0000, 0),
'Hookshot': (False, 0x1C60, 0x01, 0x0000, 0),
'Fire Rod': (False, 0x1C80, 0x01, 0x0000, 0),
'Ice Rod': (False, 0x1C80, 0x02, 0x0000, 0),
'Hammer': (False, 0x1CA0, 0x01, 0x0000, 0),
'Small Key': (False, 0x1DC0, 0x04, 0x0000, 0),
'Boomerang': (False, 0x1DE0, 0x02, 0x0000, 0),
'Red Boomerang': (False, 0x1DE0, 0x01, 0x0000, 0),
'Full Magic': (True, 0x01A0, 0x04, 0x0000, 0),
}
+142
View File
@@ -0,0 +1,142 @@
import argparse
import concurrent.futures
import multiprocessing
import subprocess
import sys
from collections import OrderedDict
cpu_threads = multiprocessing.cpu_count()
py_version = f"{sys.version_info.major}.{sys.version_info.minor}"
def main(args=None):
successes = []
errors = []
task_mapping = []
tests = OrderedDict()
successes.append(f"Testing {args.dr} DR with {args.count} Tests" + (f" (intensity={args.tense})" if args.dr in ['basic', 'crossed'] else ""))
print(successes[0])
max_attempts = args.count
pool = concurrent.futures.ThreadPoolExecutor(max_workers=cpu_threads)
dead_or_alive = 0
alive = 0
def test(testname: str, command: str):
tests[testname] = [command]
for mode in [['Open', ''],
['Std ', ' --mode standard'],
['Inv ', ' --mode inverted']]:
basecommand = f"python DungeonRandomizer.py --door_shuffle {args.dr} --intensity {args.tense} --suppress_rom --spoiler none"
def gen_seed():
taskcommand = basecommand + " " + command + mode[1]
return subprocess.run(taskcommand, capture_output=True, shell=True, text=True)
for x in range(1, max_attempts + 1):
task = pool.submit(gen_seed)
task.success = False
task.name = testname
task.mode = mode[0]
task.cmd = basecommand + " " + command + mode[1]
task_mapping.append(task)
test("Vanilla ", "--shuffle vanilla")
test("Retro ", "--retro --shuffle vanilla")
test("Keysanity ", "--shuffle vanilla --keydropshuffle --keysanity")
test("Shopsanity", "--shuffle vanilla --shopsanity")
test("Simple ", "--shuffle simple")
test("Full ", "--shuffle full")
test("Lite ", "--shuffle lite")
test("Lean ", "--shuffle lean")
test("District ", "--shuffle district")
test("Swapped ", "--shuffle swapped")
test("Crossed ", "--shuffle crossed")
test("Insanity ", "--shuffle insanity")
test("OWG ", "--logic owglitches")
test("OW Full ", "--ow_shuffle full")
from tqdm import tqdm
with tqdm(concurrent.futures.as_completed(task_mapping),
total=len(task_mapping), unit="seed(s)",
desc=f"Success rate: 0.00%") as progressbar:
for task in progressbar:
dead_or_alive += 1
try:
result = task.result()
if result.returncode:
errors.append([task.name + task.mode, task.cmd, result.stderr])
else:
alive += 1
task.success = True
except Exception as e:
raise e
progressbar.set_description(f"Success rate: {(alive/dead_or_alive)*100:.2f}% - {task.name}{task.mode}")
def get_results(testname: str):
result = ""
for mode in ['Open', 'Std ', 'Inv ']:
dead_or_alive = [task.success for task in task_mapping if task.name == testname and task.mode == mode]
alive = [x for x in dead_or_alive if x]
success = f"{testname}{mode} Rate: {(len(alive) / len(dead_or_alive)) * 100:.2f}%"
successes.append(success)
print(success)
result += f"{(len(alive)/len(dead_or_alive))*100:.2f}%\t"
return result.strip()
results = []
for t in tests.keys():
results.append(get_results(t))
for result in results:
print(result)
successes.append(result)
return successes, errors
if __name__ == "__main__":
successes = []
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--count', default=0, type=lambda value: max(int(value), 0))
parser.add_argument('--cpu_threads', default=cpu_threads, type=lambda value: max(int(value), 1))
parser.add_argument('--help', default=False, action='store_true')
args = parser.parse_args()
if args.help:
parser.print_help()
exit(0)
cpu_threads = args.cpu_threads
for dr in [['vanilla', args.count if args.count else 2, 1],
['basic', args.count if args.count else 5, 3],
['crossed', args.count if args.count else 10, 3]]:
for tense in range(1, dr[2] + 1):
args = argparse.Namespace()
args.dr = dr[0]
args.tense = tense
args.count = dr[1]
s, errors = main(args=args)
if successes:
successes += [""] * 2
successes += s
print()
if errors:
with open(f"{dr[0]}{(f'-{tense}' if dr[0] in ['basic', 'crossed'] else '')}-errors.txt", 'w') as stream:
for error in errors:
stream.write(error[0] + "\n")
stream.write(error[1] + "\n")
stream.write(error[2] + "\n\n")
with open("success.txt", "w") as stream:
stream.write(str.join("\n", successes))
input("Press enter to continue")
+144
View File
@@ -0,0 +1,144 @@
import subprocess
import sys
import multiprocessing
import concurrent.futures
import argparse
import sqlite3
from collections import OrderedDict
from datetime import datetime
cpu_threads = multiprocessing.cpu_count()
py_version = f"{sys.version_info.major}.{sys.version_info.minor}"
def main(args=None):
successes = []
errors = []
task_mapping = []
tests = OrderedDict()
max_attempts = 1 #args and args.count if args.count is not None else 1
print(f"Testing Random OWR with {max_attempts} Tests")
pool = concurrent.futures.ThreadPoolExecutor(max_workers=cpu_threads)
dead_or_alive = 0
alive = 0
basecommand = f'py Mystery.py --suppress_rom --suppress_meta --spoiler full --outputpath L:/_Work/Zelda/ROMs/Bug/Automate/{datetime.now().strftime("%y%m%d")} --weights L:/_Work/Zelda/ROMs/Bug/Automate/_test.yml'
def gen_seed():
return subprocess.run(basecommand, capture_output=True, shell=True, text=True)
for x in range(1, max_attempts + 1):
task = pool.submit(gen_seed)
task.success = False
task.name = "OWR Random Test"
task.mode = ""
task.cmd = basecommand
task_mapping.append(task)
from tqdm import tqdm
with tqdm(concurrent.futures.as_completed(task_mapping),
total=len(task_mapping), unit="seed(s)",
desc=f"Success rate: 0.00%") as progressbar:
#with open("L:/_Work/Zelda/ROMs/Bug/Automate/_error_.txt", "a") as ff:
# ff.write("seed")
for task in progressbar:
dead_or_alive += 1
try:
result = task.result()
if result.returncode:
errors.append([datetime.now(), result.stderr])
#print(result.stderr)
#print(result.stdout)
else:
alive += 1
successes.append([datetime.now(), result.stderr])
task.success = True
except Exception as e:
with open("L:/_Work/Zelda/ROMs/Bug/Automate" + datetime.now().strftime("%y%m%d") + "/_error_.txt", "a") as ff:
exc_type, exc_obj, exc_tb = sys.exc_info()
ff.write(exc_type)
ff.write(exc_tb.tb_lineno)
raise e
progressbar.set_description(f"Success rate: {(alive/dead_or_alive)*100:.2f}% - {task.name}{task.mode}")
def get_results(testname: str):
result = ""
dead_or_alive = [task.success for task in task_mapping]
alive = [x for x in dead_or_alive if x]
success = f"Rate: {(len(alive) / len(dead_or_alive)) * 100:.2f}%"
#successes.append(success)
#print(success)
result += f"{(len(alive)/len(dead_or_alive))*100:.2f}%\t"
return result.strip()
results = []
results.append(get_results(""))
#for result in results:
#print(result)
#successes.append(result)
return successes, errors
if __name__ == "__main__":
successes = []
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--count', default=1, type=lambda value: max(int(value), 1))
parser.add_argument('--cpu_threads', default=cpu_threads, type=lambda value: max(int(value), 1))
parser.add_argument('--help', default=False, action='store_true')
args = parser.parse_args()
if args.help:
parser.print_help()
exit(0)
cpu_threads = args.cpu_threads
args = argparse.Namespace()
successes, errors = main(args=args)
# if successes:
# successes += [""] * 2
# successes += s
# print()
if errors:
with open(f"L:/_Work/Zelda/ROMs/Bug/Automate/{datetime.now().strftime('%y%m%d')}/_error_{datetime.now().strftime('%y%m%d')}.txt", 'a') as stream:
for error in errors:
stream.write("Run at: " + error[0].strftime("%Y-%m-%d %H:%M:%S") + "\n")
stream.write(error[1] + "\n\n")
stream.write("----------------------------------------------------\n")
if successes:
with open(f"L:/_Work/Zelda/ROMs/Bug/Automate/{datetime.now().strftime('%y%m%d')}/_success_{datetime.now().strftime('%y%m%d')}.txt", 'a') as stream:
for success in successes:
stream.write("Run at: " + success[0].strftime("%Y-%m-%d %H:%M:%S") + "\n")
stream.write(success[1] + "\n\n")
stream.write("----------------------------------------------------\n")
# with open(f"L:\\_Work\\Zelda\\ROMs\\Bug\\Automate\\{datetime.now().strftime('%y%m%d')}\\_success.txt", "w") as stream:
# stream.write(str.join("\n", successes))
#conn = sqlite3.connect(f"L:/_Work/Zelda/ROMs/Bug/Automate/{datetime.now().strftime('%y%m%d')}/log.db")
# conn.execute('''CREATE TABLE SEEDGEN
# (SEED INT NOT NULL,
# MYSTERY CHAR(10),
# SETTINGSCODE CHAR(20) NOT NULL,
# VERSION CHAR(10) NOT NULL,
# TIMESTAMP INT NOT NULL,
# SUCCESS INT,
# LOG TEXT);''')
#input("Press enter to continue")
#conn.close()
exit(0)
+330
View File
@@ -0,0 +1,330 @@
import argparse
import concurrent.futures
import csv
import multiprocessing
import subprocess
import sys
from collections import OrderedDict
cpu_threads = multiprocessing.cpu_count()
py_version = f"{sys.version_info.major}.{sys.version_info.minor}"
ALL_SETTINGS = {
'mode': ['open', 'standard', 'inverted'],
'goal': ['ganon', 'pedestal', 'triforcehunt', 'trinity', 'crystals', 'dungeons'],
'swords': ['random', 'swordless', 'assured'],
'shuffle': ['vanilla','simple','restricted','full','dungeonssimple','dungeonsfull','lite','lean','district','swapped','crossed','insanity'],
'shufflelinks': [True, False],
'shuffleganon': [True, False],
'door_shuffle': ['vanilla', 'basic', 'crossed'],
'intensity': ['1','2','3'],
'ow_shuffle': ['vanilla', 'parallel', 'full'],
'ow_fluteshuffle': ['vanilla', 'balanced', 'random'],
'ow_keepsimilar': [True, False],
'ow_mixed': [True, False],
'ow_crossed': [True, False],
'accessibility': [True, False],
'difficulty': [True, False],
'shufflepots': [True, False],
'keydropshuffle': [True, False],
'keysanity': [True, False],
'retro': [True, False],
'bombbag': [True, False],
'shopsanity': [True, False]
}
SETTINGS = {
'mode': ['standard', 'open', 'inverted'],
'goal': ['ganon'],
'swords': ['random'],
'shuffle': ['vanilla',
'dungeonssimple', 'dungeonsfull', 'simple', 'restricted', 'full', 'lite', 'lean', 'district', 'swapped', 'crossed', 'insanity'
],
'shufflelinks': [True, False],
'shuffleganon': [True, False],
'door_shuffle': ['vanilla', 'crossed'],
'intensity': ['2'],
'ow_shuffle': ['vanilla', 'parallel', 'full'],
'ow_fluteshuffle': ['balanced'],
'ow_keepsimilar': [True, False],
'ow_mixed': [True, False],
'ow_crossed': ['none', 'polar', 'grouped', 'unrestricted'],
'accessibility': [True],
'difficulty': [False],
'shufflepots': [False],
'keydropshuffle': [False],
'keysanity': [False],
'retro': [True, False],
'bombbag': [False],
'shopsanity': [True, False]
}
optionsList = []
for sett,options in SETTINGS.items():
for option in options:
if isinstance(option, str):
optionsList.append(f'{option}')
else:
optionsList.append('{}-{}'.format(sett,str(option)))
headerList = list(SETTINGS.keys())
def main(args=None):
successes = []
errors = []
task_mapping = []
tests = OrderedDict()
successes.append(f"Testing {args.ow} with {args.count} Tests" + (f" (intensity={args.tense})" if args.ow in ['basic', 'crossed'] else ""))
print(successes[0])
max_attempts = args.count
pool = concurrent.futures.ThreadPoolExecutor(max_workers=cpu_threads)
dead_or_alive = 0
alive = 0
def test(testname: list, command: str):
tests[' '.join(testname)] = [command]
basecommand = f"py DungeonRandomizer.py --shuffle {args.ow} --suppress_rom --suppress_spoiler"
def gen_seed():
taskcommand = basecommand + ' ' + command
return subprocess.run(taskcommand, capture_output=True, shell=True, text=True)
for _ in range(1, max_attempts + 1):
task = pool.submit(gen_seed)
task.success = False
task.name = ' '.join(testname)
task.settings = testname
task.cmd = basecommand + ' ' + command
task_mapping.append(task)
for mode in SETTINGS['mode']:
for goal in SETTINGS['goal']:
for swords in SETTINGS['swords']:
#for shuffle in SETTINGS['shuffle']:
for ow_shuffle in SETTINGS['ow_shuffle']:
for shufflelinks in SETTINGS['shufflelinks']:
for shuffleganon in SETTINGS['shuffleganon']:
for door_shuffle in SETTINGS['door_shuffle']:
for intensity in SETTINGS['intensity']:
for ow_fluteshuffle in SETTINGS['ow_fluteshuffle']:
for ow_keepsimilar in SETTINGS['ow_keepsimilar']:
for ow_mixed in SETTINGS['ow_mixed']:
for ow_crossed in SETTINGS['ow_crossed']:
for difficulty in SETTINGS['difficulty']:
for shufflepots in SETTINGS['shufflepots']:
for accessibility in SETTINGS['accessibility']:
for keydropshuffle in SETTINGS['keydropshuffle']:
for keysanity in SETTINGS['keysanity']:
for retro in SETTINGS['retro']:
for bombbag in SETTINGS['bombbag']:
for shopsanity in SETTINGS['shopsanity']:
commands = ''
name = []
commands = commands + f' --mode {mode}'
name.append(mode)
commands = commands + f' --goal {goal}'
name.append(goal)
commands = commands + f' --swords {swords}'
name.append(swords)
# if shuffle != 'vanilla': #since this is the output is grouped on this, we only want one of these in the loop
# continue
# commands = commands + f' --shuffle {shuffle}'
# name.append(f'ER{shuffle}')
commands = commands + f' --ow_shuffle {ow_shuffle}'
name.append(ow_shuffle)
if shufflelinks:
commands = commands + f' --shufflelinks'
name.append('shufflelinks-True')
else:
name.append('shufflelinks-False')
if shuffleganon:
commands = commands + f' --shuffleganon'
name.append('shuffleganon-True')
else:
name.append('shuffleganon-False')
commands = commands + f' --door_shuffle {door_shuffle}'
name.append(door_shuffle)
if intensity == '3' and door_shuffle == 'vanilla':
continue
commands = commands + f' --intensity {intensity}'
name.append(intensity)
commands = commands + f' --ow_fluteshuffle {ow_fluteshuffle}'
name.append(ow_fluteshuffle)
if difficulty:
commands = commands + f' --difficulty expert'
commands = commands + f' --item_functionality expert'
name.append('difficulty-True')
else:
name.append('difficulty-False')
if ow_keepsimilar:
commands = commands + f' --ow_keepsimilar'
name.append('ow_keepsimilar-True')
else:
if ow_crossed in ['none', 'polar', 'grouped']:
continue
name.append('ow_keepsimilar-False')
if ow_mixed:
commands = commands + f' --ow_mixed'
name.append('ow_mixed-True')
else:
if ow_crossed == 'polar':
continue
name.append('ow_mixed-False')
commands = commands + f' --ow_crossed {ow_crossed}'
name.append(ow_crossed)
if shufflepots:
commands = commands + f' --shufflepots'
name.append('shufflepots-True')
else:
name.append('shufflepots-False')
if not accessibility:
commands = commands + f' --accessibility none'
name.append('accessibility-False')
else:
name.append('accessibility-True')
if keydropshuffle:
commands = commands + f' --keydropshuffle'
name.append('keydropshuffle-True')
else:
name.append('keydropshuffle-False')
if keysanity:
commands = commands + f' --keysanity'
name.append('keysanity-True')
else:
name.append('keysanity-False')
if retro:
commands = commands + f' --retro'
name.append('retro-True')
else:
name.append('retro-False')
if bombbag:
commands = commands + f' --bombbag'
name.append('bombbag-True')
else:
name.append('bombbag-False')
if shopsanity:
commands = commands + f' --shopsanity'
name.append('shopsanity-True')
else:
name.append('shopsanity-False')
test(name, commands)
# test("Vanilla ", "--futuro --shuffle vanilla")
# test("Basic ", "--futuro --retro --shuffle vanilla")
# test("Keysanity ", "--futuro --shuffle vanilla --keydropshuffle --keysanity")
# test("Simple ", "--futuro --shuffle simple")
# test("Crossed ", "--futuro --shuffle crossed")
# test("Insanity ", "--futuro --shuffle insanity")
# test("CrossKeys ", "--futuro --shuffle crossed --keydropshuffle --keysanity")
from tqdm import tqdm
with tqdm(concurrent.futures.as_completed(task_mapping),
total=len(task_mapping), unit="seed(s)",
desc=f"Success rate: 0.00%") as progressbar:
for task in progressbar:
dead_or_alive += 1
try:
result = task.result()
if result.returncode:
errors.append([task.name, task.cmd, result.stderr])
else:
alive += 1
task.success = True
except Exception as e:
raise e
progressbar.set_description(f"Success rate: {(alive/dead_or_alive)*100:.2f}% - {task.name}")
def get_results(option: str):
result = ""
dead_or_alive = [task.success for task in task_mapping if option in task.settings]
if len(dead_or_alive):
alive = [x for x in dead_or_alive if x]
success = f"{option} Rate: {(len(alive) / len(dead_or_alive)) * 100:.1f}%"
successes.append(success)
print(success)
result += f"{(len(alive)/len(dead_or_alive))*100:.2f}%\t"
else:
success = f"{option} Rate: NULL%"
print(success)
result += f"NULL%\t"
return result.strip()
results = []
for option in optionsList:
results.append(get_results(option))
for result in results:
successes.append(result)
tabresultsfile = './output/' + args.ow + '.tsv'
with open(tabresultsfile, 'w+', newline='') as f:
writer = csv.writer(f, delimiter='\t')
header = headerList.copy()
header.append('Success')
writer.writerow(header)
for task in task_mapping:
settings = []
for option in headerList:
if option in task.settings:
settings.append(1)
elif str(option + '-True') in task.settings:
settings.append(1)
else:
settings.append(0)
if task.success:
settings.append(1)
else:
settings.append(0)
writer.writerow(settings)
return successes, errors
if __name__ == "__main__":
successes = []
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--count', default=0, type=lambda value: max(int(value), 0))
parser.add_argument('--cpu_threads', default=cpu_threads, type=lambda value: max(int(value), 1))
parser.add_argument('--help', default=False, action='store_true')
args = parser.parse_args()
if args.help:
parser.print_help()
exit(0)
cpu_threads = args.cpu_threads
# for ow in [['full', args.count if args.count else 2, 1]]:
# for ow in [['vanilla', args.count if args.count else 2, 1],
# ['parallel', args.count if args.count else 5, 1],
# ['full', args.count if args.count else 10, 1]]:
count = args.count if args.count else 1
for ow in SETTINGS['shuffle']:
for tense in range(1, 2): #ow[2] + 1): #unnecessary when DR is not the root setting
args = argparse.Namespace()
args.ow = ow #ow[0]
args.tense = tense
args.count = count #ow[1]
s, errors = main(args=args)
if successes:
successes += [""] * 2
successes += s
print()
if errors:
with open(f"./output/{ow[0]}{(f'-{tense}' if ow in ['parallel', 'full'] else '')}-errors.txt", 'w+') as stream:
for error in errors:
stream.write(error[0] + "\n")
stream.write(error[1] + "\n")
stream.write(error[2] + "\n\n")
with open("./output/success.txt", "w+") as stream:
stream.write(str.join("\n", successes))
input("Press enter to continue")
+85 -64
View File
@@ -1,7 +1,10 @@
# -*- coding: UTF-8 -*-
from collections import OrderedDict
import logging
import re
import warnings
from collections import OrderedDict
warnings.filterwarnings("ignore", category=SyntaxWarning)
text_addresses = {'Pedestal': (0x180300, 256),
'Triforce': (0x180400, 256),
@@ -96,9 +99,9 @@ Triforce_texts = [
"\n G G",
" All your base\n are belong\n to us.",
" You have ended\n the domination\n of Dr. Wily",
" Thanks for\n playing!!!",
" Thanks for\n playing!!!",
"\n You Win!",
" Thank you!\n Your quest\n is over.",
" Thank you!\n Your quest\n is over.",
" A winner\n is you!",
"\n WINNER!!",
"\n I'm sorry\n\nbut our princess is\n in another castle",
@@ -106,18 +109,18 @@ Triforce_texts = [
" Whelp…\n that just\n happened",
" Oh hey…\n it's you",
"\n Wheeeeee!!",
" Time for\n another one?",
" Time for\n another one?",
" And\n\n scene",
"\n GOT EM!!",
"\n THE VALUUUE!!!",
" Cool seed,\n\n right?",
"\n We did it!",
" Spam those\n emotes in\n wilds chat",
"\n O M G",
"\n O M G",
" Hello. Will you\n you be my friend?",
" Beetorp\n was\n here!",
" The Wind Fish\n will wake soon.\n Hoot!",
" Meow Meow Meow\n Meow Meow Meow\n Oh my god!",
" Meow Meow Meow\n Meow Meow Meow\n Oh My God!",
" Ahhhhhhhhh\n Ya ya yaaaah\n Ya ya yaaah",
" .done\n\n .comment lol",
" You get to\n drink from\n the firehose",
@@ -125,13 +128,14 @@ Triforce_texts = [
" You get one\n wish. Choose\n wisely, hero!",
" Can you please\n break us three\n up? Thanks.",
" Pick us up\n before we\n get dizzy!",
" Thank you,\n Mikey. Youre\n 2 minutes late",
" Thank you,\n Mikey. You're\n 2 minutes late",
" This was a\n 7000 series\n train.",
" I'd buy\n that for\n a rupee!",
" Did you like\n that bow\n placement?",
" I promise the\n next seed will\n be better.",
"\n Honk.",
" Breakfast\n is served!",
"\n send help",
]
BombShop2_texts = ['Bombs!\nBombs!\nBiggest!\nBestest!\nGreatest!\nBoomest!']
Sahasrahla2_texts = ['You already got my item, idiot.', 'Why are you still talking to me?', 'This text won\'t change.', 'Have you met my brother, Hasarahshla?']
@@ -190,7 +194,7 @@ Blind_texts = [
"Gloves open\na handful\nof checks",
"Red mail?\nReturn to\nsender.",
"For sale:\nBaby boots,\nNever found",
"SRL or rtGG?\nI prefer the\nLadder",
"SRL or rtGG?\nI prefer the\nStepladder",
"Ladders are\nalways up\nto something",
"Zelda's\nfashion is\nvery chic",
"Zombie geese\nare waterfoul.\n",
@@ -232,30 +236,37 @@ Ganon_Phase_3_No_Silvers_texts = [
"Did you find\nthe arrows on\nThe Moon?",
"Did you find\nthe arrows\nIn dev null?",
"I have sold\nthe arrows for\na green big 20",
"Did you find\nThe arrows in\nCount Dracula?",
"Did you find\nthe arrows in\nCount Dracula?",
"Error 404\nSilver arrows\nnot found.",
"No arrows for\nYou today,\nSorry",
"No arrows for\nyou today.\nSorry.",
"No arrows?\nCheck your\njunk mail."
"Careful, all\nthat spinning\nmakes me dizzy",
"Did you find\nthe arrows in\nJabu's belly?",
"Silver is not\nan appropriate\narrow material",
"Did you find\nthe arrows in\nNarnia?",
"Are you ready\nTo spin\nTo win?",
"DID YOU FIND\nTHE ARROWS IN\nKEFKA'S TOWER",
"Did you find\nthe arrows in\nRecycle Bin?",
"Did you find\nthe arrows in\nyour Recycle Bin?",
"Silver Arrows?\n\nLUL",
"Imagine\nfinding the\narrows",
"Did you find\nsilvers in\nscenic Ohio?",
"Did you find\nThe arrows in\n*mumblemumble*",
"\nSpin To Win!\n",
"did you find\nthe arrows in\nthe hourglass?",
"Did you find\nthe arrows in\n*mumblemumble*",
"Did you find\nthe arrows in\nthe hourglass?",
"Silver Arrows\nare so v30",
"OH, NO, THEY\nACTUALLY SAID\nSILVER MARROW",
"SURELY THE\nLEFTMOST TILES\nWILL STAY UP",
"Did you find\nthe arrows in\nWorld 4-2?",
"SILLY HERO,\nSILVER IS FOR\nWEREWOLVES!",
"Did you find\nthe silvers in\nGanti's ears",
]
Ganon_Phase_3_No_Weakness_texts = [
"Error 404\nWeakness\nnot found.",
"No weakness\nfor you today.\nSorry",
"Careful, all\nthat spinning\nmakes me dizzy",
"Are you ready\nTo spin\nTo win?",
"\nSpin To Win!\n",
"SURELY THE\nLEFTMOST TILES\nWILL STAY UP",
"You Spin Me\nRight Round\nLike A Record",
"SILLY HERO,\nSILVER IS FOR\nWEREWOLVES!",
"Did you find\nthe silvers in\nganti's ears",
]
TavernMan_texts = [
@@ -339,6 +350,8 @@ junk_texts = [
KingsReturn_texts = [
'Who is this even',
'When did he get here',
'The Harem'
] * 2 + [
"the return of the king",
"fellowship of the ring",
@@ -376,11 +389,10 @@ DeathMountain_texts = [
]
LostWoods_texts = [
'thieves\' stump',
'He\'s got wood',
] * 2 + [
"the forest thief",
"dancing pickles",
"flying vultures",
"flying crows",
]
WishingWell_texts = [
"venus. queen of faeries",
@@ -392,7 +404,7 @@ WishingWell_texts = [
"Venus Love Chain",
"Venus Crescent Beam",
]
DesertPalace_texts = ['vultures rule the desert', 'literacy moves']
DesertPalace_texts = ['vultures rule the desert', 'literacy that moves']
MountainTower_texts = ['the bully makes a friend', 'up up and away']
LinksHouse_texts = ['your uncle recovers', 'Home Sweet Home', 'Only one bed']
Lumberjacks_texts = [
@@ -637,7 +649,7 @@ class MultiByteCoreTextMapper(object):
outbuf = bytearray()
lineindex = 0
is_intro = '{INTRO}' in text
first_line=True
first_line = True
while lines:
linespace = wrap
@@ -668,20 +680,19 @@ class MultiByteCoreTextMapper(object):
outbuf.extend(cls.special_commands[start_command])
word = word.replace(start_command, '')
match = re.search(r'(\{[A-Z0-9_:]+\})\.?$', word)
match = re.search(r'(\{[A-Z0-9_:]+\})$', word)
if match:
end_command = match.group(1)
word = word.replace(end_command, '')
period = word.endswith('.')
else:
end_command, period = None, False
end_command = None
# sanity check: if the word we have is more than 19 characters,
# we take as much as we can still fit and push the rest back for later
if cls.wordlen(word) > wrap:
(word_first, word_rest) = cls.splitword(word, linespace)
if end_command:
word_rest = (word_rest[:-1] + end_command + '.') if period else (word_rest + end_command)
word_rest = word_rest + end_command
words.insert(0, word_rest)
lines.insert(0, ' '.join(words))
@@ -694,16 +705,13 @@ class MultiByteCoreTextMapper(object):
if cls.wordlen(word) < linespace:
pending_space = True
linespace -= cls.wordlen(word) + 1 if pending_space else 0
word_to_map = word[:-1] if period else word
outbuf.extend(RawMBTextMapper.convert(word_to_map))
outbuf.extend(RawMBTextMapper.convert(word))
if end_command:
outbuf.extend(cls.special_commands[end_command])
if period:
outbuf.extend(RawMBTextMapper.convert('.'))
else:
# ran out of space, push word and lines back and continue with next line
if end_command:
word = (word[:-1] + end_command + '.') if period else (word + end_command)
word = word + end_command
words.insert(0, word)
lines.insert(0, ' '.join(words))
break
@@ -840,9 +848,9 @@ class RawMBTextMapper(CharTextMapper):
'': 0xCE,
':': 0xEA,
'@': [0x6A], # Links name (only works if compressed)
'>': [0x00, 0x9B, 0x00, 0x9C], # Link's face
'>': [0x00, 0x9B, 0x00, 0x9C], # Link's face
"'": 0x9D,
'': 0x9D,
'': 0xD8,
'¼': [0x00, 0xE5, 0x00, 0xE7], # ¼ heart
'½': [0x00, 0xE6, 0x00, 0xE7], # ½ heart
'¾': [0x00, 0xE8, 0x00, 0xE9], # ¾ heart
@@ -1308,6 +1316,7 @@ class GoldCreditMapper(CharTextMapper):
class GreenCreditMapper(CharTextMapper):
char_map = {' ': 0x9F,
'.': 0x52,
'·': 0x52}
alpha_offset = -0x29
alpha_lower_offset = -0x29
@@ -1433,6 +1442,7 @@ class TextTable(object):
'item_get_pendant_power',
'item_get_pendant_wisdom',
'item_get_mushroom',
'item_get_book',
'item_get_moonpearl',
'item_get_compass',
'item_get_map', #60
@@ -1449,6 +1459,7 @@ class TextTable(object):
'item_get_bottle',
'item_get_big_key',
'item_get_titans_mitts',
'item_get_magic_mirror',
'item_get_fake_mastersword',
'post_item_get_mastersword',
'item_get_red_potion',
@@ -1647,7 +1658,7 @@ class TextTable(object):
text['sign_east_of_desert'] = CompressedTextMapper.convert("← Desert\n\n It's hot.")
text['sign_east_of_sanctuary'] = CompressedTextMapper.convert("↑→ Potions!\n\nWish waterfall")
text['sign_east_of_castle'] = CompressedTextMapper.convert("→ East Palace\n\n← Castle")
text['sign_north_of_lake'] = CompressedTextMapper.convert("\n Lake Hylia")
text['sign_north_of_lake'] = CompressedTextMapper.convert("\n Lake Hiriah")
text['sign_desert_thief'] = CompressedTextMapper.convert("Don't talk to me or touch my sign!")
text['sign_lumberjacks_house'] = CompressedTextMapper.convert("Lumberjacks, Inc.\nYou see 'em, we saw 'em.")
text['sign_north_kakariko'] = CompressedTextMapper.convert("↓ Kakariko\n Village")
@@ -1671,7 +1682,7 @@ class TextTable(object):
text['item_get_pendant_power'] = CompressedTextMapper.convert("We have the Pendant of Power! How robust!")
text['item_get_pendant_wisdom'] = CompressedTextMapper.convert("We have the Pendant of Wisdom! How astute!")
text['item_get_mushroom'] = CompressedTextMapper.convert("Mushroom! Don't eat it. Find a witch.")
text['item_get_book'] = CompressedTextMapper.convert("This book has a new feature--it can change the state of colored pegs!")
text['item_get_book'] = CompressedTextMapper.convert("Book! Are you well read?")
text['item_get_moonpearl'] = CompressedTextMapper.convert("Moon Pearl! Rabbit Be Gone!")
text['item_get_compass'] = CompressedTextMapper.convert("A compass! I can now find the boss.")
# 60
@@ -1689,7 +1700,7 @@ class TextTable(object):
text['item_get_bottle'] = CompressedTextMapper.convert("Bottle! Store all manner of things")
text['item_get_big_key'] = CompressedTextMapper.convert("Yo! You got a Big Key!")
text['item_get_titans_mitts'] = CompressedTextMapper.convert("Mitts! Lift ALL the rocks!")
text['item_get_magic_mirror'] = CompressedTextMapper.convert("Your Mirror has been upgraded and now works in both worlds!")
text['item_get_magic_mirror'] = CompressedTextMapper.convert("Mirror! Take some time to reflect on this moment!")
text['item_get_fake_mastersword'] = CompressedTextMapper.convert("It's the Master Sword! …or not…\n\n FOOL!")
# 70
text['post_item_get_mastersword'] = CompressedTextMapper.convert("{NOBORDER}\n{SPEED6}\n@, you got the sword!\n{CHANGEMUSIC}\nNow let's go beat up Agahnim!")
@@ -1770,19 +1781,16 @@ class TextTable(object):
text['mastersword_pedestal_translated'] = CompressedTextMapper.convert("A test of strength: If you have 3 pendants, I'm yours.")
text['telepathic_tile_spectacle_rock'] = CompressedTextMapper.convert("{NOBORDER}\n{NOBORDER}\nUse the Mirror, or the Hookshot and Hammer, to get to Tower of Hera!")
text['telepathic_tile_swamp_entrance'] = CompressedTextMapper.convert("{NOBORDER}\nDrain the floodgate to raise the water here!")
text['telepathic_tile_thieves_town_upstairs'] = CompressedTextMapper.convert("{NOBORDER}\nBlind hate's bright light.")
text['telepathic_tile_thieves_town_upstairs'] = CompressedTextMapper.convert("{NOBORDER}\nBlind hates bright light.")
text['telepathic_tile_misery_mire'] = CompressedTextMapper.convert("{NOBORDER}\nLighting 4 torches will open your way forward!")
text['hylian_text_2'] = CompressedTextMapper.convert("%%^= %==%\n ^ =%^=\n==%= ^^%^")
text['desert_entry_translated'] = CompressedTextMapper.convert("Kneel before this stone, and magic will move around you.")
text['telepathic_tile_under_ganon'] = CompressedTextMapper.convert(
" ALTTPR League" \
" Winners\n{HARP}\n\n" \
" ~~~Season 5~~~\n OKDUDES: \n GanonsGoneWild\n Telethar\n Hitsuyan1337\n\n" \
" ~~~Season 4~~~\nThe Titan's Mitts:\n SailorNep\n Relkin\n Daaanty\n\n" \
" ~~~Season 3~~~\nPhenandra Drifters:\n Megawott\n Frostbite3030\n Jet082\n\n" \
" ~~~Season 2~~~\n Team すごい:\n IIYoshiII\n Hitsuyan1337\n Ramond\n\n" \
" ~~~Season 1~~~\n Team すごい:\n IIYoshiII\n Thalane\n Hitsuyan1337\n\n" \
)
text['telepathic_tile_under_ganon'] = CompressedTextMapper.convert("Doors Async League winners\n{HARP}\n"
" ~~~2025~~~\nSchulzer\n\n"
" ~~~2024~~~\nhumbugh\n\n"
" ~~~2023~~~\nEriror\n\n"
" ~~~2022~~~\nAndy\n\n"
" ~~~2021~~~\nprdwong")
text['telepathic_tile_palace_of_darkness'] = CompressedTextMapper.convert("{NOBORDER}\nThis is a funny looking Enemizer")
# C0
text['telepathic_tile_desert_bonk_torch_room'] = CompressedTextMapper.convert("{NOBORDER}\nThings can be knocked down, if you fancy yourself a dashing dude.")
@@ -1792,15 +1800,15 @@ class TextTable(object):
text['telepathic_tile_ice_entrance'] = CompressedTextMapper.convert("{NOBORDER}\nYou can use Fire Rod or Bombos to pass.")
text['telepathic_tile_ice_stalfos_knights_room'] = CompressedTextMapper.convert("{NOBORDER}\nKnock 'em down and then bomb them dead.")
text['telepathic_tile_tower_of_hera_entrance'] = CompressedTextMapper.convert("{NOBORDER}\nThis is a bad place, with a guy who will make you fall…\n\n\na lot.")
text['houlihan_room'] = CompressedTextMapper.convert(
" Crosskeys\n" \
" Tournament\n" \
" Winners\n{HARP}\n" \
" ~~~2022~~~\n Schulzer\n\n" \
" ~~~2021~~~\n Goomba\n\n" \
" ~~~2020~~~\n Linlinlin\n\n" \
" ~~~2019~~~\n Kohrek\n" \
)
text['houlihan_room'] = CompressedTextMapper.convert("Randomizer tournament winners\n{HARP}\n"
" ~~~2025~~~\nGammachuu\n\n"
" ~~~2024~~~\nGammachuu\n\n"
" ~~~2023~~~\nGanonsGoneWild\n\n"
" ~~~2022~~~\nObscure\n\n"
" ~~~2021~~~\nDaaanty\n\n"
" ~~~2019~~~\nJet082\n\n"
" ~~~2018~~~\nAndy\n\n"
" ~~~2017~~~\nA: ajneb174\nS: ajneb174")
text['caught_a_bee'] = CompressedTextMapper.convert("Caught a Bee\n ≥ Keep\n Release\n{CHOICE}")
text['caught_a_fairy'] = CompressedTextMapper.convert("Caught Fairy!\n ≥ Keep\n Release\n{CHOICE}")
text['no_empty_bottles'] = CompressedTextMapper.convert("Whoa, bucko!\nNo empty bottles.")
@@ -1885,13 +1893,18 @@ class TextTable(object):
text['magic_bat_wake'] = CompressedTextMapper.convert("You bum! I was sleeping! Where's my magic bolts?")
text['magic_bat_give_half_magic'] = CompressedTextMapper.convert("How you like me now?")
text['intro_main'] = CompressedTextMapper.convert(
"{INTRO}\n Episode III\n{PAUSE3}\n A Link to\n the Past\n"
+ "{PAUSE3}\n Randomizer\n{PAUSE3}\nAfter mostly disregarding what happened in the first two games.\n"
+ "{PAUSE3}\nLink awakens to his uncle leaving the house.\n{PAUSE3}\nHe just runs out the door,\n"
+ "{PAUSE3}\ninto the rainy night.\n{PAUSE3}\n{CHANGEPIC}\nGanon has moved around all the items in Hyrule.\n"
+ "{PAUSE7}\nYou will have to find all the items necessary to beat Ganon.\n"
+ "{PAUSE7}\nThis is your chance to be a hero.\n{PAUSE3}\n{CHANGEPIC}\n"
+ "You must get the 7 crystals to beat Ganon.\n{PAUSE9}\n{CHANGEPIC}", False)
"{INTRO}\n Episode III"
+ "{PAUSE3}\n A Link to the Past"
+ "{PAUSE3}\n Randomizer"
+ "{PAUSE3}\n\n\n"
+ "{PAUSE3}\nAfter mostly disregarding what happened in the first two games,"
+ "{PAUSE3}\nLink awakens to his uncle leaving the house."
+ "{PAUSE3}\nHe just runs out the door, into the rainy night."
+ "{PAUSE3} {CHANGEPIC}\nGanon has moved around all the items in Hyrule."
+ "{PAUSE7}\nYou will have to find all the items necessary to beat Ganon."
+ "{PAUSE7}\nThis is your chance to be a hero."
+ "{PAUSE3} {CHANGEPIC}\nYou must get the 7 crystals to beat Ganon."
+ "{PAUSE9} {CHANGEPIC}", False)
text['intro_throne_room'] = CompressedTextMapper.convert("{IBOX}\nLook at this Stalfos on the throne.", False)
text['intro_zelda_cell'] = CompressedTextMapper.convert("{IBOX}\nIt is your time to shine!", False)
text['intro_agahnim'] = CompressedTextMapper.convert("{IBOX}\nAlso, you need to defeat this guy!", False)
@@ -2003,7 +2016,7 @@ class TextTable(object):
text['thief_desert_rupee_cave'] = CompressedTextMapper.convert("So you, like, busted down my door, and are being a jerk by talking to me? Normally I would be angry and make you pay for it, but I bet you're just going to break all my pots and steal my 50 rupees.")
text['thief_ice_rupee_cave'] = CompressedTextMapper.convert("I'm a rupee pot farmer. One day I will take over the world with my skillz. Have you met my brother in the desert? He's way richer than I am.")
text['telepathic_tile_south_east_darkworld_cave'] = CompressedTextMapper.convert("~~ dev cave ~~\n no farming\n required")
text['cukeman'] = CompressedTextMapper.convert("Did you hear that Veetorp beat ajneb174 in a 1 on 1 race at AGDQ?")
text['cukeman'] = CompressedTextMapper.convert("Trans rights!")
text['cukeman_2'] = CompressedTextMapper.convert("You found Shabadoo, huh?\nNiiiiice.")
text['potion_shop_no_cash'] = CompressedTextMapper.convert("Yo! I'm not running a charity here.")
text['kakariko_powdered_chicken'] = CompressedTextMapper.convert("Smallhacker…\n\n\nWas hiding, you found me!\n\n\nOkay, you can leave now.")
@@ -2028,7 +2041,14 @@ class TextTable(object):
text['ganon_fall_in_alt'] = CompressedTextMapper.convert("You think you are ready to face me?\n\nI will not die unless you complete your goals. Dingus!")
text['ganon_phase_3_alt'] = CompressedTextMapper.convert("Got wax in your ears? I cannot die!")
# 190
text['sign_east_death_mountain_bridge'] = CompressedTextMapper.convert("Glitched\ntournament\nwinners\n{HARP}\n~~~HMG 2021~~~\nKrithel\n\n~~~OWG 2019~~~\nGlan\n\n~~~OWG 2018~~~\nChristosOwen\nthe numpty")
text['sign_east_death_mountain_bridge'] = CompressedTextMapper.convert("Glitched\ntournament\nwinners\n{HARP}\n"
"~~~HMG 2025~~~\nSkele\n"
"~~~No Logic 2024~~~\ntam\n\n"
"~~~HMG 2023~~~\ntam\n\n"
"~~~No Logic 2022~~~\nChexhuman\n\n"
"~~~HMG 2021~~~\nKrithel\n\n"
"~~~OWG 2019~~~\nGlan\n\n"
"~~~OWG 2018~~~\nChristosOwen\nthe numpty")
text['fish_money'] = CompressedTextMapper.convert("It's a secret to everyone.")
text['sign_ganons_tower'] = CompressedTextMapper.convert("You need all 7 crystals to enter.")
text['sign_ganon'] = CompressedTextMapper.convert("You need all 7 crystals to beat Ganon.")
@@ -2036,6 +2056,7 @@ class TextTable(object):
text['ganon_phase_3_no_silvers_alt'] = CompressedTextMapper.convert("You can't best me without silver arrows!")
text['ganon_phase_3_no_silvers'] = CompressedTextMapper.convert("You can't best me without silver arrows!")
text['ganon_phase_3_silvers'] = CompressedTextMapper.convert("Oh no! Silver! My one true weakness!")
text['murahdahla'] = CompressedTextMapper.convert("Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n{PAUSE3}\n… … …\nWait! you can see me? I knew I should have\nhidden in a hollow tree.")
text['murahdahla'] = CompressedTextMapper.convert("Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n{PAUSE3}\n… … …\nWait! You can see me? I knew I should have\nhidden in a hollow tree.")
text['mastersword_pedestal_goal'] = CompressedTextMapper.convert("To claim thy reward, you must present all 3 Pendants of Virtue.")
text['end_pad_data'] = bytearray([0xfb])
text['terminator'] = bytearray([0xFF, 0xFF])
+372
View File
@@ -0,0 +1,372 @@
import functools
import Rules
from BaseClasses import Door, DoorType, Entrance
from DoorShuffle import connect_simple_door
kikiskip_spots = [
("Kiki Skip", "Spectacle Rock Cave (Bottom)", "Palace of Darkness Portal")
]
mirehera_spots = [("Mire to Hera Clip", "Mire Torches Top", "Hera Portal")]
heraswamp_spots = [("Hera to Swamp Clip", "Mire Torches Top", "Swamp Portal")]
icepalace_spots = [("Ice Lobby Clip", "Ice Lobby", "Ice Bomb Drop - Top")]
thievesdesert_spots = [
("Thieves to Desert West Clip", "Thieves Attic", "Desert West Portal"),
("Thieves to Desert South Clip", "Thieves Attic", "Desert South Portal"),
("Thieves to Desert East Clip", "Thieves Attic", "Desert East Portal"),
]
specrock_spots = [
("Spec Rock Clip", "Spectacle Rock Cave (Peak)", "Spectacle Rock Cave (Top)")
]
paradox_spots = [
("Paradox Front Teleport", "Paradox Cave Front", "Paradox Cave Chest Area")
]
def create_hmg_entrances_regions(world, player):
for spots in [
kikiskip_spots,
mirehera_spots,
heraswamp_spots,
icepalace_spots,
thievesdesert_spots,
specrock_spots,
paradox_spots,
]:
for entrance, parent_region, _, *_ in spots:
parent = world.get_region(parent_region, player)
connection = Entrance(player, entrance, parent)
connection.spot_type = 'HMG'
if connection not in parent.exits:
parent.exits.append(connection)
ip_bomb_top_reg = world.get_region("Ice Bomb Drop - Top", player)
ip_clip_entrance = Entrance(player, "Ice Bomb Drop Clip", ip_bomb_top_reg)
ip_bomb_top_reg.exits.append(ip_clip_entrance)
def connect_hmg_entrances_regions(world, player):
for spots in [
kikiskip_spots,
mirehera_spots,
heraswamp_spots,
icepalace_spots,
thievesdesert_spots,
specrock_spots,
paradox_spots,
]:
for entrance, _, target_region, *_ in spots:
connection = world.get_entrance(entrance, player)
if world.fix_fake_world[player] and target_region.endswith(" Portal"):
target = world.get_portal(target_region[:-7], player).find_portal_entrance().parent_region
else:
target = world.get_region(target_region, player)
connection.connect(target)
# Add the new Ice path (back of bomb drop to front) to the world and model it properly
ip_clip_entrance = world.get_entrance('Ice Bomb Drop Clip', player)
clip_door = Door(player, "Ice Bomb Drop Clip", DoorType.Logical, ip_clip_entrance)
world.doors += [clip_door]
world.initialize_doors([clip_door])
connect_simple_door(world, "Ice Bomb Drop Clip", "Ice Bomb Drop", player)
# For some entrances, we need to fake having pearl, because we're in fake DW/LW.
# This creates a copy of the input state that has Moon Pearl.
def fake_pearl_state(state, player):
if state.has("Moon Pearl", player):
return state
fake_state = state.copy()
fake_state.prog_items["Moon Pearl", player] += 1
return fake_state
# Sets the rules on where we can actually go using this clip.
# Behavior differs based on what type of ER shuffle we're playing.
def dungeon_reentry_rules(
world,
player,
clip: Entrance,
dungeon_region: str,
):
fix_dungeon_exits = world.fix_palaceofdarkness_exit[player]
fix_fake_worlds = world.fix_fake_world[player]
all_clips = [
x[0]
for x in kikiskip_spots
+ mirehera_spots
+ heraswamp_spots
+ icepalace_spots
+ thievesdesert_spots
+ specrock_spots
+ paradox_spots
]
dungeon_entrance = [
r
for r in world.get_region(dungeon_region, player).entrances
if r.name not in all_clips
][0]
dungeon_exit = [
r
for r in world.get_region(dungeon_region, player).exits
if r.name not in all_clips
][0]
if not fix_dungeon_exits:
# vanilla, simple, restricted, dungeonssimple; should never have fake worlds fix
# Dungeons are only shuffled among themselves. We need to check SW, MM, and AT because they can't be reentered trivially.
# entrance doesn't exist until you fire rod it from the other side
if dungeon_entrance.name == "Skull Woods Final Section":
Rules.set_rule(clip, lambda state: False)
elif dungeon_entrance.name == "Misery Mire":
if world.swords[player] == "swordless":
Rules.add_rule(
clip, lambda state: state.has_misery_mire_medallion(player)
)
else:
Rules.add_rule(
clip,
lambda state: state.has_sword(player)
and state.has_misery_mire_medallion(player),
)
elif dungeon_entrance.name == "Agahnims Tower":
Rules.add_rule(
clip,
lambda state: state.has("Cape", player)
or state.has_beam_sword(player)
or state.has("Beat Agahnim 1", player),
)
# Then we set a restriction on exiting the dungeon, so you can't leave unless you got in normally.
Rules.add_rule(
world.get_entrance(dungeon_exit, player),
lambda state: dungeon_entrance.can_reach(state),
)
elif (
not fix_fake_worlds
): # full, dungeonsfull; fixed dungeon exits, but no fake worlds fix
# Entry requires the entrance's requirements plus a fake pearl, but you don't gain logical access to the surrounding region.
Rules.add_rule(
clip,
lambda state: dungeon_entrance.access_rule(fake_pearl_state(state, player)),
)
# exiting restriction
Rules.add_rule(
world.get_entrance(dungeon_exit, player),
lambda state: dungeon_entrance.can_reach(state),
)
# Otherwise, the shuffle type is lean, lite, crossed, or insanity; all of these do not need additional rules on where we can go,
# since the clip links directly to the exterior region.
def underworld_glitches_rules(world, player):
def mire_clip(state):
torches = world.get_region("Mire Torches Top", player)
return (state.can_dash_clip(torches, player)
or (state.can_bomb_clip(torches, player) and state.has_fire_source(player))
) and state.can_reach(torches, player)
def hera_clip(state):
hera = world.get_region("Hera 4F", player)
return (state.can_bomb_clip(hera, player) or state.can_dash_clip(hera, player)) \
and state.has("Flippers", player) and state.can_reach(hera) and mire_clip(state)
# We use these plus functool.partial because lambdas don't work in loops properly.
def bomb_clip(state, region, player):
return state.can_bomb_clip(region, player) and state.can_reach(region, player)
def dash_clip(state, region, player):
return state.can_dash_clip(region, player) and state.can_reach(region, player)
# Bomb clips
for clip in (
kikiskip_spots
+ icepalace_spots
+ thievesdesert_spots
+ specrock_spots
):
region = world.get_region(clip[1], player)
Rules.set_rule(
world.get_entrance(clip[0], player),
functools.partial(bomb_clip, region=region, player=player),
)
# Dash clips
for clip in icepalace_spots:
region = world.get_region(clip[1], player)
Rules.add_rule(
world.get_entrance(clip[0], player),
functools.partial(dash_clip, region=region, player=player),
combine="or",
)
for spot in kikiskip_spots + thievesdesert_spots:
dungeon_reentry_rules(
world,
player,
world.get_entrance(spot[0], player),
spot[2],
)
for clip in mirehera_spots:
Rules.set_rule(
world.get_entrance(clip[0], player),
lambda state: mire_clip(state),
)
# Need to be able to escape by hitting the switch from the back
Rules.set_rule(
world.get_entrance("Ice Bomb Drop Clip", player),
lambda state: (
state.can_use_bombs(player) or state.has("Cane of Somaria", player)
),
)
# Allow mire big key to be used in Hera
Rules.add_rule(
world.get_entrance("Hera Startile Corner NW", player),
lambda state: state.has("Big Key (Misery Mire)", player) and mire_clip(state),
combine="or",
)
Rules.add_rule(
world.get_location("Tower of Hera - Big Chest", player),
lambda state: state.has("Big Key (Misery Mire)", player) and mire_clip(state),
combine="or",
)
# This uses the mire clip because it's always expected to come from mire
Rules.set_rule(
world.get_entrance("Hera to Swamp Clip", player),
lambda state: state.has("Flippers", player) and mire_clip(state),
)
Rules.add_rule(
world.get_location("Swamp Palace - Big Chest", player),
lambda state: (state.has("Big Key (Misery Mire)", player) or state.has("Big Key (Tower of Hera)", player)) \
and state.has("Flippers", player) and mire_clip(state),
combine="or",
)
# We need to set _all_ swamp doors to be openable with mire keys, otherwise the small key can't be behind them - 6 keys because of Pots
# Flippers required for all of these doors to prevent locks when flooding
for door in [
"Swamp Trench 1 Approach ES",
"Swamp Hammer Switch SW",
"Swamp Entrance Down Stairs",
"Swamp Pot Row WS",
"Swamp Trench 1 Key Ledge NW",
"Swamp Hub WN",
"Swamp Hub North Ledge N",
"Swamp Crystal Switch EN",
"Swamp Push Statue S",
"Swamp Waterway NW",
"Swamp T SW",
]:
Rules.add_rule(
world.get_entrance(door, player),
lambda state: state.has("Flippers", player)
and state.has("Small Key (Misery Mire)", player, count=6)
and mire_clip(state),
combine="or",
)
Rules.add_rule(
world.get_location("Trench 1 Switch", player),
lambda state: mire_clip(state) or hera_clip(state),
combine="or",
)
# Build the rule for SP moat.
# We need to be able to s+q to old man, then go to either Mire or Hera at either Hera or GT.
# First we require a certain type of entrance shuffle, then build the rule from its pieces.
if not world.swamp_patch_required[player] and world.shuffle[player] in [
"vanilla",
"dungeonssimple",
"dungeonsfull",
]:
rule_map = {
"Mire Portal": (
lambda state: state.can_reach("Mire Torches Top", "Entrance", player)
),
"Hera Portal": (
lambda state: state.can_reach(
"Hera Startile Corner NW", "Entrance", player
)
),
}
inverted_dm = (world.mode[player] == "inverted") != world.is_tile_swapped(0x03, player)
def hera_rule(state):
return (state.has("Moon Pearl", player) or not inverted_dm) and rule_map.get(
world.get_entrance("Tower of Hera", player).connected_region.name,
lambda state: False,
)(state)
def gt_rule(state):
return (state.has("Moon Pearl", player) or inverted_dm) and rule_map.get(
world.get_entrance(("Ganons Tower"), player).connected_region.name,
lambda state: False,
)(state)
def mirrorless_moat_rule(state):
return (
state.can_reach("Old Man S&Q", "Entrance", player)
and state.has("Flippers", player)
and (hera_rule(state) or gt_rule(state))
and mire_clip(state)
)
Rules.add_rule(
world.get_entrance("Swamp Lobby Moat", player),
lambda state: mirrorless_moat_rule(state),
combine="or",
)
desert_exits = ["West", "South", "East"]
for desert_exit in desert_exits:
Rules.add_rule(
world.get_entrance(f"Thieves to Desert {desert_exit} Clip", player),
lambda state: state.can_dash_clip(
world.get_region("Thieves Attic", player), player
),
)
# Collecting left chests in Paradox Cave using a dash clip -> dash citrus, 1f right, teleport up
paradox_left_chests = [
"Paradox Cave Lower - Far Left",
"Paradox Cave Lower - Left",
"Paradox Cave Lower - Middle",
]
for location in paradox_left_chests:
Rules.add_rule(
world.get_location(location, player),
lambda state: state.can_dash_clip(
world.get_location(location, player).parent_region, player
),
"or",
)
# Collecting right chests in Paradox Cave using a dash clip on left side -> dash citrus, 1f right, teleport up, then hitting the switch
paradox_right_chests = [
"Paradox Cave Lower - Right",
"Paradox Cave Lower - Far Right",
]
for location in paradox_right_chests:
Rules.add_rule(
world.get_location(location, player),
lambda state: (
state.can_dash_clip(
world.get_location(location, player).parent_region, player
)
and state.can_hit_crystal(player)
),
"or",
)
+742 -62
View File
@@ -1,82 +1,90 @@
#!/usr/bin/env python3
import fileinput
import os
import re
import subprocess
import sys
import urllib.parse
import urllib.request
import xml.etree.ElementTree as ET
from collections import defaultdict
from hashlib import md5
from itertools import count
from math import factorial
from pathlib import Path
import yaml
def int16_as_bytes(value):
value = value & 0xFFFF
return [value & 0xFF, (value >> 8) & 0xFF]
def int24_as_bytes(value):
value = value & 0xFFFFFF
return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF]
def int32_as_bytes(value):
value = value & 0xFFFFFFFF
return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF]
def pc_to_snes(value):
return ((value<<1) & 0x7F0000)|(value & 0x7FFF)|0x8000
return ((value << 1) & 0x7F0000) | (value & 0x7FFF) | 0x8000
def snes_to_pc(value):
return ((value & 0x7F0000)>>1)|(value & 0x7FFF)
return ((value & 0x7F0000) >> 1) | (value & 0x7FFF)
def parse_player_names(names, players, teams):
names = [n for n in re.split(r'[, ]', names) if n]
ret = []
while names or len(ret) < teams:
team = [n[:16] for n in names[:players]]
while len(team) != players:
team.append(f"Player {len(team) + 1}")
ret.append(team)
names = names[players:]
return ret
def is_bundled():
return getattr(sys, 'frozen', False)
def count_set_bits(val):
if val == 0:
return 0
else:
return (val & 1) + count_set_bits(val >> 1)
def local_path(path):
# just do stuff here and bail
return os.path.join(".", 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 = sys._MEIPASS # pylint: disable=protected-access,no-member
else:
# we are running in a normal Python environment
local_path.cached_path = os.path.dirname(os.path.abspath(__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():
if output_path.cached_path is None:
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
return os.path.join(output_path.cached_path, path)
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, 'ALttPEntranceRandomizer')
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 open_file(filename):
if sys.platform == 'win32':
os.startfile(filename)
@@ -84,40 +92,712 @@ def open_file(filename):
open_command = 'open' if sys.platform == 'darwin' else 'xdg-open'
subprocess.call([open_command, filename])
def close_console():
if sys.platform == 'win32':
#windows
# windows
import ctypes.wintypes
try:
ctypes.windll.kernel32.FreeConsole()
except Exception:
pass
def make_new_base2current(old_rom='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc', new_rom='working.sfc'):
from collections import OrderedDict
import json
import hashlib
with open(old_rom, 'rb') as stream:
old_rom_data = bytearray(stream.read())
def get_new_romhash(new_rom='working.sfc'):
with open(new_rom, 'rb') as stream:
new_rom_data = bytearray(stream.read())
# extend to 2 mb
old_rom_data.extend(bytearray([0x00] * (2097152 - len(old_rom_data))))
out_data = OrderedDict()
for idx, old in enumerate(old_rom_data):
new = new_rom_data[idx]
if old != new:
out_data[idx] = [int(new)]
for offset in reversed(list(out_data.keys())):
if offset - 1 in out_data:
out_data[offset-1].extend(out_data.pop(offset))
with open('data/base2current.json', 'wt') as outfile:
json.dump([{key:value} for key, value in out_data.items()], outfile, separators=(",", ":"))
basemd5 = hashlib.md5()
basemd5 = md5()
basemd5.update(new_rom_data)
return "New Rom Hash: " + basemd5.hexdigest()
return basemd5.hexdigest()
def kth_combination(k, l, r):
if r == 0:
return []
elif len(l) == r:
return l
else:
i = ncr(len(l)-1, r-1)
if k < i:
return l[0:1] + kth_combination(k, l[1:], r-1)
else:
return kth_combination(k-i, l[1:], r)
def ncr(n, r):
if r == 0 or r >= n:
return 1
return factorial(n) // factorial(r) // factorial(n-r)
entrance_offsets = {
'Sanctuary': 0x2,
'HC West': 0x3,
'HC South': 0x4,
'HC East': 0x5,
'Eastern': 0x8,
'Desert West': 0x9,
'Desert South': 0xa,
'Desert East': 0xb,
'Desert Back': 0xc,
'TR Lazy Eyes': 0x15,
'TR Eye Bridge': 0x18,
'TR Chest': 0x19,
'Aga Tower': 0x24,
'Swamp': 0x25,
'Palace of Darkness': 0x26,
'Mire': 0x27,
'Skull 2 West': 0x28,
'Skull 2 East': 0x29,
'Skull 1': 0x2a,
'Skull 3': 0x2b,
'Ice': 0x2d,
'Hera': 0x33,
'Thieves': 0x34,
'TR Main': 0x35,
'GT': 0x37,
'Skull Pots': 0x76,
'Skull Left Drop': 0x77,
'Skull Pinball': 0x78,
'Skull Back Drop': 0x79,
'Sewer Drop': 0x81
}
entrance_data = {
'Room Ids': (0x14577, 2),
'Relative coords': (0x14681, 8),
'ScrollX': (0x14AA9, 2),
'ScrollY': (0x14BB3, 2),
'LinkX': (0x14CBD, 2),
'LinkY': (0x14DC7, 2),
'CameraX': (0x14ED1, 2),
'CameraY': (0x14FDB, 2),
'Blockset': (0x150e5, 1),
'FloorValues': (0x1516A, 1),
'Dungeon Value': (0x151EF, 1),
'Frame on Exit': (0x15274, 1),
'BG Setting': (0x152F9, 1),
'HV Scroll': (0x1537E, 1),
'Scroll Quad': (0x15403, 1),
'Exit Door': (0x15488, 2),
'Music': (0x15592, 1)
}
def read_layout_data(old_rom='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc'):
with open(old_rom, 'rb') as stream:
old_rom_data = bytearray(stream.read())
string = ''
for room in range(0, 0xff+1):
# print(ent)
pointer_start = 0xf8000+room*3
highbyte = old_rom_data[pointer_start+2]
midbyte = old_rom_data[pointer_start+1]
midbyte = midbyte - 0x80 if highbyte % 2 == 0 else midbyte
pointer = highbyte // 2 * 0x10000
pointer += midbyte * 0x100
pointer += old_rom_data[pointer_start]
layout_byte = old_rom_data[pointer+1]
layout = (layout_byte & 0x1c) >> 2
string += hex(room) + ':' + str(layout) + '\n'
print(string)
def read_entrance_data(old_rom='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc'):
with open(old_rom, 'rb') as stream:
old_rom_data = bytearray(stream.read())
for ent, offset in entrance_offsets.items():
# print(ent)
string = ent
for dp, data in entrance_data.items():
byte_array = []
address, size = data
for i in range(0, size):
byte_array.append(old_rom_data[address+(offset*size)+i])
some_bytes = ', '.join('0x{:02x}'.format(x) for x in byte_array)
string += '\t'+some_bytes
# print("%s: %s" % (dp, bytes))
print(string)
def room_palette_data(old_rom):
with open(old_rom, 'rb') as stream:
old_rom_data = bytearray(stream.read())
offset = defaultdict(list)
for i in range(0, 256):
pointer_offset = 0x0271e2+i*2
header_offset = old_rom_data[pointer_offset + 1] << 8
header_offset += old_rom_data[pointer_offset]
header_offset -= 0x8000
header_offset += 0x020000
offset[header_offset].append(i)
# print(f'{hex(i)}: {hex(old_rom_data[header_offset+1])}')
for header_offset, rooms in offset.items():
print(f'{hex(header_offset)}: {[hex(x) for x in rooms]}')
# Palette notes:
# HC: 0
# Sewer/Dungeon: 1
# AT: 0xc near boss, 0x0 (other) 26 (f4, f1)
# Sanc: 0x1d
# Hera: 0x6
# Desert: 0x4 (boss and near boss), 0x9 (desert tiles 1 + desert main)
# Eastern: 0xb
# Pod: 0xf, x10 (boss)
# Swamp: 0x8 (boss), 0xa (other)
# Skull: 0xe (boss), 0xd (other)
# TT: 0x17, 0x23 (attic)
# Ice: 0x13, 0x14 (boss)
# Mire: 0x11 (other) , 0x12 (boss/preroom)
# TR: 0x18, 0x19 (boss+pre)
# GT: 0x28 (entrance + B1), 0x1a (other) 0x24 (Gauntlet - Lanmo) 0x25 (conveyor-torch-wizzrode moldorm pit f5?)
# Aga2: 0x1b, 0x1b (Pre aga2)
# Caves: 0x7, 0x20
# Uncle: 0x1
# Ganon: 0x21
# Houses: 0x2
def print_wiki_doors_by_region(d_regions, world, player):
for d, region_list in d_regions.items():
tile_map = {}
for region in region_list:
tile = None
r = world.get_region(region, player)
for ext in r.exits:
door = world.check_for_door(ext.name, player)
if door is not None and door.roomIndex != -1:
tile = door.roomIndex
break
if tile is not None:
if tile not in tile_map:
tile_map[tile] = []
tile_map[tile].append(r)
toprint = ""
toprint += ('<!-- ' + d + ' -->') + "\n"
toprint += ('== Room List ==') + "\n"
toprint += "\n"
toprint += ('{| class="wikitable"') + "\n"
toprint += ('|-') + "\n"
toprint += ('! Room !! Supertile !! Doors') + "\n"
for tile, region_list in tile_map.items():
tile_done = False
for region in region_list:
toprint += ('|-') + "\n"
toprint += ('| {{Dungeon Room|{{PAGENAME}}|' + region.name + '}}') + "\n"
if not tile_done:
listlen = len(region_list)
link = '| {{UnderworldMapLink|'+str(tile)+'}}'
toprint += (link if listlen < 2 else '| rowspan = '+str(listlen)+' '+link) + "\n"
tile_done = True
strs_to_print = []
for ext in region.exits:
strs_to_print.append('{{Dungeon Door|{{PAGENAME}}|' + ext.name + '}}')
toprint += ('| '+'<br />'.join(strs_to_print))
toprint += "\n"
toprint += ('|}') + "\n"
with open(os.path.join(".", "resources", "user", "regions-" + d + ".txt"), "w+") as f:
f.write(toprint)
def update_deprecated_args(args):
if args:
argVars = vars(args)
truthy = [1, True, "True", "true"]
if "multi" in argVars:
players = int(args.multi)
else:
players = 1
# Hints default to FALSE
# Don't do: Yes
# Do: No
if "no_hints" in argVars:
if args.no_hints in truthy:
if isinstance(argVars["hints"], dict):
tmp = {}
for idx in range(1, len(argVars["hints"]) + 1):
tmp[idx] = False
args.hints = tmp
else:
args.hints = False
# Spoiler defaults to TRUE
# Don't do: Yes
# Do: No
if "suppress_spoiler" in argVars:
args.spoiler = 'none'
# Don't do: No
# Do: Yes
if "create_spoiler" in argVars:
args.spoiler = 'full'
# ROM defaults to TRUE
# Don't do: Yes
# Do: No
if "suppress_rom" in argVars:
args.create_rom = not args.suppress_rom in truthy
# Don't do: No
# Do: Yes
if "create_rom" in argVars:
args.suppress_rom = not args.create_rom in truthy
# Shuffle Ganon defaults to TRUE
# Don't do: Yes
# Do: No
if "no_shuffleganon" in argVars:
if isinstance(args.shuffleganon, dict):
for player in range(1, players + 1):
args.shuffleganon[player] = not args.no_shuffleganon in truthy
else:
args.shuffleganon = not args.no_shuffleganon in truthy
# OW Parallel defaults to TRUE
# Don't do: Yes
# Do: No
if "ow_unparallel" in argVars:
if isinstance(args.ow_parallel, dict):
for player in range(1, players + 1):
args.ow_parallel[player] = not args.ow_unparallel in truthy
else:
args.ow_parallel = not args.ow_unparallel in truthy
# OW Fog defaults to TRUE
# Don't do: Yes
# Do: No
if "ow_no_fog" in argVars:
if isinstance(args.ow_fog, dict):
for player in range(1, players + 1):
args.ow_fog[player] = not args.ow_no_fog in truthy
else:
args.ow_fog = not args.ow_no_fog in truthy
# Playthrough defaults to TRUE
# Don't do: Yes
# Do: No
if "skip_playthrough" in argVars:
args.calc_playthrough = not args.skip_playthrough in truthy
# Don't do: No
# Do: Yes
if "calc_playthrough" in argVars:
args.skip_playthrough = not args.calc_playthrough in truthy
return args
def print_wiki_doors_by_room(d_regions, world, player):
for d, region_list in d_regions.items():
tile_map = {}
for region in region_list:
tile = None
r = world.get_region(region, player)
for ext in r.exits:
door = world.check_for_door(ext.name, player)
if door is not None and door.roomIndex != -1:
tile = door.roomIndex
break
if tile is not None:
if tile not in tile_map:
tile_map[tile] = []
tile_map[tile].append(r)
toprint = ""
toprint += ('<!-- ' + d + ' -->') + "\n"
for tile, region_list in tile_map.items():
for region in region_list:
toprint += ('<!-- ' + region.name + ' -->') + "\n"
toprint += ('{{Infobox dungeon room') + "\n"
toprint += ('| dungeon = {{ROOTPAGENAME}}') + "\n"
toprint += ('| supertile = ' + str(tile)) + "\n"
toprint += ('| tile = x') + "\n"
toprint += ('}}') + "\n"
toprint += ('') + "\n"
toprint += ('== Doors ==') + "\n"
toprint += ('{| class="wikitable"') + "\n"
toprint += ('|-') + "\n"
toprint += ('! Door !! Room Side !! Requirement') + "\n"
for ext in region.exits:
ext_part = ext.name.replace(region.name, '')
ext_part = ext_part.strip()
toprint += ('{{DungeonRoomDoorList/Row|{{ROOTPAGENAME}}|{{SUBPAGENAME}}|' + ext_part + '|Side|}}') + "\n"
toprint += ('|}') + "\n"
toprint += ('') + "\n"
with open(os.path.join(".", "resources", "user", "rooms-" + d + ".txt"), "w+") as f:
f.write(toprint)
def print_xml_doors(d_regions, world, player):
root = ET.Element('root')
for d, region_list in d_regions.items():
tile_map = {}
for region in region_list:
tile = None
r = world.get_region(region, player)
for ext in r.exits:
door = world.check_for_door(ext.name, player)
if door is not None and door.roomIndex != -1:
tile = door.roomIndex
break
if tile is not None:
if tile not in tile_map:
tile_map[tile] = []
tile_map[tile].append(r)
dungeon = ET.SubElement(root, 'dungeon', {'name': d})
for tile, r_list in tile_map.items():
supertile = ET.SubElement(dungeon, 'supertile', {'id': str(tile)})
for region in r_list:
room = ET.SubElement(supertile, 'room', {'name': region.name})
for ext in region.exits:
ET.SubElement(room, 'door', {'name': ext.name})
ET.dump(root)
def print_graph(world):
root = ET.Element('root')
for region in world.regions:
r = ET.SubElement(root, 'region', {'name': region.name})
for ext in region.exits:
attribs = {'name': ext.name}
if ext.connected_region:
attribs['connected_region'] = ext.connected_region.name
if ext.door and ext.door.dest:
attribs['dest'] = ext.door.dest.name
ET.SubElement(r, 'exit', attribs)
ET.dump(root)
def extract_data_from_us_rom(rom):
with open(rom, 'rb') as stream:
rom_data = bytearray(stream.read())
rooms = [0x1c, 0x1d, 0x4e]
# rooms = [0x9a, 0x69, 0x78, 0x79, 0x7a, 0x88, 0x8a, 0xad]
for room in rooms:
b2idx = room*2
b3idx = room*3
headerptr = 0x110000 + b2idx # zscream specific
headerloc = rom_data[headerptr] + rom_data[headerptr+1]*0x100 + 0x108000 # zscream specific
header, objectdata, spritedata, secretdata = [], [], [], []
for i in range(0, 14):
header.append(rom_data[headerloc+i])
objectptr = 0xF8000 + b3idx
objectloc = rom_data[objectptr] + rom_data[objectptr+1]*0x100 + rom_data[objectptr+2]*0x10000
bank = rom_data[objectptr+2]
even = bank % 2 == 0
adjustment = ((bank // 2 if even else bank // 2 + 1) << 16) + (0x8000 if even else 0)
objectloc -= adjustment
stop, idx = False, 0
ffcnt = 0
mode = 0
# first two bytes
b1 = rom_data[objectloc+idx]
b2 = rom_data[objectloc+idx+1]
objectdata.append(b1)
objectdata.append(b2)
idx += 2
while ffcnt < 3:
b1 = rom_data[objectloc+idx]
b2 = rom_data[objectloc+idx+1]
b3 = rom_data[objectloc+idx+2]
objectdata.append(b1)
objectdata.append(b2)
if b1 == 0xff and b2 == 0xff:
ffcnt += 1
mode = 0
idx += 2
elif b1 == 0xf0 and b2 == 0xff:
mode = 1
idx += 2
elif not mode and ffcnt < 3:
objectdata.append(b3)
idx += 3
else:
idx += 2
spriteptr = 0x4d62e + b2idx
spriteloc = rom_data[spriteptr] + rom_data[spriteptr+1]*0x100 + 0x40000
done, idx = False, 0
while not done:
b1 = rom_data[spriteloc+idx]
spritedata.append(b1)
if b1 == 0xff:
done = True
idx += 1
secretptr = 0xdb69 + b2idx
secretloc = rom_data[secretptr] + rom_data[secretptr+1]*0x100
done, idx = False, 0
while not done:
b1 = rom_data[secretloc+idx]
b2 = rom_data[secretloc+idx+1]
b3 = rom_data[secretloc+idx+2]
secretdata.append(b1)
secretdata.append(b2)
if b1 == 0xff and b2 == 0xff:
done = True
else:
secretdata.append(b3)
idx += 3
print(f'Room {room:02x}')
print(f'db {",".join([f"${x:02x}" for x in header])}')
print(f'Obj Length: {len(objectdata)}')
print_data_block(objectdata)
print('Sprites')
print_data_block(spritedata)
print('Secrets')
print_data_block(secretdata)
blockdata, torchdata = [], []
blockloc = 0x271de
for i in range(0, 128):
idx = i*4
b1 = rom_data[blockloc+idx]
b2 = rom_data[blockloc+idx+1]
room_idx = b1 + b2*0x100
if room_idx in rooms:
blockdata.append(b1)
blockdata.append(b2)
blockdata.append(rom_data[blockloc+idx+2])
blockdata.append(rom_data[blockloc+idx+3])
torchloc = 0x2736A
nomatch = False
append = False
for i in range(0, 192):
idx = i*2
b1 = rom_data[torchloc+idx]
b2 = rom_data[torchloc+idx+1]
if nomatch:
if b1 == 0xff and b2 == 0xff:
nomatch = False
elif not append:
room_idx = b1 + b2*0x100
if room_idx in rooms:
append = True
else:
nomatch = True
if append:
torchdata.append(b1)
torchdata.append(b2)
if b1 == 0xff and b2 == 0xff:
append = False
print('Blocks')
print_data_block(blockdata)
print('Torches')
print_data_block(torchdata)
print()
def print_data_block(block):
for i in range(0, len(block)//16 + 1):
slice = block[i*16:i*16+16]
print(f'db {",".join([f"${x:02x}" for x in slice])}')
def extract_data_from_jp_rom(rom):
with open(rom, 'rb') as stream:
rom_data = bytearray(stream.read())
rooms = range(0, 0x128)
# rooms = [0x7b, 0x7c, 0x7d, 0x8b, 0x8c, 0x8d, 0x9b, 0x9c, 0x9d]
# rooms = [0x1a, 0x2a, 0xd1]
for room in rooms:
# print(f'Room {room:02x}')
b2idx = room*2
b3idx = room*3
headerptr = 0x271e2 + b2idx
headerloc = rom_data[headerptr] + rom_data[headerptr+1]*0x100 + 0x18000
header, objectdata, spritedata, secretdata = [], [], [], []
for i in range(0, 14):
header.append(rom_data[headerloc+i])
objectptr = 0xF8000 + b3idx
objectloc = rom_data[objectptr] + rom_data[objectptr+1]*0x100 + rom_data[objectptr+2]*0x10000
bank = rom_data[objectptr+2]
even = bank % 2 == 0
adjustment = ((bank // 2 if even else bank // 2 + 1) << 16) + (0x8000 if even else 0)
objectloc -= adjustment
stop, idx = False, 0
ffcnt = 0
mode = 0
secret_cnt = 0
# first two bytes
b1 = rom_data[objectloc+idx]
b2 = rom_data[objectloc+idx+1]
objectdata.append(b1)
objectdata.append(b2)
idx += 2
while ffcnt < 3:
b1 = rom_data[objectloc+idx]
b2 = rom_data[objectloc+idx+1]
b3 = rom_data[objectloc+idx+2]
objectdata.append(b1)
objectdata.append(b2)
if b1 == 0xff and b2 == 0xff:
ffcnt += 1
mode = 0
idx += 2
elif b1 == 0xf0 and b2 == 0xff:
mode = 1
idx += 2
elif not mode and ffcnt < 3:
objectdata.append(b3)
if b3 == 0xFA and ((b2 & 0x3) << 2) | (b1 & 0x3) in [0xf, 0xc]:
# potcalc
vram = ((b1 & 0xFC) >> 1) | ((b2 & 0xFC) << 5)
low = vram & 0xFF
high = (vram & 0xFF00) >> 8
if ffcnt == 1:
high |= 0x20
print(f'db {", ".join([f"${low:02x}", f"${high:02x}"])}')
secret_cnt += 1
idx += 3
else:
idx += 2
if secret_cnt:
print(f'Room {room:02x} {secret_cnt}')
spriteptr = 0x4d62e + b2idx
spriteloc = rom_data[spriteptr] + rom_data[spriteptr+1]*0x100 + 0x40000
secretptr = 0xdb67 + b2idx
secretloc = rom_data[secretptr] + rom_data[secretptr+1]*0x100
done, idx = False, 0
while not done:
b1 = rom_data[spriteloc+idx]
spritedata.append(b1)
if b1 == 0xff:
done = True
idx += 1
done, idx = False, 0
while not done:
b1 = rom_data[secretloc+idx]
b2 = rom_data[secretloc+idx+1]
b3 = rom_data[secretloc+idx+2]
secretdata.append(b1)
secretdata.append(b2)
if b1 == 0xff and b2 == 0xff:
done = True
else:
secretdata.append(b3)
idx += 3
# print(f'Room {room:02x}')
# print(f'HeaderPtr {headerptr:06x}')
# print(f'HeaderLoc {headerloc:06x}')
# print(f'db {",".join([f"${x:02x}" for x in header])}')
# print(f'Obj Length: {len(objectdata)}')
# print(f'ObjectPtr {objectptr:06x}')
# print(f'ObjectLoc {objectloc:06x}')
# for i in range(0, len(objectdata)//16 + 1):
# slice = objectdata[i*16:i*16+16]
# print(f'db {",".join([f"${x:02x}" for x in slice])}')
# print(f'SpritePtr {spriteptr:06x}')
# print(f'SpriteLoc {spriteloc:06x}')
# print_data_block(spritedata)
# print(f'SecretPtr {secretptr:06x}')
# print(f'SecretLoc {secretloc:06x}')
# print_data_block(secretdata)
# print()
def count_set_bits(val):
if val == 0:
return 0
else:
return (val & 1) + count_set_bits(val >> 1)
def check_pots():
from PotShuffle import vanilla_pots
for supertile, pot_list in vanilla_pots.items():
for i,pot in enumerate(pot_list):
if pot.obj_ref:
r = pot.obj_ref
secret_vram = pot.x | (pot.y << 8)
tile_vram = ((r.data[1] & 0xFC) << 5) | ((r.data[0] & 0xFC) >> 1)
if secret_vram != tile_vram:
print(f'{pot.room}#{i+1} secret: {hex(secret_vram)} tile: {hex(tile_vram)}')
def stack_size3a(size=2):
# See reference: https://stackoverflow.com/questions/34115298/how-do-i-get-the-current-depth-of-the-python-interpreter-stack
"""Get stack size for caller's frame."""
frame = sys._getframe(size)
try:
for size in count(size, 8):
frame = frame.f_back.f_back.f_back.f_back.\
f_back.f_back.f_back.f_back
except AttributeError:
while frame:
frame = frame.f_back
size += 1
return size - 1
def find_and_replace():
for data_line in fileinput.input('scratch.txt', inplace=True):
if '=' in data_line:
one, two = data_line.split(' = ')
number = int(two.strip())
print(data_line.replace(two, hex(number)))
def load_yaml(path_list):
path = os.path.join(*path_list)
if os.path.exists(Path(path)):
with open(path, "r", encoding="utf-8") as f:
return yaml.load(f, Loader=yaml.SafeLoader)
elif urllib.parse.urlparse(path).scheme in ['http', 'https']:
return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader)
yaml_cache = {}
def load_cached_yaml(path_list):
path = os.path.join(*path_list)
if path in yaml_cache:
return yaml_cache[path]
else:
if os.path.exists(Path(path)):
with open(path, "r", encoding="utf-8") as f:
data = yaml.load(f, Loader=yaml.SafeLoader)
yaml_cache[path] = data
return data
elif urllib.parse.urlparse(path).scheme in ['http', 'https']:
data = yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader)
yaml_cache[path] = data
return data
class bidict(dict):
def __init__(self, *args, **kwargs):
super(bidict, self).__init__(*args, **kwargs)
self.inverse = {}
for key, value in self.items():
self.inverse.setdefault(value,[]).append(key)
def __setitem__(self, key, value):
if key in self:
self.inverse[self[key]].remove(key)
super(bidict, self).__setitem__(key, value)
self.inverse.setdefault(value,[]).append(key)
def __delitem__(self, key):
value = self[key]
self.inverse.setdefault(value,[]).remove(key)
if value in self.inverse and not self.inverse[value]:
del self.inverse[value]
super(bidict, self).__delitem__(key)
class HexInt(int): pass
def hex_representer(dumper, data):
return yaml.ScalarNode('tag:yaml.org,2002:int', f"{data:#0{4}x}")
if __name__ == '__main__':
print(make_new_base2current(new_rom="../working.sfc"))
print("New Rom Hash:", get_new_romhash())
# read_entrance_data(old_rom=sys.argv[1])
# room_palette_data(old_rom=sys.argv[1])
# extract_data_from_us_rom(sys.argv[1])
# extract_data_from_jp_rom(sys.argv[1])
# check_pots()
# find_and_replace()
+3
View File
@@ -0,0 +1,3 @@
GKVersion = '1.1.0'
ORVersion = '0.7.0.3'
DRVersion = '1.5.6-u'
+139
View File
@@ -0,0 +1,139 @@
# Site settings
title: ALttP Dungeon Randomizer
description: Advanced dungeon randomization for The Legend of Zelda - A Link to the Past
baseurl: "/ALttPDoorRandomizer"
url: "https://aerinon.github.io"
# Theme
theme: jekyll-theme-slate
remote_theme: just-the-docs/just-the-docs
# Logo and branding
# logo: "/assets/images/logo.png"
# Navigation
nav_enabled: true
nav_external_links:
- title: GitHub
url: https://github.com/aerinon/ALttPDoorRandomizer
- title: Discord
url: https://discordapp.com/invite/alttprandomizer
- title: Download
url: https://github.com/aerinon/ALttPDoorRandomizer/releases
# Search
search_enabled: true
search:
heading_level: 2
previews: 3
preview_words_before: 5
preview_words_after: 10
tokenizer_separator: /[\s/]+/
rel_url: true
button: true
# Heading anchors
heading_anchors: true
# Aux links
aux_links:
"Door Randomizer on GitHub":
- "https://github.com/aerinon/ALttPDoorRandomizer"
"ALTTP Rando Discord":
- "https://discordapp.com/invite/alttprandomizer"
aux_links_new_tab: true
# Footer
footer_content: "Copyright &copy; 2026 ALttP Door Randomizer Team. Based on ALttP Entrance Randomizer."
# Back to top link
back_to_top: true
back_to_top_text: "Back to top"
# Collections for blog posts
collections:
posts:
output: true
permalink: /blog/:year/:month/:day/:title/
# Defaults
defaults:
- scope:
path: ""
type: "posts"
values:
layout: "default"
- scope:
path: ""
values:
layout: "default"
# Build settings
markdown: kramdown
kramdown:
input: GFM
syntax_highlighter: rouge
syntax_highlighter_opts:
css_class: 'highlight'
plugins:
- jekyll-feed
- jekyll-seo-tag
- jekyll-sitemap
# Exclude from processing
exclude:
- .git/
- .github/
- .gitignore
- .gitattributes
- source/
- test/
- resources/
- data/
- debug/
- analysis/
- analysis2/
- alttp_dungeon_randomizer.egg-info/
- DR/
- "*.py"
- "*.pyc"
- "*.pyd"
- "*.pyo"
- "*.egg-info"
- "*.spec"
- requirements*.txt
- setup.py
- TestSuite.py
- DungeonRandomizer.py
- Gui.py
- MultiServer.py
- MultiClient.py
- CLAUDE.md
- LICENSE
- libbz2-dev
- tlogbfs.txt
# Include files
include:
- _posts
- blog
- docs/Customizer.md
- docs/BUILDING.md
- docs/DR_hint_reference.md
# Color scheme (for just-the-docs theme)
color_scheme: dark
# Google Analytics (optional - add your tracking ID)
# ga_tracking: UA-XXXXXXXX-X
# Compress HTML
compress_html:
clippings: all
comments: all
endings: all
startings: []
blanklines: false
profile: false
@@ -0,0 +1,74 @@
---
layout: default
title: "Welcome to the ALttP Door Randomizer Blog"
date: 2026-01-26
author: Door Randomizer Team
category: development
excerpt: "Introducing the new Door Randomizer documentation site and blog. Learn about what's new, what's coming, and how to get involved."
---
# Welcome to the ALttP Door Randomizer Blog
We're excited to launch the official documentation site and development blog for ALttP Door Randomizer! This site serves as a central hub for all things Door Rando - from comprehensive feature documentation to release notes and development updates.
## What's New Here?
### Comprehensive Documentation
We've reorganized and expanded our documentation to make it easier to find what you need:
- **[Features Guide](/features)** - Complete reference for all randomizer settings and modes
- **[Installation & Usage](/installation)** - Step-by-step setup instructions for all platforms
- **[Known Issues](/known-issues)** - Tracking current bugs and limitations
- **[Roadmap](/roadmap)** - Our vision for the future of Door Randomizer
### Development Blog
This blog will be your source for:
- **Feature highlights** - Deep dives into specific features
- **Development updates** - Behind-the-scenes looks at ongoing work
- **Technical articles** - How the randomizer works under the hood
## What is Door Randomizer?
If you're new here, Door Randomizer takes the ALttP randomizer experience to the next level by shuffling the connections between rooms within dungeons. Walk through a door in Eastern Palace and you might end up in Tower of Hera, Ice Palace, or anywhere else!
Key features include:
- **Four shuffle modes** - From basic (within dungeon) to crossed (full chaos)
- **Three intensity levels** - Control how thoroughly dungeons are shuffled
- **Advanced key logic** - Multiple algorithms to prevent self-locking
- **Pottery shuffle** - Randomize items under pots with multiple modes
- **Shopsanity** - 32+ shop locations with intelligent pricing
- **Enemizer integration** - Enemy and boss randomization with logic
- **Custom seeds** - Create your own dungeons and rooms
[Learn more about features →](/features)
[Read the Customizer guide →](https://github.com/aerinon/ALttPDoorRandomizer/blob/DoorDev/docs/Customizer.md)
## What's Coming Next?
We have plans for Door Randomizer's future. Check out our [Roadmap](/roadmap) for details. (Still very much a work in progress!)
## Community
Join the Door Randomizer community:
- **Discord**: [ALTTP Randomizer Discord](https://discordapp.com/invite/alttprandomizer)
- `#door-rando` - General discussion and help
- `#bug-reports` - Report bugs and issues
- **GitHub**: [aerinon/ALttPDoorRandomizer](https://github.com/aerinon/ALttPDoorRandomizer)
## Stay Tuned
We'll be posting irregular updates here as development continues.
Thank you to everyone who has contributed to Door Randomizer through code, testing, feedback, and community support. We're excited about the future and can't wait to see what lies in store!
Happy randomizing!
---
*Have questions or feedback about the new documentation site? Let us know in Discord!*
@@ -1,5 +0,0 @@
Mike Lenzen <m.lenzen@gmail.com> https://github.com/mlenzen
Caleb Levy <caleb.levy@berkeley.edu> https://github.com/caleblevy
Marein Könings <mail@marein.org> https://github.com/MareinK
Jad Kik <jadkik94@gmail.com> https://github.com/jadkik
Kuba Marek <blue.cube@seznam.cz> https://github.com/bluecube
-191
View File
@@ -1,191 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-55
View File
@@ -1,55 +0,0 @@
"""collections_extended contains a few extra basic data structures."""
from ._compat import Collection
from .bags import bag, frozenbag
from .setlists import setlist, frozensetlist
from .bijection import bijection
from .range_map import RangeMap, MappedRange
__version__ = '1.0.2'
__all__ = (
'collection',
'setlist',
'frozensetlist',
'bag',
'frozenbag',
'bijection',
'RangeMap',
'MappedRange',
'Collection',
)
def collection(iterable=None, mutable=True, ordered=False, unique=False):
"""Return a Collection with the specified properties.
Args:
iterable (Iterable): collection to instantiate new collection from.
mutable (bool): Whether or not the new collection is mutable.
ordered (bool): Whether or not the new collection is ordered.
unique (bool): Whether or not the new collection contains only unique values.
"""
if iterable is None:
iterable = tuple()
if unique:
if ordered:
if mutable:
return setlist(iterable)
else:
return frozensetlist(iterable)
else:
if mutable:
return set(iterable)
else:
return frozenset(iterable)
else:
if ordered:
if mutable:
return list(iterable)
else:
return tuple(iterable)
else:
if mutable:
return bag(iterable)
else:
return frozenbag(iterable)
-53
View File
@@ -1,53 +0,0 @@
"""Python 2/3 compatibility helpers."""
import sys
is_py2 = sys.version_info[0] == 2
if is_py2:
def keys_set(d):
"""Return a set of passed dictionary's keys."""
return set(d.keys())
else:
keys_set = dict.keys
if sys.version_info < (3, 6):
from collections import Sized, Iterable, Container
def _check_methods(C, *methods):
mro = C.__mro__
for method in methods:
for B in mro:
if method in B.__dict__:
if B.__dict__[method] is None:
return NotImplemented
break
else:
return NotImplemented
return True
class Collection(Sized, Iterable, Container):
"""Backport from Python3.6."""
__slots__ = tuple()
@classmethod
def __subclasshook__(cls, C):
if cls is Collection:
return _check_methods(C, "__len__", "__iter__", "__contains__")
return NotImplemented
else:
from collections.abc import Collection
def handle_rich_comp_not_implemented():
"""Correctly handle unimplemented rich comparisons.
In Python 3, return NotImplemented.
In Python 2, raise a TypeError.
"""
if is_py2:
raise TypeError()
else:
return NotImplemented
-16
View File
@@ -1,16 +0,0 @@
"""util functions for collections_extended."""
def hash_iterable(it):
"""Perform a O(1) memory hash of an iterable of arbitrary length.
hash(tuple(it)) creates a temporary tuple containing all values from it
which could be a problem if it is large.
See discussion at:
https://groups.google.com/forum/#!msg/python-ideas/XcuC01a8SYs/e-doB9TbDwAJ
"""
hash_value = hash(type(it))
for value in it:
hash_value = hash((hash_value, value))
return hash_value
-527
View File
@@ -1,527 +0,0 @@
"""Bag class definitions."""
import heapq
from operator import itemgetter
from collections.abc import Set, MutableSet, Hashable
from . import _compat
class _basebag(Set):
"""Base class for bag classes.
Base class for bag and frozenbag. Is not mutable and not hashable, so there's
no reason to use this instead of either bag or frozenbag.
"""
# Basic object methods
def __init__(self, iterable=None):
"""Create a new basebag.
If iterable isn't given, is None or is empty then the bag starts empty.
Otherwise each element from iterable will be added to the bag
however many times it appears.
This runs in O(len(iterable))
"""
self._dict = dict()
self._size = 0
if iterable:
if isinstance(iterable, _basebag):
for elem, count in iterable._dict.items():
self._dict[elem] = count
self._size += count
else:
for value in iterable:
self._dict[value] = self._dict.get(value, 0) + 1
self._size += 1
def __repr__(self):
if self._size == 0:
return '{0}()'.format(self.__class__.__name__)
else:
repr_format = '{class_name}({values!r})'
return repr_format.format(
class_name=self.__class__.__name__,
values=tuple(self),
)
def __str__(self):
if self._size == 0:
return '{class_name}()'.format(class_name=self.__class__.__name__)
else:
format_single = '{elem!r}'
format_mult = '{elem!r}^{mult}'
strings = []
for elem, mult in self._dict.items():
if mult > 1:
strings.append(format_mult.format(elem=elem, mult=mult))
else:
strings.append(format_single.format(elem=elem))
return '{%s}' % ', '.join(strings)
# New public methods (not overriding/implementing anything)
def num_unique_elements(self):
"""Return the number of unique elements.
This runs in O(1) time
"""
return len(self._dict)
def unique_elements(self):
"""Return a view of unique elements in this bag.
In Python 3:
This runs in O(1) time and returns a view of the unique elements
In Python 2:
This runs in O(n) and returns set of the current elements.
"""
return _compat.keys_set(self._dict)
def count(self, value):
"""Return the number of value present in this bag.
If value is not in the bag no Error is raised, instead 0 is returned.
This runs in O(1) time
Args:
value: The element of self to get the count of
Returns:
int: The count of value in self
"""
return self._dict.get(value, 0)
def nlargest(self, n=None):
"""List the n most common elements and their counts.
List is from the most
common to the least. If n is None, the list all element counts.
Run time should be O(m log m) where m is len(self)
Args:
n (int): The number of elements to return
"""
if n is None:
return sorted(self._dict.items(), key=itemgetter(1), reverse=True)
else:
return heapq.nlargest(n, self._dict.items(), key=itemgetter(1))
@classmethod
def _from_iterable(cls, it):
return cls(it)
@classmethod
def from_mapping(cls, mapping):
"""Create a bag from a dict of elem->count.
Each key in the dict is added if the value is > 0.
"""
out = cls()
for elem, count in mapping.items():
if count > 0:
out._dict[elem] = count
out._size += count
return out
def copy(self):
"""Create a shallow copy of self.
This runs in O(len(self.num_unique_elements()))
"""
return self.from_mapping(self._dict)
# implementing Sized methods
def __len__(self):
"""Return the cardinality of the bag.
This runs in O(1)
"""
return self._size
# implementing Container methods
def __contains__(self, value):
"""Return the multiplicity of the element.
This runs in O(1)
"""
return self._dict.get(value, 0)
# implementing Iterable methods
def __iter__(self):
"""Iterate through all elements.
Multiple copies will be returned if they exist.
"""
for value, count in self._dict.items():
for i in range(count):
yield(value)
# Comparison methods
def _is_subset(self, other):
"""Check that every element in self has a count <= in other.
Args:
other (Set)
"""
if isinstance(other, _basebag):
for elem, count in self._dict.items():
if not count <= other._dict.get(elem, 0):
return False
else:
for elem in self:
if self._dict.get(elem, 0) > 1 or elem not in other:
return False
return True
def _is_superset(self, other):
"""Check that every element in self has a count >= in other.
Args:
other (Set)
"""
if isinstance(other, _basebag):
for elem, count in other._dict.items():
if not self._dict.get(elem, 0) >= count:
return False
else:
for elem in other:
if elem not in self:
return False
return True
def __le__(self, other):
if not isinstance(other, Set):
return _compat.handle_rich_comp_not_implemented()
return len(self) <= len(other) and self._is_subset(other)
def __lt__(self, other):
if not isinstance(other, Set):
return _compat.handle_rich_comp_not_implemented()
return len(self) < len(other) and self._is_subset(other)
def __gt__(self, other):
if not isinstance(other, Set):
return _compat.handle_rich_comp_not_implemented()
return len(self) > len(other) and self._is_superset(other)
def __ge__(self, other):
if not isinstance(other, Set):
return _compat.handle_rich_comp_not_implemented()
return len(self) >= len(other) and self._is_superset(other)
def __eq__(self, other):
if not isinstance(other, Set):
return False
if isinstance(other, _basebag):
return self._dict == other._dict
if not len(self) == len(other):
return False
for elem in other:
if self._dict.get(elem, 0) != 1:
return False
return True
def __ne__(self, other):
return not (self == other)
# Operations - &, |, +, -, ^, * and isdisjoint
def __and__(self, other):
"""Intersection is the minimum of corresponding counts.
This runs in O(l + n) where:
n is self.num_unique_elements()
if other is a bag:
l = 1
else:
l = len(other)
"""
if not isinstance(other, _basebag):
other = self._from_iterable(other)
values = dict()
for elem in self._dict:
values[elem] = min(other._dict.get(elem, 0), self._dict.get(elem, 0))
return self.from_mapping(values)
def isdisjoint(self, other):
"""Return if this bag is disjoint with the passed collection.
This runs in O(len(other))
TODO move isdisjoint somewhere more appropriate
"""
for value in other:
if value in self:
return False
return True
def __or__(self, other):
"""Union is the maximum of all elements.
This runs in O(m + n) where:
n is self.num_unique_elements()
if other is a bag:
m = other.num_unique_elements()
else:
m = len(other)
"""
if not isinstance(other, _basebag):
other = self._from_iterable(other)
values = dict()
for elem in self.unique_elements() | other.unique_elements():
values[elem] = max(self._dict.get(elem, 0), other._dict.get(elem, 0))
return self.from_mapping(values)
def __add__(self, other):
"""Return a new bag also containing all the elements of other.
self + other = self & other + self | other
This runs in O(m + n) where:
n is self.num_unique_elements()
m is len(other)
Args:
other (Iterable): elements to add to self
"""
out = self.copy()
for value in other:
out._dict[value] = out._dict.get(value, 0) + 1
out._size += 1
return out
def __sub__(self, other):
"""Difference between the sets.
For normal sets this is all x s.t. x in self and x not in other.
For bags this is count(x) = max(0, self.count(x)-other.count(x))
This runs in O(m + n) where:
n is self.num_unique_elements()
m is len(other)
Args:
other (Iterable): elements to remove
"""
out = self.copy()
for value in other:
old_count = out._dict.get(value, 0)
if old_count == 1:
del out._dict[value]
out._size -= 1
elif old_count > 1:
out._dict[value] = old_count - 1
out._size -= 1
return out
def __mul__(self, other):
"""Cartesian product of the two sets.
other can be any iterable.
Both self and other must contain elements that can be added together.
This should run in O(m*n+l) where:
m is the number of unique elements in self
n is the number of unique elements in other
if other is a bag:
l is 0
else:
l is the len(other)
The +l will only really matter when other is an iterable with MANY
repeated elements.
For example: {'a'^2} * 'bbbbbbbbbbbbbbbbbbbbbbbbbb'
The algorithm will be dominated by counting the 'b's
"""
if not isinstance(other, _basebag):
other = self._from_iterable(other)
values = dict()
for elem, count in self._dict.items():
for other_elem, other_count in other._dict.items():
new_elem = elem + other_elem
new_count = count * other_count
values[new_elem] = new_count
return self.from_mapping(values)
def __xor__(self, other):
"""Symmetric difference between the sets.
other can be any iterable.
This runs in O(m + n) where:
m = len(self)
n = len(other)
"""
return (self - other) | (other - self)
class bag(_basebag, MutableSet):
"""bag is a mutable unhashable bag."""
def pop(self):
"""Remove and return an element of self."""
# TODO can this be done more efficiently (no need to create an iterator)?
it = iter(self)
try:
value = next(it)
except StopIteration:
raise KeyError
self.discard(value)
return value
def add(self, elem):
"""Add elem to self."""
self._dict[elem] = self._dict.get(elem, 0) + 1
self._size += 1
def discard(self, elem):
"""Remove elem from this bag, silent if it isn't present."""
try:
self.remove(elem)
except ValueError:
pass
def remove(self, elem):
"""Remove elem from this bag, raising a ValueError if it isn't present.
Args:
elem: object to remove from self
Raises:
ValueError: if the elem isn't present
"""
old_count = self._dict.get(elem, 0)
if old_count == 0:
raise ValueError
elif old_count == 1:
del self._dict[elem]
else:
self._dict[elem] -= 1
self._size -= 1
def discard_all(self, other):
"""Discard all of the elems from other."""
if not isinstance(other, _basebag):
other = self._from_iterable(other)
for elem, other_count in other._dict.items():
old_count = self._dict.get(elem, 0)
new_count = old_count - other_count
if new_count >= 0:
if new_count == 0:
if elem in self:
del self._dict[elem]
else:
self._dict[elem] = new_count
self._size += new_count - old_count
def remove_all(self, other):
"""Remove all of the elems from other.
Raises a ValueError if the multiplicity of any elem in other is greater
than in self.
"""
if not self._is_superset(other):
raise ValueError
self.discard_all(other)
def clear(self):
"""Remove all elements from this bag."""
self._dict = dict()
self._size = 0
# In-place operations
def __ior__(self, other):
"""Set multiplicity of each element to the maximum of the two collections.
if isinstance(other, _basebag):
This runs in O(other.num_unique_elements())
else:
This runs in O(len(other))
"""
if not isinstance(other, _basebag):
other = self._from_iterable(other)
for elem, other_count in other._dict.items():
old_count = self._dict.get(elem, 0)
new_count = max(other_count, old_count)
self._dict[elem] = new_count
self._size += new_count - old_count
return self
def __iand__(self, other):
"""Set multiplicity of each element to the minimum of the two collections.
if isinstance(other, _basebag):
This runs in O(other.num_unique_elements())
else:
This runs in O(len(other))
"""
if not isinstance(other, _basebag):
other = self._from_iterable(other)
for elem, old_count in set(self._dict.items()):
other_count = other._dict.get(elem, 0)
new_count = min(other_count, old_count)
if new_count == 0:
del self._dict[elem]
else:
self._dict[elem] = new_count
self._size += new_count - old_count
return self
def __ixor__(self, other):
"""Set self to the symmetric difference between the sets.
if isinstance(other, _basebag):
This runs in O(other.num_unique_elements())
else:
This runs in O(len(other))
"""
if not isinstance(other, _basebag):
other = self._from_iterable(other)
other_minus_self = other - self
self -= other
self |= other_minus_self
return self
def __isub__(self, other):
"""Discard the elements of other from self.
if isinstance(it, _basebag):
This runs in O(it.num_unique_elements())
else:
This runs in O(len(it))
"""
self.discard_all(other)
return self
def __iadd__(self, other):
"""Add all of the elements of other to self.
if isinstance(it, _basebag):
This runs in O(it.num_unique_elements())
else:
This runs in O(len(it))
"""
if not isinstance(other, _basebag):
other = self._from_iterable(other)
for elem, other_count in other._dict.items():
self._dict[elem] = self._dict.get(elem, 0) + other_count
self._size += other_count
return self
class frozenbag(_basebag, Hashable):
"""frozenbag is an immutable, hashable bab."""
def __hash__(self):
"""Compute the hash value of a frozenbag.
This was copied directly from _collections_abc.Set._hash in Python3 which
is identical to _abcoll.Set._hash
We can't call it directly because Python2 raises a TypeError.
"""
if not hasattr(self, '_hash_value'):
self._hash_value = self._hash()
return self._hash_value
-94
View File
@@ -1,94 +0,0 @@
"""Class definition for bijection."""
from collections.abc import MutableMapping, Mapping
class bijection(MutableMapping):
"""A one-to-one onto mapping, a dict with unique values."""
def __init__(self, iterable=None, **kwarg):
"""Create a bijection from an iterable.
Matches dict.__init__.
"""
self._data = {}
self.__inverse = self.__new__(bijection)
self.__inverse._data = {}
self.__inverse.__inverse = self
if iterable is not None:
if isinstance(iterable, Mapping):
for key, value in iterable.items():
self[key] = value
else:
for pair in iterable:
self[pair[0]] = pair[1]
for key, value in kwarg.items():
self[key] = value
def __repr__(self):
if len(self._data) == 0:
return '{0}()'.format(self.__class__.__name__)
else:
repr_format = '{class_name}({values!r})'
return repr_format.format(
class_name=self.__class__.__name__,
values=self._data,
)
@property
def inverse(self):
"""Return the inverse of this bijection."""
return self.__inverse
# Required for MutableMapping
def __len__(self):
return len(self._data)
# Required for MutableMapping
def __getitem__(self, key):
return self._data[key]
# Required for MutableMapping
def __setitem__(self, key, value):
if key in self:
del self.inverse._data[self[key]]
if value in self.inverse:
del self._data[self.inverse[value]]
self._data[key] = value
self.inverse._data[value] = key
# Required for MutableMapping
def __delitem__(self, key):
value = self._data.pop(key)
del self.inverse._data[value]
# Required for MutableMapping
def __iter__(self):
return iter(self._data)
def __contains__(self, key):
return key in self._data
def clear(self):
"""Remove everything from this bijection."""
self._data.clear()
self.inverse._data.clear()
def copy(self):
"""Return a copy of this bijection."""
return bijection(self)
def items(self):
"""See Mapping.items."""
return self._data.items()
def keys(self):
"""See Mapping.keys."""
return self._data.keys()
def values(self):
"""See Mapping.values."""
return self.inverse.keys()
def __eq__(self, other):
return isinstance(other, bijection) and self._data == other._data
-385
View File
@@ -1,385 +0,0 @@
"""RangeMap class definition."""
from bisect import bisect_left, bisect_right
from collections import namedtuple
from collections.abc import Mapping, MappingView, Set
# Used to mark unmapped ranges
_empty = object()
MappedRange = namedtuple('MappedRange', ('start', 'stop', 'value'))
class KeysView(MappingView, Set):
"""A view of the keys that mark the starts of subranges.
Since iterating over all the keys is impossible, the KeysView only
contains the keys that start each subrange.
"""
__slots__ = ()
@classmethod
def _from_iterable(self, it):
return set(it)
def __contains__(self, key):
loc = self._mapping._bisect_left(key)
return self._mapping._keys[loc] == key and \
self._mapping._values[loc] is not _empty
def __iter__(self):
for item in self._mapping.ranges():
yield item.start
class ItemsView(MappingView, Set):
"""A view of the items that mark the starts of subranges.
Since iterating over all the keys is impossible, the ItemsView only
contains the items that start each subrange.
"""
__slots__ = ()
@classmethod
def _from_iterable(self, it):
return set(it)
def __contains__(self, item):
key, value = item
loc = self._mapping._bisect_left(key)
return self._mapping._keys[loc] == key and \
self._mapping._values[loc] == value
def __iter__(self):
for mapped_range in self._mapping.ranges():
yield (mapped_range.start, mapped_range.value)
class ValuesView(MappingView):
"""A view on the values of a Mapping."""
__slots__ = ()
def __contains__(self, value):
return value in self._mapping._values
def __iter__(self):
for value in self._mapping._values:
if value is not _empty:
yield value
def _check_start_stop(start, stop):
"""Check that start and stop are valid - orderable and in the right order.
Raises:
ValueError: if stop <= start
TypeError: if unorderable
"""
if start is not None and stop is not None and stop <= start:
raise ValueError('stop must be > start')
def _check_key_slice(key):
if not isinstance(key, slice):
raise TypeError('Can only set and delete slices')
if key.step is not None:
raise ValueError('Cannot set or delete slices with steps')
class RangeMap(Mapping):
"""Map ranges of orderable elements to values."""
def __init__(self, iterable=None, **kwargs):
"""Create a RangeMap.
A mapping or other iterable can be passed to initialize the RangeMap.
If mapping is passed, it is interpreted as a mapping from range start
indices to values.
If an iterable is passed, each element will define a range in the
RangeMap and should be formatted (start, stop, value).
default_value is a an optional keyword argument that will initialize the
entire RangeMap to that value. Any missing ranges will be mapped to that
value. However, if ranges are subsequently deleted they will be removed
and *not* mapped to the default_value.
Args:
iterable: A Mapping or an Iterable to initialize from.
default_value: If passed, the return value for all keys less than the
least key in mapping or missing ranges in iterable. If no mapping
or iterable, the return value for all keys.
"""
default_value = kwargs.pop('default_value', _empty)
if kwargs:
raise TypeError('Unknown keyword arguments: %s' % ', '.join(kwargs.keys()))
self._keys = [None]
self._values = [default_value]
if iterable:
if isinstance(iterable, Mapping):
self._init_from_mapping(iterable)
else:
self._init_from_iterable(iterable)
@classmethod
def from_mapping(cls, mapping):
"""Create a RangeMap from a mapping of interval starts to values."""
obj = cls()
obj._init_from_mapping(mapping)
return obj
def _init_from_mapping(self, mapping):
for key, value in sorted(mapping.items()):
self.set(value, key)
@classmethod
def from_iterable(cls, iterable):
"""Create a RangeMap from an iterable of tuples defining each range.
Each element of the iterable is a tuple (start, stop, value).
"""
obj = cls()
obj._init_from_iterable(iterable)
return obj
def _init_from_iterable(self, iterable):
for start, stop, value in iterable:
self.set(value, start=start, stop=stop)
def __str__(self):
range_format = '({range.start}, {range.stop}): {range.value}'
values = ', '.join([range_format.format(range=r) for r in self.ranges()])
return 'RangeMap(%s)' % values
def __repr__(self):
range_format = '({range.start!r}, {range.stop!r}, {range.value!r})'
values = ', '.join([range_format.format(range=r) for r in self.ranges()])
return 'RangeMap([%s])' % values
def _bisect_left(self, key):
"""Return the index of the key or the last key < key."""
if key is None:
return 0
else:
return bisect_left(self._keys, key, lo=1)
def _bisect_right(self, key):
"""Return the index of the first key > key."""
if key is None:
return 1
else:
return bisect_right(self._keys, key, lo=1)
def ranges(self, start=None, stop=None):
"""Generate MappedRanges for all mapped ranges.
Yields:
MappedRange
"""
_check_start_stop(start, stop)
start_loc = self._bisect_right(start)
if stop is None:
stop_loc = len(self._keys)
else:
stop_loc = self._bisect_left(stop)
start_val = self._values[start_loc - 1]
candidate_keys = [start] + self._keys[start_loc:stop_loc] + [stop]
candidate_values = [start_val] + self._values[start_loc:stop_loc]
for i, value in enumerate(candidate_values):
if value is not _empty:
start_key = candidate_keys[i]
stop_key = candidate_keys[i + 1]
yield MappedRange(start_key, stop_key, value)
def __contains__(self, value):
try:
self.__getitem(value) is not _empty
except KeyError:
return False
else:
return True
def __iter__(self):
for key, value in zip(self._keys, self._values):
if value is not _empty:
yield key
def __bool__(self):
if len(self._keys) > 1:
return True
else:
return self._values[0] != _empty
__nonzero__ = __bool__
def __getitem(self, key):
"""Get the value for a key (not a slice)."""
loc = self._bisect_right(key) - 1
value = self._values[loc]
if value is _empty:
raise KeyError(key)
else:
return value
def get(self, key, restval=None):
"""Get the value of the range containing key, otherwise return restval."""
try:
return self.__getitem(key)
except KeyError:
return restval
def get_range(self, start=None, stop=None):
"""Return a RangeMap for the range start to stop.
Returns:
A RangeMap
"""
return self.from_iterable(self.ranges(start, stop))
def set(self, value, start=None, stop=None):
"""Set the range from start to stop to value."""
_check_start_stop(start, stop)
# start_index, stop_index will denote the sections we are replacing
start_index = self._bisect_left(start)
if start is not None: # start_index == 0
prev_value = self._values[start_index - 1]
if prev_value == value:
# We're setting a range where the left range has the same
# value, so create one big range
start_index -= 1
start = self._keys[start_index]
if stop is None:
new_keys = [start]
new_values = [value]
stop_index = len(self._keys)
else:
stop_index = self._bisect_right(stop)
stop_value = self._values[stop_index - 1]
stop_key = self._keys[stop_index - 1]
if stop_key == stop and stop_value == value:
new_keys = [start]
new_values = [value]
else:
new_keys = [start, stop]
new_values = [value, stop_value]
self._keys[start_index:stop_index] = new_keys
self._values[start_index:stop_index] = new_values
def delete(self, start=None, stop=None):
"""Delete the range from start to stop from self.
Raises:
KeyError: If part of the passed range isn't mapped.
"""
_check_start_stop(start, stop)
start_loc = self._bisect_right(start) - 1
if stop is None:
stop_loc = len(self._keys)
else:
stop_loc = self._bisect_left(stop)
for value in self._values[start_loc:stop_loc]:
if value is _empty:
raise KeyError((start, stop))
# this is inefficient, we've already found the sub ranges
self.set(_empty, start=start, stop=stop)
def empty(self, start=None, stop=None):
"""Empty the range from start to stop.
Like delete, but no Error is raised if the entire range isn't mapped.
"""
self.set(_empty, start=start, stop=stop)
def clear(self):
"""Remove all elements."""
self._keys = [None]
self._values = [_empty]
@property
def start(self):
"""Get the start key of the first range.
None if RangeMap is empty or unbounded to the left.
"""
if self._values[0] is _empty:
try:
return self._keys[1]
except IndexError:
# This is empty or everything is mapped to a single value
return None
else:
# This is unbounded to the left
return self._keys[0]
@property
def end(self):
"""Get the stop key of the last range.
None if RangeMap is empty or unbounded to the right.
"""
if self._values[-1] is _empty:
return self._keys[-1]
else:
# This is unbounded to the right
return None
def __eq__(self, other):
if isinstance(other, RangeMap):
return (
self._keys == other._keys and
self._values == other._values
)
else:
return False
def __getitem__(self, key):
try:
_check_key_slice(key)
except TypeError:
return self.__getitem(key)
else:
return self.get_range(key.start, key.stop)
def __setitem__(self, key, value):
_check_key_slice(key)
self.set(value, key.start, key.stop)
def __delitem__(self, key):
_check_key_slice(key)
self.delete(key.start, key.stop)
def __len__(self):
count = 0
for v in self._values:
if v is not _empty:
count += 1
return count
def keys(self):
"""Return a view of the keys."""
return KeysView(self)
def values(self):
"""Return a view of the values."""
return ValuesView(self)
def items(self):
"""Return a view of the item pairs."""
return ItemsView(self)
# Python2 - override slice methods
def __setslice__(self, i, j, value):
"""Implement __setslice__ to override behavior in Python 2.
This is required because empty slices pass integers in python2 as opposed
to None in python 3.
"""
raise SyntaxError('Assigning slices doesn\t work in Python 2, use set')
def __delslice__(self, i, j):
raise SyntaxError('Deleting slices doesn\t work in Python 2, use delete')
def __getslice__(self, i, j):
raise SyntaxError('Getting slices doesn\t work in Python 2, use get_range.')
-552
View File
@@ -1,552 +0,0 @@
"""Setlist class definitions."""
import random as random_
from collections.abc import (
Sequence,
Set,
MutableSequence,
MutableSet,
Hashable,
)
from . import _util
class _basesetlist(Sequence, Set):
"""A setlist is an ordered Collection of unique elements.
_basesetlist is the superclass of setlist and frozensetlist. It is immutable
and unhashable.
"""
def __init__(self, iterable=None, raise_on_duplicate=False):
"""Create a setlist.
Args:
iterable (Iterable): Values to initialize the setlist with.
"""
self._list = list()
self._dict = dict()
if iterable:
if raise_on_duplicate:
self._extend(iterable)
else:
self._update(iterable)
def __repr__(self):
if len(self) == 0:
return '{0}()'.format(self.__class__.__name__)
else:
repr_format = '{class_name}({values!r})'
return repr_format.format(
class_name=self.__class__.__name__,
values=tuple(self),
)
# Convenience methods
def _fix_neg_index(self, index):
if index < 0:
index += len(self)
if index < 0:
raise IndexError('index is out of range')
return index
def _fix_end_index(self, index):
if index is None:
return len(self)
else:
return self._fix_neg_index(index)
def _append(self, value):
# Checking value in self will check that value is Hashable
if value in self:
raise ValueError('Value "%s" already present' % str(value))
else:
self._dict[value] = len(self)
self._list.append(value)
def _extend(self, values):
new_values = set()
for value in values:
if value in new_values:
raise ValueError('New values contain duplicates')
elif value in self:
raise ValueError('New values contain elements already present in self')
else:
new_values.add(value)
for value in values:
self._dict[value] = len(self)
self._list.append(value)
def _add(self, item):
if item not in self:
self._dict[item] = len(self)
self._list.append(item)
def _update(self, values):
for value in values:
if value not in self:
self._dict[value] = len(self)
self._list.append(value)
@classmethod
def _from_iterable(cls, it, **kwargs):
return cls(it, **kwargs)
# Implement Container
def __contains__(self, value):
return value in self._dict
# Iterable we get by inheriting from Sequence
# Implement Sized
def __len__(self):
return len(self._list)
# Implement Sequence
def __getitem__(self, index):
if isinstance(index, slice):
return self._from_iterable(self._list[index])
return self._list[index]
def count(self, value):
"""Return the number of occurences of value in self.
This runs in O(1)
Args:
value: The value to count
Returns:
int: 1 if the value is in the setlist, otherwise 0
"""
if value in self:
return 1
else:
return 0
def index(self, value, start=0, end=None):
"""Return the index of value between start and end.
By default, the entire setlist is searched.
This runs in O(1)
Args:
value: The value to find the index of
start (int): The index to start searching at (defaults to 0)
end (int): The index to stop searching at (defaults to the end of the list)
Returns:
int: The index of the value
Raises:
ValueError: If the value is not in the list or outside of start - end
IndexError: If start or end are out of range
"""
try:
index = self._dict[value]
except KeyError:
raise ValueError
else:
start = self._fix_neg_index(start)
end = self._fix_end_index(end)
if start <= index and index < end:
return index
else:
raise ValueError
@classmethod
def _check_type(cls, other, operand_name):
if not isinstance(other, _basesetlist):
message = (
"unsupported operand type(s) for {operand_name}: "
"'{self_type}' and '{other_type}'").format(
operand_name=operand_name,
self_type=cls,
other_type=type(other),
)
raise TypeError(message)
def __add__(self, other):
self._check_type(other, '+')
out = self.copy()
out._extend(other)
return out
# Implement Set
def issubset(self, other):
return self <= other
def issuperset(self, other):
return self >= other
def union(self, other):
out = self.copy()
out.update(other)
return out
def intersection(self, other):
other = set(other)
return self._from_iterable(item for item in self if item in other)
def difference(self, other):
other = set(other)
return self._from_iterable(item for item in self if item not in other)
def symmetric_difference(self, other):
return self.union(other) - self.intersection(other)
def __sub__(self, other):
self._check_type(other, '-')
return self.difference(other)
def __and__(self, other):
self._check_type(other, '&')
return self.intersection(other)
def __or__(self, other):
self._check_type(other, '|')
return self.union(other)
def __xor__(self, other):
self._check_type(other, '^')
return self.symmetric_difference(other)
# Comparison
def __eq__(self, other):
if not isinstance(other, _basesetlist):
return False
if not len(self) == len(other):
return False
for self_elem, other_elem in zip(self, other):
if self_elem != other_elem:
return False
return True
def __ne__(self, other):
return not (self == other)
# New methods
def sub_index(self, sub, start=0, end=None):
"""Return the index of a subsequence.
This runs in O(len(sub))
Args:
sub (Sequence): An Iterable to search for
Returns:
int: The index of the first element of sub
Raises:
ValueError: If sub isn't a subsequence
TypeError: If sub isn't iterable
IndexError: If start or end are out of range
"""
start_index = self.index(sub[0], start, end)
end = self._fix_end_index(end)
if start_index + len(sub) > end:
raise ValueError
for i in range(1, len(sub)):
if sub[i] != self[start_index + i]:
raise ValueError
return start_index
def copy(self):
return self.__class__(self)
class setlist(_basesetlist, MutableSequence, MutableSet):
"""A mutable (unhashable) setlist."""
def __str__(self):
return '{[%s}]' % ', '.join(repr(v) for v in self)
# Helper methods
def _delete_all(self, elems_to_delete, raise_errors):
indices_to_delete = set()
for elem in elems_to_delete:
try:
elem_index = self._dict[elem]
except KeyError:
if raise_errors:
raise ValueError('Passed values contain elements not in self')
else:
if elem_index in indices_to_delete:
if raise_errors:
raise ValueError('Passed vales contain duplicates')
indices_to_delete.add(elem_index)
self._delete_values_by_index(indices_to_delete)
def _delete_values_by_index(self, indices_to_delete):
deleted_count = 0
for i, elem in enumerate(self._list):
if i in indices_to_delete:
deleted_count += 1
del self._dict[elem]
else:
new_index = i - deleted_count
self._list[new_index] = elem
self._dict[elem] = new_index
# Now remove deleted_count items from the end of the list
if deleted_count:
self._list = self._list[:-deleted_count]
# Set/Sequence agnostic
def pop(self, index=-1):
"""Remove and return the item at index."""
value = self._list.pop(index)
del self._dict[value]
return value
def clear(self):
"""Remove all elements from self."""
self._dict = dict()
self._list = list()
# Implement MutableSequence
def __setitem__(self, index, value):
if isinstance(index, slice):
old_values = self[index]
for v in value:
if v in self and v not in old_values:
raise ValueError
self._list[index] = value
self._dict = {}
for i, v in enumerate(self._list):
self._dict[v] = i
else:
index = self._fix_neg_index(index)
old_value = self._list[index]
if value in self:
if value == old_value:
return
else:
raise ValueError
del self._dict[old_value]
self._list[index] = value
self._dict[value] = index
def __delitem__(self, index):
if isinstance(index, slice):
indices_to_delete = set(self.index(e) for e in self._list[index])
self._delete_values_by_index(indices_to_delete)
else:
index = self._fix_neg_index(index)
value = self._list[index]
del self._dict[value]
for elem in self._list[index + 1:]:
self._dict[elem] -= 1
del self._list[index]
def insert(self, index, value):
"""Insert value at index.
Args:
index (int): Index to insert value at
value: Value to insert
Raises:
ValueError: If value already in self
IndexError: If start or end are out of range
"""
if value in self:
raise ValueError
index = self._fix_neg_index(index)
self._dict[value] = index
for elem in self._list[index:]:
self._dict[elem] += 1
self._list.insert(index, value)
def append(self, value):
"""Append value to the end.
Args:
value: Value to append
Raises:
ValueError: If value alread in self
TypeError: If value isn't hashable
"""
self._append(value)
def extend(self, values):
"""Append all values to the end.
If any of the values are present, ValueError will
be raised and none of the values will be appended.
Args:
values (Iterable): Values to append
Raises:
ValueError: If any values are already present or there are duplicates
in the passed values.
TypeError: If any of the values aren't hashable.
"""
self._extend(values)
def __iadd__(self, values):
"""Add all values to the end of self.
Args:
values (Iterable): Values to append
Raises:
ValueError: If any values are already present
"""
self._check_type(values, '+=')
self.extend(values)
return self
def remove(self, value):
"""Remove value from self.
Args:
value: Element to remove from self
Raises:
ValueError: if element is already present
"""
try:
index = self._dict[value]
except KeyError:
raise ValueError('Value "%s" is not present.')
else:
del self[index]
def remove_all(self, elems_to_delete):
"""Remove all elements from elems_to_delete, raises ValueErrors.
See Also:
discard_all
Args:
elems_to_delete (Iterable): Elements to remove.
Raises:
ValueError: If the count of any element is greater in
elems_to_delete than self.
TypeError: If any of the values aren't hashable.
"""
self._delete_all(elems_to_delete, raise_errors=True)
# Implement MutableSet
def add(self, item):
"""Add an item.
Note:
This does not raise a ValueError for an already present value like
append does. This is to match the behavior of set.add
Args:
item: Item to add
Raises:
TypeError: If item isn't hashable.
"""
self._add(item)
def update(self, values):
"""Add all values to the end.
If any of the values are present, silently ignore
them (as opposed to extend which raises an Error).
See also:
extend
Args:
values (Iterable): Values to add
Raises:
TypeError: If any of the values are unhashable.
"""
self._update(values)
def discard_all(self, elems_to_delete):
"""Discard all the elements from elems_to_delete.
This is much faster than removing them one by one.
This runs in O(len(self) + len(elems_to_delete))
Args:
elems_to_delete (Iterable): Elements to discard.
Raises:
TypeError: If any of the values aren't hashable.
"""
self._delete_all(elems_to_delete, raise_errors=False)
def discard(self, value):
"""Discard an item.
Note:
This does not raise a ValueError for a missing value like remove does.
This is to match the behavior of set.discard
"""
try:
self.remove(value)
except ValueError:
pass
def difference_update(self, other):
"""Update self to include only the differene with other."""
other = set(other)
indices_to_delete = set()
for i, elem in enumerate(self):
if elem in other:
indices_to_delete.add(i)
if indices_to_delete:
self._delete_values_by_index(indices_to_delete)
def intersection_update(self, other):
"""Update self to include only the intersection with other."""
other = set(other)
indices_to_delete = set()
for i, elem in enumerate(self):
if elem not in other:
indices_to_delete.add(i)
if indices_to_delete:
self._delete_values_by_index(indices_to_delete)
def symmetric_difference_update(self, other):
"""Update self to include only the symmetric difference with other."""
other = setlist(other)
indices_to_delete = set()
for i, item in enumerate(self):
if item in other:
indices_to_delete.add(i)
for item in other:
self.add(item)
self._delete_values_by_index(indices_to_delete)
def __isub__(self, other):
self._check_type(other, '-=')
self.difference_update(other)
return self
def __iand__(self, other):
self._check_type(other, '&=')
self.intersection_update(other)
return self
def __ior__(self, other):
self._check_type(other, '|=')
self.update(other)
return self
def __ixor__(self, other):
self._check_type(other, '^=')
self.symmetric_difference_update(other)
return self
# New methods
def shuffle(self, random=None):
"""Shuffle all of the elements in self randomly."""
random_.shuffle(self._list, random=random)
for i, elem in enumerate(self._list):
self._dict[elem] = i
def sort(self, *args, **kwargs):
"""Sort this setlist in place."""
self._list.sort(*args, **kwargs)
for index, value in enumerate(self._list):
self._dict[value] = index
class frozensetlist(_basesetlist, Hashable):
"""An immutable (hashable) setlist."""
def __hash__(self):
if not hasattr(self, '_hash_value'):
self._hash_value = _util.hash_iterable(self)
return self._hash_value
-28
View File
@@ -1,28 +0,0 @@
version: '{build}'
pull_requests:
do_not_increment_build_number: true
environment:
ProjectVersion: build$(APPVEYOR_BUILD_VERSION)
matrix:
- PYTHON: C:\PYTHON36
install:
- ps: 'if(Test-Path env:APPVEYOR_REPO_TAG_NAME) {$env:ProjectVersion=$env:APPVEYOR_REPO_TAG_NAME}'
- '%PYTHON%\python.exe --version'
- '%PYTHON%\Scripts\pip install pyinstaller'
- '%PYTHON%\Scripts\pip install markdown'
- '%PYTHON%\python.exe -m markdown README.md > README.html'
- '%PYTHON%\Scripts\pyinstaller bundle\EntranceRandomizer.spec'
- 'mkdir dist\EntranceRandomizer\ext'
- 'move dist\EntranceRandomizer\*.pyd dist\EntranceRandomizer\ext'
- 'move dist\EntranceRandomizer\tcl*.dll dist\EntranceRandomizer\ext'
- 'move dist\EntranceRandomizer\tk*.dll dist\EntranceRandomizer\ext'
- ps: '$env:ER_Version= &"$env:PYTHON\python.exe" -c "import Main; import re; print(re.match(''[0-9]+\\.[0-9]+\\.[0-9]+'',Main.__version__).group(0))"'
- '"%WIX%\bin\heat.exe" dir "dist\EntranceRandomizer" -sfrag -srd -suid -dr INSTALLDIR -cg ERFiles -ag -template fragment -t bundle\components.xslt -out build\components.wxs'
- '"%WIX%\bin\candle.exe" -out build\ bundle\*.wxs build\*.wxs'
- '"%WIX%\bin\light.exe" -ext WixUIExtension build\*.wixobj -o dist\EntranceRandomizer-Installer-%ProjectVersion%-win32.msi -b dist\EntranceRandomizer'
build: off
artifacts:
- path: dist/EntranceRandomizer*.msi
name: EntranceRandomizer-Installer-$(ProjectVersion)-win32.msi
- path: dist/EntranceRandomizer/
name: EntranceRandomizer-Raw-$(ProjectVersion)-win32.zip
+100
View File
@@ -0,0 +1,100 @@
---
layout: default
title: Blog
nav_order: 6
has_children: false
---
# Development Blog
{: .no_toc }
Latest updates, release notes, and development insights for ALttP Door Randomizer.
{: .fs-6 .fw-300 }
---
## Recent Posts
{% assign posts = site.posts | sort: 'date' | reverse %}
{% for post in posts limit:10 %}
<div class="post-entry" style="margin-bottom: 2em; padding-bottom: 1em; border-bottom: 1px solid #eeebee;">
<h3 style="margin-bottom: 0.5em;">
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
</h3>
<p style="color: #5C5962; font-size: 0.9em; margin-bottom: 0.5em;">
{{ post.date | date: "%B %d, %Y" }}
{% if post.author %} • by {{ post.author }}{% endif %}
</p>
<p>{{ post.excerpt | strip_html | truncatewords: 50 }}</p>
<p><a href="{{ post.url | relative_url }}">Read more →</a></p>
</div>
{% endfor %}
---
## Categories
Browse posts by category:
- [Release Notes](#release-notes)
- [Development Updates](#development-updates)
- [Feature Highlights](#feature-highlights)
- [Technical Deep Dives](#technical-deep-dives)
### Release Notes
{% assign release_posts = site.posts | where: "category", "release" %}
{% for post in release_posts limit:5 %}
- [{{ post.title }}]({{ post.url | relative_url }}) - {{ post.date | date: "%B %d, %Y" }}
{% endfor %}
### Development Updates
{% assign dev_posts = site.posts | where: "category", "development" %}
{% for post in dev_posts limit:5 %}
- [{{ post.title }}]({{ post.url | relative_url }}) - {{ post.date | date: "%B %d, %Y" }}
{% endfor %}
### Feature Highlights
{% assign feature_posts = site.posts | where: "category", "features" %}
{% for post in feature_posts limit:5 %}
- [{{ post.title }}]({{ post.url | relative_url }}) - {{ post.date | date: "%B %d, %Y" }}
{% endfor %}
### Technical Deep Dives
{% assign feature_posts = site.posts | where: "category", "features" %}
{% for post in feature_posts limit:5 %}
- [{{ post.title }}]({{ post.url | relative_url }}) - {{ post.date | date: "%B %d, %Y" }}
{% endfor %}
---
## Subscribe
Stay up to date with Door Randomizer development:
- **Discord**: Join [ALTTP Randomizer Discord](https://discordapp.com/invite/alttprandomizer) in `#door-rando`
---
## Archive
View all posts by year:
{% assign posts_by_year = site.posts | group_by_exp: "post", "post.date | date: '%Y'" %}
{% for year in posts_by_year %}
### {{ year.name }}
{% for post in year.items %}
- [{{ post.title }}]({{ post.url | relative_url }}) - {{ post.date | date: "%B %d, %Y" }}
{% endfor %}
{% endfor %}
---
## Contributing to the Blog
Want to write a guest post or contribute content?
Contact us on Discord to discuss your ideas!
+1 -1
View File
@@ -1,4 +1,4 @@
import sys
import os
import sys
sys.path.append(os.path.join(sys._MEIPASS, "ext"))
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Some files were not shown because too many files have changed in this diff Show More