Merge remote-tracking branch 'origin/master' into owg_test
# Conflicts: # easy.yaml
This commit is contained in:
		
						commit
						1a4be3d2d8
					
				| 
						 | 
				
			
			@ -15,8 +15,11 @@ Configuration can be found in host.yaml
 | 
			
		|||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
import sys
 | 
			
		||||
import threading
 | 
			
		||||
import concurrent.futures
 | 
			
		||||
 | 
			
		||||
def feedback(text:str):
 | 
			
		||||
 | 
			
		||||
def feedback(text: str):
 | 
			
		||||
    print(text)
 | 
			
		||||
    input("Press Enter to ignore and probably crash.")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -133,38 +136,58 @@ if __name__ == "__main__":
 | 
			
		|||
                                  2: "7z",
 | 
			
		||||
                                  3: "bz2"}[zip_format]
 | 
			
		||||
 | 
			
		||||
            ziplock = threading.Lock()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            def pack_file(file: str):
 | 
			
		||||
                zf.write(os.path.join(output_path, file), file)
 | 
			
		||||
                print(f"Packed {file} into zipfile {zipname}")
 | 
			
		||||
                with ziplock:
 | 
			
		||||
                    zf.write(os.path.join(output_path, file), file)
 | 
			
		||||
                    print(f"Packed {file} into zipfile {zipname}")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            def remove_zipped_file(file: str):
 | 
			
		||||
                os.remove(os.path.join(output_path, file))
 | 
			
		||||
                print(f"Removed {file} which is now present in the zipfile")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            zipname = os.path.join(output_path, f"ER_{seedname}.{typical_zip_ending}")
 | 
			
		||||
 | 
			
		||||
            print(f"Creating zipfile {zipname}")
 | 
			
		||||
            ipv4 = (host if host else get_public_ipv4()) + ":" + str(port)
 | 
			
		||||
            with zipfile.ZipFile(zipname, "w", compression=compression, compresslevel=9) as zf:
 | 
			
		||||
                for file in os.listdir(output_path):
 | 
			
		||||
                    if file.endswith(".sfc") and seedname in file:
 | 
			
		||||
                        if zip_diffs:
 | 
			
		||||
                            diff = os.path.split(create_patch_file(os.path.join(output_path, file), ipv4))[1]
 | 
			
		||||
                            pack_file(diff)
 | 
			
		||||
                            if zip_diffs == 2:
 | 
			
		||||
                                remove_zipped_file(diff)
 | 
			
		||||
                        if zip_roms:
 | 
			
		||||
                            pack_file(file)
 | 
			
		||||
                            if zip_roms == 2 and player_name.lower() not in file.lower():
 | 
			
		||||
                                remove_zipped_file(file)
 | 
			
		||||
                if zip_multidata and os.path.exists(os.path.join(output_path, multidataname)):
 | 
			
		||||
                    pack_file(multidataname)
 | 
			
		||||
                    if zip_multidata == 2:
 | 
			
		||||
                        remove_zipped_file(multidataname)
 | 
			
		||||
                if zip_spoiler and create_spoiler:
 | 
			
		||||
                    pack_file(spoilername)
 | 
			
		||||
                    if zip_spoiler == 2:
 | 
			
		||||
                        remove_zipped_file(spoilername)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            def _handle_file(file: str):
 | 
			
		||||
                if zip_diffs:
 | 
			
		||||
                    # the main reason for using threading, the patch is created using bsdiff4, which frees the GIL
 | 
			
		||||
                    diff = os.path.split(create_patch_file(os.path.join(output_path, file), ipv4))[1]
 | 
			
		||||
                    pack_file(diff)
 | 
			
		||||
                    if zip_diffs == 2:
 | 
			
		||||
                        remove_zipped_file(diff)
 | 
			
		||||
                if zip_roms:
 | 
			
		||||
                    pack_file(file)
 | 
			
		||||
                    if zip_roms == 2 and player_name.lower() not in file.lower():
 | 
			
		||||
                        remove_zipped_file(file)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            with concurrent.futures.ThreadPoolExecutor() as pool:
 | 
			
		||||
                futures = []
 | 
			
		||||
                with zipfile.ZipFile(zipname, "w", compression=compression, compresslevel=9) as zf:
 | 
			
		||||
                    for file in os.listdir(output_path):
 | 
			
		||||
                        if file.endswith(".sfc") and seedname in file:
 | 
			
		||||
                            futures.append(pool.submit(_handle_file, file))
 | 
			
		||||
 | 
			
		||||
                    if zip_multidata and os.path.exists(os.path.join(output_path, multidataname)):
 | 
			
		||||
                        pack_file(multidataname)
 | 
			
		||||
                        if zip_multidata == 2:
 | 
			
		||||
                            remove_zipped_file(multidataname)
 | 
			
		||||
 | 
			
		||||
                    if zip_spoiler and create_spoiler:
 | 
			
		||||
                        pack_file(spoilername)
 | 
			
		||||
                        if zip_spoiler == 2:
 | 
			
		||||
                            remove_zipped_file(spoilername)
 | 
			
		||||
 | 
			
		||||
                    for future in futures:
 | 
			
		||||
                        future.result()  # make sure we close the zip AFTER any packing is done
 | 
			
		||||
 | 
			
		||||
        if os.path.exists(os.path.join(output_path, multidataname)):
 | 
			
		||||
            if os.path.exists("BerserkerMultiServer.exe"):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								Rom.py
								
								
								
								
							
							
						
						
									
										3
									
								
								Rom.py
								
								
								
								
							| 
						 | 
				
			
			@ -1002,6 +1002,9 @@ def patch_rom(world, rom, player, team, enemized):
 | 
			
		|||
                    'Big Key (Desert Palace)': (0x367, 0x10), 'Compass (Desert Palace)': (0x365, 0x10), 'Map (Desert Palace)': (0x369, 0x10),
 | 
			
		||||
                    'Big Key (Tower of Hera)': (0x366, 0x20), 'Compass (Tower of Hera)': (0x364, 0x20), 'Map (Tower of Hera)': (0x368, 0x20),
 | 
			
		||||
                    'Big Key (Escape)': (0x367, 0xC0), 'Compass (Escape)': (0x365, 0xC0), 'Map (Escape)': (0x369, 0xC0),
 | 
			
		||||
                    # doors-specific items
 | 
			
		||||
                    'Big Key (Agahnims Tower)': (0x367, 0x08), 'Compass (Agahnims Tower)': (0x365, 0x08), 'Map (Agahnims Tower)': (0x369, 0x08),
 | 
			
		||||
                    # end of doors-specific items
 | 
			
		||||
                    'Big Key (Palace of Darkness)': (0x367, 0x02), 'Compass (Palace of Darkness)': (0x365, 0x02), 'Map (Palace of Darkness)': (0x369, 0x02),
 | 
			
		||||
                    'Big Key (Thieves Town)': (0x366, 0x10), 'Compass (Thieves Town)': (0x364, 0x10), 'Map (Thieves Town)': (0x368, 0x10),
 | 
			
		||||
                    'Big Key (Skull Woods)': (0x366, 0x80), 'Compass (Skull Woods)': (0x364, 0x80), 'Map (Skull Woods)': (0x368, 0x80),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										250
									
								
								easy.yaml
								
								
								
								
							
							
						
						
									
										250
									
								
								easy.yaml
								
								
								
								
							| 
						 | 
				
			
			@ -1,21 +1,45 @@
 | 
			
		|||
