Underworld dropshuffle
This commit is contained in:
+5
-3
@@ -2132,6 +2132,7 @@ class Location(object):
|
|||||||
self.real = not crystal
|
self.real = not crystal
|
||||||
self.always_allow = lambda item, state: False
|
self.always_allow = lambda item, state: False
|
||||||
self.access_rule = lambda state: True
|
self.access_rule = lambda state: True
|
||||||
|
self.verbose_rule = None
|
||||||
self.item_rule = lambda item: True
|
self.item_rule = lambda item: True
|
||||||
self.player = player
|
self.player = player
|
||||||
self.skip = False
|
self.skip = False
|
||||||
@@ -2601,7 +2602,7 @@ class Spoiler(object):
|
|||||||
outfile.write(f"Decouple Doors: {yn(self.metadata['decoupledoors'][player])}\n")
|
outfile.write(f"Decouple Doors: {yn(self.metadata['decoupledoors'][player])}\n")
|
||||||
outfile.write(f"Experimental: {yn(self.metadata['experimental'][player])}\n")
|
outfile.write(f"Experimental: {yn(self.metadata['experimental'][player])}\n")
|
||||||
outfile.write(f"Dungeon Counters: {self.metadata['dungeon_counters'][player]}\n")
|
outfile.write(f"Dungeon Counters: {self.metadata['dungeon_counters'][player]}\n")
|
||||||
outfile.write(f"Drop Shuffle: {yn(self.metadata['dropshuffle'][player])}\n")
|
outfile.write(f"Drop Shuffle: {self.metadata['dropshuffle'][player]}\n")
|
||||||
outfile.write(f"Pottery Mode: {self.metadata['pottery'][player]}\n")
|
outfile.write(f"Pottery Mode: {self.metadata['pottery'][player]}\n")
|
||||||
outfile.write(f"Pot Shuffle (Legacy): {yn(self.metadata['potshuffle'][player])}\n")
|
outfile.write(f"Pot Shuffle (Legacy): {yn(self.metadata['potshuffle'][player])}\n")
|
||||||
outfile.write('Map shuffle: %s\n' % ('Yes' if self.metadata['mapshuffle'][player] else 'No'))
|
outfile.write('Map shuffle: %s\n' % ('Yes' if self.metadata['mapshuffle'][player] else 'No'))
|
||||||
@@ -2861,6 +2862,7 @@ mixed_travel_mode = {"prevent": 0, "allow": 1, "force": 2}
|
|||||||
|
|
||||||
# new byte 4: TDDD PPPP (tavern shuffle, drop, pottery)
|
# new byte 4: TDDD PPPP (tavern shuffle, drop, pottery)
|
||||||
# dropshuffle reserves 2 bits, pottery needs 4)
|
# dropshuffle reserves 2 bits, pottery needs 4)
|
||||||
|
drop_shuffle_mode = {'none': 0, 'keys': 1, 'underworld': 2}
|
||||||
pottery_mode = {'none': 0, 'keys': 2, 'lottery': 3, 'dungeon': 4, 'cave': 5, 'cavekeys': 6, 'reduced': 7,
|
pottery_mode = {'none': 0, 'keys': 2, 'lottery': 3, 'dungeon': 4, 'cave': 5, 'cavekeys': 6, 'reduced': 7,
|
||||||
'clustered': 8, 'nonempty': 9}
|
'clustered': 8, 'nonempty': 9}
|
||||||
|
|
||||||
@@ -2919,7 +2921,7 @@ class Settings(object):
|
|||||||
| (0x8 if w.standardize_palettes[p] == "original" else 0)
|
| (0x8 if w.standardize_palettes[p] == "original" else 0)
|
||||||
| (0 if w.intensity[p] == "random" else w.intensity[p]),
|
| (0 if w.intensity[p] == "random" else w.intensity[p]),
|
||||||
|
|
||||||
(0x80 if w.shuffletavern[p] else 0) | (0x10 if w.dropshuffle[p] else 0) | (pottery_mode[w.pottery[p]]),
|
(0x80 if w.shuffletavern[p] else 0) | (drop_shuffle_mode[w.dropshuffle[p]] << 4) | (pottery_mode[w.pottery[p]]),
|
||||||
|
|
||||||
((8 if w.crystals_gt_orig[p] == "random" else int(w.crystals_gt_orig[p])) << 3)
|
((8 if w.crystals_gt_orig[p] == "random" else int(w.crystals_gt_orig[p])) << 3)
|
||||||
| (counter_mode[w.dungeon_counters[p]] << 1) | (1 if w.experimental[p] else 0),
|
| (counter_mode[w.dungeon_counters[p]] << 1) | (1 if w.experimental[p] else 0),
|
||||||
@@ -2974,7 +2976,7 @@ class Settings(object):
|
|||||||
args.intensity[p] = "random" if intensity == 0 else intensity
|
args.intensity[p] = "random" if intensity == 0 else intensity
|
||||||
|
|
||||||
args.shuffletavern[p] = True if settings[4] & 0x80 else False
|
args.shuffletavern[p] = True if settings[4] & 0x80 else False
|
||||||
args.dropshuffle[p] = True if settings[4] & 0x10 else False
|
args.dropshuffle[p] = r(drop_shuffle_mode)[settings[4] & 0x70]
|
||||||
args.pottery[p] = r(pottery_mode)[settings[4] & 0x0F]
|
args.pottery[p] = r(pottery_mode)[settings[4] & 0x0F]
|
||||||
|
|
||||||
args.dungeon_counters[p] = r(counter_mode)[(settings[5] & 0x6) >> 1]
|
args.dungeon_counters[p] = r(counter_mode)[(settings[5] & 0x6) >> 1]
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ def parse_cli(argv, no_defaults=False):
|
|||||||
ret.keyshuffle = 'wild'
|
ret.keyshuffle = 'wild'
|
||||||
|
|
||||||
if ret.keydropshuffle:
|
if ret.keydropshuffle:
|
||||||
ret.dropshuffle = True
|
ret.dropshuffle = 'keys' if ret.dropshuffle == 'none' else ret.dropshuffle
|
||||||
ret.pottery = 'keys' if ret.pottery == 'none' else ret.pottery
|
ret.pottery = 'keys' if ret.pottery == 'none' else ret.pottery
|
||||||
|
|
||||||
if ret.retro or ret.mode == 'retro':
|
if ret.retro or ret.mode == 'retro':
|
||||||
@@ -196,7 +196,7 @@ def parse_settings():
|
|||||||
|
|
||||||
"shopsanity": False,
|
"shopsanity": False,
|
||||||
'keydropshuffle': False,
|
'keydropshuffle': False,
|
||||||
'dropshuffle': False,
|
'dropshuffle': 'none',
|
||||||
'pottery': 'none',
|
'pottery': 'none',
|
||||||
'colorizepots': False,
|
'colorizepots': False,
|
||||||
'shufflepots': False,
|
'shufflepots': False,
|
||||||
|
|||||||
+5
-5
@@ -841,10 +841,10 @@ def main_dungeon_pool(dungeon_pool, world, player):
|
|||||||
all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items))
|
all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items))
|
||||||
target_items = 34
|
target_items = 34
|
||||||
if world.keyshuffle[player] == 'universal':
|
if world.keyshuffle[player] == 'universal':
|
||||||
target_items += 1 if world.dropshuffle[player] else 0 # the hc big key
|
target_items += 1 if world.dropshuffle[player] != 'none' else 0 # the hc big key
|
||||||
else:
|
else:
|
||||||
target_items += 29 # small keys in chests
|
target_items += 29 # small keys in chests
|
||||||
if world.dropshuffle[player]:
|
if world.dropshuffle[player] != 'none':
|
||||||
target_items += 14 # 13 dropped smalls + 1 big
|
target_items += 14 # 13 dropped smalls + 1 big
|
||||||
if world.pottery[player] not in ['none', 'cave']:
|
if world.pottery[player] not in ['none', 'cave']:
|
||||||
target_items += 19 # 19 pot keys
|
target_items += 19 # 19 pot keys
|
||||||
@@ -1246,10 +1246,10 @@ def cross_dungeon(world, player):
|
|||||||
all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items))
|
all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items))
|
||||||
target_items = 34
|
target_items = 34
|
||||||
if world.keyshuffle[player] == 'universal':
|
if world.keyshuffle[player] == 'universal':
|
||||||
target_items += 1 if world.dropshuffle[player] else 0 # the hc big key
|
target_items += 1 if world.dropshuffle[player] != 'none' else 0 # the hc big key
|
||||||
else:
|
else:
|
||||||
target_items += 29 # small keys in chests
|
target_items += 29 # small keys in chests
|
||||||
if world.dropshuffle[player]:
|
if world.dropshuffle[player] != 'none':
|
||||||
target_items += 14 # 13 dropped smalls + 1 big
|
target_items += 14 # 13 dropped smalls + 1 big
|
||||||
if world.pottery[player] not in ['none', 'cave']:
|
if world.pottery[player] not in ['none', 'cave']:
|
||||||
target_items += 19 # 19 pot keys
|
target_items += 19 # 19 pot keys
|
||||||
@@ -1335,7 +1335,7 @@ def assign_cross_keys(dungeon_builders, world, player):
|
|||||||
start = time.process_time()
|
start = time.process_time()
|
||||||
if world.keyshuffle[player] == 'universal':
|
if world.keyshuffle[player] == 'universal':
|
||||||
remaining = 29
|
remaining = 29
|
||||||
if world.dropshuffle[player]:
|
if world.dropshuffle[player] != 'none':
|
||||||
remaining += 13
|
remaining += 13
|
||||||
if world.pottery[player] not in ['none', 'cave']:
|
if world.pottery[player] not in ['none', 'cave']:
|
||||||
remaining += 19
|
remaining += 19
|
||||||
|
|||||||
+1
-1
@@ -414,7 +414,7 @@ def generate_itempool(world, player):
|
|||||||
if world.take_any[player] != 'none':
|
if world.take_any[player] != 'none':
|
||||||
set_up_take_anys(world, player, skip_pool_adjustments)
|
set_up_take_anys(world, player, skip_pool_adjustments)
|
||||||
if world.keyshuffle[player] == 'universal':
|
if world.keyshuffle[player] == 'universal':
|
||||||
if world.dropshuffle[player] and not skip_pool_adjustments:
|
if world.dropshuffle[player] != 'none' and not skip_pool_adjustments:
|
||||||
world.itempool += [ItemFactory('Small Key (Universal)', player)] * 13
|
world.itempool += [ItemFactory('Small Key (Universal)', player)] * 13
|
||||||
if world.pottery[player] not in ['none', 'cave'] and not skip_pool_adjustments:
|
if world.pottery[player] not in ['none', 'cave'] and not skip_pool_adjustments:
|
||||||
world.itempool += [ItemFactory('Small Key (Universal)', player)] * 19
|
world.itempool += [ItemFactory('Small Key (Universal)', player)] * 19
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
|
|||||||
'Single Bomb': (False, False, None, 0x27, 5, 'I make things\ngo BOOM! But\njust once.', 'and the explosion', 'the bomb-holding kid', 'firecracker for sale', 'blend fungus into bomb', '\'splosion boy explodes again', 'a bomb'),
|
'Single Bomb': (False, False, None, 0x27, 5, 'I make things\ngo BOOM! But\njust once.', '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, 0x5A, 15, 'This will give\nyou five shots\nwith your bow!', 'and the arrow pack', 'stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again', 'five arrows'),
|
'Arrows (5)': (False, False, None, 0x5A, 15, 'This will give\nyou five shots\nwith your bow!', '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, 'A bit of magic', 'and the bit of magic', 'bit-o-magic kid', 'magic bit for sale', 'fungus for magic', 'magic boy conjures again', 'a bit of magic'),
|
'Small Magic': (False, False, None, 0x45, 5, 'A bit of magic', '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, 0x5A, 40, 'A lot of magic', 'and lots of magic', 'lot-o-magic kid', 'magic refill for sale', 'fungus for magic', 'magic boy conjures again', 'a magic refill'),
|
'Big Magic': (False, False, None, 0xB4, 40, 'A lot of magic', '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, 0x5A, 999, 'Cucco of Legend', 'and the legendary cucco', 'chicken kid', 'fried chicken for sale', 'fungus for chicken', 'cucco boy clucks again', 'a cucco'),
|
'Chicken': (False, False, None, 0xB3, 999, '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, 'I make things\ngo triple\nBOOM!!!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'three bombs'),
|
'Bombs (3)': (False, False, None, 0x28, 15, 'I make things\ngo triple\nBOOM!!!', '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, 'I make things\ngo BOOM! Ten\ntimes!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'ten bombs'),
|
'Bombs (10)': (False, False, None, 0x31, 50, 'I make things\ngo BOOM! Ten\ntimes!', '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, 'Increase bomb\nstorage, low\nlow price', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'),
|
'Bomb Upgrade (+10)': (False, False, None, 0x52, 100, 'Increase bomb\nstorage, low\nlow price', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'),
|
||||||
@@ -174,7 +174,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
|
|||||||
'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'),
|
'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'),
|
'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'),
|
||||||
'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'),
|
'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'),
|
||||||
'Fairy': (False, False, None, 0x5A, 50, 'Just a pixie!', 'and the pixie', 'the pixie kid', 'pixie for sale', 'pixie fungus', 'bottle boy has pixie again', 'a pixie'),
|
'Fairy': (False, False, None, 0xB2, 50, 'Just a pixie!', 'and the pixie', 'the pixie kid', 'pixie for sale', 'pixie fungus', 'bottle boy has pixie again', 'a pixie'),
|
||||||
'Beat Agahnim 1': (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),
|
'Beat Agahnim 2': (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),
|
'Get Frog': (True, False, 'Event', 999, None, None, None, None, None, None, None, None),
|
||||||
|
|||||||
+1
-1
@@ -1422,7 +1422,7 @@ def prize_relevance_sig2(start_regions, d_name, dungeon_entrance):
|
|||||||
|
|
||||||
def validate_bk_layout(proposal, builder, start_regions, world, player):
|
def validate_bk_layout(proposal, builder, start_regions, world, player):
|
||||||
bk_special = check_bk_special(builder.master_sector.regions, world, player)
|
bk_special = check_bk_special(builder.master_sector.regions, world, player)
|
||||||
if world.bigkeyshuffle[player] and (world.dropshuffle[player] or not bk_special):
|
if world.bigkeyshuffle[player] and (world.dropshuffle[player] != 'none' or not bk_special):
|
||||||
return True
|
return True
|
||||||
flat_proposal = flatten_pair_list(proposal)
|
flat_proposal = flatten_pair_list(proposal)
|
||||||
state = ExplorationState(dungeon=builder.name)
|
state = ExplorationState(dungeon=builder.name)
|
||||||
|
|||||||
@@ -461,11 +461,13 @@ def copy_world(world):
|
|||||||
ret.bigkeyshuffle = world.bigkeyshuffle.copy()
|
ret.bigkeyshuffle = world.bigkeyshuffle.copy()
|
||||||
ret.bombbag = world.bombbag.copy()
|
ret.bombbag = world.bombbag.copy()
|
||||||
ret.flute_mode = world.flute_mode.copy()
|
ret.flute_mode = world.flute_mode.copy()
|
||||||
|
ret.bow_mode = world.bow_mode.copy()
|
||||||
ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy()
|
ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy()
|
||||||
ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy()
|
ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy()
|
||||||
ret.crystals_ganon_orig = world.crystals_ganon_orig.copy()
|
ret.crystals_ganon_orig = world.crystals_ganon_orig.copy()
|
||||||
ret.crystals_gt_orig = world.crystals_gt_orig.copy()
|
ret.crystals_gt_orig = world.crystals_gt_orig.copy()
|
||||||
ret.open_pyramid = world.open_pyramid.copy()
|
ret.open_pyramid = world.open_pyramid.copy()
|
||||||
|
ret.take_any = world.take_any.copy()
|
||||||
ret.boss_shuffle = world.boss_shuffle.copy()
|
ret.boss_shuffle = world.boss_shuffle.copy()
|
||||||
ret.enemy_shuffle = world.enemy_shuffle.copy()
|
ret.enemy_shuffle = world.enemy_shuffle.copy()
|
||||||
ret.enemy_health = world.enemy_health.copy()
|
ret.enemy_health = world.enemy_health.copy()
|
||||||
@@ -481,6 +483,7 @@ def copy_world(world):
|
|||||||
ret.mixed_travel = world.mixed_travel.copy()
|
ret.mixed_travel = world.mixed_travel.copy()
|
||||||
ret.standardize_palettes = world.standardize_palettes.copy()
|
ret.standardize_palettes = world.standardize_palettes.copy()
|
||||||
ret.restrict_boss_items = world.restrict_boss_items.copy()
|
ret.restrict_boss_items = world.restrict_boss_items.copy()
|
||||||
|
ret.data_tables = world.data_tables # can be changed...
|
||||||
|
|
||||||
for player in range(1, world.players + 1):
|
for player in range(1, world.players + 1):
|
||||||
if world.mode[player] != 'inverted':
|
if world.mode[player] != 'inverted':
|
||||||
|
|||||||
+2
-2
@@ -1023,8 +1023,8 @@ def adjust_locations(world, player):
|
|||||||
loc.address = pot_address(pot_index, datum[1])
|
loc.address = pot_address(pot_index, datum[1])
|
||||||
loc.pot = pot
|
loc.pot = pot
|
||||||
pot.location = loc
|
pot.location = loc
|
||||||
if (not world.dropshuffle[player] and drop_location)\
|
if ((world.dropshuffle[player] == 'none' and drop_location)
|
||||||
or (not drop_location and world.pottery[player] in ['none', 'cave']):
|
or (not drop_location and world.pottery[player] in ['none', 'cave'])):
|
||||||
loc.skip = True
|
loc.skip = True
|
||||||
else:
|
else:
|
||||||
key_item = loc.item
|
key_item = loc.item
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ from InitialSram import InitialSram
|
|||||||
|
|
||||||
from source.classes.SFX import randomize_sfx
|
from source.classes.SFX import randomize_sfx
|
||||||
from source.item.FillUtil import valid_pot_items
|
from source.item.FillUtil import valid_pot_items
|
||||||
from source.dungeon.RoomList import Room0127
|
from source.dungeon.EnemyList import EnemySprite
|
||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = '0587709ac8c5f2abf95b14d1e1264945'
|
RANDOMIZERBASEHASH = '81d7cf07a34d06ec875074296c39cd97'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -616,18 +616,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
location.pot.indicator = standing_item_flag
|
location.pot.indicator = standing_item_flag
|
||||||
location.pot.standing_item_code = code
|
location.pot.standing_item_code = code
|
||||||
continue
|
continue
|
||||||
elif location.type == LocationType.Drop:
|
elif location.type == LocationType.Drop: # handled in the sprite table routine
|
||||||
if location.item.player != player:
|
|
||||||
code = 0xF9
|
|
||||||
else:
|
|
||||||
code = 0xF8
|
|
||||||
sprite_pointer = snes_to_pc(location.address)
|
|
||||||
rom.write_byte(sprite_pointer, handle_native_dungeon(location, itemid))
|
|
||||||
if code == 0xF9:
|
|
||||||
rom.write_byte(sprite_pointer+1, location.item.player)
|
|
||||||
else:
|
|
||||||
rom.write_byte(sprite_pointer+1, 0)
|
|
||||||
rom.write_byte(sprite_pointer+2, code)
|
|
||||||
continue
|
continue
|
||||||
if location.address is None or (type(location.address) is int and location.address >= 0x400000):
|
if location.address is None or (type(location.address) is int and location.address >= 0x400000):
|
||||||
continue
|
continue
|
||||||
@@ -764,7 +753,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
valid_loc_by_dungeon = valid_dungeon_locations(valid_locations)
|
valid_loc_by_dungeon = valid_dungeon_locations(valid_locations)
|
||||||
|
|
||||||
# fix hc big key problems (map and compass too)
|
# fix hc big key problems (map and compass too)
|
||||||
if (world.doorShuffle[player] not in ['vanilla', 'basic'] or world.dropshuffle[player]
|
if (world.doorShuffle[player] not in ['vanilla', 'basic'] or world.dropshuffle[player] != 'none'
|
||||||
or world.pottery[player] not in ['none', 'cave']):
|
or world.pottery[player] not in ['none', 'cave']):
|
||||||
rom.write_byte(0x151f1, 2)
|
rom.write_byte(0x151f1, 2)
|
||||||
rom.write_byte(0x15270, 2)
|
rom.write_byte(0x15270, 2)
|
||||||
@@ -894,9 +883,9 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
|
|
||||||
credits_total = len(valid_locations)
|
credits_total = len(valid_locations)
|
||||||
|
|
||||||
if world.dropshuffle[player] or world.pottery[player] != 'none':
|
if world.dropshuffle[player] != 'none' or world.pottery[player] != 'none':
|
||||||
rom.write_byte(0x142A50, 1) # StandingItemsOn
|
rom.write_byte(0x142A50, 1) # StandingItemsOn
|
||||||
multiClientFlags = ((0x1 if world.dropshuffle[player] else 0)
|
multiClientFlags = ((0x1 if world.dropshuffle[player] != 'none' else 0)
|
||||||
| (0x2 if world.shopsanity[player] else 0)
|
| (0x2 if world.shopsanity[player] else 0)
|
||||||
| (0x4 if world.take_any[player] != 'none' else 0)
|
| (0x4 if world.take_any[player] != 'none' else 0)
|
||||||
| (0x8 if world.pottery[player] != 'none' else 0)
|
| (0x8 if world.pottery[player] != 'none' else 0)
|
||||||
@@ -904,7 +893,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_byte(0x142A51, multiClientFlags)
|
rom.write_byte(0x142A51, multiClientFlags)
|
||||||
# StandingItemCounterMask
|
# StandingItemCounterMask
|
||||||
rom.write_byte(0x142A55, ((0x1 if world.pottery[player] not in ['none', 'cave'] else 0)
|
rom.write_byte(0x142A55, ((0x1 if world.pottery[player] not in ['none', 'cave'] else 0)
|
||||||
| (0x2 if world.dropshuffle[player] else 0)))
|
| (0x2 if world.dropshuffle[player] != 'none' else 0)))
|
||||||
if world.pottery[player] not in ['none', 'keys']:
|
if world.pottery[player] not in ['none', 'keys']:
|
||||||
# Cuccos should not prevent kill rooms from opening
|
# Cuccos should not prevent kill rooms from opening
|
||||||
rom.write_byte(snes_to_pc(0x0DB457), 0x40)
|
rom.write_byte(snes_to_pc(0x0DB457), 0x40)
|
||||||
@@ -1249,8 +1238,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed
|
rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed
|
||||||
|
|
||||||
gametype = 0x04 # item
|
gametype = 0x04 # item
|
||||||
if (world.shuffle[player] != 'vanilla' or world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player]
|
if (world.shuffle[player] != 'vanilla' or world.doorShuffle[player] != 'vanilla'
|
||||||
or world.pottery[player] != 'none'):
|
or world.dropshuffle[player] != 'none' or world.pottery[player] != 'none'):
|
||||||
gametype |= 0x02 # entrance/door
|
gametype |= 0x02 # entrance/door
|
||||||
if enemized:
|
if enemized:
|
||||||
gametype |= 0x01 # enemizer
|
gametype |= 0x01 # enemizer
|
||||||
@@ -1350,7 +1339,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_byte(0x18003C, 0x00)
|
rom.write_byte(0x18003C, 0x00)
|
||||||
elif world.dungeon_counters[player] == 'on':
|
elif world.dungeon_counters[player] == 'on':
|
||||||
compass_mode = 0x02 # always on
|
compass_mode = 0x02 # always on
|
||||||
elif (world.compassshuffle[player] or world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player]
|
elif (world.compassshuffle[player] or world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player] != 'none'
|
||||||
or world.dungeon_counters[player] == 'pickup' or world.pottery[player] not in ['none', 'cave']):
|
or world.dungeon_counters[player] == 'pickup' or world.pottery[player] not in ['none', 'cave']):
|
||||||
compass_mode = 0x01 # show on pickup
|
compass_mode = 0x01 # show on pickup
|
||||||
if world.shuffle[player] != 'vanilla' and world.overworld_map[player] != 'default':
|
if world.shuffle[player] != 'vanilla' and world.overworld_map[player] != 'default':
|
||||||
@@ -1518,10 +1507,11 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
if item_dungeon == 'Escape':
|
if item_dungeon == 'Escape':
|
||||||
item_dungeon = 'Hyrule Castle'
|
item_dungeon = 'Hyrule Castle'
|
||||||
is_small_key_this_dungeon = hera_basement.parent_region.dungeon.name == item_dungeon
|
is_small_key_this_dungeon = hera_basement.parent_region.dungeon.name == item_dungeon
|
||||||
|
# hera small key is 11th in list, 10th sprite because of overlord
|
||||||
if is_small_key_this_dungeon:
|
if is_small_key_this_dungeon:
|
||||||
rom.write_byte(0x4E3BB, 0xE4)
|
world.data_tables[player].uw_enemy_table.room_map[0x87][11].kind = EnemySprite.SmallKey
|
||||||
else:
|
else:
|
||||||
rom.write_byte(0x4E3BB, 0xEB)
|
world.data_tables[player].uw_enemy_table.room_map[0x87][11].kind = EnemySprite.HeartPiece
|
||||||
|
|
||||||
# fix trock doors for reverse entrances
|
# fix trock doors for reverse entrances
|
||||||
if world.fix_trock_doors[player]:
|
if world.fix_trock_doors[player]:
|
||||||
@@ -1533,7 +1523,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_byte(0xFED31, 0x0E) # preopen bombable exit
|
rom.write_byte(0xFED31, 0x0E) # preopen bombable exit
|
||||||
rom.write_byte(0xFEE41, 0x0E) # preopen bombable exit
|
rom.write_byte(0xFEE41, 0x0E) # preopen bombable exit
|
||||||
|
|
||||||
if (world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player]
|
# todo: combine this with data_tables for in place edits
|
||||||
|
if (world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player] != 'none'
|
||||||
or world.pottery[player] != 'none'):
|
or world.pottery[player] != 'none'):
|
||||||
for room in world.rooms:
|
for room in world.rooms:
|
||||||
if room.player == player and room.modified:
|
if room.player == player and room.modified:
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ from Dungeons import dungeon_table
|
|||||||
from RoomData import DoorKind
|
from RoomData import DoorKind
|
||||||
from OverworldGlitchRules import overworld_glitches_rules
|
from OverworldGlitchRules import overworld_glitches_rules
|
||||||
|
|
||||||
|
from source.dungeon.EnemyList import kill_rules
|
||||||
|
|
||||||
|
|
||||||
def set_rules(world, player):
|
def set_rules(world, player):
|
||||||
|
|
||||||
@@ -35,6 +37,7 @@ def set_rules(world, player):
|
|||||||
|
|
||||||
bomb_rules(world, player)
|
bomb_rules(world, player)
|
||||||
pot_rules(world, player)
|
pot_rules(world, player)
|
||||||
|
drop_rules(world, player)
|
||||||
|
|
||||||
if world.logic[player] == 'noglitches':
|
if world.logic[player] == 'noglitches':
|
||||||
no_glitches_rules(world, player)
|
no_glitches_rules(world, player)
|
||||||
@@ -770,6 +773,17 @@ def pot_rules(world, player):
|
|||||||
add_rule(l, lambda state: state.can_hit_crystal(player))
|
add_rule(l, lambda state: state.can_hit_crystal(player))
|
||||||
|
|
||||||
|
|
||||||
|
def drop_rules(world, player):
|
||||||
|
data_tables = world.data_tables[player]
|
||||||
|
defeat_rules = kill_rules(world, player, data_tables.enemy_stats)
|
||||||
|
for super_tile, enemy_list in data_tables.uw_enemy_table.room_map.items():
|
||||||
|
for enemy in enemy_list:
|
||||||
|
if enemy.location:
|
||||||
|
# could handle odd health rules here? assume harder variant for now
|
||||||
|
verbose_rule = defeat_rules[enemy.kind]
|
||||||
|
enemy.location.verbose_rule = verbose_rule
|
||||||
|
add_rule(enemy.location, verbose_rule.rule_lambda)
|
||||||
|
|
||||||
|
|
||||||
def default_rules(world, player):
|
def default_rules(world, player):
|
||||||
# overworld requirements
|
# overworld requirements
|
||||||
|
|||||||
Binary file not shown.
@@ -4,7 +4,7 @@ meta:
|
|||||||
settings:
|
settings:
|
||||||
1:
|
1:
|
||||||
door_shuffle: vanilla
|
door_shuffle: vanilla
|
||||||
dropshuffle: true
|
dropshuffle: keys
|
||||||
experimental: true
|
experimental: true
|
||||||
goal: ganon
|
goal: ganon
|
||||||
hints: false
|
hints: false
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ meta:
|
|||||||
settings:
|
settings:
|
||||||
1:
|
1:
|
||||||
door_shuffle: basic
|
door_shuffle: basic
|
||||||
dropshuffle: true
|
dropshuffle: keys
|
||||||
experimental: true
|
experimental: true
|
||||||
goal: ganon
|
goal: ganon
|
||||||
hints: true
|
hints: true
|
||||||
|
|||||||
+3
-2
@@ -24,8 +24,9 @@
|
|||||||
chaos: 1
|
chaos: 1
|
||||||
decoupledoors: off
|
decoupledoors: off
|
||||||
dropshuffle:
|
dropshuffle:
|
||||||
on: 1
|
none: 4
|
||||||
off: 1
|
keys: 1
|
||||||
|
underworld: 1
|
||||||
pottery:
|
pottery:
|
||||||
none: 8
|
none: 8
|
||||||
keys: 1
|
keys: 1
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ intensity:
|
|||||||
2: 1
|
2: 1
|
||||||
3: 2 # intensity 3 usually yield more errors
|
3: 2 # intensity 3 usually yield more errors
|
||||||
dropshuffle:
|
dropshuffle:
|
||||||
on: 1
|
none: 10 # fewer locations
|
||||||
off: 1
|
keys: 1
|
||||||
|
underworld: 1
|
||||||
pottery:
|
pottery:
|
||||||
none: 10 # fewer locations
|
none: 10 # fewer locations
|
||||||
keys: 1
|
keys: 1
|
||||||
|
|||||||
@@ -89,8 +89,11 @@
|
|||||||
"type": "bool"
|
"type": "bool"
|
||||||
},
|
},
|
||||||
"dropshuffle" : {
|
"dropshuffle" : {
|
||||||
"action": "store_true",
|
"choices" : [
|
||||||
"type": "bool"
|
"none",
|
||||||
|
"keys",
|
||||||
|
"underworld"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"pottery" : {
|
"pottery" : {
|
||||||
"choices" : [
|
"choices" : [
|
||||||
|
|||||||
@@ -277,7 +277,11 @@
|
|||||||
"keyshuffle": [ "Small Keys are no longer restricted to their dungeons, but can be anywhere. (default: %(default)s)" ],
|
"keyshuffle": [ "Small Keys are no longer restricted to their dungeons, but can be anywhere. (default: %(default)s)" ],
|
||||||
"bigkeyshuffle": [ "Big Keys are no longer restricted to their dungeons, but can be anywhere. (default: %(default)s)" ],
|
"bigkeyshuffle": [ "Big Keys are no longer restricted to their dungeons, but can be anywhere. (default: %(default)s)" ],
|
||||||
"shopsanity": ["Shop contents are shuffle in the main item pool and other items can take their place. (default: %(default)s)"],
|
"shopsanity": ["Shop contents are shuffle in the main item pool and other items can take their place. (default: %(default)s)"],
|
||||||
"dropshuffle": [ "Keys dropped by enemies are shuffled and other items can take their place. (default: %(default)s)"],
|
"dropshuffle": [ "Controls how enemies drop items (default: %(default)s)",
|
||||||
|
"None: Enemies drops prize packs or keys as normal",
|
||||||
|
"Keys: Enemies that drop keys can drop other items and the keys are shuffled into the pool",
|
||||||
|
"Underworld: All killable enemies in the underworld can drop items"
|
||||||
|
],
|
||||||
"pottery": [ "Controls how items under pots are shuffled and if other items can take their place:",
|
"pottery": [ "Controls how items under pots are shuffled and if other items can take their place:",
|
||||||
"None: No pots are changed",
|
"None: No pots are changed",
|
||||||
"Keys: Key pots are included in the location pool and other items can take their place",
|
"Keys: Key pots are included in the location pool and other items can take their place",
|
||||||
|
|||||||
@@ -59,7 +59,10 @@
|
|||||||
"randomizer.dungeon.bigkeyshuffle": "Big Keys",
|
"randomizer.dungeon.bigkeyshuffle": "Big Keys",
|
||||||
"randomizer.dungeon.keydropshuffle": "Key Drop Shuffle (Legacy)",
|
"randomizer.dungeon.keydropshuffle": "Key Drop Shuffle (Legacy)",
|
||||||
"randomizer.dungeon.decoupledoors": "Decouple Doors",
|
"randomizer.dungeon.decoupledoors": "Decouple Doors",
|
||||||
"randomizer.dungeon.dropshuffle": "Shuffle Enemy Key Drops",
|
"randomizer.dungeon.dropshuffle": "Shuffle Enemy Drops",
|
||||||
|
"randomizer.dungeon.none": "None",
|
||||||
|
"randomizer.dungeon.keys": "Small Key Enemies",
|
||||||
|
"randomizer.dungeon.underworld": "Underworld Enemies",
|
||||||
"randomizer.dungeon.potshuffle": "Pot Shuffle (Legacy)",
|
"randomizer.dungeon.potshuffle": "Pot Shuffle (Legacy)",
|
||||||
"randomizer.dungeon.pottery": "Pottery",
|
"randomizer.dungeon.pottery": "Pottery",
|
||||||
"randomizer.dungeon.pottery.none": "None",
|
"randomizer.dungeon.pottery.none": "None",
|
||||||
|
|||||||
@@ -65,7 +65,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"colorizepots": { "type": "checkbox" },
|
"colorizepots": { "type": "checkbox" },
|
||||||
"dropshuffle": { "type": "checkbox" },
|
"dropshuffle": {
|
||||||
|
"type": "selectbox",
|
||||||
|
"default": "none",
|
||||||
|
"options": [
|
||||||
|
"none",
|
||||||
|
"keys",
|
||||||
|
"underworld"
|
||||||
|
]},
|
||||||
"potshuffle": { "type": "checkbox" },
|
"potshuffle": { "type": "checkbox" },
|
||||||
"experimental": { "type": "checkbox" },
|
"experimental": { "type": "checkbox" },
|
||||||
"dungeon_counters": {
|
"dungeon_counters": {
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ class CustomSettings(object):
|
|||||||
args.pottery[p] = get_setting(settings['pottery'], args.pottery[p])
|
args.pottery[p] = get_setting(settings['pottery'], args.pottery[p])
|
||||||
|
|
||||||
if get_setting(settings['keydropshuffle'], args.keydropshuffle[p]):
|
if get_setting(settings['keydropshuffle'], args.keydropshuffle[p]):
|
||||||
args.dropshuffle[p] = True
|
if args.dropshuffle[p] == 'none':
|
||||||
|
args.dropshuffle[p] = 'keys'
|
||||||
if args.pottery[p] == 'none':
|
if args.pottery[p] == 'none':
|
||||||
args.pottery[p] = 'keys'
|
args.pottery[p] = 'keys'
|
||||||
|
|
||||||
|
|||||||
+87
-77
@@ -17,15 +17,27 @@ from source.logic.Rule import RuleFactory
|
|||||||
|
|
||||||
|
|
||||||
class EnemyStats:
|
class EnemyStats:
|
||||||
def __init__(self, sprite, static, drop_flag=False, prize_pack: typing.Union[tuple, int] = 0, sub_type=0):
|
def __init__(self, sprite, static, drop_flag=False, prize_pack: typing.Union[tuple, int] = 0,
|
||||||
|
sub_type=0, health=None):
|
||||||
self.sprite = sprite
|
self.sprite = sprite
|
||||||
self.sub_type = sub_type
|
self.sub_type = sub_type
|
||||||
self.static = static
|
self.static = static
|
||||||
# self.health = health
|
self.health = health
|
||||||
# self.damage = damage
|
# self.damage = damage
|
||||||
self.drop_flag = drop_flag
|
self.drop_flag = drop_flag
|
||||||
self.prize_pack = prize_pack
|
self.prize_pack = prize_pack
|
||||||
|
|
||||||
|
# health special cases:
|
||||||
|
# Octorok light/dark world
|
||||||
|
# Hardhat Beetle - starting position
|
||||||
|
# Tektike - starting position?
|
||||||
|
# RatCricket light/dark world
|
||||||
|
# Keese light/dark world
|
||||||
|
# Rope light/dark world
|
||||||
|
# Raven light/dark world
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EnemySprite(FastEnum):
|
class EnemySprite(FastEnum):
|
||||||
Raven = 0x00
|
Raven = 0x00
|
||||||
@@ -252,34 +264,34 @@ def init_enemy_stats():
|
|||||||
stats = {
|
stats = {
|
||||||
EnemySprite.CorrectPullSwitch: EnemyStats(EnemySprite.CorrectPullSwitch, True),
|
EnemySprite.CorrectPullSwitch: EnemyStats(EnemySprite.CorrectPullSwitch, True),
|
||||||
EnemySprite.WrongPullSwitch: EnemyStats(EnemySprite.WrongPullSwitch, True),
|
EnemySprite.WrongPullSwitch: EnemyStats(EnemySprite.WrongPullSwitch, True),
|
||||||
EnemySprite.Octorok: EnemyStats(EnemySprite.Octorok, False, True, 2),
|
EnemySprite.Octorok: EnemyStats(EnemySprite.Octorok, False, True, 2, health=4),
|
||||||
EnemySprite.Moldorm: EnemyStats(EnemySprite.Moldorm, True, False),
|
EnemySprite.Moldorm: EnemyStats(EnemySprite.Moldorm, True, False),
|
||||||
EnemySprite.Cucco: EnemyStats(EnemySprite.Cucco, False, False),
|
EnemySprite.Cucco: EnemyStats(EnemySprite.Cucco, False, False),
|
||||||
|
|
||||||
EnemySprite.Octoballoon: EnemyStats(EnemySprite.Octoballoon, False, False, 0),
|
EnemySprite.Octoballoon: EnemyStats(EnemySprite.Octoballoon, False, False, 0, health=2),
|
||||||
EnemySprite.OctoballoonBaby: EnemyStats(EnemySprite.OctoballoonBaby, False),
|
EnemySprite.OctoballoonBaby: EnemyStats(EnemySprite.OctoballoonBaby, False),
|
||||||
EnemySprite.Hinox: EnemyStats(EnemySprite.Hinox, False, True, 4),
|
EnemySprite.Hinox: EnemyStats(EnemySprite.Hinox, False, True, 4, health=20),
|
||||||
EnemySprite.Moblin: EnemyStats(EnemySprite.Moblin, False, True, 1),
|
EnemySprite.Moblin: EnemyStats(EnemySprite.Moblin, False, True, 1, health=4),
|
||||||
EnemySprite.MiniHelmasaur: EnemyStats(EnemySprite.MiniHelmasaur, False, True, 7),
|
EnemySprite.MiniHelmasaur: EnemyStats(EnemySprite.MiniHelmasaur, False, True, 7, health=4),
|
||||||
EnemySprite.ThievesTownGrate: EnemyStats(EnemySprite.ThievesTownGrate, True),
|
EnemySprite.ThievesTownGrate: EnemyStats(EnemySprite.ThievesTownGrate, True),
|
||||||
EnemySprite.AntiFairy: EnemyStats(EnemySprite.AntiFairy, False, False),
|
EnemySprite.AntiFairy: EnemyStats(EnemySprite.AntiFairy, False, False),
|
||||||
EnemySprite.Wiseman: EnemyStats(EnemySprite.Wiseman, True),
|
EnemySprite.Wiseman: EnemyStats(EnemySprite.Wiseman, True),
|
||||||
EnemySprite.Hoarder: EnemyStats(EnemySprite.Hoarder, False, False),
|
EnemySprite.Hoarder: EnemyStats(EnemySprite.Hoarder, False, False, health=2),
|
||||||
EnemySprite.MiniMoldorm: EnemyStats(EnemySprite.MiniMoldorm, False, True, 2),
|
EnemySprite.MiniMoldorm: EnemyStats(EnemySprite.MiniMoldorm, False, True, 2, health=3),
|
||||||
EnemySprite.Poe: EnemyStats(EnemySprite.Poe, False, True, 6),
|
EnemySprite.Poe: EnemyStats(EnemySprite.Poe, False, True, 6, health=8),
|
||||||
EnemySprite.Smithy: EnemyStats(EnemySprite.Smithy, True),
|
EnemySprite.Smithy: EnemyStats(EnemySprite.Smithy, True),
|
||||||
EnemySprite.Arrow: EnemyStats(EnemySprite.Arrow, True),
|
EnemySprite.Arrow: EnemyStats(EnemySprite.Arrow, True),
|
||||||
EnemySprite.Statue: EnemyStats(EnemySprite.Statue, True),
|
EnemySprite.Statue: EnemyStats(EnemySprite.Statue, True),
|
||||||
EnemySprite.FluteQuest: EnemyStats(EnemySprite.FluteQuest, True),
|
EnemySprite.FluteQuest: EnemyStats(EnemySprite.FluteQuest, True),
|
||||||
EnemySprite.CrystalSwitch: EnemyStats(EnemySprite.CrystalSwitch, True),
|
EnemySprite.CrystalSwitch: EnemyStats(EnemySprite.CrystalSwitch, True),
|
||||||
EnemySprite.SickKid: EnemyStats(EnemySprite.SickKid, True),
|
EnemySprite.SickKid: EnemyStats(EnemySprite.SickKid, True),
|
||||||
EnemySprite.Sluggula: EnemyStats(EnemySprite.Sluggula, False, True, 4),
|
EnemySprite.Sluggula: EnemyStats(EnemySprite.Sluggula, False, True, 4, health=8),
|
||||||
EnemySprite.WaterSwitch: EnemyStats(EnemySprite.WaterSwitch, True),
|
EnemySprite.WaterSwitch: EnemyStats(EnemySprite.WaterSwitch, True),
|
||||||
EnemySprite.Ropa: EnemyStats(EnemySprite.Ropa, False, True, 2),
|
EnemySprite.Ropa: EnemyStats(EnemySprite.Ropa, False, True, 2, health=8),
|
||||||
EnemySprite.RedBari: EnemyStats(EnemySprite.RedBari, False, True, 6, 2),
|
EnemySprite.RedBari: EnemyStats(EnemySprite.RedBari, False, True, 6, 2, health=2),
|
||||||
EnemySprite.BlueBari: EnemyStats(EnemySprite.BlueBari, False, True, 6, 2),
|
EnemySprite.BlueBari: EnemyStats(EnemySprite.BlueBari, False, True, 6, 2, health=2),
|
||||||
EnemySprite.TalkingTree: EnemyStats(EnemySprite.TalkingTree, True),
|
EnemySprite.TalkingTree: EnemyStats(EnemySprite.TalkingTree, True),
|
||||||
EnemySprite.HardhatBeetle: EnemyStats(EnemySprite.HardhatBeetle, False, True, (2, 6)),
|
EnemySprite.HardhatBeetle: EnemyStats(EnemySprite.HardhatBeetle, False, True, (2, 6), health=32),
|
||||||
EnemySprite.Deadrock: EnemyStats(EnemySprite.Deadrock, False, False),
|
EnemySprite.Deadrock: EnemyStats(EnemySprite.Deadrock, False, False),
|
||||||
EnemySprite.DarkWorldHintNpc: EnemyStats(EnemySprite.DarkWorldHintNpc, True),
|
EnemySprite.DarkWorldHintNpc: EnemyStats(EnemySprite.DarkWorldHintNpc, True),
|
||||||
EnemySprite.AdultNpc: EnemyStats(EnemySprite.AdultNpc, True),
|
EnemySprite.AdultNpc: EnemyStats(EnemySprite.AdultNpc, True),
|
||||||
@@ -303,30 +315,30 @@ def init_enemy_stats():
|
|||||||
EnemySprite.BonkItem: EnemyStats(EnemySprite.BonkItem, True),
|
EnemySprite.BonkItem: EnemyStats(EnemySprite.BonkItem, True),
|
||||||
EnemySprite.KidInKak: EnemyStats(EnemySprite.KidInKak, True),
|
EnemySprite.KidInKak: EnemyStats(EnemySprite.KidInKak, True),
|
||||||
EnemySprite.OldSnitch: EnemyStats(EnemySprite.OldSnitch, True),
|
EnemySprite.OldSnitch: EnemyStats(EnemySprite.OldSnitch, True),
|
||||||
EnemySprite.Hoarder2: EnemyStats(EnemySprite.Hoarder2, False, False),
|
EnemySprite.Hoarder2: EnemyStats(EnemySprite.Hoarder2, False, False, health=2),
|
||||||
EnemySprite.TutorialGuard: EnemyStats(EnemySprite.TutorialGuard, True),
|
EnemySprite.TutorialGuard: EnemyStats(EnemySprite.TutorialGuard, True),
|
||||||
|
|
||||||
EnemySprite.LightningGate: EnemyStats(EnemySprite.LightningGate, True),
|
EnemySprite.LightningGate: EnemyStats(EnemySprite.LightningGate, True),
|
||||||
EnemySprite.BlueGuard: EnemyStats(EnemySprite.BlueGuard, False, True, 1),
|
EnemySprite.BlueGuard: EnemyStats(EnemySprite.BlueGuard, False, True, 1, health=6),
|
||||||
EnemySprite.GreenGuard: EnemyStats(EnemySprite.GreenGuard, False, True, 1),
|
EnemySprite.GreenGuard: EnemyStats(EnemySprite.GreenGuard, False, True, 1, health=4),
|
||||||
EnemySprite.RedSpearGuard: EnemyStats(EnemySprite.RedSpearGuard, False, True, 1),
|
EnemySprite.RedSpearGuard: EnemyStats(EnemySprite.RedSpearGuard, False, True, 1, health=8),
|
||||||
EnemySprite.BluesainBolt: EnemyStats(EnemySprite.BluesainBolt, False, True, 7),
|
EnemySprite.BluesainBolt: EnemyStats(EnemySprite.BluesainBolt, False, True, 7, health=6),
|
||||||
EnemySprite.UsainBolt: EnemyStats(EnemySprite.UsainBolt, False, True, 1),
|
EnemySprite.UsainBolt: EnemyStats(EnemySprite.UsainBolt, False, True, 1, health=8),
|
||||||
EnemySprite.BlueArcher: EnemyStats(EnemySprite.BlueArcher, False, True, 5),
|
EnemySprite.BlueArcher: EnemyStats(EnemySprite.BlueArcher, False, True, 5, health=6),
|
||||||
EnemySprite.GreenBushGuard: EnemyStats(EnemySprite.GreenBushGuard, False, True, 5),
|
EnemySprite.GreenBushGuard: EnemyStats(EnemySprite.GreenBushGuard, False, True, 5, health=4),
|
||||||
EnemySprite.RedJavelinGuard: EnemyStats(EnemySprite.RedJavelinGuard, False, True, 3),
|
EnemySprite.RedJavelinGuard: EnemyStats(EnemySprite.RedJavelinGuard, False, True, 3, health=8),
|
||||||
EnemySprite.RedBushGuard: EnemyStats(EnemySprite.RedBushGuard, False, True, 7),
|
EnemySprite.RedBushGuard: EnemyStats(EnemySprite.RedBushGuard, False, True, 7, health=8),
|
||||||
EnemySprite.BombGuard: EnemyStats(EnemySprite.BombGuard, False, True, 4),
|
EnemySprite.BombGuard: EnemyStats(EnemySprite.BombGuard, False, True, 4, health=8),
|
||||||
EnemySprite.GreenKnifeGuard: EnemyStats(EnemySprite.GreenKnifeGuard, False, True, 1),
|
EnemySprite.GreenKnifeGuard: EnemyStats(EnemySprite.GreenKnifeGuard, False, True, 1, health=4),
|
||||||
EnemySprite.Geldman: EnemyStats(EnemySprite.Geldman, False, True, 2),
|
EnemySprite.Geldman: EnemyStats(EnemySprite.Geldman, False, True, 2, health=4),
|
||||||
EnemySprite.Popo: EnemyStats(EnemySprite.Popo, False, True, 2),
|
EnemySprite.Popo: EnemyStats(EnemySprite.Popo, False, True, 2, health=2),
|
||||||
EnemySprite.Popo2: EnemyStats(EnemySprite.Popo2, False, True, 2),
|
EnemySprite.Popo2: EnemyStats(EnemySprite.Popo2, False, True, 2, health=2),
|
||||||
|
|
||||||
EnemySprite.ArmosKnight: EnemyStats(EnemySprite.ArmosKnight, True, False),
|
EnemySprite.ArmosKnight: EnemyStats(EnemySprite.ArmosKnight, True, False),
|
||||||
EnemySprite.Lanmolas: EnemyStats(EnemySprite.Lanmolas, True, False),
|
EnemySprite.Lanmolas: EnemyStats(EnemySprite.Lanmolas, True, False),
|
||||||
EnemySprite.Zora: EnemyStats(EnemySprite.Zora, False, True, 4),
|
EnemySprite.Zora: EnemyStats(EnemySprite.Zora, False, True, 4),
|
||||||
EnemySprite.DesertStatue: EnemyStats(EnemySprite.DesertStatue, True),
|
EnemySprite.DesertStatue: EnemyStats(EnemySprite.DesertStatue, True),
|
||||||
EnemySprite.Crab: EnemyStats(EnemySprite.Crab, False, True, 1),
|
EnemySprite.Crab: EnemyStats(EnemySprite.Crab, False, True, 1, health=2),
|
||||||
EnemySprite.LostWoodsBird: EnemyStats(EnemySprite.LostWoodsBird, True),
|
EnemySprite.LostWoodsBird: EnemyStats(EnemySprite.LostWoodsBird, True),
|
||||||
EnemySprite.LostWoodsSquirrel: EnemyStats(EnemySprite.LostWoodsSquirrel, True),
|
EnemySprite.LostWoodsSquirrel: EnemyStats(EnemySprite.LostWoodsSquirrel, True),
|
||||||
EnemySprite.SparkCW: EnemyStats(EnemySprite.SparkCW, False, False),
|
EnemySprite.SparkCW: EnemyStats(EnemySprite.SparkCW, False, False),
|
||||||
@@ -337,20 +349,20 @@ def init_enemy_stats():
|
|||||||
EnemySprite.RollerHorizontalRight: EnemyStats(EnemySprite.RollerHorizontalRight, False, False),
|
EnemySprite.RollerHorizontalRight: EnemyStats(EnemySprite.RollerHorizontalRight, False, False),
|
||||||
EnemySprite.Beamos: EnemyStats(EnemySprite.Beamos, False, False),
|
EnemySprite.Beamos: EnemyStats(EnemySprite.Beamos, False, False),
|
||||||
EnemySprite.MasterSword: EnemyStats(EnemySprite.MasterSword, True),
|
EnemySprite.MasterSword: EnemyStats(EnemySprite.MasterSword, True),
|
||||||
EnemySprite.DebirandoPit: EnemyStats(EnemySprite.DebirandoPit, False, True, 2),
|
EnemySprite.DebirandoPit: EnemyStats(EnemySprite.DebirandoPit, False, True, 2, health=4),
|
||||||
EnemySprite.Debirando: EnemyStats(EnemySprite.Debirando, False, True, 2),
|
EnemySprite.Debirando: EnemyStats(EnemySprite.Debirando, False, True, 2, health=4),
|
||||||
EnemySprite.ArcheryNpc: EnemyStats(EnemySprite.ArcheryNpc, True),
|
EnemySprite.ArcheryNpc: EnemyStats(EnemySprite.ArcheryNpc, True),
|
||||||
EnemySprite.WallCannonVertLeft: EnemyStats(EnemySprite.WallCannonVertLeft, True),
|
EnemySprite.WallCannonVertLeft: EnemyStats(EnemySprite.WallCannonVertLeft, True),
|
||||||
EnemySprite.WallCannonVertRight: EnemyStats(EnemySprite.WallCannonVertRight, True),
|
EnemySprite.WallCannonVertRight: EnemyStats(EnemySprite.WallCannonVertRight, True),
|
||||||
EnemySprite.WallCannonHorzTop: EnemyStats(EnemySprite.WallCannonHorzTop, True),
|
EnemySprite.WallCannonHorzTop: EnemyStats(EnemySprite.WallCannonHorzTop, True),
|
||||||
EnemySprite.WallCannonHorzBottom: EnemyStats(EnemySprite.WallCannonHorzBottom, True),
|
EnemySprite.WallCannonHorzBottom: EnemyStats(EnemySprite.WallCannonHorzBottom, True),
|
||||||
EnemySprite.BallNChain: EnemyStats(EnemySprite.BallNChain, False, True, 2),
|
EnemySprite.BallNChain: EnemyStats(EnemySprite.BallNChain, False, True, 2, health=16),
|
||||||
EnemySprite.CannonTrooper: EnemyStats(EnemySprite.CannonTrooper, False, True, 1),
|
EnemySprite.CannonTrooper: EnemyStats(EnemySprite.CannonTrooper, False, True, 1, health=3),
|
||||||
EnemySprite.CricketRat: EnemyStats(EnemySprite.CricketRat, False, True, 2),
|
EnemySprite.CricketRat: EnemyStats(EnemySprite.CricketRat, False, True, 2, health=8),
|
||||||
EnemySprite.Snake: EnemyStats(EnemySprite.Snake, False, True, (1, 7)),
|
EnemySprite.Snake: EnemyStats(EnemySprite.Snake, False, True, (1, 7), health=8),
|
||||||
EnemySprite.Keese: EnemyStats(EnemySprite.Keese, False, True, (0, 7)),
|
EnemySprite.Keese: EnemyStats(EnemySprite.Keese, False, True, (0, 7), health=4),
|
||||||
|
|
||||||
EnemySprite.Leever: EnemyStats(EnemySprite.Leever, False, True, 1),
|
EnemySprite.Leever: EnemyStats(EnemySprite.Leever, False, True, 1, health=4),
|
||||||
EnemySprite.FairyPondTrigger: EnemyStats(EnemySprite.FairyPondTrigger, True),
|
EnemySprite.FairyPondTrigger: EnemyStats(EnemySprite.FairyPondTrigger, True),
|
||||||
EnemySprite.UnclePriest: EnemyStats(EnemySprite.UnclePriest, True),
|
EnemySprite.UnclePriest: EnemyStats(EnemySprite.UnclePriest, True),
|
||||||
EnemySprite.RunningNpc: EnemyStats(EnemySprite.RunningNpc, True),
|
EnemySprite.RunningNpc: EnemyStats(EnemySprite.RunningNpc, True),
|
||||||
@@ -358,26 +370,26 @@ def init_enemy_stats():
|
|||||||
EnemySprite.Zelda: EnemyStats(EnemySprite.Zelda, True),
|
EnemySprite.Zelda: EnemyStats(EnemySprite.Zelda, True),
|
||||||
EnemySprite.Grandma: EnemyStats(EnemySprite.Grandma, True),
|
EnemySprite.Grandma: EnemyStats(EnemySprite.Grandma, True),
|
||||||
EnemySprite.Agahnim: EnemyStats(EnemySprite.Agahnim, True),
|
EnemySprite.Agahnim: EnemyStats(EnemySprite.Agahnim, True),
|
||||||
EnemySprite.FloatingSkull: EnemyStats(EnemySprite.FloatingSkull, False, True, 7),
|
EnemySprite.FloatingSkull: EnemyStats(EnemySprite.FloatingSkull, False, True, 7, health=24),
|
||||||
EnemySprite.BigSpike: EnemyStats(EnemySprite.BigSpike, False, False),
|
EnemySprite.BigSpike: EnemyStats(EnemySprite.BigSpike, False, False),
|
||||||
EnemySprite.FirebarCW: EnemyStats(EnemySprite.FirebarCW, False, False),
|
EnemySprite.FirebarCW: EnemyStats(EnemySprite.FirebarCW, False, False),
|
||||||
EnemySprite.FirebarCCW: EnemyStats(EnemySprite.FirebarCCW, False, False),
|
EnemySprite.FirebarCCW: EnemyStats(EnemySprite.FirebarCCW, False, False),
|
||||||
EnemySprite.Firesnake: EnemyStats(EnemySprite.Firesnake, False, False),
|
EnemySprite.Firesnake: EnemyStats(EnemySprite.Firesnake, False, False),
|
||||||
EnemySprite.Hover: EnemyStats(EnemySprite.Hover, False, True, 2),
|
EnemySprite.Hover: EnemyStats(EnemySprite.Hover, False, True, 2, health=4),
|
||||||
EnemySprite.AntiFairyCircle: EnemyStats(EnemySprite.AntiFairyCircle, False, False),
|
EnemySprite.AntiFairyCircle: EnemyStats(EnemySprite.AntiFairyCircle, False, False),
|
||||||
EnemySprite.GreenEyegoreMimic: EnemyStats(EnemySprite.GreenEyegoreMimic, False, True, 5),
|
EnemySprite.GreenEyegoreMimic: EnemyStats(EnemySprite.GreenEyegoreMimic, False, True, 5, health=16),
|
||||||
EnemySprite.RedEyegoreMimic: EnemyStats(EnemySprite.RedEyegoreMimic, False, True, 5),
|
EnemySprite.RedEyegoreMimic: EnemyStats(EnemySprite.RedEyegoreMimic, False, True, 5, health=8),
|
||||||
EnemySprite.YellowStalfos: EnemyStats(EnemySprite.YellowStalfos, True),
|
EnemySprite.YellowStalfos: EnemyStats(EnemySprite.YellowStalfos, True, health=8),
|
||||||
EnemySprite.Kondongo: EnemyStats(EnemySprite.Kondongo, False, True, 6),
|
EnemySprite.Kondongo: EnemyStats(EnemySprite.Kondongo, False, True, 6, health=1),
|
||||||
EnemySprite.Mothula: EnemyStats(EnemySprite.Mothula, True),
|
EnemySprite.Mothula: EnemyStats(EnemySprite.Mothula, True),
|
||||||
EnemySprite.SpikeBlock: EnemyStats(EnemySprite.SpikeBlock, False, False),
|
EnemySprite.SpikeBlock: EnemyStats(EnemySprite.SpikeBlock, False, False),
|
||||||
EnemySprite.Gibdo: EnemyStats(EnemySprite.Gibdo, False, True, 3),
|
EnemySprite.Gibdo: EnemyStats(EnemySprite.Gibdo, False, True, 3, health=32),
|
||||||
EnemySprite.Arrghus: EnemyStats(EnemySprite.Arrghus, True),
|
EnemySprite.Arrghus: EnemyStats(EnemySprite.Arrghus, True),
|
||||||
EnemySprite.Arrghi: EnemyStats(EnemySprite.Arrghi, True),
|
EnemySprite.Arrghi: EnemyStats(EnemySprite.Arrghi, True),
|
||||||
EnemySprite.Terrorpin: EnemyStats(EnemySprite.Terrorpin, False, True, 2),
|
EnemySprite.Terrorpin: EnemyStats(EnemySprite.Terrorpin, False, True, 2, health=8),
|
||||||
EnemySprite.Blob: EnemyStats(EnemySprite.Blob, False, True, 1),
|
EnemySprite.Blob: EnemyStats(EnemySprite.Blob, False, True, 1, health=4),
|
||||||
EnemySprite.Wallmaster: EnemyStats(EnemySprite.Wallmaster, True),
|
EnemySprite.Wallmaster: EnemyStats(EnemySprite.Wallmaster, True),
|
||||||
EnemySprite.StalfosKnight: EnemyStats(EnemySprite.StalfosKnight, False, True, 4),
|
EnemySprite.StalfosKnight: EnemyStats(EnemySprite.StalfosKnight, False, True, 4, health=64),
|
||||||
EnemySprite.HelmasaurKing: EnemyStats(EnemySprite.HelmasaurKing, True),
|
EnemySprite.HelmasaurKing: EnemyStats(EnemySprite.HelmasaurKing, True),
|
||||||
EnemySprite.Bumper: EnemyStats(EnemySprite.Bumper, True),
|
EnemySprite.Bumper: EnemyStats(EnemySprite.Bumper, True),
|
||||||
EnemySprite.Pirogusu: EnemyStats(EnemySprite.Pirogusu, True),
|
EnemySprite.Pirogusu: EnemyStats(EnemySprite.Pirogusu, True),
|
||||||
@@ -385,21 +397,21 @@ def init_enemy_stats():
|
|||||||
EnemySprite.LaserEyeRight: EnemyStats(EnemySprite.LaserEyeRight, True),
|
EnemySprite.LaserEyeRight: EnemyStats(EnemySprite.LaserEyeRight, True),
|
||||||
EnemySprite.LaserEyeTop: EnemyStats(EnemySprite.LaserEyeTop, True),
|
EnemySprite.LaserEyeTop: EnemyStats(EnemySprite.LaserEyeTop, True),
|
||||||
EnemySprite.LaserEyeBottom: EnemyStats(EnemySprite.LaserEyeBottom, True),
|
EnemySprite.LaserEyeBottom: EnemyStats(EnemySprite.LaserEyeBottom, True),
|
||||||
EnemySprite.Pengator: EnemyStats(EnemySprite.Pengator, False, True, 3),
|
EnemySprite.Pengator: EnemyStats(EnemySprite.Pengator, False, True, 3, health=16),
|
||||||
EnemySprite.Kyameron: EnemyStats(EnemySprite.Kyameron, False, False),
|
EnemySprite.Kyameron: EnemyStats(EnemySprite.Kyameron, False, False, health=4),
|
||||||
EnemySprite.Wizzrobe: EnemyStats(EnemySprite.Wizzrobe, False, True, 1),
|
EnemySprite.Wizzrobe: EnemyStats(EnemySprite.Wizzrobe, False, True, 1, health=2),
|
||||||
EnemySprite.Zoro: EnemyStats(EnemySprite.Zoro, True),
|
EnemySprite.Zoro: EnemyStats(EnemySprite.Zoro, True, health=4),
|
||||||
EnemySprite.Babasu: EnemyStats(EnemySprite.Babasu, False, True, 0),
|
EnemySprite.Babasu: EnemyStats(EnemySprite.Babasu, False, True, 0, health=4),
|
||||||
EnemySprite.GroveOstritch: EnemyStats(EnemySprite.GroveOstritch, True),
|
EnemySprite.GroveOstritch: EnemyStats(EnemySprite.GroveOstritch, True),
|
||||||
EnemySprite.GroveRabbit: EnemyStats(EnemySprite.GroveRabbit, True),
|
EnemySprite.GroveRabbit: EnemyStats(EnemySprite.GroveRabbit, True),
|
||||||
EnemySprite.GroveBird: EnemyStats(EnemySprite.GroveBird, True),
|
EnemySprite.GroveBird: EnemyStats(EnemySprite.GroveBird, True),
|
||||||
EnemySprite.Freezor: EnemyStats(EnemySprite.Freezor, True, True, 0),
|
EnemySprite.Freezor: EnemyStats(EnemySprite.Freezor, True, True, 0, health=16),
|
||||||
EnemySprite.Kholdstare: EnemyStats(EnemySprite.Kholdstare, True),
|
EnemySprite.Kholdstare: EnemyStats(EnemySprite.Kholdstare, True),
|
||||||
EnemySprite.KholdstareShell: EnemyStats(EnemySprite.KholdstareShell, True),
|
EnemySprite.KholdstareShell: EnemyStats(EnemySprite.KholdstareShell, True),
|
||||||
EnemySprite.FallingIce: EnemyStats(EnemySprite.FallingIce, True),
|
EnemySprite.FallingIce: EnemyStats(EnemySprite.FallingIce, True),
|
||||||
EnemySprite.BlueZazak: EnemyStats(EnemySprite.BlueZazak, False, True, 6),
|
EnemySprite.BlueZazak: EnemyStats(EnemySprite.BlueZazak, False, True, 6, health=4),
|
||||||
EnemySprite.RedZazak: EnemyStats(EnemySprite.RedZazak, False, True, 6),
|
EnemySprite.RedZazak: EnemyStats(EnemySprite.RedZazak, False, True, 6, health=8),
|
||||||
EnemySprite.Stalfos: EnemyStats(EnemySprite.Stalfos, False, True, 6),
|
EnemySprite.Stalfos: EnemyStats(EnemySprite.Stalfos, False, True, 6, health=4),
|
||||||
# ... OW
|
# ... OW
|
||||||
EnemySprite.OldMan: EnemyStats(EnemySprite.OldMan, True),
|
EnemySprite.OldMan: EnemyStats(EnemySprite.OldMan, True),
|
||||||
EnemySprite.PipeDown: EnemyStats(EnemySprite.PipeDown, True),
|
EnemySprite.PipeDown: EnemyStats(EnemySprite.PipeDown, True),
|
||||||
@@ -418,23 +430,23 @@ def init_enemy_stats():
|
|||||||
EnemySprite.Catfish: EnemyStats(EnemySprite.Catfish, True),
|
EnemySprite.Catfish: EnemyStats(EnemySprite.Catfish, True),
|
||||||
EnemySprite.CutsceneAgahnim: EnemyStats(EnemySprite.CutsceneAgahnim, True),
|
EnemySprite.CutsceneAgahnim: EnemyStats(EnemySprite.CutsceneAgahnim, True),
|
||||||
EnemySprite.Boulder: EnemyStats(EnemySprite.Boulder, True),
|
EnemySprite.Boulder: EnemyStats(EnemySprite.Boulder, True),
|
||||||
EnemySprite.Gibo: EnemyStats(EnemySprite.Gibo, False, True, 0), # patrick!
|
EnemySprite.Gibo: EnemyStats(EnemySprite.Gibo, False, True, 0, health=8), # patrick!
|
||||||
EnemySprite.Thief: EnemyStats(EnemySprite.Thief, False, False), # could drop if killable thieves is on
|
EnemySprite.Thief: EnemyStats(EnemySprite.Thief, False, False), # could drop if killable thieves is on
|
||||||
EnemySprite.Medusa: EnemyStats(EnemySprite.Medusa, True),
|
EnemySprite.Medusa: EnemyStats(EnemySprite.Medusa, True),
|
||||||
EnemySprite.FourWayShooter: EnemyStats(EnemySprite.FourWayShooter, True),
|
EnemySprite.FourWayShooter: EnemyStats(EnemySprite.FourWayShooter, True),
|
||||||
EnemySprite.Pokey: EnemyStats(EnemySprite.Pokey, False, True, 7),
|
EnemySprite.Pokey: EnemyStats(EnemySprite.Pokey, False, True, 7, health=32),
|
||||||
EnemySprite.BigFairy: EnemyStats(EnemySprite.BigFairy, True),
|
EnemySprite.BigFairy: EnemyStats(EnemySprite.BigFairy, True),
|
||||||
EnemySprite.Tektite: EnemyStats(EnemySprite.Tektite, False, True, 2),
|
EnemySprite.Tektite: EnemyStats(EnemySprite.Tektite, False, True, 2, health=12),
|
||||||
EnemySprite.Chainchomp: EnemyStats(EnemySprite.Chainchomp, False, False),
|
EnemySprite.Chainchomp: EnemyStats(EnemySprite.Chainchomp, False, False),
|
||||||
EnemySprite.TrinexxRockHead: EnemyStats(EnemySprite.TrinexxRockHead, True),
|
EnemySprite.TrinexxRockHead: EnemyStats(EnemySprite.TrinexxRockHead, True),
|
||||||
EnemySprite.TrinexxFireHead: EnemyStats(EnemySprite.TrinexxFireHead, True),
|
EnemySprite.TrinexxFireHead: EnemyStats(EnemySprite.TrinexxFireHead, True),
|
||||||
EnemySprite.TrinexxIceHead: EnemyStats(EnemySprite.TrinexxIceHead, True),
|
EnemySprite.TrinexxIceHead: EnemyStats(EnemySprite.TrinexxIceHead, True),
|
||||||
EnemySprite.Blind: EnemyStats(EnemySprite.Blind, True),
|
EnemySprite.Blind: EnemyStats(EnemySprite.Blind, True),
|
||||||
EnemySprite.Swamola: EnemyStats(EnemySprite.Swamola, False, True, 0),
|
EnemySprite.Swamola: EnemyStats(EnemySprite.Swamola, False, True, 0, health=16),
|
||||||
EnemySprite.Lynel: EnemyStats(EnemySprite.Lynel, False, True, 7),
|
EnemySprite.Lynel: EnemyStats(EnemySprite.Lynel, False, True, 7, health=24),
|
||||||
EnemySprite.BunnyBeam: EnemyStats(EnemySprite.BunnyBeam, False, False), # todo: medallions can kill bunny beams?
|
EnemySprite.BunnyBeam: EnemyStats(EnemySprite.BunnyBeam, False, False), # todo: medallions can kill bunny beams?
|
||||||
EnemySprite.FloppingFish: EnemyStats(EnemySprite.FloppingFish, True),
|
EnemySprite.FloppingFish: EnemyStats(EnemySprite.FloppingFish, True),
|
||||||
EnemySprite.Stal: EnemyStats(EnemySprite.Stal, False, True, 1),
|
EnemySprite.Stal: EnemyStats(EnemySprite.Stal, False, True, 1, health=4),
|
||||||
EnemySprite.Ganon: EnemyStats(EnemySprite.Ganon, True),
|
EnemySprite.Ganon: EnemyStats(EnemySprite.Ganon, True),
|
||||||
|
|
||||||
EnemySprite.Faerie: EnemyStats(EnemySprite.Faerie, True),
|
EnemySprite.Faerie: EnemyStats(EnemySprite.Faerie, True),
|
||||||
@@ -497,8 +509,6 @@ class Sprite(object):
|
|||||||
|
|
||||||
# map of super_tile to list of Sprite objects:
|
# map of super_tile to list of Sprite objects:
|
||||||
vanilla_sprites = {}
|
vanilla_sprites = {}
|
||||||
enemy_stats = {}
|
|
||||||
|
|
||||||
|
|
||||||
def create_sprite(super_tile, kind, sub_type, layer, tile_x, tile_y, region=None,
|
def create_sprite(super_tile, kind, sub_type, layer, tile_x, tile_y, region=None,
|
||||||
drops_item=False, drop_item_kind=None):
|
drops_item=False, drop_item_kind=None):
|
||||||
@@ -1984,8 +1994,6 @@ def init_vanilla_sprites():
|
|||||||
create_sprite(0x0126, EnemySprite.Faerie, 0x00, 0, 0x08, 0x16)
|
create_sprite(0x0126, EnemySprite.Faerie, 0x00, 0, 0x08, 0x16)
|
||||||
create_sprite(0x0126, EnemySprite.HeartPiece, 0x00, 0, 0x1c, 0x14)
|
create_sprite(0x0126, EnemySprite.HeartPiece, 0x00, 0, 0x1c, 0x14)
|
||||||
create_sprite(0x0127, EnemySprite.HeartPiece, 0x00, 0, 0x07, 0x16)
|
create_sprite(0x0127, EnemySprite.HeartPiece, 0x00, 0, 0x07, 0x16)
|
||||||
global enemy_stats
|
|
||||||
enemy_stats = init_enemy_stats()
|
|
||||||
|
|
||||||
|
|
||||||
def kill_rules(world, player, stats):
|
def kill_rules(world, player, stats):
|
||||||
@@ -2015,6 +2023,7 @@ def kill_rules(world, player, stats):
|
|||||||
EnemySprite.GreenKnifeGuard: defeat_rule(world, player, h(EnemySprite.GreenKnifeGuard)),
|
EnemySprite.GreenKnifeGuard: defeat_rule(world, player, h(EnemySprite.GreenKnifeGuard)),
|
||||||
EnemySprite.Popo: defeat_rule(world, player, h(EnemySprite.Popo), hook=True),
|
EnemySprite.Popo: defeat_rule(world, player, h(EnemySprite.Popo), hook=True),
|
||||||
EnemySprite.Popo2: defeat_rule(world, player, h(EnemySprite.Popo2), hook=True),
|
EnemySprite.Popo2: defeat_rule(world, player, h(EnemySprite.Popo2), hook=True),
|
||||||
|
EnemySprite.DebirandoPit: defeat_rule(world, player, h(EnemySprite.Debirando), fire=1, ice=1, boomerang=True),
|
||||||
EnemySprite.Debirando: defeat_rule(world, player, h(EnemySprite.Debirando), fire=1, ice=1, boomerang=True),
|
EnemySprite.Debirando: defeat_rule(world, player, h(EnemySprite.Debirando), fire=1, ice=1, boomerang=True),
|
||||||
EnemySprite.BallNChain: defeat_rule(world, player, h(EnemySprite.BallNChain)),
|
EnemySprite.BallNChain: defeat_rule(world, player, h(EnemySprite.BallNChain)),
|
||||||
EnemySprite.CannonTrooper: defeat_rule(world, player, h(EnemySprite.CannonTrooper), fire=1, ice=1),
|
EnemySprite.CannonTrooper: defeat_rule(world, player, h(EnemySprite.CannonTrooper), fire=1, ice=1),
|
||||||
@@ -2101,8 +2110,8 @@ def valid_drop_location(sprite, world, player):
|
|||||||
if sprite.drops_item and sprite.drop_item_kind == 0xe4:
|
if sprite.drops_item and sprite.drop_item_kind == 0xe4:
|
||||||
# already has a location
|
# already has a location
|
||||||
return False
|
return False
|
||||||
else:
|
elif sprite.sub_type != SpriteType.Overlord:
|
||||||
stat = enemy_stats[sprite.kind]
|
stat = world.data_tables[player].enemy_stats[sprite.kind]
|
||||||
return not stat.static and stat.drop_flag
|
return not stat.static and stat.drop_flag
|
||||||
|
|
||||||
|
|
||||||
@@ -2120,6 +2129,7 @@ def create_drop_location(sprite, index, super_tile, world, player):
|
|||||||
drop_location.drop = sprite
|
drop_location.drop = sprite
|
||||||
sprite.location = drop_location
|
sprite.location = drop_location
|
||||||
drop_location.type = LocationType.Drop
|
drop_location.type = LocationType.Drop
|
||||||
|
parent.locations.append(drop_location)
|
||||||
|
|
||||||
|
|
||||||
# todo: placeholder address
|
# todo: placeholder address
|
||||||
@@ -2149,12 +2159,12 @@ prize_pack_selector = {
|
|||||||
def add_drop_contents(world, player):
|
def add_drop_contents(world, player):
|
||||||
retro_bow = world.bow_mode[player].startswith('retro')
|
retro_bow = world.bow_mode[player].startswith('retro')
|
||||||
index_selector = [0]*8
|
index_selector = [0]*8
|
||||||
for super_tile, enemy_list in world.enemy_list[player].room_map.items():
|
for super_tile, enemy_list in world.data_tables[player].uw_enemy_table.room_map.items():
|
||||||
for sprite in enemy_list:
|
for sprite in enemy_list:
|
||||||
if sprite.drops_item and sprite.drop_item_kind == 0xe4:
|
if sprite.drops_item and sprite.drop_item_kind == 0xe4:
|
||||||
continue
|
continue
|
||||||
else:
|
elif sprite.sub_type != SpriteType.Overlord:
|
||||||
stat = enemy_stats[sprite.kind]
|
stat = world.data_tables[player].enemy_stats[sprite.kind]
|
||||||
if not stat.static and stat.drop_flag:
|
if not stat.static and stat.drop_flag:
|
||||||
pack = 0
|
pack = 0
|
||||||
if isinstance(stat.prize_pack, int):
|
if isinstance(stat.prize_pack, int):
|
||||||
@@ -2283,10 +2293,10 @@ def defeat_rule(world, player, health, class1=1,
|
|||||||
else:
|
else:
|
||||||
rules.append(can_fire_rod_kill(world, player, fire_rod_damage[fire], health))
|
rules.append(can_fire_rod_kill(world, player, fire_rod_damage[fire], health))
|
||||||
if ice is not None:
|
if ice is not None:
|
||||||
rules.append(can_ice_rod_kill(world, player, ice_rod_damage[fire], health))
|
rules.append(can_ice_rod_kill(world, player, ice_rod_damage[ice], health))
|
||||||
if boomerang:
|
if boomerang:
|
||||||
rules.append(has_boomerang(player))
|
rules.append(has_boomerang(player))
|
||||||
return or_rule(rules)
|
return or_rule(*rules)
|
||||||
|
|
||||||
|
|
||||||
def has_blunt_weapon(player):
|
def has_blunt_weapon(player):
|
||||||
@@ -2298,7 +2308,7 @@ def find_shops_that_sell(item, world, player):
|
|||||||
|
|
||||||
|
|
||||||
def can_shoot_arrows(world, player):
|
def can_shoot_arrows(world, player):
|
||||||
if world.retro[player]:
|
if world.bow_mode[player].startswith('retro'):
|
||||||
# todo: Non-progressive silvers grant wooden arrows, but progressive bows do not.
|
# todo: Non-progressive silvers grant wooden arrows, but progressive bows do not.
|
||||||
# Always require shop arrows to be safe
|
# Always require shop arrows to be safe
|
||||||
shops = find_shops_that_sell('Single Arrow', world, player)
|
shops = find_shops_that_sell('Single Arrow', world, player)
|
||||||
@@ -2309,7 +2319,7 @@ def can_shoot_arrows(world, player):
|
|||||||
|
|
||||||
|
|
||||||
def can_use_bombs(world, player):
|
def can_use_bombs(world, player):
|
||||||
return or_rule(RuleFactory.static_rule(not world.bombag[player]), has('Bomb Upgrade (+10)', player))
|
return or_rule(RuleFactory.static_rule(not world.bombbag[player]), has('Bomb Upgrade (+10)', player))
|
||||||
|
|
||||||
enemy_names = {
|
enemy_names = {
|
||||||
0x00: 'Raven',
|
0x00: 'Raven',
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ def create_guiargs(parent):
|
|||||||
|
|
||||||
# Key drop shuffle stuff
|
# Key drop shuffle stuff
|
||||||
if guiargs.keydropshuffle:
|
if guiargs.keydropshuffle:
|
||||||
guiargs.dropshuffle = 1
|
guiargs.dropshuffle = 'keys' if guiargs.dropshuffle == 'none' else guiargs.dropshuffle
|
||||||
guiargs.pottery = 'keys' if guiargs.pottery == 'none' else guiargs.pottery
|
guiargs.pottery = 'keys' if guiargs.pottery == 'none' else guiargs.pottery
|
||||||
|
|
||||||
if guiargs.retro or guiargs.mode == 'retro':
|
if guiargs.retro or guiargs.mode == 'retro':
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import RaceRandom as random
|
|||||||
import logging
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from source.dungeon.EnemyList import enemy_stats
|
|
||||||
from source.item.District import resolve_districts
|
from source.item.District import resolve_districts
|
||||||
from BaseClasses import PotItem, PotFlags
|
from BaseClasses import PotItem, PotFlags
|
||||||
from DoorShuffle import validate_vanilla_reservation
|
from DoorShuffle import validate_vanilla_reservation
|
||||||
@@ -66,7 +65,7 @@ def create_item_pool_config(world):
|
|||||||
for player in range(1, world.players + 1):
|
for player in range(1, world.players + 1):
|
||||||
config.static_placement[player] = defaultdict(list)
|
config.static_placement[player] = defaultdict(list)
|
||||||
config.static_placement[player].update(vanilla_mapping)
|
config.static_placement[player].update(vanilla_mapping)
|
||||||
if world.dropshuffle[player]:
|
if world.dropshuffle[player] != 'none':
|
||||||
for item, locs in keydrop_vanilla_mapping.items():
|
for item, locs in keydrop_vanilla_mapping.items():
|
||||||
config.static_placement[player][item].extend(locs)
|
config.static_placement[player][item].extend(locs)
|
||||||
if world.pottery[player] not in ['none', 'cave']:
|
if world.pottery[player] not in ['none', 'cave']:
|
||||||
@@ -92,7 +91,7 @@ def create_item_pool_config(world):
|
|||||||
for item, locs in vanilla_mapping.items():
|
for item, locs in vanilla_mapping.items():
|
||||||
if 'Small Key' in item:
|
if 'Small Key' in item:
|
||||||
universal_key_locations.extend(locs)
|
universal_key_locations.extend(locs)
|
||||||
if world.dropshuffle[player]:
|
if world.dropshuffle[player] != 'none':
|
||||||
for item, locs in keydrop_vanilla_mapping.items():
|
for item, locs in keydrop_vanilla_mapping.items():
|
||||||
if 'Small Key' in item:
|
if 'Small Key' in item:
|
||||||
universal_key_locations.extend(locs)
|
universal_key_locations.extend(locs)
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ class RuleFactory(object):
|
|||||||
rule.sub_rules.extend(r.sub_rules) # todo: this extension for the lambda calc
|
rule.sub_rules.extend(r.sub_rules) # todo: this extension for the lambda calc
|
||||||
elif r.rule_type == RuleType.Static and r.principal: # remove static flag if unnecessary
|
elif r.rule_type == RuleType.Static and r.principal: # remove static flag if unnecessary
|
||||||
continue
|
continue
|
||||||
|
elif r.rule_type == RuleType.Static and not r.principal: # always evaluates to false
|
||||||
|
return r
|
||||||
else:
|
else:
|
||||||
rule.sub_rules.append(r)
|
rule.sub_rules.append(r)
|
||||||
if not rule_lambda:
|
if not rule_lambda:
|
||||||
@@ -128,6 +130,8 @@ class RuleFactory(object):
|
|||||||
rule.sub_rules.extend(r.sub_rules) # todo: this extension for the lambda calc
|
rule.sub_rules.extend(r.sub_rules) # todo: this extension for the lambda calc
|
||||||
elif r.rule_type == RuleType.Static and not r.principal: # remove static flag if unnecessary
|
elif r.rule_type == RuleType.Static and not r.principal: # remove static flag if unnecessary
|
||||||
continue
|
continue
|
||||||
|
elif r.rule_type == RuleType.Static and r.principal: # always evaluates to true
|
||||||
|
return r
|
||||||
else:
|
else:
|
||||||
rule.sub_rules.append(r)
|
rule.sub_rules.append(r)
|
||||||
if not rule_lambda:
|
if not rule_lambda:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from Utils import snes_to_pc, int24_as_bytes, int16_as_bytes
|
from Utils import snes_to_pc, int24_as_bytes, int16_as_bytes
|
||||||
|
|
||||||
from source.dungeon.EnemyList import EnemyTable, init_vanilla_sprites, vanilla_sprites
|
from source.dungeon.EnemyList import EnemyTable, init_vanilla_sprites, vanilla_sprites, init_enemy_stats
|
||||||
from source.dungeon.RoomHeader import init_room_headers
|
from source.dungeon.RoomHeader import init_room_headers
|
||||||
from source.dungeon.RoomList import Room0127
|
from source.dungeon.RoomList import Room0127
|
||||||
from source.enemizer.SpriteSheets import init_sprite_sheets, init_sprite_requirements
|
from source.enemizer.SpriteSheets import init_sprite_sheets, init_sprite_requirements
|
||||||
@@ -17,6 +17,7 @@ class DataTables:
|
|||||||
|
|
||||||
# associated data
|
# associated data
|
||||||
self.sprite_requirements = None
|
self.sprite_requirements = None
|
||||||
|
self.enemy_stats = None
|
||||||
|
|
||||||
def write_to_rom(self, rom, colorize_pots=False):
|
def write_to_rom(self, rom, colorize_pots=False):
|
||||||
if self.pot_secret_table.size() > 0x11c0:
|
if self.pot_secret_table.size() > 0x11c0:
|
||||||
@@ -56,6 +57,7 @@ def init_data_tables(world, player):
|
|||||||
data_tables.sprite_requirements = init_sprite_requirements()
|
data_tables.sprite_requirements = init_sprite_requirements()
|
||||||
data_tables.sprite_sheets = init_sprite_sheets(data_tables.sprite_requirements)
|
data_tables.sprite_sheets = init_sprite_sheets(data_tables.sprite_requirements)
|
||||||
init_vanilla_sprites()
|
init_vanilla_sprites()
|
||||||
|
data_tables.enemy_stats = init_enemy_stats()
|
||||||
uw_table = data_tables.uw_enemy_table = EnemyTable()
|
uw_table = data_tables.uw_enemy_table = EnemyTable()
|
||||||
for room, sprite_list in vanilla_sprites.items():
|
for room, sprite_list in vanilla_sprites.items():
|
||||||
for sprite in sprite_list:
|
for sprite in sprite_list:
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ def roll_settings(weights):
|
|||||||
ret.pseudoboots = get_choice('pseudoboots') == 'on'
|
ret.pseudoboots = get_choice('pseudoboots') == 'on'
|
||||||
ret.shopsanity = get_choice('shopsanity') == 'on'
|
ret.shopsanity = get_choice('shopsanity') == 'on'
|
||||||
keydropshuffle = get_choice('keydropshuffle') == 'on'
|
keydropshuffle = get_choice('keydropshuffle') == 'on'
|
||||||
ret.dropshuffle = get_choice('dropshuffle') == 'on' or keydropshuffle
|
ret.dropshuffle = get_choice('dropshuffle') if 'dropshuffle' in weights else 'none'
|
||||||
|
ret.dropshuffle = 'keys' if ret.dropshuffle == 'none' and keydropshuffle else ret.dropshuffle
|
||||||
ret.pottery = get_choice('pottery') if 'pottery' in weights else 'none'
|
ret.pottery = get_choice('pottery') if 'pottery' in weights else 'none'
|
||||||
ret.pottery = 'keys' if ret.pottery == 'none' and keydropshuffle else ret.pottery
|
ret.pottery = 'keys' if ret.pottery == 'none' and keydropshuffle else ret.pottery
|
||||||
ret.colorizepots = get_choice('colorizepots') == 'on'
|
ret.colorizepots = get_choice('colorizepots') == 'on'
|
||||||
|
|||||||
Reference in New Issue
Block a user