diff --git a/BaseClasses.py b/BaseClasses.py index 4691ef4b..19725779 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -3656,7 +3656,7 @@ bigkeyshuffle_mode = {'none': 0, 'off': 0, 'nearby': 2, 'wild': 3, 'on': 3} # byte 8: HHHD DPEE (enemy_health, enemy_dmg, potshuffle, enemies) e_health = {"default": 0, "easy": 1, "normal": 2, "hard": 3, "expert": 4} e_dmg = {"default": 0, "shuffled": 1, "random": 2} -enemy_mode = {"none": 0, "shuffled": 1, "chaos": 2, "random": 2, "legacy": 3} +enemy_mode = {"none": 0, "shuffled": 1, "chaos": 2, "random": 2, "mimics": 3} # byte 9: RRAA ABBB (restrict boss mode, algorithm, boss shuffle) rb_mode = {"none": 0, "mapcompass": 1, "dungeon": 2} diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 8b9fa77c..54fea6cb 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -587,7 +587,8 @@ "shuffleenemies": { "choices": [ "none", - "shuffled" + "shuffled", + "mimics" ] }, "enemy_health": { @@ -638,4 +639,4 @@ "outputname": {}, "notes": {}, "code": {} -} \ No newline at end of file +} diff --git a/source/enemizer/Enemizer.py b/source/enemizer/Enemizer.py index 90c7ef34..c71fed59 100644 --- a/source/enemizer/Enemizer.py +++ b/source/enemizer/Enemizer.py @@ -3,6 +3,7 @@ from Utils import snes_to_pc from source.dungeon.EnemyList import SpriteType, EnemySprite, sprite_translation from source.dungeon.RoomList import Room010C +from source.enemizer.SpecialEnemyModes import get_enemy_map_uw, get_enemy_map_ow from source.enemizer.SpriteSheets import sub_group_choices from source.enemizer.SpriteSheets import randomize_underworld_sprite_sheets, randomize_overworld_sprite_sheets from source.enemizer.TilePattern import tile_patterns @@ -427,7 +428,8 @@ skip_sprites = { def randomize_enemies(world, player): if world.enemy_shuffle[player] != 'none': data_tables = world.data_tables[player] - custom_uw, custom_ow = {}, {} + custom_ow = get_enemy_map_ow(world.enemy_shuffle[player], data_tables) + custom_uw = get_enemy_map_uw(world.enemy_shuffle[player], data_tables) enemy_map = world.customizer.get_enemies() if world.customizer else None if enemy_map and player in enemy_map: if 'Underworld' in enemy_map[player]: diff --git a/source/enemizer/SpecialEnemyModes.py b/source/enemizer/SpecialEnemyModes.py new file mode 100644 index 00000000..8e0df1cb --- /dev/null +++ b/source/enemizer/SpecialEnemyModes.py @@ -0,0 +1,46 @@ +from source.dungeon.EnemyList import EnemySprite, SpriteType, sprite_translation, enemy_names + +def can_combine_req(req1, req2): + for i in range(0, 4): + if req1.sub_groups[i] and req2.sub_groups[i]: + if len(set(req1.sub_groups[i]).intersection(req2.sub_groups[i])) == 0: + return False + return True + +def get_enemy_map(mode, reqs, vanilla_map): + data = {} + + if mode != "mimics": + return data + + green_mimic = reqs.get((EnemySprite.GreenMimic, 0)) + + for room_id, sprites in vanilla_map.items(): + data[room_id] = {} + for idx, sprite in enumerate(sprites): + subtype = 0 if sprite.sub_type != SpriteType.Overlord else sprite.sub_type + req = reqs.get((sprite.kind, subtype)) + if not req or isinstance(req, dict) or req.boss: + continue + if req.static: + if not can_combine_req(green_mimic, req): + data[room_id] = {} + break + continue + if req.killable: + data[room_id][idx] = 'GreenMimic' + else: + data[room_id][idx] = enemy_names[sprite.kind] + if len(data[room_id]) == 0: + del data[room_id] + return data + + +def get_enemy_map_ow(mode, data_tables): + reqs = data_tables.sprite_requirements + return get_enemy_map(mode, reqs, data_tables.ow_enemy_table) + +def get_enemy_map_uw(mode, data_tables): + reqs = data_tables.sprite_requirements + return get_enemy_map(mode, reqs, data_tables.uw_enemy_table.room_map) +