From 694f942c06ee028b08de64ec870e16cb91f1ccaf Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Mon, 6 Sep 2021 23:39:27 -0500 Subject: [PATCH 1/9] Renamed RiskOfRainItem to RiskOfRain2Item to prevent any potential problems if someone adds Risk of Rain 1 --- worlds/ror2/Items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/ror2/Items.py b/worlds/ror2/Items.py index 35992e1f..0e993404 100644 --- a/worlds/ror2/Items.py +++ b/worlds/ror2/Items.py @@ -2,7 +2,7 @@ from BaseClasses import Item import typing -class RiskOfRainItem(Item): +class RiskOfRain2Item(Item): game: str = "Risk of Rain 2" # 37000 - 38000 From 8d05aa62622da38a34a53f1368f999fa57bca7dc Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Mon, 6 Sep 2021 23:40:39 -0500 Subject: [PATCH 2/9] Added a custom dynamic item weights pool option. --- worlds/ror2/Options.py | 114 +++++++++++++++++++++++++++++++++++++--- worlds/ror2/__init__.py | 34 ++++++++---- 2 files changed, 131 insertions(+), 17 deletions(-) diff --git a/worlds/ror2/Options.py b/worlds/ror2/Options.py index a58104e4..ae84a82f 100644 --- a/worlds/ror2/Options.py +++ b/worlds/ror2/Options.py @@ -1,5 +1,5 @@ import typing -from Options import Option, Toggle, Range +from Options import Option, DefaultOnToggle, Range, OptionList class TotalLocations(Range): @@ -27,21 +27,121 @@ class ItemPickupStep(Range): range_end = 5 default = 1 -class AllowLunarItems(Toggle): + +class AllowLunarItems(DefaultOnToggle): """Allows Lunar items in the item pool.""" displayname = "Enable Lunar Item Shuffling" - default = True -class StartWithRevive(Toggle): + +class StartWithRevive(DefaultOnToggle): """Start the game with a `Dio's Best Friend` item.""" displayname = "Start with a Revive" - default = True +class GreenScrap(Range): + """Weight of Green Scraps in the item pool.""" + displayname = "Green Scraps" + range_start = 0 + range_end = 100 + default = 15 + + +class RedScrap(Range): + """Weight of Red Scraps in the item pool.""" + displayname = "Red Scraps" + range_start = 0 + range_end = 100 + default = 5 + + +class YellowScrap(Range): + """Weight of yellow scraps in the item pool.""" + displayname = "Yellow Scraps" + range_start = 0 + range_end = 100 + default = 1 + + +class WhiteScrap(Range): + """Weight of white scraps in the item pool.""" + displayname = "White Scraps" + range_start = 0 + range_end = 100 + default = 30 + + +class CommonItem(Range): + """Weight of common items in the item pool.""" + displayname = "Common Items" + range_start = 0 + range_end = 100 + default = 75 + + +class UncommonItem(Range): + """Weight of uncommon items in the item pool.""" + displayname = "Uncommon Items" + range_start = 0 + range_end = 100 + default = 40 + + +class LegendaryItem(Range): + """Weight of legendary items in the item pool.""" + displayname = "Legendary Items" + range_start = 0 + range_end = 100 + default = 10 + + +class BossItem(Range): + """Weight of boss items in the item pool.""" + displayname = "Boss Items" + range_start = 0 + range_end = 100 + default = 5 + + +class LunarItem(Range): + """Weight of lunar items in the item pool.""" + displayname = "Lunar Items" + range_start = 0 + range_end = 100 + default = 15 + + +class Equipment(Range): + """Weight of equipment items in the item pool.""" + displayname = "Equipment" + range_start = 0 + range_end = 100 + default = 25 + + +class WeightPresets(Choice): + """Preset item weight options.""" + displayname = "Item Weight Preset" + option_default = 0 + + +ror2_weights: typing.Dict[str, type(Option)] = { + "green_scrap": GreenScrap, + "red_scrap": RedScrap, + "yellow_scrap": YellowScrap, + "white_scrap": WhiteScrap, + "common_item": CommonItem, + "uncommon_item": UncommonItem, + "legendary_item": LegendaryItem, + "boss_item": BossItem, + "lunar_item": LunarItem, + "equipment": Equipment +} + ror2_options: typing.Dict[str, type(Option)] = { "total_locations": TotalLocations, "total_revivals": TotalRevivals, "start_with_revive": StartWithRevive, "item_pickup_step": ItemPickupStep, - "enable_lunar": AllowLunarItems -} + "enable_lunar": AllowLunarItems, + **ror2_weights +} \ No newline at end of file diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index d05851db..eff407a5 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -1,10 +1,10 @@ import string -from .Items import RiskOfRainItem, item_table, junk_weights +from .Items import RiskOfRain2Item, item_table, junk_weights from .Locations import location_table, RiskOfRainLocation, base_location_table from .Rules import set_rules from BaseClasses import Region, Entrance, Item, MultiWorld -from .Options import ror2_options +from .Options import ror2_options, ror2_weights from ..AutoWorld import World client_version = 1 @@ -31,9 +31,22 @@ class RiskOfRainWorld(World): if self.world.start_with_revive[self.player].value: self.world.push_precollected(self.world.create_item("Dio's Best Friend", self.player)) + junk_pool ={ + "Item Scrap, Green": self.world.green_scrap[self.player].value, + "Item Scrap, Red": self.world.red_scrap[self.player].value, + "Item Scrap, Yellow": self.world.yellow_scrap[self.player].value, + "Item Scrap, White": self.world.white_scrap[self.player].value, + "Common Item": self.world.common_item[self.player].value, + "Uncommon Item": self.world.uncommon_item[self.player].value, + "Legendary Item": self.world.legendary_item[self.player].value, + "Boss Item": self.world.boss_item[self.player].value, + "Lunar Item": self.world.lunar_item[self.player].value, + "Equipment": self.world.equipment[self.player].value + } + + # Generate item pool itempool = [] - junk_pool = junk_weights.copy() # Add revive items for the player itempool += ["Dio's Best Friend"] * self.world.total_revivals[self.player] @@ -41,6 +54,7 @@ class RiskOfRainWorld(World): if not self.world.enable_lunar[self.player]: junk_pool.pop("Lunar Item") + # Fill remaining items with randomly generated junk itempool += self.world.random.choices(list(junk_pool.keys()), weights=list(junk_pool.values()), k=self.world.total_locations[self.player] - @@ -68,7 +82,7 @@ class RiskOfRainWorld(World): def create_item(self, name: str) -> Item: item_id = item_table[name] - item = RiskOfRainItem(name, True, item_id, self.player) + item = RiskOfRain2Item(name, True, item_id, self.player) return item @@ -81,12 +95,12 @@ def create_regions(world, player: int): ] world.get_entrance("Lobby", player).connect(world.get_region("Petrichor V", player)) - world.get_location("Level One", player).place_locked_item(RiskOfRainItem("Beat Level One", True, None, player)) - world.get_location("Level Two", player).place_locked_item(RiskOfRainItem("Beat Level Two", True, None, player)) - world.get_location("Level Three", player).place_locked_item(RiskOfRainItem("Beat Level Three", True, None, player)) - world.get_location("Level Four", player).place_locked_item(RiskOfRainItem("Beat Level Four", True, None, player)) - world.get_location("Level Five", player).place_locked_item(RiskOfRainItem("Beat Level Five", True, None, player)) - world.get_location("Victory", player).place_locked_item(RiskOfRainItem("Victory", True, None, player)) + world.get_location("Level One", player).place_locked_item(RiskOfRain2Item("Beat Level One", True, None, player)) + world.get_location("Level Two", player).place_locked_item(RiskOfRain2Item("Beat Level Two", True, None, player)) + world.get_location("Level Three", player).place_locked_item(RiskOfRain2Item("Beat Level Three", True, None, player)) + world.get_location("Level Four", player).place_locked_item(RiskOfRain2Item("Beat Level Four", True, None, player)) + world.get_location("Level Five", player).place_locked_item(RiskOfRain2Item("Beat Level Five", True, None, player)) + world.get_location("Victory", player).place_locked_item(RiskOfRain2Item("Victory", True, None, player)) def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): From 29ed40051dccd03837d9a29caebf1be0d9efd144 Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Mon, 6 Sep 2021 23:58:59 -0500 Subject: [PATCH 3/9] Added descriptions to all currently existing options. Please end me --- worlds/alttp/Options.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index 93225e05..4910245c 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -5,6 +5,7 @@ from Options import Choice, Range, Option, Toggle, DefaultOnToggle class Logic(Choice): + """Logic Rules used for item access.""" option_no_glitches = 0 option_minor_glitches = 1 option_overworld_glitches = 2 @@ -23,6 +24,7 @@ class Objective(Choice): class Goal(Choice): + """Goal to win.""" option_kill_ganon = 0 option_kill_ganon_and_gt_agahnim = 1 option_hand_in = 2 @@ -74,31 +76,44 @@ class Crystals(Range): class CrystalsTower(Crystals): + """Number of crystals required to open Ganon's Tower.""" default = 7 class CrystalsGanon(Crystals): + """Number of crystals required to harm Ganon.""" default = 7 class TriforcePieces(Range): + """Number of triforce pieces required to complete the goal.""" default = 30 range_start = 1 range_end = 90 class ShopItemSlots(Range): + """Amount of items placed in shops.""" range_start = 0 range_end = 30 class WorldState(Choice): + """Starting world state. Standard starts with the Princess Escape sequence. + Open starts with full world access. + Inverted starts with Link's house in the dark world and some other + locations moved around for this altered world.""" option_standard = 1 option_open = 0 option_inverted = 2 class Bosses(Choice): + """Bosses get shuffled around. Simple will keep the number of appearances of each boss vanilla + but shuffle them around. Therefor there will be two sets of Armos Knights, Lanmolas' and Moldorm. + Full does the same as Simple except the 3 duplicated bosses are chosen randomly. + Chaos chooses bosses entirely at random. Singularity will choose a random boss and place it in every + location it can. If there are locations it can't put it in a second boss will be chosen for those locations.""" option_vanilla = 0 option_simple = 1 option_full = 2 @@ -107,12 +122,16 @@ class Bosses(Choice): class Enemies(Choice): + """Enemies get shuffled around the game.""" option_vanilla = 0 option_shuffled = 1 option_chaos = 2 class Progressive(Choice): + """Determines if items that are usually progressive stay progressive. + For random, each category is grouped together then turned either progressive on or off. + The groups are swords, gloves, boomerangs, shields, and mail.""" displayname = "Progressive Items" option_off = 0 option_grouped_random = 1 @@ -140,30 +159,37 @@ class Palette(Choice): class OWPalette(Palette): + """The Palette definition for the Overworld.""" displayname = "Overworld Palette" class UWPalette(Palette): + """The Palette definition for the Underworld.""" displayname = "Underworld Palette" class HUDPalette(Palette): + """The Palette definition for the HUD.""" displayname = "Menu Palette" class SwordPalette(Palette): + """The Palette definition for Link's Sword.""" displayname = "Sword Palette" class ShieldPalette(Palette): + """The Palette definition for Link's Shield.""" displayname = "Shield Palette" class LinkPalette(Palette): + """The Palette definition for Link.""" displayname = "Link Palette" class HeartBeep(Choice): + """How fast or slow the heart beep at low health is.""" displayname = "Heart Beep Rate" option_normal = 0 option_double = 1 @@ -174,6 +200,7 @@ class HeartBeep(Choice): class HeartColor(Choice): + """The color of your hearts in the HUD.""" displayname = "Heart Color" option_red = 0 option_blue = 1 @@ -189,10 +216,12 @@ class HeartColor(Choice): class QuickSwap(DefaultOnToggle): + """Enable/Disable Quickswapping items with the L/R buttons.""" displayname = "L/R Quickswapping" class MenuSpeed(Choice): + """How fast relative to vanilla the menu screen appears and disappears.""" displayname = "Menu Speed" option_normal = 0 option_instant = 1, @@ -203,14 +232,17 @@ class MenuSpeed(Choice): class Music(DefaultOnToggle): + """Enable/Disable whether music plays in the game.""" displayname = "Play music" class ReduceFlashing(DefaultOnToggle): + """Reduces flashing of certain scenes.""" displayname = "Reduce Screen Flashes" class TriforceHud(Choice): + """Decides whether the HUD for Triforce hunt goal should appear.""" displayname = "Display Method for Triforce Hunt" option_normal = 0 option_hide_goal = 1 From 24802d64c75bb1a7ffadda17f2e90db4e99bf92e Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Tue, 7 Sep 2021 09:22:12 -0500 Subject: [PATCH 4/9] Reverted some changes --- worlds/ror2/Items.py | 2 +- worlds/ror2/Options.py | 6 ------ worlds/ror2/__init__.py | 12 ++++++------ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/worlds/ror2/Items.py b/worlds/ror2/Items.py index 0e993404..35992e1f 100644 --- a/worlds/ror2/Items.py +++ b/worlds/ror2/Items.py @@ -2,7 +2,7 @@ from BaseClasses import Item import typing -class RiskOfRain2Item(Item): +class RiskOfRainItem(Item): game: str = "Risk of Rain 2" # 37000 - 38000 diff --git a/worlds/ror2/Options.py b/worlds/ror2/Options.py index ae84a82f..f8b109b6 100644 --- a/worlds/ror2/Options.py +++ b/worlds/ror2/Options.py @@ -118,12 +118,6 @@ class Equipment(Range): default = 25 -class WeightPresets(Choice): - """Preset item weight options.""" - displayname = "Item Weight Preset" - option_default = 0 - - ror2_weights: typing.Dict[str, type(Option)] = { "green_scrap": GreenScrap, "red_scrap": RedScrap, diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index eff407a5..c3d2b7fc 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -95,12 +95,12 @@ def create_regions(world, player: int): ] world.get_entrance("Lobby", player).connect(world.get_region("Petrichor V", player)) - world.get_location("Level One", player).place_locked_item(RiskOfRain2Item("Beat Level One", True, None, player)) - world.get_location("Level Two", player).place_locked_item(RiskOfRain2Item("Beat Level Two", True, None, player)) - world.get_location("Level Three", player).place_locked_item(RiskOfRain2Item("Beat Level Three", True, None, player)) - world.get_location("Level Four", player).place_locked_item(RiskOfRain2Item("Beat Level Four", True, None, player)) - world.get_location("Level Five", player).place_locked_item(RiskOfRain2Item("Beat Level Five", True, None, player)) - world.get_location("Victory", player).place_locked_item(RiskOfRain2Item("Victory", True, None, player)) + world.get_location("Level One", player).place_locked_item(RiskOfRainItem("Beat Level One", True, None, player)) + world.get_location("Level Two", player).place_locked_item(RiskOfRainItem("Beat Level Two", True, None, player)) + world.get_location("Level Three", player).place_locked_item(RiskOfRainItem("Beat Level Three", True, None, player)) + world.get_location("Level Four", player).place_locked_item(RiskOfRainItem("Beat Level Four", True, None, player)) + world.get_location("Level Five", player).place_locked_item(RiskOfRainItem("Beat Level Five", True, None, player)) + world.get_location("Victory", player).place_locked_item(RiskOfRainItem("Victory", True, None, player)) def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): From 6c9293e4f65e8efc5f3388d219942ee2c3a24804 Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Tue, 7 Sep 2021 17:14:20 -0500 Subject: [PATCH 5/9] Added a dynamicallly loaded item weight pool with presets. --- worlds/ror2/Items.py | 122 +++++++++++++++++++++++++++++++++++++++- worlds/ror2/Options.py | 45 +++++++++++---- worlds/ror2/Rules.py | 3 +- worlds/ror2/__init__.py | 15 +++-- 4 files changed, 164 insertions(+), 21 deletions(-) diff --git a/worlds/ror2/Items.py b/worlds/ror2/Items.py index 35992e1f..104540d8 100644 --- a/worlds/ror2/Items.py +++ b/worlds/ror2/Items.py @@ -1,6 +1,6 @@ from BaseClasses import Item import typing - +from random import randint class RiskOfRainItem(Item): game: str = "Risk of Rain 2" @@ -26,7 +26,7 @@ item_table = { "Beat Level Five": None, } -junk_weights = { +default_weights = { "Item Scrap, Green": 16, "Item Scrap, Red": 4, "Item Scrap, Yellow": 1, @@ -36,7 +36,123 @@ junk_weights = { "Legendary Item": 8, "Boss Item": 4, "Lunar Item": 16, - "Equipment": 32, + "Equipment": 32 +} + +new_weights = { + "Item Scrap, Green": 15, + "Item Scrap, Red": 5, + "Item Scrap, Yellow": 1, + "Item Scrap, White": 30, + "Common Item": 75, + "Uncommon Item": 40, + "Legendary Item": 10, + "Boss Item": 5, + "Lunar Item": 15, + "Equipment": 25 +} + +uncommon_weights = { + "Item Scrap, Green": 15, + "Item Scrap, Red": 5, + "Item Scrap, Yellow": 1, + "Item Scrap, White": 30, + "Common Item": 45, + "Uncommon Item": 100, + "Legendary Item": 10, + "Boss Item": 5, + "Lunar Item": 15, + "Equipment": 25 +} + +legendary_weights = { + "Item Scrap, Green": 15, + "Item Scrap, Red": 5, + "Item Scrap, Yellow": 1, + "Item Scrap, White": 30, + "Common Item": 50, + "Uncommon Item": 25, + "Legendary Item": 100, + "Boss Item": 5, + "Lunar Item": 15, + "Equipment": 25 +} + +lunartic_weights = { + "Item Scrap, Green": 0, + "Item Scrap, Red": 0, + "Item Scrap, Yellow": 0, + "Item Scrap, White": 0, + "Common Item": 0, + "Uncommon Item": 0, + "Legendary Item": 0, + "Boss Item": 0, + "Lunar Item": 100, + "Equipment": 0 +} + +no_scraps_weights = { + "Item Scrap, Green": 0, + "Item Scrap, Red": 0, + "Item Scrap, Yellow": 0, + "Item Scrap, White": 0, + "Common Item": 80, + "Uncommon Item": 30, + "Legendary Item": 15, + "Boss Item": 5, + "Lunar Item": 10, + "Equipment": 25 +} + +even_weights = { + "Item Scrap, Green": 1, + "Item Scrap, Red": 1, + "Item Scrap, Yellow": 1, + "Item Scrap, White": 1, + "Common Item": 1, + "Uncommon Item": 1, + "Legendary Item": 1, + "Boss Item": 1, + "Lunar Item": 1, + "Equipment": 1 +} + +chaos_weights = { + "Item Scrap, Green": randint(0, 100), + "Item Scrap, Red": randint(0, 100), + "Item Scrap, Yellow": randint(0, 80), + "Item Scrap, White": randint(0, 100), + "Common Item": randint(0, 100), + "Uncommon Item": randint(0, 70), + "Legendary Item": randint(0, 25), + "Boss Item": randint(0, 10), + "Lunar Item": randint(0, 40), + "Equipment": randint(0, 40) +} + +scraps_only_weights = { + "Item Scrap, Green": 80, + "Item Scrap, Red": 40, + "Item Scrap, Yellow": 10, + "Item Scrap, White": 100, + "Common Item": 0, + "Uncommon Item": 0, + "Legendary Item": 0, + "Boss Item": 0, + "Lunar Item": 0, + "Equipment": 0 +} + +item_pool_weights: typing.Dict[int, typing.Dict[str, int]] = { + 0: default_weights, + 1: new_weights, + 2: uncommon_weights, + 3: legendary_weights, + 4: lunartic_weights, + 5: chaos_weights, + 6: no_scraps_weights, + 7: even_weights, + 8: scraps_only_weights } lookup_id_to_name: typing.Dict[int, str] = {id: name for name, id in item_table.items() if id} diff --git a/worlds/ror2/Options.py b/worlds/ror2/Options.py index f8b109b6..2af4ca75 100644 --- a/worlds/ror2/Options.py +++ b/worlds/ror2/Options.py @@ -1,5 +1,5 @@ import typing -from Options import Option, DefaultOnToggle, Range, OptionList +from Options import Option, DefaultOnToggle, Range, Choice class TotalLocations(Range): @@ -7,7 +7,7 @@ class TotalLocations(Range): displayname = "Total Locations" range_start = 10 range_end = 50 - default = 15 + default = 20 class TotalRevivals(Range): @@ -25,7 +25,7 @@ class ItemPickupStep(Range): displayname = "Item Pickup Step" range_start = 0 range_end = 5 - default = 1 + default = 2 class AllowLunarItems(DefaultOnToggle): @@ -43,7 +43,7 @@ class GreenScrap(Range): displayname = "Green Scraps" range_start = 0 range_end = 100 - default = 15 + default = 16 class RedScrap(Range): @@ -51,7 +51,7 @@ class RedScrap(Range): displayname = "Red Scraps" range_start = 0 range_end = 100 - default = 5 + default = 4 class YellowScrap(Range): @@ -67,7 +67,7 @@ class WhiteScrap(Range): displayname = "White Scraps" range_start = 0 range_end = 100 - default = 30 + default = 32 class CommonItem(Range): @@ -75,7 +75,7 @@ class CommonItem(Range): displayname = "Common Items" range_start = 0 range_end = 100 - default = 75 + default = 64 class UncommonItem(Range): @@ -83,7 +83,7 @@ class UncommonItem(Range): displayname = "Uncommon Items" range_start = 0 range_end = 100 - default = 40 + default = 32 class LegendaryItem(Range): @@ -91,7 +91,7 @@ class LegendaryItem(Range): displayname = "Legendary Items" range_start = 0 range_end = 100 - default = 10 + default = 8 class BossItem(Range): @@ -99,7 +99,7 @@ class BossItem(Range): displayname = "Boss Items" range_start = 0 range_end = 100 - default = 5 + default = 4 class LunarItem(Range): @@ -107,7 +107,7 @@ class LunarItem(Range): displayname = "Lunar Items" range_start = 0 range_end = 100 - default = 15 + default = 16 class Equipment(Range): @@ -115,9 +115,28 @@ class Equipment(Range): displayname = "Equipment" range_start = 0 range_end = 100 - default = 25 + default = 32 +class ItemPoolPresetToggle(DefaultOnToggle): + """Will use the item weight presets when set to true, otherwise will use the custom set item pool weights.""" + displayname = "Item Weight Presets" + +class ItemWeights(Choice): + """Preset choices for determining the weights of the item pool. + Only used if custom weights are unmodified or deleted.""" + displayname = "Item Weights" + option_default = 0 + option_new = 1 + option_uncommon = 2 + option_legendary = 3 + option_lunartic = 4 + option_chaos = 5 + option_no_scraps = 6 + option_even = 7 + option_scraps_only = 8 + +#define a dictionary for the weights of the generated item pool. ror2_weights: typing.Dict[str, type(Option)] = { "green_scrap": GreenScrap, "red_scrap": RedScrap, @@ -137,5 +156,7 @@ ror2_options: typing.Dict[str, type(Option)] = { "start_with_revive": StartWithRevive, "item_pickup_step": ItemPickupStep, "enable_lunar": AllowLunarItems, + "item_weights": ItemWeights, + "item_pool_presets": ItemPoolPresetToggle, **ror2_weights } \ No newline at end of file diff --git a/worlds/ror2/Rules.py b/worlds/ror2/Rules.py index c1992be5..3653f047 100644 --- a/worlds/ror2/Rules.py +++ b/worlds/ror2/Rules.py @@ -6,7 +6,8 @@ from ..generic.Rules import set_rule class RiskOfRainLogic(LogicMixin): def _ror_has_items(self, player: int, amount: int) -> bool: count: int = self.item_count("Common Item", player) + self.item_count("Uncommon Item", player) + \ - self.item_count("Legendary Item", player) + self.item_count("Boss Item", player) + self.item_count("Legendary Item", player) + self.item_count("Boss Item", player) + \ + self.item_count("Lunar Item", player) + self.item_count("Equipment", player) return count >= amount diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index c3d2b7fc..394cdbe0 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -1,10 +1,10 @@ import string -from .Items import RiskOfRain2Item, item_table, junk_weights +from .Items import RiskOfRainItem, item_table, item_pool_weights from .Locations import location_table, RiskOfRainLocation, base_location_table from .Rules import set_rules from BaseClasses import Region, Entrance, Item, MultiWorld -from .Options import ror2_options, ror2_weights +from .Options import ror2_options from ..AutoWorld import World client_version = 1 @@ -31,7 +31,8 @@ class RiskOfRainWorld(World): if self.world.start_with_revive[self.player].value: self.world.push_precollected(self.world.create_item("Dio's Best Friend", self.player)) - junk_pool ={ + # fills junk_pool with yaml weight values + junk_pool = { "Item Scrap, Green": self.world.green_scrap[self.player].value, "Item Scrap, Red": self.world.red_scrap[self.player].value, "Item Scrap, Yellow": self.world.yellow_scrap[self.player].value, @@ -44,6 +45,10 @@ class RiskOfRainWorld(World): "Equipment": self.world.equipment[self.player].value } + # if presets are enabled generate junk_pool from the selected preset + if self.world.item_pool_presets[self.player].value: + pool_option = self.world.item_weights[self.player].value + junk_pool = item_pool_weights[pool_option] # Generate item pool itempool = [] @@ -58,7 +63,7 @@ class RiskOfRainWorld(World): # Fill remaining items with randomly generated junk itempool += self.world.random.choices(list(junk_pool.keys()), weights=list(junk_pool.values()), k=self.world.total_locations[self.player] - - self.world.total_revivals[self.player]) + self.world.total_revivals[self.player] - self.world.start_with_revive[self.player].value) # Convert itempool into real items itempool = [item for item in map(lambda name: self.create_item(name), itempool)] @@ -82,7 +87,7 @@ class RiskOfRainWorld(World): def create_item(self, name: str) -> Item: item_id = item_table[name] - item = RiskOfRain2Item(name, True, item_id, self.player) + item = RiskOfRainItem(name, True, item_id, self.player) return item From 062615b6b1f9171b7e37320a2ccfe34e789073f4 Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Tue, 7 Sep 2021 17:24:25 -0500 Subject: [PATCH 6/9] Revert "Added descriptions to all currently existing options. Please end me" This reverts commit 29ed40051dccd03837d9a29caebf1be0d9efd144. --- worlds/alttp/Options.py | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index 4910245c..93225e05 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -5,7 +5,6 @@ from Options import Choice, Range, Option, Toggle, DefaultOnToggle class Logic(Choice): - """Logic Rules used for item access.""" option_no_glitches = 0 option_minor_glitches = 1 option_overworld_glitches = 2 @@ -24,7 +23,6 @@ class Objective(Choice): class Goal(Choice): - """Goal to win.""" option_kill_ganon = 0 option_kill_ganon_and_gt_agahnim = 1 option_hand_in = 2 @@ -76,44 +74,31 @@ class Crystals(Range): class CrystalsTower(Crystals): - """Number of crystals required to open Ganon's Tower.""" default = 7 class CrystalsGanon(Crystals): - """Number of crystals required to harm Ganon.""" default = 7 class TriforcePieces(Range): - """Number of triforce pieces required to complete the goal.""" default = 30 range_start = 1 range_end = 90 class ShopItemSlots(Range): - """Amount of items placed in shops.""" range_start = 0 range_end = 30 class WorldState(Choice): - """Starting world state. Standard starts with the Princess Escape sequence. - Open starts with full world access. - Inverted starts with Link's house in the dark world and some other - locations moved around for this altered world.""" option_standard = 1 option_open = 0 option_inverted = 2 class Bosses(Choice): - """Bosses get shuffled around. Simple will keep the number of appearances of each boss vanilla - but shuffle them around. Therefor there will be two sets of Armos Knights, Lanmolas' and Moldorm. - Full does the same as Simple except the 3 duplicated bosses are chosen randomly. - Chaos chooses bosses entirely at random. Singularity will choose a random boss and place it in every - location it can. If there are locations it can't put it in a second boss will be chosen for those locations.""" option_vanilla = 0 option_simple = 1 option_full = 2 @@ -122,16 +107,12 @@ class Bosses(Choice): class Enemies(Choice): - """Enemies get shuffled around the game.""" option_vanilla = 0 option_shuffled = 1 option_chaos = 2 class Progressive(Choice): - """Determines if items that are usually progressive stay progressive. - For random, each category is grouped together then turned either progressive on or off. - The groups are swords, gloves, boomerangs, shields, and mail.""" displayname = "Progressive Items" option_off = 0 option_grouped_random = 1 @@ -159,37 +140,30 @@ class Palette(Choice): class OWPalette(Palette): - """The Palette definition for the Overworld.""" displayname = "Overworld Palette" class UWPalette(Palette): - """The Palette definition for the Underworld.""" displayname = "Underworld Palette" class HUDPalette(Palette): - """The Palette definition for the HUD.""" displayname = "Menu Palette" class SwordPalette(Palette): - """The Palette definition for Link's Sword.""" displayname = "Sword Palette" class ShieldPalette(Palette): - """The Palette definition for Link's Shield.""" displayname = "Shield Palette" class LinkPalette(Palette): - """The Palette definition for Link.""" displayname = "Link Palette" class HeartBeep(Choice): - """How fast or slow the heart beep at low health is.""" displayname = "Heart Beep Rate" option_normal = 0 option_double = 1 @@ -200,7 +174,6 @@ class HeartBeep(Choice): class HeartColor(Choice): - """The color of your hearts in the HUD.""" displayname = "Heart Color" option_red = 0 option_blue = 1 @@ -216,12 +189,10 @@ class HeartColor(Choice): class QuickSwap(DefaultOnToggle): - """Enable/Disable Quickswapping items with the L/R buttons.""" displayname = "L/R Quickswapping" class MenuSpeed(Choice): - """How fast relative to vanilla the menu screen appears and disappears.""" displayname = "Menu Speed" option_normal = 0 option_instant = 1, @@ -232,17 +203,14 @@ class MenuSpeed(Choice): class Music(DefaultOnToggle): - """Enable/Disable whether music plays in the game.""" displayname = "Play music" class ReduceFlashing(DefaultOnToggle): - """Reduces flashing of certain scenes.""" displayname = "Reduce Screen Flashes" class TriforceHud(Choice): - """Decides whether the HUD for Triforce hunt goal should appear.""" displayname = "Display Method for Triforce Hunt" option_normal = 0 option_hide_goal = 1 From bd4f24844be1a8f597bbb51ac99de5af5ca7e705 Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Tue, 7 Sep 2021 17:50:43 -0500 Subject: [PATCH 7/9] Update documentation for new options. --- .../static/assets/tutorial/ror2/setup_en.md | 30 ++++++++++++++++++- worlds/ror2/Options.py | 9 +++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/WebHostLib/static/assets/tutorial/ror2/setup_en.md b/WebHostLib/static/assets/tutorial/ror2/setup_en.md index 6dfdc5ed..df3c6378 100644 --- a/WebHostLib/static/assets/tutorial/ror2/setup_en.md +++ b/WebHostLib/static/assets/tutorial/ror2/setup_en.md @@ -46,6 +46,28 @@ Risk of Rain 2: start_with_revive: true item_pickup_step: 1 enable_lunar: true + item_weights: + default: 50 + new: 0 + uncommon: 0 + legendary: 0 + lunartic: 0 + chaos: 0 + no_scraps: 0 + even: 0 + scraps_only: 0 + item_pool_presets: true + # custom item weights + green_scrap: 16 + red_scrap: 4 + yellow_scrap: 1 + white_scrap: 32 + common_item: 64 + uncommon_item: 32 + legendary_item: 8 + boss_item: 4 + lunar_item: 16 + equipment: 32 ``` | Name | Description | Allowed values | @@ -55,6 +77,10 @@ Risk of Rain 2: | start_with_revive | Starts the player off with a `Dio's Best Friend`. Functionally equivalent to putting a `Dio's Best Friend` in your `starting_inventory`. | true/false | | item_pickup_step | The number of item pickups which you are allowed to claim before they become an Archipelago location check. | 0 - 5 | | enable_lunar | Allows for lunar items to be shuffled into the item pool on behalf of the Risk of Rain player. | true/false | +| item_weights | Each option here is a preset item weight that can be used to customize your generate item pool with certain settings. | default, new, uncommon, legendary, lunartic, chaos, no_scraps, even, scraps_only | +| item_pool_presets | A simple toggle to determine whether the item_weight presets are used or the custom item pool as defined below | true/false | +| custom item weights | Each defined item here is a single item in the pool that will have a weight against the other items when the item pool gets generated. These values can be modified to adjust how frequently certain items appear | 0-100| + Using the example YAML above: the Risk of Rain 2 player will have 15 total items which they can pick up for other players. (total_locations = 15) @@ -66,4 +92,6 @@ They will have 4 of the items which other players can grant them replaced with ` The player will also start with a `Dio's Best Friend`. (start_with_revive = true) -The player will have lunar items shuffled into the item pool on their behalf. (enable_lunar = true) \ No newline at end of file +The player will have lunar items shuffled into the item pool on their behalf. (enable_lunar = true) + +The player will have the default preset generated item pool with the custom item weights being ignored. (item_weights: default and item_pool_presets: true) diff --git a/worlds/ror2/Options.py b/worlds/ror2/Options.py index 2af4ca75..1a011706 100644 --- a/worlds/ror2/Options.py +++ b/worlds/ror2/Options.py @@ -124,7 +124,14 @@ class ItemPoolPresetToggle(DefaultOnToggle): class ItemWeights(Choice): """Preset choices for determining the weights of the item pool. - Only used if custom weights are unmodified or deleted.""" + New is a test for a potential adjustment to the default weights. + Uncommon puts a large number of uncommon items in the pool. + Legendary puts a large number of legendary items in the pool. + lunartic makes everything a lunar item. + chaos generates the pool completely at random with rarer items having a slight cap to prevent this option being too easy. + no_scraps removes all scrap items from the item pool. + even generates the item pool with every item having an even weight. + scraps_only removes all non scrap items from the item pool.""" displayname = "Item Weights" option_default = 0 option_new = 1 From 05dac999a8f4c9abc3969c763ec8a4e3b252cab4 Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Wed, 8 Sep 2021 12:29:29 -0500 Subject: [PATCH 8/9] Fixed chaos item weight preset so it gets generated per world. --- worlds/ror2/Items.py | 14 -------------- worlds/ror2/__init__.py | 18 +++++++++++++++++- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/worlds/ror2/Items.py b/worlds/ror2/Items.py index 104540d8..3345fd6d 100644 --- a/worlds/ror2/Items.py +++ b/worlds/ror2/Items.py @@ -117,19 +117,6 @@ even_weights = { "Equipment": 1 } -chaos_weights = { - "Item Scrap, Green": randint(0, 100), - "Item Scrap, Red": randint(0, 100), - "Item Scrap, Yellow": randint(0, 80), - "Item Scrap, White": randint(0, 100), - "Common Item": randint(0, 100), - "Uncommon Item": randint(0, 70), - "Legendary Item": randint(0, 25), - "Boss Item": randint(0, 10), - "Lunar Item": randint(0, 40), - "Equipment": randint(0, 40) -} - scraps_only_weights = { "Item Scrap, Green": 80, "Item Scrap, Red": 40, @@ -149,7 +136,6 @@ item_pool_weights: typing.Dict[int, typing.Dict[str, int]] = { 2: uncommon_weights, 3: legendary_weights, 4: lunartic_weights, - 5: chaos_weights, 6: no_scraps_weights, 7: even_weights, 8: scraps_only_weights diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index 394cdbe0..da2fe244 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -6,6 +6,7 @@ from .Rules import set_rules from BaseClasses import Region, Entrance, Item, MultiWorld from .Options import ror2_options from ..AutoWorld import World +from random import randint client_version = 1 @@ -48,7 +49,22 @@ class RiskOfRainWorld(World): # if presets are enabled generate junk_pool from the selected preset if self.world.item_pool_presets[self.player].value: pool_option = self.world.item_weights[self.player].value - junk_pool = item_pool_weights[pool_option] + # generate chaos weights + if pool_option == 5: + junk_pool = { + "item Scrap, Green": randint(0, 100), + "Item Scrap, Red": randint(0, 100), + "Item Scrap, Yellow": randint(0, 100), + "Item Scrap, White": randint(0, 100), + "Common Item": randint(0, 100), + "Uncommon Item": randint(0, 70), + "Legendary Item": randint(0, 25), + "Boss Item": randint(0, 10), + "Lunar Item": randint(0, 40), + "Equipment": randint(0, 40) + } + else: + junk_pool = item_pool_weights[pool_option] # Generate item pool itempool = [] From e9beb21a98f9a5fe478f394eac4ab58f4341af08 Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Wed, 8 Sep 2021 13:53:06 -0500 Subject: [PATCH 9/9] Adjusted chaos preset weights to be a bit more chaotic and optimized item pool generation a bit. --- worlds/ror2/__init__.py | 44 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index da2fe244..a0f45346 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -6,7 +6,6 @@ from .Rules import set_rules from BaseClasses import Region, Entrance, Item, MultiWorld from .Options import ror2_options from ..AutoWorld import World -from random import randint client_version = 1 @@ -32,8 +31,27 @@ class RiskOfRainWorld(World): if self.world.start_with_revive[self.player].value: self.world.push_precollected(self.world.create_item("Dio's Best Friend", self.player)) - # fills junk_pool with yaml weight values - junk_pool = { + # if presets are enabled generate junk_pool from the selected preset + if self.world.item_pool_presets[self.player].value: + pool_option = self.world.item_weights[self.player].value + # generate chaos weights if the preset is chosen + if pool_option == 5: + junk_pool = { + "Item Scrap, Green": self.world.random.randint(0, 100), + "Item Scrap, Red": self.world.random.randint(0, 100), + "Item Scrap, Yellow": self.world.random.randint(0, 100), + "Item Scrap, White": self.world.random.randint(0, 100), + "Common Item": self.world.random.randint(0, 100), + "Uncommon Item": self.world.random.randint(0, 70), + "Legendary Item": self.world.random.randint(0, 45), + "Boss Item": self.world.random.randint(0, 30), + "Lunar Item": self.world.random.randint(0, 60), + "Equipment": self.world.random.randint(0, 50) + } + else: + junk_pool = item_pool_weights[pool_option] + else:# generate junk pool from user created presets + junk_pool = { "Item Scrap, Green": self.world.green_scrap[self.player].value, "Item Scrap, Red": self.world.red_scrap[self.player].value, "Item Scrap, Yellow": self.world.yellow_scrap[self.player].value, @@ -46,26 +64,6 @@ class RiskOfRainWorld(World): "Equipment": self.world.equipment[self.player].value } - # if presets are enabled generate junk_pool from the selected preset - if self.world.item_pool_presets[self.player].value: - pool_option = self.world.item_weights[self.player].value - # generate chaos weights - if pool_option == 5: - junk_pool = { - "item Scrap, Green": randint(0, 100), - "Item Scrap, Red": randint(0, 100), - "Item Scrap, Yellow": randint(0, 100), - "Item Scrap, White": randint(0, 100), - "Common Item": randint(0, 100), - "Uncommon Item": randint(0, 70), - "Legendary Item": randint(0, 25), - "Boss Item": randint(0, 10), - "Lunar Item": randint(0, 40), - "Equipment": randint(0, 40) - } - else: - junk_pool = item_pool_weights[pool_option] - # Generate item pool itempool = []