#More general info here: https://docs.google.com/document/d/1r7qs1-MK7YbFf2d-mEUeTy2wHykIf1ALG9pLtVvUbSw/edit
 | 
			
		||||
description: Easy/Open/Normal #please describe your options. Especially useful when you have multiple yamls for different occasions
 | 
			
		||||
name: PleaseEnterNameHere #your name ingame, space and "_" gets replaced with a dash "-"
 | 
			
		||||
glitches_required:
 | 
			
		||||
  none: 1 # the "regular" glitch-free mode
 | 
			
		||||
  overworld_glitches: 0 # puts overworld glitches like fake flipper, water-walk, link-state and boots clipping in logic
 | 
			
		||||
  no_logic: 0 # no logic at all, careful with this in multiworld as it will create item loops that put other players into glitches required
 | 
			
		||||
item_placement: basic #this is based on Entrance Randomizer, which does not (yet?) support advanced
 | 
			
		||||
map_shuffle: #to shuffle dungeon maps into the outside world and other dungeons, as well as other player's worlds in multiworld
 | 
			
		||||
# What is this file?
 | 
			
		||||
# This file contains options which allow you to configure your multiworld experience while allowing others
 | 
			
		||||
# to play how they want as well.
 | 
			
		||||
#
 | 
			
		||||
# How do I use it?
 | 
			
		||||
# The options in this file are weighted. This means the higher number you assign to a value, the more
 | 
			
		||||
# chances you have for that option to be chosen. For example, an option like this:
 | 
			
		||||
#
 | 
			
		||||
# map_shuffle:
 | 
			
		||||
#   on: 5
 | 
			
		||||
#   off: 15
 | 
			
		||||
#
 | 
			
		||||
# Means you have 5 chances for map shuffle to not occur, and 15 chances for map shuffle to be turned on
 | 
			
		||||
 | 
			
		||||
# I've never seen a file like this before. What characters am I allowed to use?
 | 
			
		||||
# This is a .yaml file. You are allowed to use most characters.
 | 
			
		||||
# To test if your yaml is valid or not, you can use this website:
 | 
			
		||||
# http://www.yamllint.com/
 | 
			
		||||
 | 
			
		||||
description: Your Description Here # Used to describe your yaml. Useful if you have multiple files
 | 
			
		||||
name: YourName # Your name in-game. Spaces and underscores will be replaced with dashes
 | 
			
		||||
glitches_required: # Determine the logic required to complete the seed
 | 
			
		||||
  none: 1 # No glitches required
 | 
			
		||||
  overworld_glitches: 0 # Assumes the player knows how to perform overworld glitches like fake flipper, water walk, etc
 | 
			
		||||
  no_logic: 0 # Items are places completely at random and with no regard for logic. Your fire rod could be on Trinexx
 | 
			
		||||
item_placement: basic # This is based on Entrance Randomizer, which does not (yet?) support advanced
 | 
			
		||||
meta_ignore: # Nullify options specified in the meta.yaml file. Adding an option here guarantees it will not occur in your seed, even if the .yaml file specifies it
 | 
			
		||||
  world_state:
 | 
			
		||||
    - inverted # Never play inverted seeds
 | 
			
		||||
    - retro # Never play retro seeds
 | 
			
		||||
  weapons:
 | 
			
		||||
    - swordless # Never play a swordless seed
 | 
			
		||||
map_shuffle: # Shuffle dungeon maps into the world and other dungeons, including other players' worlds
 | 
			
		||||
  on: 0
 | 
			
		||||
  off: 1
 | 
			
		||||
compass_shuffle: #same for compass
 | 
			
		||||
compass_shuffle: # Shuffle compasses into the world and other dungeons, including other players' worlds
 | 
			
		||||
  on: 0
 | 
			
		||||
  off: 1
 | 
			
		||||
smallkey_shuffle: #same for small keys
 | 
			
		||||
smallkey_shuffle: # Shuffle small keys into the world and other dungeons, including other players' worlds
 | 
			
		||||
  on: 0
 | 
			
		||||
  off: 1
 | 
			
		||||
