Core: implement start_inventory_from_pool (#1170)
* Core: implement start_inventory_from_pool * Factorio/LttP/Subnautica: add start_inventory_from_pool Option
This commit is contained in:
parent
8d559daa35
commit
c7284f90d9
|
@ -113,7 +113,6 @@ class MultiWorld():
|
|||
self.dark_world_light_cone = False
|
||||
self.rupoor_cost = 10
|
||||
self.aga_randomness = True
|
||||
self.lock_aga_door_in_escape = False
|
||||
self.save_and_quit_from_boss = True
|
||||
self.custom = False
|
||||
self.customitemarray = []
|
||||
|
@ -122,6 +121,7 @@ class MultiWorld():
|
|||
self.early_items = {player: {} for player in self.player_ids}
|
||||
self.local_early_items = {player: {} for player in self.player_ids}
|
||||
self.indirect_connections = {}
|
||||
self.start_inventory_from_pool = {player: Options.StartInventoryPool({}) for player in range(1, players + 1)}
|
||||
self.fix_trock_doors = self.AttributeProxy(
|
||||
lambda player: self.shuffle[player] != 'vanilla' or self.mode[player] == 'inverted')
|
||||
self.fix_skullwoods_exit = self.AttributeProxy(
|
||||
|
|
29
Main.py
29
Main.py
|
@ -115,6 +115,9 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
|
|||
for item_name, count in world.start_inventory[player].value.items():
|
||||
for _ in range(count):
|
||||
world.push_precollected(world.create_item(item_name, player))
|
||||
for item_name, count in world.start_inventory_from_pool[player].value.items():
|
||||
for _ in range(count):
|
||||
world.push_precollected(world.create_item(item_name, player))
|
||||
|
||||
logger.info('Creating World.')
|
||||
AutoWorld.call_all(world, "create_regions")
|
||||
|
@ -149,6 +152,32 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
|
|||
|
||||
AutoWorld.call_all(world, "generate_basic")
|
||||
|
||||
# remove starting inventory from pool items.
|
||||
# Because some worlds don't actually create items during create_items this has to be as late as possible.
|
||||
if any(world.start_inventory_from_pool[player].value for player in world.player_ids):
|
||||
new_items: List[Item] = []
|
||||
depletion_pool: Dict[int, Dict[str, int]] = {
|
||||
player: world.start_inventory_from_pool[player].value.copy() for player in world.player_ids}
|
||||
for player, items in depletion_pool.items():
|
||||
player_world: AutoWorld.World = world.worlds[player]
|
||||
for count in items.values():
|
||||
new_items.append(player_world.create_filler())
|
||||
target: int = sum(sum(items.values()) for items in depletion_pool.values())
|
||||
for item in world.itempool:
|
||||
if depletion_pool[item.player].get(item.name, 0):
|
||||
target -= 1
|
||||
depletion_pool[item.player][item.name] -= 1
|
||||
# quick abort if we have found all items
|
||||
if not target:
|
||||
break
|
||||
else:
|
||||
new_items.append(item)
|
||||
for player, remaining_items in depletion_pool.items():
|
||||
if remaining_items:
|
||||
raise Exception(f"{world.get_player_name(player)}"
|
||||
f" is trying to remove items from their pool that don't exist: {remaining_items}")
|
||||
world.itempool[:] = new_items
|
||||
|
||||
# temporary home for item links, should be moved out of Main
|
||||
for group_id, group in world.groups.items():
|
||||
def find_common_pool(players: Set[int], shared_pool: Set[str]) -> Tuple[
|
||||
|
|
|
@ -897,6 +897,13 @@ class StartInventory(ItemDict):
|
|||
display_name = "Start Inventory"
|
||||
|
||||
|
||||
class StartInventoryPool(StartInventory):
|
||||
"""Start with these items and don't place them in the world.
|
||||
The game decides what the replacement items will be."""
|
||||
verify_item_name = True
|
||||
display_name = "Start Inventory from Pool"
|
||||
|
||||
|
||||
class StartHints(ItemSet):
|
||||
"""Start with these item's locations prefilled into the !hint command."""
|
||||
display_name = "Start Hints"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import typing
|
||||
|
||||
from BaseClasses import MultiWorld
|
||||
from Options import Choice, Range, Option, Toggle, DefaultOnToggle, DeathLink, TextChoice, PlandoBosses
|
||||
from Options import Choice, Range, Option, Toggle, DefaultOnToggle, DeathLink, StartInventoryPool, PlandoBosses
|
||||
|
||||
|
||||
class Logic(Choice):
|
||||
|
@ -466,5 +466,6 @@ alttp_options: typing.Dict[str, type(Option)] = {
|
|||
"beemizer_total_chance": BeemizerTotalChance,
|
||||
"beemizer_trap_chance": BeemizerTrapChance,
|
||||
"death_link": DeathLink,
|
||||
"allow_collect": AllowCollect
|
||||
"allow_collect": AllowCollect,
|
||||
"start_inventory_from_pool": StartInventoryPool,
|
||||
}
|
||||
|
|
|
@ -1247,8 +1247,8 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool):
|
|||
# assorted fixes
|
||||
rom.write_byte(0x1800A2, 0x01 if world.fix_fake_world[
|
||||
player] else 0x00) # Toggle whether to be in real/fake dark world when dying in a DW dungeon before killing aga1
|
||||
rom.write_byte(0x180169,
|
||||
0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence.
|
||||
# Lock or unlock aga tower door during escape sequence.
|
||||
rom.write_byte(0x180169, 0x00)
|
||||
if world.mode[player] == 'inverted':
|
||||
rom.write_byte(0x180169, 0x02) # lock aga/ganon tower door with crystals in inverted
|
||||
rom.write_byte(0x180171,
|
||||
|
|
|
@ -2,7 +2,8 @@ from __future__ import annotations
|
|||
import typing
|
||||
import datetime
|
||||
|
||||
from Options import Choice, OptionDict, OptionSet, ItemDict, Option, DefaultOnToggle, Range, DeathLink, Toggle
|
||||
from Options import Choice, OptionDict, OptionSet, ItemDict, Option, DefaultOnToggle, Range, DeathLink, Toggle, \
|
||||
StartInventoryPool
|
||||
from schema import Schema, Optional, And, Or
|
||||
|
||||
# schema helpers
|
||||
|
@ -454,6 +455,7 @@ factorio_options: typing.Dict[str, type(Option)] = {
|
|||
"evolution_trap_increase": EvolutionTrapIncrease,
|
||||
"death_link": DeathLink,
|
||||
"energy_link": EnergyLink,
|
||||
"start_inventory_from_pool": StartInventoryPool,
|
||||
}
|
||||
|
||||
# spoilers below. If you spoil it for yourself, please at least don't spoil it for anyone else.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import typing
|
||||
|
||||
from Options import Choice, Range, DeathLink, DefaultOnToggle
|
||||
from Options import Choice, Range, DeathLink, DefaultOnToggle, StartInventoryPool
|
||||
from .Creatures import all_creatures, Definitions
|
||||
|
||||
|
||||
|
@ -104,4 +104,5 @@ options = {
|
|||
"creature_scans": CreatureScans,
|
||||
"creature_scan_logic": AggressiveScanLogic,
|
||||
"death_link": SubnauticaDeathLink,
|
||||
"start_inventory_from_pool": StartInventoryPool,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue