Added intensity parameter. Clean up for next alpha release

This commit is contained in:
aerinon
2020-09-16 15:01:01 -06:00
parent 907b13b59a
commit 357a09d5b7
14 changed files with 84 additions and 25 deletions

View File

@@ -19,11 +19,13 @@ from RoomData import Room
class World(object): class World(object):
def __init__(self, players, shuffle, doorShuffle, logic, mode, swords, difficulty, difficulty_adjustments, timer, progressive, goal, algorithm, accessibility, shuffle_ganon, retro, custom, customitemarray, hints): def __init__(self, players, shuffle, doorShuffle, logic, mode, swords, difficulty, difficulty_adjustments,
timer, progressive, goal, algorithm, accessibility, shuffle_ganon, retro, custom, customitemarray, hints):
self.players = players self.players = players
self.teams = 1 self.teams = 1
self.shuffle = shuffle.copy() self.shuffle = shuffle.copy()
self.doorShuffle = doorShuffle.copy() self.doorShuffle = doorShuffle.copy()
self.intensity = {}
self.logic = logic.copy() self.logic = logic.copy()
self.mode = mode.copy() self.mode = mode.copy()
self.swords = swords.copy() self.swords = swords.copy()
@@ -1703,6 +1705,7 @@ class Spoiler(object):
'goal': self.world.goal, 'goal': self.world.goal,
'shuffle': self.world.shuffle, 'shuffle': self.world.shuffle,
'door_shuffle': self.world.doorShuffle, 'door_shuffle': self.world.doorShuffle,
'intensity': self.world.intensity,
'item_pool': self.world.difficulty, 'item_pool': self.world.difficulty,
'item_functionality': self.world.difficulty_adjustments, 'item_functionality': self.world.difficulty_adjustments,
'gt_crystals': self.world.crystals_needed_for_gt, 'gt_crystals': self.world.crystals_needed_for_gt,
@@ -1765,6 +1768,7 @@ class Spoiler(object):
outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player]) outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player])
outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player]) outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player])
outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player]) outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player])
outfile.write('Intensity: %s\n' % self.metadata['intensity'][player])
outfile.write('Crystals required for GT: %s\n' % self.metadata['gt_crystals'][player]) outfile.write('Crystals required for GT: %s\n' % self.metadata['gt_crystals'][player])
outfile.write('Crystals required for Ganon: %s\n' % self.metadata['ganon_crystals'][player]) outfile.write('Crystals required for Ganon: %s\n' % self.metadata['ganon_crystals'][player])
outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No')) outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No'))

3
CLI.py
View File

@@ -90,7 +90,7 @@ def parse_cli(argv, no_defaults=False):
playerargs = parse_cli(shlex.split(getattr(ret,f"p{player}")), True) playerargs = parse_cli(shlex.split(getattr(ret,f"p{player}")), True)
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality',
'shuffle', 'door_shuffle', 'crystals_ganon', 'crystals_gt', 'openpyramid', 'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters',
'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots',
@@ -141,6 +141,7 @@ def parse_settings():
"bigkeyshuffle": False, "bigkeyshuffle": False,
"keysanity": False, "keysanity": False,
"door_shuffle": "basic", "door_shuffle": "basic",
"intensity": 2,
"experimental": False, "experimental": False,
"dungeon_counters": "default", "dungeon_counters": "default",

View File

@@ -34,6 +34,12 @@ def link_doors(world, player):
for ent, ext in ladders: for ent, ext in ladders:
connect_two_way(world, ent, ext, player) connect_two_way(world, ent, ext, player)
if world.intensity[player] < 2:
for entrance, ext in open_edges:
connect_two_way(world, entrance, ext, player)
for entrance, ext in straight_staircases:
connect_two_way(world, entrance, ext, player)
if world.doorShuffle[player] == 'vanilla': if world.doorShuffle[player] == 'vanilla':
for entrance, ext in open_edges: for entrance, ext in open_edges:
connect_two_way(world, entrance, ext, player) connect_two_way(world, entrance, ext, player)
@@ -49,18 +55,8 @@ def link_doors(world, player):
connect_one_way(world, ent, ext, player) connect_one_way(world, ent, ext, player)
vanilla_key_logic(world, player) vanilla_key_logic(world, player)
elif world.doorShuffle[player] == 'basic': elif world.doorShuffle[player] == 'basic':
if not world.experimental[player]:
for entrance, ext in open_edges:
connect_two_way(world, entrance, ext, player)
for entrance, ext in straight_staircases:
connect_two_way(world, entrance, ext, player)
within_dungeon(world, player) within_dungeon(world, player)
elif world.doorShuffle[player] == 'crossed': elif world.doorShuffle[player] == 'crossed':
if not world.experimental[player]:
for entrance, ext in open_edges:
connect_two_way(world, entrance, ext, player)
for entrance, ext in straight_staircases:
connect_two_way(world, entrance, ext, player)
cross_dungeon(world, player) cross_dungeon(world, player)
else: else:
logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player]) logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player])

