Merge branch 'shop-fill' into multishop-all
This commit is contained in:
commit
c66e97faf6
1
Fill.py
1
Fill.py
|
@ -229,6 +229,7 @@ def flood_items(world):
|
||||||
itempool.remove(item_to_place)
|
itempool.remove(item_to_place)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def balance_multiworld_progression(world):
|
def balance_multiworld_progression(world):
|
||||||
balanceable_players = {player for player in range(1, world.players + 1) if world.progression_balancing[player]}
|
balanceable_players = {player for player in range(1, world.players + 1) if world.progression_balancing[player]}
|
||||||
if not balanceable_players:
|
if not balanceable_players:
|
||||||
|
|
32
Main.py
32
Main.py
|
@ -177,6 +177,38 @@ def main(args, seed=None):
|
||||||
elif args.algorithm == 'balanced':
|
elif args.algorithm == 'balanced':
|
||||||
distribute_items_restrictive(world, True)
|
distribute_items_restrictive(world, True)
|
||||||
|
|
||||||
|
for x in range(1, world.players + 1):
|
||||||
|
shop_slot_bad = []
|
||||||
|
candidates = []
|
||||||
|
for location in world.get_locations():
|
||||||
|
if 'Shop Slot' in location.name and location.parent_region.shop is not None:
|
||||||
|
slot_num = int(location.name[-1]) - 1
|
||||||
|
shop_item = location.parent_region.shop.inventory[slot_num]
|
||||||
|
item = location.item
|
||||||
|
print(item.name, shop_item['item'])
|
||||||
|
if (shop_item is not None and shop_item['item'] == item.name) or 'Rupee' in item.name or (item.name in ['Bee']):
|
||||||
|
shop_slot_bad.append(location)
|
||||||
|
elif location.item.name in ['Progressive Shield', 'Bombs (3)', 'Bombs (10)', 'Bee Trap',
|
||||||
|
'Arrows (10)', 'Single Bomb', 'Single Arrow', 'Arrow Upgrade (+5)', 'Bomb Upgrade (+5)',
|
||||||
|
'Shovel', 'Progressive Mail', 'Bug Catching Net', 'Cane of Byrna', 'Triforce Piece'
|
||||||
|
'Piece of Heart', 'Boss Heart Container', 'Sanctuary Heart Container']:
|
||||||
|
candidates.append(location)
|
||||||
|
elif any([x in location.item.name for x in ['Key', 'Map', 'Compass', 'Clock']]):
|
||||||
|
candidates.append(location)
|
||||||
|
|
||||||
|
world.random.shuffle(candidates)
|
||||||
|
for slot in shop_slot_bad: # shop slot locations with redundant items
|
||||||
|
for c in candidates: # chosen item locations
|
||||||
|
if 'Rupee' in c.item.name or 'Shop Slot' in c.name: continue
|
||||||
|
if c.item_rule(slot.item):
|
||||||
|
print('Swapping {} with {}:: {} ||| {}'.format(c, slot, c.item, slot.item))
|
||||||
|
c.item, slot.item = slot.item, c.item
|
||||||
|
if not world.can_beat_game():
|
||||||
|
print('NOT GOOD')
|
||||||
|
c.item, slot.item = slot.item, c.item
|
||||||
|
else: break
|
||||||
|
|
||||||
|
|
||||||
if world.players > 1:
|
if world.players > 1:
|
||||||
balance_multiworld_progression(world)
|
balance_multiworld_progression(world)
|
||||||
|
|
||||||
|
|
|
@ -416,7 +416,7 @@ def create_shops(world, player: int):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if my_shop_slots.pop():
|
if my_shop_slots.pop():
|
||||||
additional_item = world.random.choice(['Rupees (20)', 'Rupees (50)', 'Rupees (100)'])
|
additional_item = world.random.choice(['Rupees (50)', 'Rupees (100)', 'Rupees (300)'])
|
||||||
world.itempool.append(ItemFactory(additional_item, player))
|
world.itempool.append(ItemFactory(additional_item, player))
|
||||||
slot_name = "{} Shop Slot {}".format(shop.region.name, index+1)
|
slot_name = "{} Shop Slot {}".format(shop.region.name, index+1)
|
||||||
loc = Location(player, slot_name, address=shop_table_by_location[slot_name], parent=shop.region)
|
loc = Location(player, slot_name, address=shop_table_by_location[slot_name], parent=shop.region)
|
||||||
|
@ -448,7 +448,7 @@ shop_table_by_location_id = {0x400000 + cnt: s for cnt, s in enumerate( [item fo
|
||||||
shop_table_by_location = {y:x for x,y in shop_table_by_location_id.items()}
|
shop_table_by_location = {y:x for x,y in shop_table_by_location_id.items()}
|
||||||
|
|
||||||
shop_generation_types = {
|
shop_generation_types = {
|
||||||
'default': _basic_shop_defaults + [('Bombs (3)', 20), ('Green Potion', 90), ('Blue Potion', 190), ('Bee', 10), ('Single Arrow', 5)] + [('Red Shield', 500), ('Blue Shield', 50)],
|
'default': _basic_shop_defaults + [('Bombs (3)', 20), ('Green Potion', 90), ('Blue Potion', 190), ('Bee', 10), ('Single Arrow', 5), ('Single Bomb', 10)] + [('Red Shield', 500), ('Blue Shield', 50)],
|
||||||
'potion': [('Red Potion', 150), ('Green Potion', 90), ('Blue Potion', 190)],
|
'potion': [('Red Potion', 150), ('Green Potion', 90), ('Blue Potion', 190)],
|
||||||
'discount_potion': [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)],
|
'discount_potion': [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)],
|
||||||
'bottle': [('Bee', 10)],
|
'bottle': [('Bee', 10)],
|
||||||
|
|
22
Rom.py
22
Rom.py
|
@ -633,6 +633,8 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
distinguished_prog_bow_loc.item.code = 0x65
|
distinguished_prog_bow_loc.item.code = 0x65
|
||||||
|
|
||||||
# patch items
|
# patch items
|
||||||
|
shop_items = []
|
||||||
|
|
||||||
for location in world.get_locations():
|
for location in world.get_locations():
|
||||||
if location.player != player:
|
if location.player != player:
|
||||||
continue
|
continue
|
||||||
|
@ -659,9 +661,19 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
my_item['replacement'] = my_item['item']
|
my_item['replacement'] = my_item['item']
|
||||||
my_item['replacement_price'] = my_item['price']
|
my_item['replacement_price'] = my_item['price']
|
||||||
my_item['item'] = item.name
|
my_item['item'] = item.name
|
||||||
my_item['price'] = world.random.randrange(1, 61) * 5 # can probably replace this with a price chart
|
if any([x in my_item['item'] for x in ['Single Bomb', 'Single Arrow']]):
|
||||||
|
my_item['price'] = world.random.randrange(5,35)
|
||||||
|
elif any([x in my_item['item'] for x in ['Arrows', 'Bombs', 'Clock']]):
|
||||||
|
my_item['price'] = world.random.randrange(20,120)
|
||||||
|
elif any([x in my_item['item'] for x in ['Universal Key', 'Compass', 'Map', 'Small Key', 'Piece of Heart']]):
|
||||||
|
my_item['price'] = world.random.randrange(50,150)
|
||||||
|
else:
|
||||||
|
my_item['price'] = world.random.randrange(50,300)
|
||||||
|
|
||||||
|
|
||||||
my_item['max'] = 1
|
my_item['max'] = 1
|
||||||
my_item['player'] = item.player if item.player != location.player else 0
|
my_item['player'] = item.player if item.player != location.player else 0
|
||||||
|
shop_items.append(my_item)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not location.crystal:
|
if not location.crystal:
|
||||||
|
@ -702,6 +714,14 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
for music_address in music_addresses:
|
for music_address in music_addresses:
|
||||||
rom.write_byte(music_address, music)
|
rom.write_byte(music_address, music)
|
||||||
|
|
||||||
|
my_prices = [my_item['price'] for my_item in shop_items]
|
||||||
|
price_scale = (80*max(8, len(my_prices)+2))/sum(my_prices)
|
||||||
|
for i in shop_items:
|
||||||
|
i['price'] *= price_scale
|
||||||
|
if i['price'] < 5: i['price'] = 5
|
||||||
|
else: i['price'] = int((i['price']//5)*5)
|
||||||
|
|
||||||
|
|
||||||
if world.mapshuffle[player]:
|
if world.mapshuffle[player]:
|
||||||
rom.write_byte(0x155C9, local_random.choice([0x11, 0x16])) # Randomize GT music too with map shuffle
|
rom.write_byte(0x155C9, local_random.choice([0x11, 0x16])) # Randomize GT music too with map shuffle
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,13 @@ general_options:
|
||||||
# Null means nothing, for the server this means to default the value
|
# Null means nothing, for the server this means to default the value
|
||||||
# These overwrite command line arguments!
|
# These overwrite command line arguments!
|
||||||
server_options:
|
server_options:
|
||||||
host: 0.0.0.0
|
host: null
|
||||||
port: 38281
|
port: 38281
|
||||||
password: null
|
password: null
|
||||||
multidata: null
|
multidata: null
|
||||||
savefile: null
|
savefile: null
|
||||||
disable_save: false
|
disable_save: false
|
||||||
loglevel: "debug"
|
loglevel: "info"
|
||||||
# Allows for clients to log on and manage the server. If this is null, no remote administration is possible.
|
# Allows for clients to log on and manage the server. If this is null, no remote administration is possible.
|
||||||
server_password: null
|
server_password: null
|
||||||
# Automatically forward the port that is used, then close that port after 24 hours
|
# Automatically forward the port that is used, then close that port after 24 hours
|
||||||
|
@ -28,9 +28,9 @@ server_options:
|
||||||
disable_item_cheat: false
|
disable_item_cheat: false
|
||||||
# Client hint system
|
# Client hint system
|
||||||
# Points given to a player for each acquired item in their world
|
# Points given to a player for each acquired item in their world
|
||||||
location_check_points: 50
|
location_check_points: 1
|
||||||
# Point cost to receive a hint via !hint for players
|
# Point cost to receive a hint via !hint for players
|
||||||
hint_cost: 0 # Set to 0 if you want free hints
|
hint_cost: 1000 # Set to 0 if you want free hints
|
||||||
# Forfeit modes
|
# Forfeit modes
|
||||||
# "disabled" -> clients can't forfeit,
|
# "disabled" -> clients can't forfeit,
|
||||||
# "enabled" -> clients can always forfeit
|
# "enabled" -> clients can always forfeit
|
||||||
|
|
Loading…
Reference in New Issue