Skip to content

Commit 791eb7f

Browse files
author
threeandthreee
committed
Merge branch 'ladx/not-ger' into ladx/beta-4
2 parents ba1ebb0 + c245d28 commit 791eb7f

10 files changed

Lines changed: 433 additions & 129 deletions

File tree

worlds/ladx_beta/LADXR/entranceInfo.py

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
class EntranceInfo:
3-
def __init__(self, room, alt_room=None, *, type=None, dungeon=None, index=None, instrument_room=None, target=None):
3+
def __init__(self, room, alt_room=None, *, type=None, dungeon=None, index=None, instrument_room=None, target=None, x=None, y=None):
44
if type is None and dungeon is not None:
55
type = "dungeon"
66
assert type is not None, "Missing entrance type"
@@ -11,6 +11,8 @@ def __init__(self, room, alt_room=None, *, type=None, dungeon=None, index=None,
1111
self.index = index
1212
self.instrument_room = instrument_room
1313
self.target = target
14+
self.x = x
15+
self.y = y
1416

1517

1618
ENTRANCE_INFO = {
@@ -23,22 +25,22 @@ def __init__(self, room, alt_room=None, *, type=None, dungeon=None, index=None,
2325
"left_taltal_entrance": EntranceInfo(0x15, target=0x2ea, type="connector"),
2426
"obstacle_cave_entrance": EntranceInfo(0x17, target=0x2b6, type="connector"),
2527
"left_to_right_taltalentrance": EntranceInfo(0x07, target=0x2ee, type="connector"),
26-
"obstacle_cave_outside_chest": EntranceInfo(0x18, target=0x2bb, type="connector", index=0),
27-
"obstacle_cave_exit": EntranceInfo(0x18, target=0x2bc, type="connector", index=1),
28+
"obstacle_cave_outside_chest": EntranceInfo(0x18, target=0x2bb, type="connector", index=0, x=104, y=18),
29+
"obstacle_cave_exit": EntranceInfo(0x18, target=0x2bc, type="connector", index=1, x=136, y=18),
2830
"papahl_entrance": EntranceInfo(0x19, target=0x289, type="connector"),
29-
"papahl_exit": EntranceInfo(0x0A, target=0x28b, type="connector", index=0),
30-
"rooster_house": EntranceInfo(0x0A, target=0x29f, type="dummy", index=2),
31-
"bird_cave": EntranceInfo(0x0A, target=0x27e, type="single", index=1),
32-
"multichest_left": EntranceInfo(0x1D, target=0x2f9, type="connector", index=0),
33-
"multichest_right": EntranceInfo(0x1D, target=0x2fa, type="connector", index=1),
31+
"papahl_exit": EntranceInfo(0x0A, target=0x28b, type="connector", index=0, x=24, y=112),
32+
"rooster_house": EntranceInfo(0x0A, target=0x29f, type="dummy", index=2, x=72, y=34),
33+
"bird_cave": EntranceInfo(0x0A, target=0x27e, type="single", index=1, x=120, y=112),
34+
"multichest_left": EntranceInfo(0x1D, target=0x2f9, type="connector", index=0, x=24, y=48),
35+
"multichest_right": EntranceInfo(0x1D, target=0x2fa, type="connector", index=1, x=120, y=80),
3436
"multichest_top": EntranceInfo(0x0D, target=0x2f2, type="connector"),
35-
"right_taltal_connector1": EntranceInfo(0x1E, target=0x280, type="connector", index=0),
36-
"right_taltal_connector2": EntranceInfo(0x1F, target=0x282, type="connector", index=0),
37-
"right_taltal_connector3": EntranceInfo(0x1E, target=0x283, type="connector", index=1),
38-
"right_taltal_connector4": EntranceInfo(0x1F, target=0x287, type="connector", index=2),
39-
"right_taltal_connector5": EntranceInfo(0x1F, target=0x28c, type="connector", index=1),
37+
"right_taltal_connector1": EntranceInfo(0x1E, target=0x280, type="connector", index=0, x=56, y=16),
38+
"right_taltal_connector2": EntranceInfo(0x1F, target=0x282, type="connector", index=0, x=40, y=16),
39+
"right_taltal_connector3": EntranceInfo(0x1E, target=0x283, type="connector", index=1, x=120, y=16),
40+
"right_taltal_connector4": EntranceInfo(0x1F, target=0x287, type="connector", index=2, x=88, y=64),
41+
"right_taltal_connector5": EntranceInfo(0x1F, target=0x28c, type="connector", index=1, x=120, y=16),
4042
"right_taltal_connector6": EntranceInfo(0x0F, target=0x28e, type="connector"),
41-
"right_fairy": EntranceInfo(0x1F, target=0x1fb, type="dummy", index=3),
43+
"right_fairy": EntranceInfo(0x1F, target=0x1fb, type="dummy", index=3, x=56, y=80),
4244
"d7": EntranceInfo(0x0E, "Alt0E", target=0x20e, dungeon=7, instrument_room=0x22C),
4345
# Row 2-3
4446
"writes_cave_left": EntranceInfo(0x20, target=0x2ae, type="connector"),
@@ -48,12 +50,12 @@ def __init__(self, room, alt_room=None, *, type=None, dungeon=None, index=None,
4850
"d2": EntranceInfo(0x24, target=0x136, dungeon=2, instrument_room=0x12A),
4951
"moblin_cave": EntranceInfo(0x35, target=0x2f0, type="single"),
5052
"photo_house": EntranceInfo(0x37, target=0x2b5, type="dummy"),
51-
"mambo": EntranceInfo(0x2A, target=0x2fd, type="single"),
52-
"d4": EntranceInfo(0x2B, "Alt2B", target=0x17a, dungeon=4, index=0, instrument_room=0x162),
53+
"mambo": EntranceInfo(0x2A, target=0x2fd, type="water"),
54+
"d4": EntranceInfo(0x2B, "Alt2B", target=0x17a, dungeon=4, index=0, x=72, y=34, instrument_room=0x162),
5355
# TODO
5456
# "d4_connector": EntranceInfo(0x2B, "Alt2B", index=1),
5557
# "d4_connector_exit": EntranceInfo(0x2D),
56-
"heartpiece_swim_cave": EntranceInfo(0x2E, target=0x1f2, type="single"),
58+
"heartpiece_swim_cave": EntranceInfo(0x2E, target=0x1f2, type="water"),
5759
"raft_return_exit": EntranceInfo(0x2F, target=0x1e7, type="connector"),
5860
"raft_house": EntranceInfo(0x3F, target=0x2b0, type="insanity"),
5961
"raft_return_enter": EntranceInfo(0x8F, target=0x1f7, type="connector"),
@@ -70,19 +72,19 @@ def __init__(self, room, alt_room=None, *, type=None, dungeon=None, index=None,
7072
# Castle
7173
"castle_jump_cave": EntranceInfo(0x78, target=0x1fd, type="single"),
7274
"castle_main_entrance": EntranceInfo(0x69, target=0x2d3, type="connector"),
73-
"castle_upper_left": EntranceInfo(0x59, target=0x2d5, type="connector", index=0),
74-
"castle_upper_right": EntranceInfo(0x59, target=0x2d6, type="single", index=1),
75+
"castle_upper_left": EntranceInfo(0x59, target=0x2d5, type="connector", index=0, x=24, y=48),
76+
"castle_upper_right": EntranceInfo(0x59, target=0x2d6, type="single", index=1, x=88, y=64),
7577
"castle_secret_exit": EntranceInfo(0x49, target=0x1eb, type="connector"),
7678
"castle_secret_entrance": EntranceInfo(0x4A, target=0x1ec, type="connector"),
7779
"castle_phone": EntranceInfo(0x4B, target=0x2cc, type="dummy"),
7880
# Mabe village
79-
"papahl_house_left": EntranceInfo(0x82, target=0x2a5, type="connector", index=0),
80-
"papahl_house_right": EntranceInfo(0x82, target=0x2a6, type="connector", index=1),
81+
"papahl_house_left": EntranceInfo(0x82, target=0x2a5, type="connector", index=0, x=88, y=82),
82+
"papahl_house_right": EntranceInfo(0x82, target=0x2a6, type="connector", index=1, x=120, y=82),
8183
"dream_hut": EntranceInfo(0x83, target=0x2aa, type="single"),
8284
"rooster_grave": EntranceInfo(0x92, target=0x1f4, type="single"),
8385
"shop": EntranceInfo(0x93, target=0x2a1, type="single"),
84-
"madambowwow": EntranceInfo(0xA1, target=0x2a7, type="dummy", index=1),
85-
"kennel": EntranceInfo(0xA1, target=0x2b2, type="single", index=0),
86+
"madambowwow": EntranceInfo(0xA1, target=0x2a7, type="dummy", index=1, x=56, y=66),
87+
"kennel": EntranceInfo(0xA1, target=0x2b2, type="single", index=0, x=88, y=66),
8688
"start_house": EntranceInfo(0xA2, target=0x2a3, type="start"),
8789
"library": EntranceInfo(0xB0, target=0x1fa, type="dummy"),
8890
"ulrira": EntranceInfo(0xB1, target=0x2a9, type="dummy"),
@@ -97,9 +99,9 @@ def __init__(self, room, alt_room=None, *, type=None, dungeon=None, index=None,
9799
"d3": EntranceInfo(0xB5, target=0x152, dungeon=3, instrument_room=0x159),
98100
"prairie_right_phone": EntranceInfo(0x88, target=0x29c, type="dummy"),
99101
"seashell_mansion": EntranceInfo(0x8A, target=0x2e9, type="single"),
100-
"prairie_right_cave_top": EntranceInfo(0xB8, target=0x292, type="connector", index=1),
102+
"prairie_right_cave_top": EntranceInfo(0xB8, target=0x292, type="connector", index=1, x=120, y=96),
101103
"prairie_right_cave_bottom": EntranceInfo(0xC8, target=0x293, type="connector"),
102-
"prairie_right_cave_high": EntranceInfo(0xB8, target=0x295, type="connector", index=0),
104+
"prairie_right_cave_high": EntranceInfo(0xB8, target=0x295, type="connector", index=0, x=88, y=48),
103105
"prairie_to_animal_connector": EntranceInfo(0xAA, target=0x2d0, type="connector"),
104106
"animal_to_prairie_connector": EntranceInfo(0xAB, target=0x2d1, type="connector"),
105107

@@ -126,11 +128,11 @@ def __init__(self, room, alt_room=None, *, type=None, dungeon=None, index=None,
126128
"d5": EntranceInfo(0xD9, target=0x1a1, dungeon=5, instrument_room=0x182),
127129
# Animal village
128130
"animal_phone": EntranceInfo(0xDB, target=0x2e3, type="dummy"),
129-
"animal_house1": EntranceInfo(0xCC, target=0x2db, type="dummy", index=0),
130-
"animal_house2": EntranceInfo(0xCC, target=0x2dd, type="dummy", index=1),
131-
"animal_house3": EntranceInfo(0xCD, target=0x2d9, type="trade", index=1),
132-
"animal_house4": EntranceInfo(0xCD, target=0x2da, type="dummy", index=2),
131+
"animal_house1": EntranceInfo(0xCC, target=0x2db, type="dummy", index=0, x=40, y=80),
132+
"animal_house2": EntranceInfo(0xCC, target=0x2dd, type="dummy", index=1, x=120, y=80),
133+
"animal_house3": EntranceInfo(0xCD, target=0x2d9, type="trade", index=1, x=40, y=80),
134+
"animal_house4": EntranceInfo(0xCD, target=0x2da, type="dummy", index=2, x=88, y=80),
133135
"animal_house5": EntranceInfo(0xDD, target=0x2d7, type="trade"),
134-
"animal_cave": EntranceInfo(0xCD, target=0x2f7, type="single", index=0),
136+
"animal_cave": EntranceInfo(0xCD, target=0x2f7, type="single", index=0, x=136, y=32),
135137
"desert_cave": EntranceInfo(0xCF, target=0x1f9, type="single"),
136138
}

worlds/ladx_beta/LADXR/generator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ def generateRom(base_rom: bytes, args, patch_data: Dict):
129129
assembler.const("HARD_MODE", 1 if options["hard_mode"] else 0)
130130

131131
patches.core.cleanup(rom)
132+
patches.core.fixD7exit(rom)
132133
patches.save.singleSaveSlot(rom)
133134
patches.phone.patchPhone(rom)
134135
patches.photographer.fixPhotographer(rom)

worlds/ladx_beta/LADXR/logic/__init__.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,38 @@ def __init__(self, configuration_options, *, world_setup):
5151
world.updateIndoorLocation("d0", dungeonColor.DungeonColor(configuration_options, world_setup, r).entrance)
5252

5353
if configuration_options.overworld != "random":
54-
for k in world.overworld_entrance.keys():
54+
for k in world.entrances.keys():
5555
assert k in world_setup.entrance_mapping, k
5656
for k in world_setup.entrance_mapping.keys():
57-
assert k in world.overworld_entrance, k
58-
59-
for entrance, indoor in world_setup.entrance_mapping.items():
60-
exterior = world.overworld_entrance[entrance]
61-
if world.indoor_location[indoor] is not None:
62-
exterior.location.connect(world.indoor_location[indoor], exterior.requirement)
63-
if exterior.enterIsSet():
64-
exterior.location.connect(world.indoor_location[indoor], exterior.one_way_enter_requirement, one_way=True)
65-
if exterior.exitIsSet():
66-
world.indoor_location[indoor].connect(exterior.location, exterior.one_way_exit_requirement, one_way=True)
57+
assert k in world.entrances, k
58+
59+
for source, target in world_setup.entrance_mapping.items():
60+
se = world.entrances[source]
61+
if not se.location:
62+
continue
63+
te = world.entrances[target]
64+
empty_cycle_targets = {target}
65+
while te.location is None:
66+
# If the target is empty, we need to check if we can get from that empty location to somewhere else.
67+
assert te.requirement is None
68+
assert not te.enterIsSet()
69+
assert not te.exitIsSet()
70+
target = world_setup.entrance_mapping[target]
71+
if target in empty_cycle_targets:
72+
break
73+
empty_cycle_targets.add(target)
74+
te = world.entrances[target]
75+
if te.location and te.location != se.location:
76+
if se.requirement is not None and te.requirement is not None:
77+
se.location.connect(te.location, AND(se.requirement, te.requirement), one_way=True)
78+
elif se.requirement is not None:
79+
se.location.connect(te.location, se.requirement, one_way=True)
80+
else:
81+
se.location.connect(te.location, te.requirement, one_way=True)
82+
if se.enterIsSet():
83+
se.location.connect(te.location, se.one_way_enter_requirement, one_way=True)
84+
if te.exitIsSet():
85+
se.location.connect(te.location, te.one_way_exit_requirement, one_way=True)
6786

6887
egg_trigger = AND(OCARINA, SONG1)
6988
if configuration_options.logic == 'glitched' or configuration_options.logic == 'hell':
@@ -155,7 +174,7 @@ def __init__(self, settings, rnd=None, *, world_setups=None):
155174
world_setup = WorldSetup()
156175
world_setup.randomize(options, rnd)
157176
world = Logic(options, world_setup=world_setup)
158-
if options.entranceshuffle not in ("advanced", "expert", "insanity") or len(world.iteminfo_list) == sum(itempool.ItemPool(options, rnd).toDict().values()):
177+
if options.entranceshuffle not in ("split", "mixed", "wild", "chaos", "insane", "madness") or len(world.iteminfo_list) == sum(itempool.ItemPool(options, rnd).toDict().values()):
159178
break
160179

161180
for ii in world.iteminfo_list:

worlds/ladx_beta/LADXR/logic/overworld.py

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66

77
class World:
88
def __init__(self, options, world_setup, r):
9-
self.overworld_entrance = {}
10-
self.indoor_location = {}
9+
self.entrances = {}
1110

1211
mabe_village = Location("Mabe Village")
1312
Location().add(HeartPiece(0x2A4)).connect(mabe_village, r.bush) # well
@@ -436,6 +435,7 @@ def __init__(self, options, world_setup, r):
436435
d7_platau = Location()
437436
d7_tower = Location()
438437
d7_platau.connect(d7_tower, AND(POWER_BRACELET, BIRD_KEY), one_way=True)
438+
d7_tower.connect(d7_platau, None, one_way=True)
439439
self._addEntrance("right_taltal_connector1", water_cave_hole, right_taltal_connector1, None)
440440
self._addEntrance("right_taltal_connector2", right_taltal_connector_outside1, right_taltal_connector1, None)
441441
self._addEntrance("right_taltal_connector3", right_taltal_connector_outside1, right_taltal_connector2, None)
@@ -658,33 +658,33 @@ def __init__(self, options, world_setup, r):
658658
self.windfish = windfish
659659

660660
def _addEntrance(self, name, outside, inside, requirement):
661-
assert name not in self.overworld_entrance, "Duplicate entrance: %s" % name
661+
assert name not in self.entrances, "Duplicate entrance: %s" % name
662662
assert name in ENTRANCE_INFO
663-
self.overworld_entrance[name] = EntranceExterior(outside, requirement)
664-
self.indoor_location[name] = inside
663+
self.entrances[name] = EntranceExterior(outside, requirement)
664+
self.entrances[f"{name}:inside"] = EntranceExterior(inside, None)
665665

666666
def _addEntranceRequirement(self, name, requirement):
667-
assert name in self.overworld_entrance
668-
self.overworld_entrance[name].addRequirement(requirement)
667+
assert name in self.entrances
668+
self.entrances[name].addRequirement(requirement)
669669

670670
def _addEntranceRequirementEnter(self, name, requirement):
671-
assert name in self.overworld_entrance
672-
self.overworld_entrance[name].addEnterRequirement(requirement)
671+
assert name in self.entrances
672+
self.entrances[name].addEnterRequirement(requirement)
673673

674674
def _addEntranceRequirementExit(self, name, requirement):
675-
assert name in self.overworld_entrance
676-
self.overworld_entrance[name].addExitRequirement(requirement)
675+
assert name in self.entrances
676+
self.entrances[name].addExitRequirement(requirement)
677677

678678
def updateIndoorLocation(self, name, location):
679-
assert name in self.indoor_location
680-
assert self.indoor_location[name] is None
681-
self.indoor_location[name] = location
679+
name = f"{name}:inside"
680+
assert name in self.entrances, name
681+
assert self.entrances[name].location is None
682+
self.entrances[name].location = location
682683

683684

684685
class DungeonDiveOverworld:
685686
def __init__(self, options, r):
686-
self.overworld_entrance = {}
687-
self.indoor_location = {}
687+
self.entrances = {}
688688

689689
start_house = Location("Start House").add(StartItem())
690690
Location().add(ShopItem(0)).connect(start_house, OR(COUNT("RUPEES", 200), SWORD))
@@ -702,23 +702,23 @@ def __init__(self, options, r):
702702
windfish = Location("Windfish").connect(nightmare, AND(MAGIC_POWDER, SWORD, OR(BOOMERANG, BOW)))
703703

704704
self.start = start_house
705-
self.overworld_entrance = {
706-
"d1": EntranceExterior(start_house, None),
707-
"d2": EntranceExterior(start_house, None),
708-
"d3": EntranceExterior(start_house, None),
709-
"d4": EntranceExterior(start_house, None),
710-
"d5": EntranceExterior(start_house, FLIPPERS),
711-
"d6": EntranceExterior(start_house, None),
712-
"d7": EntranceExterior(start_house, None),
713-
"d8": EntranceExterior(start_house, None),
714-
"d0": EntranceExterior(start_house, None),
705+
self.entrances = {
706+
"d1:inside": EntranceExterior(start_house, None),
707+
"d2:inside": EntranceExterior(start_house, None),
708+
"d3:inside": EntranceExterior(start_house, None),
709+
"d4:inside": EntranceExterior(start_house, None),
710+
"d5:inside": EntranceExterior(start_house, FLIPPERS),
711+
"d6:inside": EntranceExterior(start_house, None),
712+
"d7:inside": EntranceExterior(start_house, None),
713+
"d8:inside": EntranceExterior(start_house, None),
714+
"d0:inside": EntranceExterior(start_house, None),
715715
}
716716
self.egg = egg
717717
self.nightmare = nightmare
718718
self.windfish = windfish
719719

720720
def updateIndoorLocation(self, name, location):
721-
self.indoor_location[name] = location
721+
self.entrances[f"{name}:inside"].location = location
722722

723723

724724
class EntranceExterior:

worlds/ladx_beta/LADXR/patches/core.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from .. import assembler
22
from ..assembler import ASM
33
from ..entranceInfo import ENTRANCE_INFO
4-
from ..roomEditor import RoomEditor, ObjectWarp, ObjectHorizontal
4+
from ..roomEditor import RoomEditor, Object, ObjectWarp, ObjectHorizontal
55
from ..backgroundEditor import BackgroundEditor
66
from .. import utils
77

@@ -541,6 +541,16 @@ def addFrameCounter(rom, check_count):
541541
rom.banks[0x38][0x1400+n*0x20:0x1410+n*0x20] = utils.createTileData(gfx_high)
542542
rom.banks[0x38][0x1410+n*0x20:0x1420+n*0x20] = utils.createTileData(gfx_low)
543543

544+
# For the D7 exit, make it so that we can exit it properly in ER
545+
def fixD7exit(rom):
546+
re = RoomEditor(rom, 0x0E)
547+
for x in [0, 1, 2, 8, 9]:
548+
for y in range(3):
549+
re.removeObject(x, y)
550+
re.objects.append(Object(5, 2, 0xE1))
551+
re.objects.append(Object(5, 3, 0x4A))
552+
re.store(rom)
553+
544554
def addBootsControls(rom, boots_controls: int):
545555
if boots_controls == BootsControls.option_vanilla:
546556
return

0 commit comments

Comments
 (0)