13
Main.py
View File

@@ -24,7 +24,7 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute
from ItemList import generate_itempool, difficulties, fill_prizes from ItemList import generate_itempool, difficulties, fill_prizes
from Utils import output_path, parse_player_names from Utils import output_path, parse_player_names
__version__ = '0.1.0.14-u' __version__ = '0.1.0-dev'
class EnemizerError(RuntimeError): class EnemizerError(RuntimeError):
pass pass
@@ -38,7 +38,9 @@ def main(args, seed=None, fish=None):
start = time.perf_counter() start = time.perf_counter()
# initialize the world # initialize the world
world = World(args.multi, args.shuffle, args.door_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.retro, args.custom, args.customitemarray, args.hints) world = World(args.multi, args.shuffle, args.door_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.retro, args.custom, args.customitemarray, args.hints)
logger = logging.getLogger('') logger = logging.getLogger('')
if seed is None: if seed is None:
random.seed(None) random.seed(None)
@@ -60,6 +62,7 @@ def main(args, seed=None, fish=None):
world.enemy_health = args.enemy_health.copy() world.enemy_health = args.enemy_health.copy()
world.enemy_damage = args.enemy_damage.copy() world.enemy_damage = args.enemy_damage.copy()
world.beemizer = args.beemizer.copy() world.beemizer = args.beemizer.copy()
world.intensity = {player: random.randint(1, 3) if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)}
world.experimental = args.experimental.copy() world.experimental = args.experimental.copy()
world.dungeon_counters = args.dungeon_counters.copy() world.dungeon_counters = args.dungeon_counters.copy()
world.fish = fish world.fish = fish
@@ -329,7 +332,9 @@ def main(args, seed=None, fish=None):
def copy_world(world): def copy_world(world):
# ToDo: Not good yet # ToDo: Not good yet
ret = World(world.players, world.shuffle, world.doorShuffle, 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.retro, world.custom, world.customitemarray, world.hints) ret = World(world.players, world.shuffle, world.doorShuffle, 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.retro, world.custom, world.customitemarray, world.hints)
ret.teams = world.teams ret.teams = world.teams
ret.player_names = copy.deepcopy(world.player_names) ret.player_names = copy.deepcopy(world.player_names)
ret.remote_items = world.remote_items.copy() ret.remote_items = world.remote_items.copy()
@@ -364,6 +369,8 @@ def copy_world(world):
ret.enemy_health = world.enemy_health.copy() ret.enemy_health = world.enemy_health.copy()
ret.enemy_damage = world.enemy_damage.copy() ret.enemy_damage = world.enemy_damage.copy()
ret.beemizer = world.beemizer.copy() ret.beemizer = world.beemizer.copy()
ret.intensity = world.intensity.copy()
ret.experimental = world.experimental.copy()
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':

View File

@@ -149,6 +149,7 @@ def roll_settings(weights):
ret.shuffle = entrance_shuffle if entrance_shuffle != 'none' else 'vanilla' ret.shuffle = entrance_shuffle if entrance_shuffle != 'none' else 'vanilla'
door_shuffle = get_choice('door_shuffle') door_shuffle = get_choice('door_shuffle')
ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla' ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla'
ret.intensity = get_choice('intensity')
ret.experimental = get_choice('experimental') == 'on' ret.experimental = get_choice('experimental') == 'on'
ret.dungeon_counters = get_choice('dungeon_counters') if 'dungeon_counters' in weights else 'default' ret.dungeon_counters = get_choice('dungeon_counters') if 'dungeon_counters' in weights else 'default'

