Noita: Fix rare item fill failure for single-player games (#2387)
This commit is contained in:
parent
9c80a7c4ec
commit
36f95b0683
|
@ -44,20 +44,18 @@ def create_kantele(victory_condition: VictoryCondition) -> List[str]:
|
||||||
return ["Kantele"] if victory_condition.value >= VictoryCondition.option_pure_ending else []
|
return ["Kantele"] if victory_condition.value >= VictoryCondition.option_pure_ending else []
|
||||||
|
|
||||||
|
|
||||||
def create_random_items(multiworld: MultiWorld, player: int, random_count: int) -> List[str]:
|
def create_random_items(multiworld: MultiWorld, player: int, weights: Dict[str, int], count: int) -> List[str]:
|
||||||
filler_pool = filler_weights.copy()
|
filler_pool = weights.copy()
|
||||||
if multiworld.bad_effects[player].value == 0:
|
if multiworld.bad_effects[player].value == 0:
|
||||||
del filler_pool["Trap"]
|
del filler_pool["Trap"]
|
||||||
|
|
||||||
return multiworld.random.choices(
|
return multiworld.random.choices(population=list(filler_pool.keys()),
|
||||||
population=list(filler_pool.keys()),
|
|
||||||
weights=list(filler_pool.values()),
|
weights=list(filler_pool.values()),
|
||||||
k=random_count
|
k=count)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def create_all_items(multiworld: MultiWorld, player: int) -> None:
|
def create_all_items(multiworld: MultiWorld, player: int) -> None:
|
||||||
sum_locations = len(multiworld.get_unfilled_locations(player))
|
locations_to_fill = len(multiworld.get_unfilled_locations(player))
|
||||||
|
|
||||||
itempool = (
|
itempool = (
|
||||||
create_fixed_item_pool()
|
create_fixed_item_pool()
|
||||||
|
@ -66,9 +64,18 @@ def create_all_items(multiworld: MultiWorld, player: int) -> None:
|
||||||
+ create_kantele(multiworld.victory_condition[player])
|
+ create_kantele(multiworld.victory_condition[player])
|
||||||
)
|
)
|
||||||
|
|
||||||
random_count = sum_locations - len(itempool)
|
# if there's not enough shop-allowed items in the pool, we can encounter gen issues
|
||||||
itempool += create_random_items(multiworld, player, random_count)
|
# 39 is the number of shop-valid items we need to guarantee
|
||||||
|
if len(itempool) < 39:
|
||||||
|
itempool += create_random_items(multiworld, player, shop_only_filler_weights, 39 - len(itempool))
|
||||||
|
# this is so that it passes tests and gens if you have minimal locations and only one player
|
||||||
|
if multiworld.players == 1:
|
||||||
|
for location in multiworld.get_unfilled_locations(player):
|
||||||
|
if "Shop Item" in location.name:
|
||||||
|
location.item = create_item(player, itempool.pop())
|
||||||
|
locations_to_fill = len(multiworld.get_unfilled_locations(player))
|
||||||
|
|
||||||
|
itempool += create_random_items(multiworld, player, filler_weights, locations_to_fill - len(itempool))
|
||||||
multiworld.itempool += [create_item(player, name) for name in itempool]
|
multiworld.itempool += [create_item(player, name) for name in itempool]
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,7 +102,7 @@ item_table: Dict[str, ItemData] = {
|
||||||
"Tinker with Wands Everywhere Perk": ItemData(110018, "Perks", ItemClassification.progression, 1),
|
"Tinker with Wands Everywhere Perk": ItemData(110018, "Perks", ItemClassification.progression, 1),
|
||||||
"All-Seeing Eye Perk": ItemData(110019, "Perks", ItemClassification.progression, 1),
|
"All-Seeing Eye Perk": ItemData(110019, "Perks", ItemClassification.progression, 1),
|
||||||
"Spatial Awareness Perk": ItemData(110020, "Perks", ItemClassification.progression),
|
"Spatial Awareness Perk": ItemData(110020, "Perks", ItemClassification.progression),
|
||||||
"Extra Life Perk": ItemData(110021, "Repeatable Perks", ItemClassification.useful, 2),
|
"Extra Life Perk": ItemData(110021, "Repeatable Perks", ItemClassification.useful, 1),
|
||||||
"Orb": ItemData(110022, "Orbs", ItemClassification.progression_skip_balancing),
|
"Orb": ItemData(110022, "Orbs", ItemClassification.progression_skip_balancing),
|
||||||
"Random Potion": ItemData(110023, "Items", ItemClassification.filler),
|
"Random Potion": ItemData(110023, "Items", ItemClassification.filler),
|
||||||
"Secret Potion": ItemData(110024, "Items", ItemClassification.filler),
|
"Secret Potion": ItemData(110024, "Items", ItemClassification.filler),
|
||||||
|
@ -106,24 +113,27 @@ item_table: Dict[str, ItemData] = {
|
||||||
"Refreshing Gourd": ItemData(110029, "Items", ItemClassification.filler, 1),
|
"Refreshing Gourd": ItemData(110029, "Items", ItemClassification.filler, 1),
|
||||||
"Sädekivi": ItemData(110030, "Items", ItemClassification.filler),
|
"Sädekivi": ItemData(110030, "Items", ItemClassification.filler),
|
||||||
"Broken Wand": ItemData(110031, "Items", ItemClassification.filler),
|
"Broken Wand": ItemData(110031, "Items", ItemClassification.filler),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filler_weights: Dict[str, int] = {
|
shop_only_filler_weights: Dict[str, int] = {
|
||||||
"Trap": 15,
|
"Trap": 15,
|
||||||
"Extra Max HP": 25,
|
"Extra Max HP": 25,
|
||||||
"Spell Refresher": 20,
|
"Spell Refresher": 20,
|
||||||
"Potion": 40,
|
|
||||||
"Gold (200)": 15,
|
|
||||||
"Gold (1000)": 6,
|
|
||||||
"Wand (Tier 1)": 10,
|
"Wand (Tier 1)": 10,
|
||||||
"Wand (Tier 2)": 8,
|
"Wand (Tier 2)": 8,
|
||||||
"Wand (Tier 3)": 7,
|
"Wand (Tier 3)": 7,
|
||||||
"Wand (Tier 4)": 6,
|
"Wand (Tier 4)": 6,
|
||||||
"Wand (Tier 5)": 5,
|
"Wand (Tier 5)": 5,
|
||||||
"Wand (Tier 6)": 4,
|
"Wand (Tier 6)": 4,
|
||||||
"Extra Life Perk": 3,
|
"Extra Life Perk": 10,
|
||||||
"Random Potion": 10,
|
}
|
||||||
|
|
||||||
|
filler_weights: Dict[str, int] = {
|
||||||
|
**shop_only_filler_weights,
|
||||||
|
"Gold (200)": 15,
|
||||||
|
"Gold (1000)": 6,
|
||||||
|
"Potion": 40,
|
||||||
|
"Random Potion": 9,
|
||||||
"Secret Potion": 10,
|
"Secret Potion": 10,
|
||||||
"Powder Pouch": 10,
|
"Powder Pouch": 10,
|
||||||
"Chaos Die": 4,
|
"Chaos Die": 4,
|
||||||
|
@ -131,7 +141,7 @@ filler_weights: Dict[str, int] = {
|
||||||
"Kammi": 4,
|
"Kammi": 4,
|
||||||
"Refreshing Gourd": 4,
|
"Refreshing Gourd": 4,
|
||||||
"Sädekivi": 3,
|
"Sädekivi": 3,
|
||||||
"Broken Wand": 8,
|
"Broken Wand": 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,10 @@ wand_tiers: List[str] = [
|
||||||
"Wand (Tier 6)", # Temple of the Art
|
"Wand (Tier 6)", # Temple of the Art
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
items_hidden_from_shops: List[str] = ["Gold (200)", "Gold (1000)", "Potion", "Random Potion", "Secret Potion",
|
items_hidden_from_shops: List[str] = ["Gold (200)", "Gold (1000)", "Potion", "Random Potion", "Secret Potion",
|
||||||
"Chaos Die", "Greed Die", "Kammi", "Refreshing Gourd", "Sädekivi", "Broken Wand",
|
"Chaos Die", "Greed Die", "Kammi", "Refreshing Gourd", "Sädekivi", "Broken Wand",
|
||||||
"Powder Pouch"]
|
"Powder Pouch"]
|
||||||
|
|
||||||
|
|
||||||
perk_list: List[str] = list(filter(Items.item_is_perk, Items.item_table.keys()))
|
perk_list: List[str] = list(filter(Items.item_is_perk, Items.item_table.keys()))
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,6 +153,7 @@ def victory_unlock_conditions(multiworld: MultiWorld, player: int) -> None:
|
||||||
|
|
||||||
|
|
||||||
def create_all_rules(multiworld: MultiWorld, player: int) -> None:
|
def create_all_rules(multiworld: MultiWorld, player: int) -> None:
|
||||||
|
if multiworld.players > 1:
|
||||||
ban_items_from_shops(multiworld, player)
|
ban_items_from_shops(multiworld, player)
|
||||||
ban_early_high_tier_wands(multiworld, player)
|
ban_early_high_tier_wands(multiworld, player)
|
||||||
lock_holy_mountains_into_spheres(multiworld, player)
|
lock_holy_mountains_into_spheres(multiworld, player)
|
||||||
|
|
Loading…
Reference in New Issue