bigkey_shuffle: #same for big keys
 | 
			
		||||
bigkey_shuffle: # Shuffle big keys into the world and other dungeons, including other players' worlds
 | 
			
		||||
  on: 0
 | 
			
		||||
  off: 1
 | 
			
		||||
dungeon_items: # alternative to the 4 shuffles above this, does nothing until the respective 4 shuffles are deleted
 | 
			
		||||
| 
						 | 
				
			
			@ -23,97 +47,97 @@ dungeon_items: # alternative to the 4 shuffles above this, does nothing until th
 | 
			
		|||
  none: 1 # shuffle none of the 4
 | 
			
		||||
  mcsb: 0 # shuffle all of the 4, any combination of m, c, s and b will shuffle the respective item, or not if it's missing, so you can add more options here
 | 
			
		||||
accessibility:
 | 
			
		||||
  items: 0 # item accessibility means you can get all inventory items. So a key could lock itself, but you can fill your inventory
 | 
			
		||||
  locations: 1 # location accessibility means you can access every location in your seed and get all 216 checks
 | 
			
		||||
  none: 0 # no accessibility means your seed is "beatable only", meaning any items you do not need to beat the game can be unreachable. This can mean you have to defeat ganon with a lamp and master sword.
 | 
			
		||||
progressive: #not available in bonta's multiworld at this time. If you want this option, make sure the host uses the correct Multiworld
 | 
			
		||||
  on: 1 # progressive items, you will always get progressive items like swords in their order: figher sword -> master sword -> tempered sword -> golden sword
 | 
			
		||||
  off: 0 # turns progressive items off, so you can find, for example, silver arrows before a bow
 | 
			
		||||
  random: 0 # rolls a 50/50 chance for each potentially progressive item. So, for example, you can have progressive swords but non-progressive mittens
 | 
			
		||||
entrance_shuffle:
 | 
			
		||||
  none: 1 # no entrance shuffle
 | 
			
		||||
  items: 0 # Guarantees you will be able to acquire all items, but you may not be able to access all locations
 | 
			
		||||
  locations: 1 # Guarantees you will be able to access all locations, and therefore all items
 | 
			
		||||
  none: 0 # Guarantees only that the game is beatable. You may not be able to access all locations or acquire all items
 | 
			
		||||
progressive: # Enable or disable progressive items (swords, shields, bow)
 | 
			
		||||
  on: 1 # All items progressive
 | 
			
		||||
  off: 0 # No items progressive
 | 
			
		||||
  random: 0 # Randomly decides for all items. Swords could be progressive, shields might not be
 | 
			
		||||
entrance_shuffle: # Documentation: https://alttpr.com/en/options#entrance_shuffle
 | 
			
		||||
  none: 1 # Vanilla game map. All entrances and exits lead to their original locations. You probably want this option
 | 
			
		||||
  dungeonssimple: 0 # shuffle just dungeons amongst each other, swapping dungeons entirely, so Hyrule Castle is always 1 dungeon
 | 
			
		||||
  dungeonsfull: 0 # shuffle any dungeon entrance with any dungeon interior, so Hyrule Castle can be 4 different dungeons
 | 
			
		||||
  simple: 0 #dungeons are shuffled with each other and the other entrances are shuffled with each other
 | 
			
		||||
  restricted: 0 #dungeons still shuffle along each other but connects other entrances more feely with each other while keeping entrances in one world
 | 
			
		||||
  full: 0 # mixes caves and dungeons freely, except for confining all entrances to one world
 | 
			
		||||
  crossed: 0 #introduces cross world connectors
 | 
			
		||||
  insanity: 0 #any entrance can lead to any other entrance
 | 
			
		||||
  simple: 0 # Entrances are grouped together before being randomized. Simple uses the most strict grouping rules
 | 
			
		||||
  restricted: 0 # Less strict than simple
 | 
			
		||||
  full: 0 # Less strict than restricted
 | 
			
		||||
  crossed: 0 # Less strict than full
 | 
			
		||||
  insanity: 0 # Very few grouping rules. Good luck.
 | 
			
		||||
goals:
 | 
			
		||||
  ganon: 5 #beat GT and then Ganon
 | 
			
		||||
  fast_ganon: 4 # Just kill Ganon
 | 
			
		||||
  dungeons: 1 # All Dungeons, including GT, and Agahnims Tower
 | 
			
		||||
  pedestal: 0 # Pull the win out of the Pedestal
 | 
			
		||||
  triforce-hunt: 0 # Collect 20 of 30 Triforce pieces then hand them in in front of Hyrule Castle
 | 
			
		||||
  ganon: 1 # Climb GT, defeat Agahnim 2, then kill Ganon
 | 
			
		||||
  fast_ganon: 0 # Only killing Ganon is required. The hole is always open. Items may still be placed in GT, however
 | 
			
		||||
  dungeons: 0 # Defeat the boss of all dungeons, including Agahnim's tower and GT (Aga 2)
 | 
			
		||||
  pedestal: 0 # Pull the Triforce from the Master Sword pedestal
 | 
			
		||||
  triforce-hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the world, then turn them in to Murahadala in front of Hyrule Castle
 | 
			
		||||
tower_open: # Crystals required to open GT
 | 
			
		||||
  '0': 0
 | 
			
		||||
  '1': 0
 | 
			
		||||
  '2': 0
 | 
			
		||||
  '3': 0
 | 
			
		||||
  '4': 0
 | 
			
		||||
  '5': 0
 | 
			
		||||
  '6': 0
 | 
			
		||||
  '7': 0
 | 
			
		||||
  random: 1
 | 
			
		||||
  '0': 8
 | 
			
		||||
  '1': 7
 | 
			
		||||
  '2': 6
 | 
			
		||||
  '3': 5
 | 
			
		||||
  '4': 4
 | 
			
		||||
  '5': 3
 | 
			
		||||
  '6': 2
 | 
			
		||||
  '7': 1
 | 
			
		||||
  random: 0
 | 
			
		||||
