mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-25 01:13:23 -07:00
Reworked logic to no longer include Single: items as filler
Reworked logic for more performance Reworked logic to always put useful equipment in pool
This commit is contained in:
@@ -152,7 +152,7 @@ class Items:
|
||||
"Bundle: Boom Box": ItemData(G.Equipment, 1338153, count=0),
|
||||
"Bundle: Chainsaw": ItemData(G.Equipment, 1338154, count=0),
|
||||
"Bundle: Cluster Nobelisk": ItemData(G.Ammo, 1338155),
|
||||
"Bundle: Iodine-Infused Filter": ItemData(G.Ammo, 1338156), #1.1
|
||||
"Bundle: Iodine-Infused Filter": ItemData(G.Equipment, 1338156, C.useful, count=3), #1.1
|
||||
"Bundle: Cup": ItemData(G.Equipment, 1338157, count=0),
|
||||
"Bundle: Cup (gold)": ItemData(G.Equipment, 1338158, count=0),
|
||||
"Bundle: Explosive Rebar": ItemData(G.Ammo, 1338159),
|
||||
@@ -183,7 +183,7 @@ class Items:
|
||||
"Bundle: Xeno-Zapper": ItemData(G.Equipment, 1338184, count=0),
|
||||
"Bundle: Zipline": ItemData(G.Equipment, 1338185, count=0),
|
||||
"Bundle: Portable Miner": ItemData(G.Equipment, 1338186, count=0),
|
||||
"Bundle: Gas Filter": ItemData(G.Ammo, 1338187),
|
||||
"Bundle: Gas Filter": ItemData(G.Equipment, 1338187, C.useful, count=3),
|
||||
# Special cases
|
||||
"Small Inflated Pocket Dimension": ItemData(G.Upgrades, 1338188, C.useful, 11),
|
||||
"Inflated Pocket Dimension": ItemData(G.Upgrades, 1338189, C.useful, 5),
|
||||
@@ -820,49 +820,49 @@ class Items:
|
||||
#1339150 - 1339199 Equipment / Ammo
|
||||
"Single: Bacon Agaric": ItemData(G.Ammo, 1339150, count=0),
|
||||
"Single: Beryl Nut": ItemData(G.Ammo, 1339151, count=0),
|
||||
"Single: Blade Runners": ItemData(G.Equipment, 1339152),
|
||||
"Single: Blade Runners": ItemData(G.Equipment, 1339152, C.useful),
|
||||
"Single: Boom Box": ItemData(G.Equipment, 1339153),
|
||||
"Single: Chainsaw": ItemData(G.Equipment, 1339154),
|
||||
"Single: Chainsaw": ItemData(G.Equipment, 1339154, C.useful),
|
||||
"Single: Cluster Nobelisk": ItemData(G.Ammo, 1339155, count=0),
|
||||
"Single: Iodine-Infused Filter": ItemData(G.Ammo, 1339156, count=0), #1.1
|
||||
"Single: Iodine-Infused Filter": ItemData(G.Equipment, 1339156, count=0), #1.1
|
||||
"Single: Cup": ItemData(G.Equipment, 1339157),
|
||||
"Single: Cup (gold)": ItemData(G.Equipment, 1339158, count=0),
|
||||
"Single: Explosive Rebar": ItemData(G.Ammo, 1339159, count=0),
|
||||
"Single: Factory Cart": ItemData(G.Equipment, 1339160),
|
||||
"Single: Factory Cart": ItemData(G.Equipment, 1339160, C.useful),
|
||||
"Single: Factory Cart (golden)": ItemData(G.Equipment, 1339161, count=0),
|
||||
"Single: Gas Mask": ItemData(G.Equipment, 1339162),
|
||||
"Single: Gas Mask": ItemData(G.Equipment, 1339162, C.useful),
|
||||
"Single: Gas Nobelisk": ItemData(G.Ammo, 1339163, count=0),
|
||||
"Single: Hazmat Suit": ItemData(G.Equipment, 1339164),
|
||||
"Single: Hazmat Suit": ItemData(G.Equipment, 1339164, C.useful),
|
||||
"Single: Homing Rifle Ammo": ItemData(G.Ammo, 1339165, count=0),
|
||||
"Single: Hoverpack": ItemData(G.Equipment, 1339166),
|
||||
"Single: Hoverpack": ItemData(G.Equipment, 1339166, C.useful),
|
||||
"Single: Iron Rebar": ItemData(G.Ammo, 1339167, count=0),
|
||||
"Single: Jetpack": ItemData(G.Equipment, 1339168),
|
||||
"Single: Jetpack": ItemData(G.Equipment, 1339168, C.useful),
|
||||
"Single: Medicinal Inhaler": ItemData(G.Ammo, 1339169, count=0),
|
||||
"Single: Nobelisk": ItemData(G.Ammo, 1339170, count=0),
|
||||
"Single: Nobelisk Detonator": ItemData(G.Equipment, 1339171),
|
||||
"Single: Nobelisk Detonator": ItemData(G.Equipment, 1339171, C.useful),
|
||||
"Single: Nuke Nobelisk": ItemData(G.Ammo, 1339172, count=0),
|
||||
"Single: Object Scanner": ItemData(G.Equipment, 1339173),
|
||||
"Single: Paleberry": ItemData(G.Ammo, 1339174, count=0),
|
||||
"Single: Parachute": ItemData(G.Equipment, 1339175),
|
||||
"Single: Parachute": ItemData(G.Equipment, 1339175, C.useful),
|
||||
"Single: Pulse Nobelisk": ItemData(G.Ammo, 1339176, count=0),
|
||||
"Single: Rebar Gun": ItemData(G.Equipment, 1339177),
|
||||
"Single: Rifle": ItemData(G.Equipment, 1339178),
|
||||
"Single: Rebar Gun": ItemData(G.Equipment, 1339177, C.useful),
|
||||
"Single: Rifle": ItemData(G.Equipment, 1339178, C.useful),
|
||||
"Single: Rifle Ammo": ItemData(G.Ammo, 1339179, count=0),
|
||||
"Single: Shatter Rebar": ItemData(G.Ammo, 1339180, count=0),
|
||||
"Single: Stun Rebar": ItemData(G.Ammo, 1339181, count=0),
|
||||
"Single: Turbo Rifle Ammo": ItemData(G.Ammo, 1339182, count=0),
|
||||
"Single: Xeno-Basher": ItemData(G.Equipment, 1339183),
|
||||
"Single: Xeno-Zapper": ItemData(G.Equipment, 1339184),
|
||||
"Single: Zipline": ItemData(G.Equipment, 1339185),
|
||||
"Single: Xeno-Basher": ItemData(G.Equipment, 1339183, C.useful),
|
||||
"Single: Xeno-Zapper": ItemData(G.Equipment, 1339184, C.useful),
|
||||
"Single: Zipline": ItemData(G.Equipment, 1339185, C.useful),
|
||||
"Single: Portable Miner": ItemData(G.Equipment, 1339186),
|
||||
"Single: Gas Filter": ItemData(G.Ammo, 1339187, count=0)
|
||||
"Single: Gas Filter": ItemData(G.Equipment, 1339187, count=0)
|
||||
}
|
||||
|
||||
non_unique_item_categories: ClassVar[G] = G.Parts | G.Equipment | G.Ammo | G.Trap | G.Upgrades
|
||||
pool_item_categories: ClassVar[G] = G.Recipe | G.Building | G.Equipment | G.Transport | G.Upgrades
|
||||
item_names_and_ids: ClassVar[dict[str, int]] = {name: item_data.code for name, item_data in item_data.items()}
|
||||
filler_items: ClassVar[tuple[str, ...]] = tuple(item for item, details in item_data.items()
|
||||
if details.category & (G.Parts | G.Ammo))
|
||||
if details.count > 0 and details.category & (G.Parts | G.Ammo))
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -885,6 +885,9 @@ class Items:
|
||||
random: Random
|
||||
critical_path: CriticalPathCalculator
|
||||
|
||||
trap_chance: int
|
||||
enabled_traps: tuple[str]
|
||||
|
||||
def __init__(self, player: Optional[int], logic: GameLogic, random: Random,
|
||||
options: SatisfactoryOptions, critical_path: CriticalPathCalculator):
|
||||
self.player = player
|
||||
@@ -893,15 +896,18 @@ class Items:
|
||||
self.critical_path = critical_path
|
||||
self.options = options
|
||||
|
||||
self.trap_chance = self.options.trap_chance.value
|
||||
self.enabled_traps = tuple(self.options.trap_selection_override.value)
|
||||
|
||||
|
||||
@classmethod
|
||||
def create_item(cls, instance: Optional["Items"], name: str, player: int) -> Item:
|
||||
data: ItemData = cls.item_data[name]
|
||||
type = data.type
|
||||
|
||||
if (type == C.progression or type == C.useful) \
|
||||
and instance and instance.critical_path.required_item_names \
|
||||
if type == C.progression \
|
||||
and (data.category & (G.Recipe | G.Building)) and not (data.category & G.NeverExclude) \
|
||||
and instance and instance.critical_path.required_item_names \
|
||||
and name not in instance.critical_path.required_item_names:
|
||||
type = C.useful
|
||||
|
||||
@@ -909,27 +915,25 @@ class Items:
|
||||
|
||||
|
||||
def get_filler_item_name(self, filler_items: tuple[str, ...], random: Random) -> str:
|
||||
trap_chance: int = self.options.trap_chance.value
|
||||
enabled_traps: list[str] = list(self.options.trap_selection_override.value)
|
||||
|
||||
if enabled_traps and random.random() < (trap_chance / 100):
|
||||
return random.choice(enabled_traps)
|
||||
if self.enabled_traps and random.random() < (self.trap_chance / 100):
|
||||
return random.choice(self.enabled_traps)
|
||||
else:
|
||||
return random.choice(filler_items)
|
||||
|
||||
|
||||
def get_excluded_items(self, multiworld: MultiWorld) -> set[str]:
|
||||
excluded_items: set[str] = set()
|
||||
excluded_items.update("Bundle: "+ part for part in self.critical_path.parts_to_exclude)
|
||||
excluded_items.update(recipe for recipe in self.critical_path.recipes_to_exclude)
|
||||
excluded_items.update("Building: "+ building for building in self.critical_path.buildings_to_exclude)
|
||||
excluded_items: set[str] = {
|
||||
item.name
|
||||
for item in multiworld.precollected_items[self.player]
|
||||
if item.name in self.item_data
|
||||
and not (self.item_data[item.name].category & self.non_unique_item_categories)
|
||||
and item.name not in self.options.start_inventory_from_pool.value
|
||||
}
|
||||
|
||||
for item in multiworld.precollected_items[self.player]:
|
||||
if item.name in self.item_data \
|
||||
and not (self.item_data[item.name].category & self.non_unique_item_categories) \
|
||||
and item.name not in self.options.start_inventory_from_pool:
|
||||
|
||||
excluded_items.add(item.name)
|
||||
excluded_items.update({"Bundle: "+ part for part in self.critical_path.parts_to_exclude})
|
||||
excluded_items.update({"Single: "+ part for part in self.critical_path.parts_to_exclude})
|
||||
excluded_items.update({"Building: "+ building for building in self.critical_path.buildings_to_exclude})
|
||||
excluded_items.update({recipe for recipe in self.critical_path.recipes_to_exclude})
|
||||
|
||||
return excluded_items
|
||||
|
||||
@@ -937,18 +941,16 @@ class Items:
|
||||
def build_item_pool(self, random: Random, multiworld: MultiWorld, number_of_locations: int) -> list[Item]:
|
||||
excluded_from_pool: set[str] = self.get_excluded_items(multiworld) \
|
||||
.union(self.critical_path.implicitly_unlocked)
|
||||
pool: list[Item] = []
|
||||
|
||||
for name, data in self.item_data.items():
|
||||
if data.count > 0 \
|
||||
and data.category & self.pool_item_categories \
|
||||
and name not in excluded_from_pool:
|
||||
|
||||
for _ in range(data.count):
|
||||
item = self.create_item(self, name, self.player)
|
||||
if item.classification != C.filler:
|
||||
pool.append(item)
|
||||
|
||||
pool_items: list[Item] = [
|
||||
self.create_item(self, name, self.player)
|
||||
for name, data in self.item_data.items()
|
||||
for _ in range(data.count)
|
||||
if data.category & self.pool_item_categories
|
||||
and (data.category & G.Equipment or name not in excluded_from_pool)
|
||||
]
|
||||
pool: list[Item] = [item for item in pool_items if item.classification != C.filler]
|
||||
|
||||
filler_pool_size: int = number_of_locations - len(pool)
|
||||
|
||||
if (filler_pool_size < 0):
|
||||
|
||||
Reference in New Issue
Block a user