View File

@@ -36,6 +36,16 @@ Doors are shuffled between dungeons as well.
Doors are not shuffled. Doors are not shuffled.
## Intensity
#### Level 1
Normal door and spiral staircases are shuffled
#### Level 2
Same as Level 1 plus open edges and straight staircases are shuffled.
#### Level 3 (Coming soon)
Same as Level 2 plus Dungeon Lobbies are shuffled
## Map/Compass/Small Key/Big Key shuffle (aka Keysanity) ## Map/Compass/Small Key/Big Key shuffle (aka Keysanity)
These settings allow dungeon specific items to be distributed anywhere in the world and not just in their native dungeon. These settings allow dungeon specific items to be distributed anywhere in the world and not just in their native dungeon.
@@ -75,3 +85,9 @@ Show the help message and exit.
``` ```
For specifying the door shuffle you want as above. (default: basic) For specifying the door shuffle you want as above. (default: basic)
```
--intensity
```
For specifying the door shuffle intensity level you want as above. (default: 2)

2
Rom.py
View File

@@ -22,7 +22,7 @@ from EntranceShuffle import door_addresses, exit_ids
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '82a102fee15ed0718257d92cd7ba031b' RANDOMIZERBASEHASH = 'b9e578ef0af231041070bd9049a55646'
class JsonRom(object): class JsonRom(object):

File diff suppressed because one or more lines are too long

View File