ganon_open: # Crystals required to hurt Ganon
 | 
			
		||||
  '0': 0
 | 
			
		||||
  '1': 0
 | 
			
		||||
  '2': 0
 | 
			
		||||
  '3': 0
 | 
			
		||||
  '4': 0
 | 
			
		||||
  '5': 0
 | 
			
		||||
  '6': 0
 | 
			
		||||
  '7': 0
 | 
			
		||||
  random: 1
 | 
			
		||||
  '0': 8
 | 
			
		||||
  '1': 7
 | 
			
		||||
  '2': 6
 | 
			
		||||
  '3': 5
 | 
			
		||||
  '4': 4
 | 
			
		||||
  '5': 3
 | 
			
		||||
  '6': 2
 | 
			
		||||
  '7': 1
 | 
			
		||||
  random: 0
 | 
			
		||||
world_state:
 | 
			
		||||
  standard: 1 # Do standard escape to bring Zelda to Sanctuary
 | 
			
		||||
  open: 9 # Start with the ability to skip the standard opening and go where you want
 | 
			
		||||
  inverted: 0 # You start in the Dark World, the Light World has changes to it's Map and requires a Moon Pearl to not be Bunny
 | 
			
		||||
  retro: 0 # Keys are universal, you have to buy a quiver, there are take any caves and some other changes. Makes it more like Z1
 | 
			
		||||
  standard: 1 # Begin the game by rescuing Zelda from her cell and escorting her to the Sanctuary.
 | 
			
		||||
  open: 1 # Begin the game from your choice of Link's House or the Sanctuary
 | 
			
		||||
  inverted: 0 # Begin in the Dark World. The Moon Pearl is required to avoid bunny-state in Light World, and the Light World game map is altered
 | 
			
		||||
  retro: 0 # Small keys are universal, you must buy a quiver, take-any caves and an old-man cave are added to the world. You may need to find your sword from the old man's cave
 | 
			
		||||
hints:
 | 
			
		||||
  'on': 1 # Hint tiles can give useful item location hints on occasion
 | 
			
		||||
  'off': 0 # You get gameplay hints, but not location/item hints
 | 
			
		||||
weapons: # this means swords
 | 
			
		||||
  randomized: 5 # Your swords can be anywhere
 | 
			
		||||
  assured: 2 # You start with a sword, the rest are anywhere
 | 
			
		||||
  vanilla: 3 # Your swords are in vanilla locations in your own game (Uncle, Pyramid Fairy, Smiths, Pedestal)
 | 
			
		||||
  swordless: 0 # You don't have a sword. A hammer can be used like a Master Sword in certain situations
 | 
			
		||||
  'on': 1 # Hint tiles sometimes give item location hints
 | 
			
		||||
  'off': 0 # Hint tiles provide gameplay tips
 | 
			
		||||
weapons: # Specifically, swords
 | 
			
		||||
  randomized: 0 # Swords are placed randomly throughout the world
 | 
			
		||||
  assured: 1 # Begin with a sword, the rest are placed randomly throughout the world
 | 
			
		||||
  vanilla: 0 # Swords are placed in vanilla locations in your own game (Uncle, Pyramid Fairy, Smiths, Pedestal)
 | 
			
		||||
  swordless: 0 # Your swords are replaced by rupees. Gameplay changes have been made to accommodate this change.
 | 
			
		||||
item_pool:
 | 
			
		||||
  normal: 1
 | 
			
		||||
  hard: 0
 | 
			
		||||
  expert: 0
 | 
			
		||||
  crowd_control: 0
 | 
			
		||||
  normal: 1 # Item availability remains unchanged from the vanilla game
 | 
			
		||||
  hard: 0 # Reduced upgrade availability (max: 14 hearts, green mail, tempered sword, fire shield, no silvers unless swordless)
 | 
			
		||||
  expert: 0 # Minimum upgrade availability (max: 8 hearts, green mail, master sword, fighter shield, no silvers unless swordless)
 | 
			
		||||
  crowd_control: 0 # Unless you know what you're doing, leave this at 0
 | 
			
		||||
item_functionality:
 | 
			
		||||
  normal: 1
 | 
			
		||||
  hard: 0
 | 
			
		||||
  expert: 0
 | 
			
		||||
  normal: 1 # Vanilla game item functionality
 | 
			
		||||
  hard: 0 # Reduced helpfulness of items (potions less effective, can't catch faeries, cape uses double magic, byrna does not grant invulnerability, boomerangs do not stun, silvers disabled outside ganon)
 | 
			
		||||
  expert: 0 # Vastly helpfulness of items (potions barely effective, can't catch faeries, cape uses double magic, byrna does not grant invulnerability, boomerangs and hookshot do not stun, silvers disabled outside ganon)
 | 
			
		||||
boss_shuffle:
 | 
			
		||||
  none: 1
 | 
			
		||||
  simple: 0 # existing bosses gets shuffled around
 | 
			
		||||
  full: 0 # all bosses exist once, except 3 can appear twice
 | 
			
		||||
  random: 0 # any boss can appear any number of times
 | 
			
		||||
  none: 1 # No boss shuffle
 | 
			
		||||
  simple: 0 # Existing bosses except Ganon and Agahnim are shuffled throughout dungeons
 | 
			
		||||
  full: 0 # Replace GT bosses with random bosses, then follow simple logic
 | 
			
		||||
  random: 0 # Choose from one of the above options
 | 
			
		||||
