Skip to content

Commit

Permalink
Core: implement start_inventory_from_pool (ArchipelagoMW#1170)
Browse files Browse the repository at this point in the history
* Core: implement start_inventory_from_pool

* Factorio/LttP/Subnautica: add start_inventory_from_pool Option
  • Loading branch information
Berserker66 authored Apr 10, 2023
1 parent 8d559da commit c7284f9
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 7 deletions.
2 changes: 1 addition & 1 deletion BaseClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ def __init__(self, players: int):
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 = []
Expand All @@ -122,6 +121,7 @@ def __init__(self, players: int):
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(
Expand Down
29 changes: 29 additions & 0 deletions Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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[
Expand Down
7 changes: 7 additions & 0 deletions Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 3 additions & 2 deletions worlds/alttp/Options.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down Expand Up @@ -466,5 +466,6 @@ class AllowCollect(Toggle):
"beemizer_total_chance": BeemizerTotalChance,
"beemizer_trap_chance": BeemizerTrapChance,
"death_link": DeathLink,
"allow_collect": AllowCollect
"allow_collect": AllowCollect,
"start_inventory_from_pool": StartInventoryPool,
}
4 changes: 2 additions & 2 deletions worlds/alttp/Rom.py
Original file line number Diff line number Diff line change
Expand Up @@ -1247,8 +1247,8 @@ def chunk(l, n):
# 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,
Expand Down
4 changes: 3 additions & 1 deletion worlds/factorio/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
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
Expand Down Expand Up @@ -454,6 +455,7 @@ class EnergyLink(Toggle):
"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.
Expand Down
3 changes: 2 additions & 1 deletion worlds/subnautica/Options.py
Original file line number Diff line number Diff line change
@@ -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


Expand Down Expand Up @@ -104,4 +104,5 @@ class SubnauticaDeathLink(DeathLink):
"creature_scans": CreatureScans,
"creature_scan_logic": AggressiveScanLogic,
"death_link": SubnauticaDeathLink,
"start_inventory_from_pool": StartInventoryPool,
}

0 comments on commit c7284f9

Please sign in to comment.