@@ -110,6 +110,11 @@
"vanilla" "vanilla"
] ]
}, },
"intensity": {
"choices":[
"3", "2", "1", "random"
]
},
"experimental": { "experimental": {
"action": "store_true", "action": "store_true",
"type": "bool" "type": "bool"
@@ -124,12 +129,12 @@
}, },
"crystals_ganon": { "crystals_ganon": {
"choices": [ "choices": [
7, 6, 5, 4, 3, 2, 1, 0, "random" "7", "6", "5", "4", "3", "2", "1", "0", "random"
] ]
}, },
"crystals_gt": { "crystals_gt": {
"choices": [ "choices": [
7, 6, 5, 4, 3, 2, 1, 0, "random" "7", "6", "5", "4", "3", "2", "1", "0", "random"
] ]
}, },
"openpyramid": { "openpyramid": {

View File

@@ -198,6 +198,13 @@
"Vanilla: All doors are connected the same way they were in the", "Vanilla: All doors are connected the same way they were in the",
" base game." " base game."
], ],
"intensity" : [
"Door Shuffle Intensity Level (default: %(default)s)",
"1: Shuffles normal doors and spiral staircases",
"2: And shuffles open edges and straight staircases",
"3: (Coming soon) And shuffles dungeon lobbies",
"random: Picks one of those at random"
],
"experimental": [ "Enable experimental features. (default: %(default)s)" ], "experimental": [ "Enable experimental features. (default: %(default)s)" ],
"dungeon_counters": [ "Enable dungeon chest counters. (default: %(default)s)" ], "dungeon_counters": [ "Enable dungeon chest counters. (default: %(default)s)" ],
"crystals_ganon": [ "crystals_ganon": [

View File

@@ -58,6 +58,12 @@
"randomizer.dungeon.dungeondoorshuffle.basic": "Basic", "randomizer.dungeon.dungeondoorshuffle.basic": "Basic",
"randomizer.dungeon.dungeondoorshuffle.crossed": "Crossed", "randomizer.dungeon.dungeondoorshuffle.crossed": "Crossed",
"randomizer.dungeon.dungeonintensity": "Intensity Level",
"randomizer.dungeon.dungeonintensity.1": "1: Normal Supertile and Spiral Stairs",
"randomizer.dungeon.dungeonintensity.2": "2: Open Edges and Straight Stairs",
"randomizer.dungeon.dungeonintensity.3": "3: (Coming soon) Dungeon Lobbies",
"randomizer.dungeon.dungeonintensity.random": "Random",
"randomizer.dungeon.experimental": "Enable Experimental Features", "randomizer.dungeon.experimental": "Enable Experimental Features",
"randomizer.dungeon.dungeon_counters": "Dungeon Chest Counters", "randomizer.dungeon.dungeon_counters": "Dungeon Chest Counters",

View File

@@ -9,6 +9,19 @@
"crossed" "crossed"
] ]
}, },
"dungeonintensity": {
"type": "selectbox",
"default": "2",
"options": [
"1",
"2",
"3",
"random"
],
"config": {
"width": 40
}
},
"experimental": { "type": "checkbox" }, "experimental": { "type": "checkbox" },
"dungeon_counters": { "dungeon_counters": {
"type": "selectbox", "type": "selectbox",

View File

@@ -87,6 +87,7 @@ SETTINGSTOPROCESS = {
"smallkeyshuffle": "keyshuffle", "smallkeyshuffle": "keyshuffle",
"bigkeyshuffle": "bigkeyshuffle", "bigkeyshuffle": "bigkeyshuffle",
"dungeondoorshuffle": "door_shuffle", "dungeondoorshuffle": "door_shuffle",
"dungeonintensity": "intensity",
"experimental": "experimental", "experimental": "experimental",
"dungeon_counters": "dungeon_counters" "dungeon_counters": "dungeon_counters"
}, },

View File

@@ -33,7 +33,7 @@ def make_checkbox(self, parent, label, storageVar, manager, managerAttrs):
return self return self
# Make an OptionMenu with a label and pretty option labels # Make an OptionMenu with a label and pretty option labels
def make_selectbox(self, parent, label, options, storageVar, manager, managerAttrs): def make_selectbox(self, parent, label, options, storageVar, manager, managerAttrs, config=None):
self = Frame(parent) self = Frame(parent)
labels = options labels = options
@@ -96,7 +96,7 @@ def make_selectbox(self, parent, label, options, storageVar, manager, managerAtt
else: else:
self.label.pack(side=LEFT) self.label.pack(side=LEFT)
self.selectbox.config(width=20) self.selectbox.config(width=config['width'] if config and config['width'] else 20)
idx = 0 idx = 0
default = self.selectbox.options["values"][idx] default = self.selectbox.options["values"][idx]
if managerAttrs is not None and "default" in managerAttrs: if managerAttrs is not None and "default" in managerAttrs:
@@ -166,7 +166,8 @@ def make_textbox(self, parent, label, storageVar, manager, managerAttrs):
return widget return widget
# Make a generic widget # Make a generic widget
def make_widget(self, type, parent, label, storageVar=None, manager=None, managerAttrs=dict(), options=None): def make_widget(self, type, parent, label, storageVar=None, manager=None, managerAttrs=dict(),
options=None, config=None):
widget = None widget = None
if manager is None: if manager is None:
manager = "pack" manager = "pack"
@@ -184,7 +185,7 @@ def make_widget(self, type, parent, label, storageVar=None, manager=None, manage
elif type == "selectbox": elif type == "selectbox":
if thisStorageVar is None: if thisStorageVar is None:
thisStorageVar = StringVar() thisStorageVar = StringVar()
widget = make_selectbox(self, parent, label, options, thisStorageVar, manager, managerAttrs) widget = make_selectbox(self, parent, label, options, thisStorageVar, manager, managerAttrs, config)
elif type == "spinbox": elif type == "spinbox":
if thisStorageVar is None: if thisStorageVar is None:
thisStorageVar = StringVar() thisStorageVar = StringVar()
@@ -203,13 +204,14 @@ def make_widget_from_dict(self, defn, parent):
manager = defn["manager"] if "manager" in defn else None manager = defn["manager"] if "manager" in defn else None
managerAttrs = defn["managerAttrs"] if "managerAttrs" in defn else None managerAttrs = defn["managerAttrs"] if "managerAttrs" in defn else None
options = defn["options"] if "options" in defn else None options = defn["options"] if "options" in defn else None
config = defn["config"] if "config" in defn else None
if managerAttrs is None and "default" in defn: if managerAttrs is None and "default" in defn:
managerAttrs = {} managerAttrs = {}
if "default" in defn: if "default" in defn:
managerAttrs["default"] = defn["default"] managerAttrs["default"] = defn["default"]
widget = make_widget(self, type, parent, label, None, manager, managerAttrs, options) widget = make_widget(self, type, parent, label, None, manager, managerAttrs, options, config)
widget.type = type widget.type = type
return widget return widget