enemy_shuffle:
 | 
			
		||||
  none: 1
 | 
			
		||||
  shuffled: 0 # enemies get shuffled around
 | 
			
		||||
  random: 0 # any enemy can appear any number of times
 | 
			
		||||
  none: 1 # Vanilla enemy placement
 | 
			
		||||
  shuffled: 0 # Enemies are randomized
 | 
			
		||||
  random: 0 # Choose one of the above
 | 
			
		||||
enemy_damage:
 | 
			
		||||
  default: 1
 | 
			
		||||
  shuffled: 0 # damage tables get shuffled, however armor effects are not
 | 
			
		||||
  random: 0 # all damages are completely shuffled, including armor effects, making it possible red mail is worse than green
 | 
			
		||||
  default: 1 # Vanilla enemy damage
 | 
			
		||||
  shuffled: 0 # Enemies do a randomized amount of damage
 | 
			
		||||
  random: 0 # Choose one of the above
 | 
			
		||||
enemy_health:
 | 
			
		||||
  default: 1
 | 
			
		||||
  easy: 0
 | 
			
		||||
  hard: 0
 | 
			
		||||
  expert: 0
 | 
			
		||||
pot_shuffle: # Shuffle pots, their contents and whatever is hiding under them. Broken with any door shuffle that is not vanilla, do not combine
 | 
			
		||||
  on: 0
 | 
			
		||||
  off: 1
 | 
			
		||||
beemizer: # replace items with bees, that will attack you
 | 
			
		||||
  0: 1
 | 
			
		||||
  1: 0 # max 15 hearts
 | 
			
		||||
  2: 0 # max 10 hearts
 | 
			
		||||
  3: 0
 | 
			
		||||
  4: 0
 | 
			
		||||
  default: 1 # Vanilla enemy HP
 | 
			
		||||
  easy: 0 # Enemies have reduced health
 | 
			
		||||
  hard: 0 # Enemies have increased health
 | 
			
		||||
  expert: 0 # Enemies have greatly increased health
 | 
			
		||||
pot_shuffle:
 | 
			
		||||
  'on': 0 # Keys, items, and buttons hidden under pots in dungeons are shuffled with other pots in their supertile
 | 
			
		||||
  'off': 1 # Default pot item locations
 | 
			
		||||
beemizer: # Remove items from the global item pool and replace them with single bees and bee traps
 | 
			
		||||
  0: 1 # No bee traps are placed
 | 
			
		||||
  1: 0 # 25% of the non-essential item pool is replaced with bee traps
 | 
			
		||||
  2: 0 # 60% of the non-essential item pool is replaced with bee traps, of which 20% could be single bees
 | 
			
		||||
  3: 0 # 100% of the non-essential item pool is replaced with bee traps, of which 50% could be single bees
 | 
			
		||||
  4: 0 # 100% of the non-essential item pool is replaced with bee traps
 | 
			
		||||
timer:
 | 
			
		||||
  none: 1
 | 
			
		||||
  timed: 0
 | 
			
		||||
| 
						 | 
				
			
			@ -128,39 +152,39 @@ remote_items: # Warning: currently broken. Stores all your items on the server,
 | 
			
		|||
  on: 0 # intended for racing, as the item information is missing from the ROM
 | 
			
		||||
  off: 1
 | 
			
		||||
rom:
 | 
			
		||||
  sprite:
 | 
			
		||||
    random: 1
 | 
			
		||||
    randomonhit: 1
 | 
			
		||||
    link: 1 # to get other sprite names, open up gui/Creator, select a sprite and write down the sprite name as it is there
 | 
			
		||||
  disablemusic: off # turn on for V30 MSU packs
 | 
			
		||||
  extendedmsu: off #turn on to have V31 extended MSU support
 | 
			
		||||
  quickswap:
 | 
			
		||||
    on: 1 # press L/R to swap items without opening the menu
 | 
			
		||||
    off: 0
 | 
			
		||||
  menuspeed:
 | 
			
		||||
  sprite: # Enter the name of your preferred sprite and weight it appropriately
 | 
			
		||||
    random: 0
 | 
			
		||||
    randomonhit: 0
 | 
			
		||||
    link: 1
 | 
			
		||||
  disablemusic: off # If "on", all in-game music will be disabled
 | 
			
		||||
  extendedmsu: on # If "on", V31 extended MSU support will be available
 | 
			
		||||
  quickswap: # Enable switching items by pressing the L+R shoulder buttons
 | 
			
		||||
    on: 0
 | 
			
		||||
    off: 1
 | 
			
		||||
  menuspeed: # Control how fast the item menu opens and closes
 | 
			
		||||
    normal: 1
 | 
			
		||||
    instant: 0
 | 
			
		||||
    double: 0
 | 
			
		||||
    triple: 0
 | 
			
		||||
    quadruple: 0
 | 
			
		||||
    half: 0
 | 
			
		||||
  heartcolor:
 | 
			
		||||
  heartcolor: # Control the color of your health hearts
 | 
			
		||||
    red: 1
 | 
			
		||||
    blue: 1
 | 
			
		||||
    green: 1
 | 
			
		||||
    yellow: 1
 | 
			
		||||
    blue: 0
 | 
			
		||||
    green: 0
 | 
			
		||||
    yellow: 0
 | 
			
		||||
    random: 0
 | 
			
		||||
  heartbeep:
 | 
			
		||||
  heartbeep: # Control the frequency of the low-health beeping
 | 
			
		||||
    double: 0
 | 
			
		||||
    normal: 1
 | 
			
		||||
    half: 0
 | 
			
		||||
    quarter: 0
 | 
			
		||||
    off: 0
 | 
			
		||||
  ow_palettes:
 | 
			
		||||
    default: 1
 | 
			
		||||
    random: 1 # shuffle the palette of overworld colors
 | 
			
		||||
    blackout: 0 # makes everything blank, making it almost a blind playthrough
 | 
			
		||||
  uw_palettes:
 | 
			
		||||
    default: 1
 | 
			
		||||
    random: 1 # shuffle the palette of dungeon/cave colors
 | 
			
		||||
    blackout: 0 # makes everything blank, making it almost a blind playthrough
 | 
			
		||||
  ow_palettes: # Change the colors of the overworld
 | 
			
		||||
    default: 1 # No changes
 | 
			
		||||
    random: 0 # Shuffle the colors
 | 
			
		||||
    blackout: 0 # Never use this
 | 
			
		||||
  uw_palettes: # Change the colors of caves and dungeons
 | 
			
		||||
    default: 1 # No changes
 | 
			
		||||
    random: 0 # Shuffle the colors
 | 
			
		||||
    blackout: 0 # Never use this
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ multi_mystery_options:
 | 
			
		|||
  zip_spoiler: 0
 | 
			
		||||
  #include the multidata file in the zip, 2 -> delete the non-zipped one, which also means the server won't autostart
 | 
			
		||||
  zip_multidata: 0
 | 
			
		||||
  #zip algorithm to use
 | 
			
		||||
  #zip algorithm to use. zip is recommended for patch files, 7z is recommended for roms. All of them get the job done.
 | 
			
		||||
  zip_format: 1 # 1 -> zip, 2 -> 7z, 3->bz2
 | 
			
		||||
  #create roms flagged as race roms
 | 
			
		||||
  race: 0
 | 
			
		||||
							
								
								
									
										249
									
								
								inno_setup.iss
								
								
								
								
							
							
						
						
									
										249
									
								
								inno_setup.iss
								
								
								
								
							| 
						 | 
				
			
			@ -1,116 +1,133 @@
 | 
			
		|||
#define sourcepath "build\exe.win-amd64-3.8\"
 | 
			
		||||
#define MyAppName "BerserkerMultiWorld"
 | 
			
		||||
#define MyAppExeName "BerserkerMultiClient.exe"
 | 
			
		||||
#define MyAppIcon "icon.ico"
 | 
			
		||||
 | 
			
		||||
[Setup]
 | 
			
		||||
; NOTE: The value of AppId uniquely identifies this application.
 | 
			
		||||
; Do not use the same AppId value in installers for other applications.
 | 
			
		||||
AppId={{6D826EE0-49BE-4B36-BACE-09C6971CD85C}}
 | 
			
		||||
AppName={#MyAppName}
 | 
			
		||||
AppVerName={#MyAppName}
 | 
			
		||||
DefaultDirName={commonappdata}\{#MyAppName}
 | 
			
		||||
DisableProgramGroupPage=yes
 | 
			
		||||
OutputDir=setups
 | 
			
		||||
OutputBaseFilename=Setup {#MyAppName}
 | 
			
		||||
Compression=lzma2
 | 
			
		||||
SolidCompression=yes
 | 
			
		||||
LZMANumBlockThreads=8
 | 
			
		||||
ArchitecturesInstallIn64BitMode=x64
 | 
			
		||||
ChangesAssociations=yes
 | 
			
		||||
ArchitecturesAllowed=x64
 | 
			
		||||
AllowNoIcons=yes
 | 
			
		||||
SetupIconFile={#MyAppIcon}
 | 
			
		||||
UninstallDisplayIcon={app}\{#MyAppExeName}
 | 
			
		||||
LicenseFile= LICENSE
 | 
			
		||||
WizardStyle= modern
 | 
			
		||||
SetupLogging=yes
 | 
			
		||||
 | 
			
		||||
[Languages]
 | 
			
		||||
Name: "english"; MessagesFile: "compiler:Default.isl"
 | 
			
		||||
 | 
			
		||||
[Tasks]
 | 
			
		||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Dirs]
 | 
			
		||||
NAME: "{app}"; Flags: setntfscompression; Permissions: everyone-modify users-modify authusers-modify;
 | 
			
		||||
 | 
			
		||||
[Files]
 | 
			
		||||
Source: "{code:GetROMPath}"; DestDir: "{app}"; DestName: "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"; Flags: external
 | 
			
		||||
Source: "{#sourcepath}*"; Excludes: "*.key, *.log, *.hpkey"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
 | 
			
		||||
Source: "vc_redist.x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall
 | 
			
		||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
 | 
			
		||||
 | 
			
		||||
[Icons]
 | 
			
		||||
Name: "{group}\{#MyAppName} Folder"; Filename: "{app}";
 | 
			
		||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}";
 | 
			
		||||
Name: "{commondesktop}\{#MyAppName} Folder"; Filename: "{app}"; Tasks: desktopicon
 | 
			
		||||
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
 | 
			
		||||
 | 
			
		||||
[Run]
 | 
			
		||||
Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/passive /norestart"; Check: IsVCRedist64BitNeeded; StatusMsg: "Installing VC++ redistributable..."
 | 
			
		||||
; Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
 | 
			
		||||
 | 
			
		||||
[UninstallDelete]
 | 
			
		||||
Type: dirifempty; Name: "{app}"
 | 
			
		||||
 | 
			
		||||
[Registry]
 | 
			
		||||
 | 
			
		||||
Root: HKCR; Subkey: ".bmbp";                                 ValueData: "{#MyAppName}patch";        Flags: uninsdeletevalue; ValueType: string;  ValueName: ""
 | 
			
		||||
Root: HKCR; Subkey: "{#MyAppName}patch";                     ValueData: "{#MyAppName} Patch";       Flags: uninsdeletekey;   ValueType: string;  ValueName: ""
 | 
			
		||||
Root: HKCR; Subkey: "{#MyAppName}patch\DefaultIcon";         ValueData: "{app}\{#MyAppExeName},0";                           ValueType: string;  ValueName: ""
 | 
			
		||||
Root: HKCR; Subkey: "{#MyAppName}patch\shell\open\command";  ValueData: """{app}\{#MyAppExeName}"" ""%1""";                  ValueType: string;  ValueName: ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Code]
 | 
			
		||||
// See: https://stackoverflow.com/a/51614652/2287576
 | 
			
		||||
function IsVCRedist64BitNeeded(): boolean;
 | 
			
		||||
var
 | 
			
		||||
  strVersion: string;
 | 
			
		||||
begin
 | 
			
		||||
  if (RegQueryStringValue(HKEY_LOCAL_MACHINE,
 | 
			
		||||
    'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Version', strVersion)) then
 | 
			
		||||
  begin
 | 
			
		||||
    // Is the installed version at least 14.24 ? 
 | 
			
		||||
    Log('VC Redist x64 Version : found ' + strVersion);
 | 
			
		||||
    Result := (CompareStr(strVersion, 'v14.24.28127.4') < 0);
 | 
			
		||||
  end
 | 
			
		||||
  else
 | 
			
		||||
  begin
 | 
			
		||||
    // Not even an old version installed
 | 
			
		||||
    Log('VC Redist x64 is not already installed');
 | 
			
		||||
    Result := True;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
var ROMFilePage: TInputFileWizardPage;
 | 
			
		||||
var R : longint;
 | 
			
		||||
 | 
			
		||||
procedure InitializeWizard();
 | 
			
		||||
begin
 | 
			
		||||
  ROMFilePage :=
 | 
			
		||||
    CreateInputFilePage(
 | 
			
		||||
      wpLicense,
 | 
			
		||||
      'Select ROM File',
 | 
			
		||||
      'Where is your Zelda no Densetsu - Kamigami no Triforce (Japan).sfc located?',
 | 
			
		||||
      'Select the file, then click Next.');
 | 
			
		||||
 | 
			
		||||
  ROMFilePage.Add(
 | 
			
		||||
    'Location of ROM file:',         
 | 
			
		||||
    'SNES ROM files|*.sfc|All files|*.*', 
 | 
			
		||||
    '.sfc');                             
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function GetROMPath(Param: string): string;
 | 
			
		||||
begin
 | 
			
		||||
  if Assigned(RomFilePage) then
    begin
 | 
			
		||||
      R := CompareStr(GetMD5OfFile(ROMFilePage.Values[0]), '03a63945398191337e896e5771f77173')
 | 
			
		||||
      if R <> 0 then
 | 
			
		||||
        MsgBox('ROM validation failed. Very likely wrong file.', mbInformation, MB_OK);
  
 | 
			
		||||
      Result := ROMFilePage.Values[0]
 | 
			
		||||
    end
 | 
			
		||||
  else
 | 
			
		||||
    Result := '';
 | 
			
		||||
 end;
 | 
			
		||||
#define sourcepath "build\exe.win-amd64-3.8\"
 | 
			
		||||
#define MyAppName "BerserkerMultiWorld"
 | 
			
		||||
#define MyAppExeName "BerserkerMultiClient.exe"
 | 
			
		||||
#define MyAppIcon "icon.ico"
 | 
			
		||||
 | 
			
		||||
[Setup]
 | 
			
		||||
; NOTE: The value of AppId uniquely identifies this application.
 | 
			
		||||
; Do not use the same AppId value in installers for other applications.
 | 
			
		||||
AppId={{6D826EE0-49BE-4B36-BACE-09C6971CD85C}}
 | 
			
		||||
AppName={#MyAppName}
 | 
			
		||||
AppVerName={#MyAppName}
 | 
			
		||||
DefaultDirName={commonappdata}\{#MyAppName}
 | 
			
		||||
DisableProgramGroupPage=yes
 | 
			
		||||
OutputDir=setups
 | 
			
		||||
OutputBaseFilename=Setup {#MyAppName}
 | 
			
		||||
Compression=lzma2
 | 
			
		||||
SolidCompression=yes
 | 
			
		||||
LZMANumBlockThreads=8
 | 
			
		||||
ArchitecturesInstallIn64BitMode=x64
 | 
			
		||||
ChangesAssociations=yes
 | 
			
		||||
ArchitecturesAllowed=x64
 | 
			
		||||
AllowNoIcons=yes
 | 
			
		||||
SetupIconFile={#MyAppIcon}
 | 
			
		||||
UninstallDisplayIcon={app}\{#MyAppExeName}
 | 
			
		||||
LicenseFile= LICENSE
 | 
			
		||||
WizardStyle= modern
 | 
			
		||||
SetupLogging=yes
 | 
			
		||||
 | 
			
		||||
[Languages]
 | 
			
		||||
Name: "english"; MessagesFile: "compiler:Default.isl"
 | 
			
		||||
 | 
			
		||||
[Tasks]
 | 
			
		||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Dirs]
 | 
			
		||||
NAME: "{app}"; Flags: setntfscompression; Permissions: everyone-modify users-modify authusers-modify;
 | 
			
		||||
 | 
			
		||||
[Files]
 | 
			
		||||
Source: "{code:GetROMPath}"; DestDir: "{app}"; DestName: "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"; Flags: external
 | 
			
		||||
Source: "{#sourcepath}*"; Excludes: "*.key, *.log, *.hpkey"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
 | 
			
		||||
Source: "vc_redist.x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall
 | 
			
		||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
 | 
			
		||||
 | 
			
		||||
[Icons]
 | 
			
		||||
Name: "{group}\{#MyAppName} Folder"; Filename: "{app}";
 | 
			
		||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}";
 | 
			
		||||
Name: "{commondesktop}\{#MyAppName} Folder"; Filename: "{app}"; Tasks: desktopicon
 | 
			
		||||
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
 | 
			
		||||
 | 
			
		||||
[Run]
 | 
			
		||||
Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/passive /norestart"; Check: IsVCRedist64BitNeeded; StatusMsg: "Installing VC++ redistributable..."
 | 
			
		||||
 | 
			
		||||
[UninstallDelete]
 | 
			
		||||
Type: dirifempty; Name: "{app}"
 | 
			
		||||
 | 
			
		||||
[Registry]
 | 
			
		||||
 | 
			
		||||
Root: HKCR; Subkey: ".bmbp";                                 ValueData: "{#MyAppName}patch";        Flags: uninsdeletevalue; ValueType: string;  ValueName: ""
 | 
			
		||||
Root: HKCR; Subkey: "{#MyAppName}patch";                     ValueData: "{#MyAppName} Patch";       Flags: uninsdeletekey;   ValueType: string;  ValueName: ""
 | 
			
		||||
Root: HKCR; Subkey: "{#MyAppName}patch\DefaultIcon";         ValueData: "{app}\{#MyAppExeName},0";                           ValueType: string;  ValueName: ""
 | 
			
		||||
Root: HKCR; Subkey: "{#MyAppName}patch\shell\open\command";  ValueData: """{app}\{#MyAppExeName}"" ""%1""";                  ValueType: string;  ValueName: ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Code]
 | 
			
		||||
// See: https://stackoverflow.com/a/51614652/2287576
 | 
			
		||||
function IsVCRedist64BitNeeded(): boolean;
 | 
			
		||||
var
 | 
			
		||||
  strVersion: string;
 | 
			
		||||
begin
 | 
			
		||||
  if (RegQueryStringValue(HKEY_LOCAL_MACHINE,
 | 
			
		||||
    'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Version', strVersion)) then
 | 
			
		||||
  begin
 | 
			
		||||
    // Is the installed version at least 14.24 ? 
 | 
			
		||||
    Log('VC Redist x64 Version : found ' + strVersion);
 | 
			
		||||
    Result := (CompareStr(strVersion, 'v14.24.28127.4') < 0);
 | 
			
		||||
  end
 | 
			
		||||
  else
 | 
			
		||||
  begin
 | 
			
		||||
    // Not even an old version installed
 | 
			
		||||
    Log('VC Redist x64 is not already installed');
 | 
			
		||||
    Result := True;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
var ROMFilePage: TInputFileWizardPage;
 | 
			
		||||
var R : longint;
 | 
			
		||||
var rom: string;
 | 
			
		||||
 | 
			
		||||
procedure InitializeWizard();
 | 
			
		||||
begin
 | 
			
		||||
  rom := FileSearch('Zelda no Densetsu - Kamigami no Triforce (Japan).sfc', WizardDirValue());
 | 
			
		||||
  if Length(rom) > 0 then
 | 
			
		||||
    begin
 | 
			
		||||
      log('existing ROM found');
 | 
			
		||||
      log(IntToStr(CompareStr(GetMD5OfFile(rom), '03a63945398191337e896e5771f77173')));
 | 
			
		||||
      if CompareStr(GetMD5OfFile(rom), '03a63945398191337e896e5771f77173') = 0 then
 | 
			
		||||
        begin
 | 
			
		||||
        log('existing ROM verified');
 | 
			
		||||
        exit;
 | 
			
		||||
        end;
 | 
			
		||||
      log('existing ROM failed verification');
 | 
			
		||||
    end;
 | 
			
		||||
  rom := ''
 | 
			
		||||
  ROMFilePage :=
 | 
			
		||||
    CreateInputFilePage(
 | 
			
		||||
      wpLicense,
 | 
			
		||||
      'Select ROM File',
 | 
			
		||||
      'Where is your Zelda no Densetsu - Kamigami no Triforce (Japan).sfc located?',
 | 
			
		||||
      'Select the file, then click Next.');
 | 
			
		||||
 | 
			
		||||
  ROMFilePage.Add(
 | 
			
		||||
    'Location of ROM file:',         
 | 
			
		||||
    'SNES ROM files|*.sfc|All files|*.*', 
 | 
			
		||||
    '.sfc');                             
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function GetROMPath(Param: string): string;
 | 
			
		||||
begin
 | 
			
		||||
  if Length(rom) > 0 then
 | 
			
		||||
    Result := rom
 | 
			
		||||
  else if Assigned(RomFilePage) then
 | 
			
		||||
    begin
 | 
			
		||||
      R := CompareStr(GetMD5OfFile(ROMFilePage.Values[0]), '03a63945398191337e896e5771f77173')
 | 
			
		||||
      if R <> 0 then
 | 
			
		||||
        MsgBox('ROM validation failed. Very likely wrong file.', mbInformation, MB_OK);
 | 
			
		||||
  
 | 
			
		||||
      Result := ROMFilePage.Values[0]
 | 
			
		||||
    end
 | 
			
		||||
  else
 | 
			
		||||
    Result := '';
 | 
			
		||||
 end;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								setup.py
								
								
								
								
							
							
						
						
									
										6
									
								
								setup.py
								
								
								
								
							| 
						 | 
				
			
			@ -100,5 +100,11 @@ extra_data = ["LICENSE", "data", "EnemizerCLI", "host.yaml", "QUsb2Snes", "meta.
 | 
			
		|||
for data in extra_data:
 | 
			
		||||
    installfile(Path(data))
 | 
			
		||||
 | 
			
		||||
os.makedirs(buildfolder / "Players", exist_ok=True)
 | 
			
		||||
shutil.copyfile("easy.yaml", buildfolder / "Players" / "easy.yaml")
 | 
			
		||||
 | 
			
		||||
qusb2sneslog = buildfolder / "QUsb2Snes" / "log.txt"
 | 
			
		||||
if os.path.exists(qusb2sneslog):
 | 
			
		||||
    os.remove(qusb2sneslog)
 | 
			
		||||
 | 
			
		||||
manifest_creation()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue