Individual settings: shufflebosses shuffleenemies enemy_health enemy_damage
This commit is contained in:
parent
8a5eef11ce
commit
1ecb5fe40b
|
@ -8,7 +8,7 @@ from Utils import int16_as_bytes
|
|||
|
||||
class World(object):
|
||||
|
||||
def __init__(self, players, shuffle, logic, mode, swords, difficulty, difficulty_adjustments, timer, progressive, goal, algorithm, accessibility, shuffle_ganon, quickswap, fastmenu, disable_music, retro, custom, customitemarray, boss_shuffle, hints):
|
||||
def __init__(self, players, shuffle, logic, mode, swords, difficulty, difficulty_adjustments, timer, progressive, goal, algorithm, accessibility, shuffle_ganon, quickswap, fastmenu, disable_music, retro, custom, customitemarray, hints):
|
||||
self.players = players
|
||||
self.shuffle = shuffle.copy()
|
||||
self.logic = logic.copy()
|
||||
|
@ -73,7 +73,10 @@ class World(object):
|
|||
self.can_take_damage = True
|
||||
self.difficulty_requirements = {player: None for player in range(1, players + 1)}
|
||||
self.fix_fake_world = True
|
||||
self.boss_shuffle = boss_shuffle
|
||||
self.boss_shuffle = {player: 'none' for player in range(1, players + 1)}
|
||||
self.enemy_shuffle = {player: 'none' for player in range(1, players + 1)}
|
||||
self.enemy_health = {player: 'default' for player in range(1, players + 1)}
|
||||
self.enemy_damage = {player: 'default' for player in range(1, players + 1)}
|
||||
self.escape_assist = {player: [] for player in range(1, players + 1)}
|
||||
self.hints = hints.copy()
|
||||
self.crystals_needed_for_ganon = {}
|
||||
|
@ -1059,6 +1062,10 @@ class Spoiler(object):
|
|||
'compassshuffle': self.world.compassshuffle,
|
||||
'keyshuffle': self.world.keyshuffle,
|
||||
'bigkeyshuffle': self.world.bigkeyshuffle,
|
||||
'boss_shuffle': self.world.boss_shuffle,
|
||||
'enemy_shuffle': self.world.enemy_shuffle,
|
||||
'enemy_health': self.world.enemy_health,
|
||||
'enemy_damage': self.world.enemy_damage,
|
||||
'players': self.world.players
|
||||
}
|
||||
|
||||
|
@ -1072,8 +1079,7 @@ class Spoiler(object):
|
|||
out['Shops'] = self.shops
|
||||
out['playthrough'] = self.playthrough
|
||||
out['paths'] = self.paths
|
||||
if self.world.boss_shuffle != 'none':
|
||||
out['Bosses'] = self.bosses
|
||||
out['Bosses'] = self.bosses
|
||||
out['meta'] = self.metadata
|
||||
|
||||
return json.dumps(out)
|
||||
|
@ -1101,6 +1107,10 @@ class Spoiler(object):
|
|||
outfile.write('Compass shuffle: %s\n' % {k: 'Yes' if v else 'No' for k, v in self.metadata['compassshuffle'].items()})
|
||||
outfile.write('Small Key shuffle: %s\n' % {k: 'Yes' if v else 'No' for k, v in self.metadata['keyshuffle'].items()})
|
||||
outfile.write('Big Key shuffle: %s\n' % {k: 'Yes' if v else 'No' for k, v in self.metadata['bigkeyshuffle'].items()})
|
||||
outfile.write('Boss shuffle: %s\n' % self.metadata['boss_shuffle'])
|
||||
outfile.write('Enemy shuffle: %s\n' % self.metadata['enemy_shuffle'])
|
||||
outfile.write('Enemy health: %s\n' % self.metadata['enemy_health'])
|
||||
outfile.write('Enemy damage: %s\n' % self.metadata['enemy_damage'])
|
||||
outfile.write('Hints: %s\n' % {k: 'Yes' if v else 'No' for k, v in self.metadata['hints'].items()})
|
||||
outfile.write('Players: %d' % self.world.players)
|
||||
if self.entrances:
|
||||
|
|
|
@ -138,7 +138,7 @@ def can_place_boss(world, player, 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[player] != 'inverted':
|
||||
|
@ -177,7 +177,7 @@ def place_bosses(world, player):
|
|||
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']]
|
||||
|
||||
if world.boss_shuffle in ["basic", "normal"]:
|
||||
if world.boss_shuffle[player] in ["basic", "normal"]:
|
||||
# temporary hack for swordless kholdstare:
|
||||
if world.swords[player] == 'swordless':
|
||||
world.get_dungeon('Ice Palace', player).boss = BossFactory('Kholdstare', player)
|
||||
|
@ -185,7 +185,7 @@ def place_bosses(world, player):
|
|||
boss_locations.remove(['Ice Palace', None])
|
||||
placeable_bosses.remove('Kholdstare')
|
||||
|
||||
if world.boss_shuffle == "basic": # vanilla bosses shuffled
|
||||
if world.boss_shuffle[player] == "basic": # 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)]
|
||||
|
@ -202,7 +202,7 @@ def place_bosses(world, player):
|
|||
|
||||
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
|
||||
elif world.boss_shuffle[player] == "chaos": #all bosses chosen at random
|
||||
for [loc, level] in boss_locations:
|
||||
loc_text = loc + (' ('+level+')' if level else '')
|
||||
try:
|
||||
|
|
|
@ -281,7 +281,8 @@ def parse_arguments(argv, no_defaults=False):
|
|||
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality',
|
||||
'shuffle', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle',
|
||||
'retro', 'accessibility', 'hints']:
|
||||
'retro', 'accessibility', 'hints',
|
||||
'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage']:
|
||||
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
|
||||
if player == 1:
|
||||
setattr(ret, name, {1: value})
|
||||
|
|
21
Main.py
21
Main.py
|
@ -25,7 +25,7 @@ def main(args, seed=None):
|
|||
start = time.process_time()
|
||||
|
||||
# initialize the world
|
||||
world = World(args.multi, args.shuffle, args.logic, args.mode, args.swords, args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm, args.accessibility, args.shuffleganon, args.quickswap, args.fastmenu, args.disablemusic, args.retro, args.custom, args.customitemarray, args.shufflebosses, args.hints)
|
||||
world = World(args.multi, args.shuffle, args.logic, args.mode, args.swords, args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm, args.accessibility, args.shuffleganon, args.quickswap, args.fastmenu, args.disablemusic, args.retro, args.custom, args.customitemarray, args.hints)
|
||||
logger = logging.getLogger('')
|
||||
if seed is None:
|
||||
random.seed(None)
|
||||
|
@ -41,6 +41,10 @@ def main(args, seed=None):
|
|||
world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)}
|
||||
world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)}
|
||||
world.open_pyramid = args.openpyramid.copy()
|
||||
world.boss_shuffle = args.shufflebosses.copy()
|
||||
world.enemy_shuffle = args.shuffleenemies.copy()
|
||||
world.enemy_health = args.enemy_health.copy()
|
||||
world.enemy_damage = args.enemy_damage.copy()
|
||||
|
||||
world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)}
|
||||
|
||||
|
@ -49,7 +53,7 @@ def main(args, seed=None):
|
|||
for player in range(1, world.players + 1):
|
||||
world.difficulty_requirements[player] = difficulties[world.difficulty[player]]
|
||||
|
||||
if world.mode[player] == 'standard' and (args.shuffleenemies != 'none' or args.enemy_health not in ['default', 'easy']):
|
||||
if world.mode[player] == 'standard' and (world.enemy_shuffle[player] != 'none' or world.enemy_health[player] not in ['default', 'easy']):
|
||||
world.escape_assist[player].append(['bombs']) # enemized escape assumes infinite bombs available and will likely be unbeatable without it
|
||||
|
||||
if world.mode[player] != 'inverted':
|
||||
|
@ -128,8 +132,6 @@ def main(args, seed=None):
|
|||
player_names = parse_names_string(args.names)
|
||||
outfilebase = 'ER_%s' % (args.outputname if args.outputname else world.seed)
|
||||
|
||||
use_enemizer = args.enemizercli and (args.shufflebosses != 'none' or args.shuffleenemies != 'none' or args.enemy_health != 'default' or args.enemy_health != 'default' or args.enemy_damage or args.shufflepalette or args.shufflepots)
|
||||
|
||||
jsonout = {}
|
||||
if not args.suppress_rom:
|
||||
from MultiServer import MultiWorld
|
||||
|
@ -137,6 +139,9 @@ def main(args, seed=None):
|
|||
multidata.players = world.players
|
||||
|
||||
for player in range(1, world.players + 1):
|
||||
use_enemizer = (world.boss_shuffle[player] != 'none' or world.enemy_shuffle[player] != 'none'
|
||||
or world.enemy_health[player] != 'default' or world.enemy_damage[player] != 'default'
|
||||
or args.shufflepalette or args.shufflepots)
|
||||
|
||||
local_rom = None
|
||||
if args.jsonout:
|
||||
|
@ -151,7 +156,7 @@ def main(args, seed=None):
|
|||
|
||||
enemizer_patch = []
|
||||
if use_enemizer:
|
||||
enemizer_patch = get_enemizer_patch(world, player, rom, args.rom, args.enemizercli, args.shuffleenemies, args.enemy_health, args.enemy_damage, args.shufflepalette, args.shufflepots)
|
||||
enemizer_patch = get_enemizer_patch(world, player, rom, args.rom, args.enemizercli, args.shufflepalette, args.shufflepots)
|
||||
|
||||
multidata.rom_names[player] = list(rom.name)
|
||||
for location in world.get_filled_locations(player):
|
||||
|
@ -218,7 +223,7 @@ def main(args, seed=None):
|
|||
|
||||
def copy_world(world):
|
||||
# ToDo: Not good yet
|
||||
ret = World(world.players, world.shuffle, world.logic, world.mode, world.swords, world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm, world.accessibility, world.shuffle_ganon, world.quickswap, world.fastmenu, world.disable_music, world.retro, world.custom, world.customitemarray, world.boss_shuffle, world.hints)
|
||||
ret = World(world.players, world.shuffle, world.logic, world.mode, world.swords, world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm, world.accessibility, world.shuffle_ganon, world.quickswap, world.fastmenu, world.disable_music, world.retro, world.custom, world.customitemarray, world.hints)
|
||||
ret.required_medallions = world.required_medallions.copy()
|
||||
ret.swamp_patch_required = world.swamp_patch_required.copy()
|
||||
ret.ganon_at_pyramid = world.ganon_at_pyramid.copy()
|
||||
|
@ -245,6 +250,10 @@ def copy_world(world):
|
|||
ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy()
|
||||
ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy()
|
||||
ret.open_pyramid = world.open_pyramid.copy()
|
||||
ret.boss_shuffle = world.boss_shuffle.copy()
|
||||
ret.enemy_shuffle = world.enemy_shuffle.copy()
|
||||
ret.enemy_health = world.enemy_health.copy()
|
||||
ret.enemy_damage = world.enemy_damage.copy()
|
||||
|
||||
for player in range(1, world.players + 1):
|
||||
if world.mode[player] != 'inverted':
|
||||
|
|
|
@ -23,7 +23,7 @@ def main(args):
|
|||
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', 'noglitches', 'standard', 'normal', 'none', 'on', 'ganon', 'freshness', False, False, False, args.quickswap, args.fastmenu, args.disablemusic, False, False, False, None, False)
|
||||
logger = logging.getLogger('')
|
||||
|
||||
hasher = hashlib.md5()
|
||||
|
|
20
Rom.py
20
Rom.py
|
@ -161,7 +161,7 @@ def read_rom(stream):
|
|||
buffer = buffer[0x200:]
|
||||
return buffer
|
||||
|
||||
def get_enemizer_patch(world, player, rom, baserom_path, enemizercli, shuffleenemies, enemy_health, enemy_damage, shufflepalette, shufflepots):
|
||||
def get_enemizer_patch(world, player, rom, baserom_path, enemizercli, shufflepalette, shufflepots):
|
||||
baserom_path = os.path.abspath(baserom_path)
|
||||
basepatch_path = os.path.abspath(local_path('data/base2current.json'))
|
||||
randopatch_path = os.path.abspath(output_path('enemizer_randopatch.json'))
|
||||
|
@ -170,16 +170,16 @@ def get_enemizer_patch(world, player, rom, baserom_path, enemizercli, shuffleene
|
|||
|
||||
# write options file for enemizer
|
||||
options = {
|
||||
'RandomizeEnemies': shuffleenemies != 'none',
|
||||
'RandomizeEnemies': world.enemy_shuffle[player] != 'none',
|
||||
'RandomizeEnemiesType': 3,
|
||||
'RandomizeBushEnemyChance': shuffleenemies == 'chaos',
|
||||
'RandomizeEnemyHealthRange': enemy_health != 'default',
|
||||
'RandomizeEnemyHealthType': {'default': 0, 'easy': 0, 'normal': 1, 'hard': 2, 'expert': 3}[enemy_health],
|
||||
'RandomizeBushEnemyChance': world.enemy_shuffle[player] == 'chaos',
|
||||
'RandomizeEnemyHealthRange': world.enemy_health[player] != 'default',
|
||||
'RandomizeEnemyHealthType': {'default': 0, 'easy': 0, 'normal': 1, 'hard': 2, 'expert': 3}[world.enemy_health[player]],
|
||||
'OHKO': False,
|
||||
'RandomizeEnemyDamage': enemy_damage != 'default',
|
||||
'RandomizeEnemyDamage': world.enemy_damage[player] != 'default',
|
||||
'AllowEnemyZeroDamage': True,
|
||||
'ShuffleEnemyDamageGroups': enemy_damage != 'default',
|
||||
'EnemyDamageChaosMode': enemy_damage == 'chaos',
|
||||
'ShuffleEnemyDamageGroups': world.enemy_damage[player] != 'default',
|
||||
'EnemyDamageChaosMode': world.enemy_damage[player] == 'chaos',
|
||||
'EasyModeEscape': False,
|
||||
'EnemiesAbsorbable': False,
|
||||
'AbsorbableSpawnRate': 10,
|
||||
|
@ -218,9 +218,9 @@ def get_enemizer_patch(world, player, rom, baserom_path, enemizercli, shuffleene
|
|||
'SwordGraphics': "sword_gfx/normal.gfx",
|
||||
'BeeMizer': False,
|
||||
'BeesLevel': 0,
|
||||
'RandomizeTileTrapPattern': shuffleenemies == 'chaos',
|
||||
'RandomizeTileTrapPattern': world.enemy_shuffle[player] == 'chaos',
|
||||
'RandomizeTileTrapFloorTile': False,
|
||||
'AllowKillableThief': bool(random.randint(0,1)) if shuffleenemies == 'chaos' else shuffleenemies != 'none',
|
||||
'AllowKillableThief': bool(random.randint(0,1)) if world.enemy_shuffle[player] == 'chaos' else world.enemy_shuffle[player] != 'none',
|
||||
'RandomizeSpriteOnHit': False,
|
||||
'DebugMode': False,
|
||||
'DebugForceEnemy': False,
|
||||
|
|
Loading…
Reference in New Issue