Undertale: Fixes a major logic bug, and updates Undertale to use the new Options API (#3528)
* Updated the options definitions to the new api * Fixed the wrong base class being used for UndertaleOptions * Undertale: Added get_filler_item_name to Undertale, changed multiworld.per_slot_randoms to self.random, removed some unused imports in options.py, and fixed rules.py still using state.multiworld instead of world.options, and simplified the set_completion_rules function in rules.py * Undertale: Fixed it trying to add strings to the finished item pool * fixed 1000g item not being in the key items pool for Undertale * Removed ".copy()" for the junk_weights, reformatted the requested lines to have less new lines, and changed "itempool += [self.create_filler()]" to "itempool.append(self.create_filler())"
This commit is contained in:
		| @@ -105,7 +105,6 @@ item_table = { | ||||
| non_key_items = { | ||||
|     "Butterscotch Pie": 1, | ||||
|     "500G": 2, | ||||
|     "1000G": 2, | ||||
|     "Face Steak": 1, | ||||
|     "Snowman Piece": 1, | ||||
|     "Instant Noodles": 1, | ||||
| @@ -147,6 +146,7 @@ plot_items = { | ||||
| key_items = { | ||||
|     "Complete Skeleton": 1, | ||||
|     "Fish": 1, | ||||
|     "1000G": 2, | ||||
|     "DT Extractor": 1, | ||||
|     "Mettaton Plush": 1, | ||||
|     "Punch Card": 3, | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import typing | ||||
| from Options import Choice, Option, Toggle, Range | ||||
| from Options import Choice, Toggle, Range, PerGameCommonOptions | ||||
| from dataclasses import dataclass | ||||
|  | ||||
|  | ||||
| class RouteRequired(Choice): | ||||
| @@ -86,17 +86,17 @@ class RandoBattleOptions(Toggle): | ||||
|     default = 0 | ||||
|  | ||||
|  | ||||
| undertale_options: typing.Dict[str, type(Option)] = { | ||||
|     "route_required":                           RouteRequired, | ||||
|     "starting_area":                            StartingArea, | ||||
|     "key_hunt":                                 KeyHunt, | ||||
|     "key_pieces":                               KeyPieces, | ||||
|     "rando_love":                               RandomizeLove, | ||||
|     "rando_stats":                              RandomizeStats, | ||||
|     "temy_include":                             IncludeTemy, | ||||
|     "no_equips":                                NoEquips, | ||||
|     "only_flakes":                              OnlyFlakes, | ||||
|     "prog_armor":                               ProgressiveArmor, | ||||
|     "prog_weapons":                             ProgressiveWeapons, | ||||
|     "rando_item_button":                     RandoBattleOptions, | ||||
| } | ||||
| @dataclass | ||||
| class UndertaleOptions(PerGameCommonOptions): | ||||
|     route_required:                           RouteRequired | ||||
|     starting_area:                            StartingArea | ||||
|     key_hunt:                                 KeyHunt | ||||
|     key_pieces:                               KeyPieces | ||||
|     rando_love:                               RandomizeLove | ||||
|     rando_stats:                              RandomizeStats | ||||
|     temy_include:                             IncludeTemy | ||||
|     no_equips:                                NoEquips | ||||
|     only_flakes:                              OnlyFlakes | ||||
|     prog_armor:                               ProgressiveArmor | ||||
|     prog_weapons:                             ProgressiveWeapons | ||||
|     rando_item_button:                        RandoBattleOptions | ||||
|   | ||||
| @@ -1,18 +1,22 @@ | ||||
| from worlds.generic.Rules import set_rule, add_rule, add_item_rule | ||||
| from BaseClasses import MultiWorld, CollectionState | ||||
| from worlds.generic.Rules import set_rule, add_rule | ||||
| from BaseClasses import CollectionState | ||||
| from typing import TYPE_CHECKING | ||||
|  | ||||
| if TYPE_CHECKING: | ||||
|     from . import UndertaleWorld | ||||
|  | ||||
|  | ||||
| def _undertale_is_route(state: CollectionState, player: int, route: int): | ||||
| def _undertale_is_route(world: "UndertaleWorld", route: int): | ||||
|     if route == 3: | ||||
|         return state.multiworld.route_required[player].current_key == "all_routes" | ||||
|     if state.multiworld.route_required[player].current_key == "all_routes": | ||||
|         return world.options.route_required.current_key == "all_routes" | ||||
|     if world.options.route_required.current_key == "all_routes": | ||||
|         return True | ||||
|     if route == 0: | ||||
|         return state.multiworld.route_required[player].current_key == "neutral" | ||||
|         return world.options.route_required.current_key == "neutral" | ||||
|     if route == 1: | ||||
|         return state.multiworld.route_required[player].current_key == "pacifist" | ||||
|         return world.options.route_required.current_key == "pacifist" | ||||
|     if route == 2: | ||||
|         return state.multiworld.route_required[player].current_key == "genocide" | ||||
|         return world.options.route_required.current_key == "genocide" | ||||
|     return False | ||||
|  | ||||
|  | ||||
| @@ -27,7 +31,7 @@ def _undertale_has_plot(state: CollectionState, player: int, item: str): | ||||
|         return state.has("DT Extractor", player) | ||||
|  | ||||
|  | ||||
| def _undertale_can_level(state: CollectionState, exp: int, lvl: int): | ||||
| def _undertale_can_level(exp: int, lvl: int): | ||||
|     if exp >= 10 and lvl == 1: | ||||
|         return True | ||||
|     elif exp >= 30 and lvl == 2: | ||||
| @@ -70,7 +74,9 @@ def _undertale_can_level(state: CollectionState, exp: int, lvl: int): | ||||
|  | ||||
|  | ||||
| # Sets rules on entrances and advancements that are always applied | ||||
| def set_rules(multiworld: MultiWorld, player: int): | ||||
| def set_rules(world: "UndertaleWorld"): | ||||
|     player = world.player | ||||
|     multiworld = world.multiworld | ||||
|     set_rule(multiworld.get_entrance("Ruins Hub", player), lambda state: state.has("Ruins Key", player)) | ||||
|     set_rule(multiworld.get_entrance("Snowdin Hub", player), lambda state: state.has("Snowdin Key", player)) | ||||
|     set_rule(multiworld.get_entrance("Waterfall Hub", player), lambda state: state.has("Waterfall Key", player)) | ||||
| @@ -81,16 +87,16 @@ def set_rules(multiworld: MultiWorld, player: int): | ||||
|     set_rule(multiworld.get_entrance("New Home Exit", player), | ||||
|              lambda state: (state.has("Left Home Key", player) and | ||||
|                             state.has("Right Home Key", player)) or | ||||
|                            state.has("Key Piece", player, state.multiworld.key_pieces[player].value)) | ||||
|     if _undertale_is_route(multiworld.state, player, 1): | ||||
|                            state.has("Key Piece", player, world.options.key_pieces.value)) | ||||
|     if _undertale_is_route(world, 1): | ||||
|         set_rule(multiworld.get_entrance("Papyrus\" Home Entrance", player), | ||||
|                  lambda state: _undertale_has_plot(state, player, "Complete Skeleton")) | ||||
|         set_rule(multiworld.get_entrance("Undyne\"s Home Entrance", player), | ||||
|                  lambda state: _undertale_has_plot(state, player, "Fish") and state.has("Papyrus Date", player)) | ||||
|         set_rule(multiworld.get_entrance("Lab Elevator", player), | ||||
|                  lambda state: state.has("Alphys Date", player) and state.has("DT Extractor", player) and | ||||
|                                 ((state.has("Left Home Key", player) and state.has("Right Home Key", player)) or | ||||
|                                 state.has("Key Piece", player, state.multiworld.key_pieces[player].value))) | ||||
|                                ((state.has("Left Home Key", player) and state.has("Right Home Key", player)) or | ||||
|                                  state.has("Key Piece", player, world.options.key_pieces.value))) | ||||
|         set_rule(multiworld.get_location("Alphys Date", player), | ||||
|                  lambda state: state.can_reach("New Home", "Region", player) and state.has("Undyne Letter EX", player) | ||||
|                                and state.has("Undyne Date", player)) | ||||
| @@ -101,7 +107,10 @@ def set_rules(multiworld: MultiWorld, player: int): | ||||
|         set_rule(multiworld.get_location("True Lab Plot", player), | ||||
|                  lambda state: state.can_reach("New Home", "Region", player) | ||||
|                                and state.can_reach("Letter Quest", "Location", player) | ||||
|                                and state.can_reach("Alphys Date", "Location", player)) | ||||
|                                and state.can_reach("Alphys Date", "Location", player) | ||||
|                                and ((state.has("Left Home Key", player) and | ||||
|                                     state.has("Right Home Key", player)) or | ||||
|                                     state.has("Key Piece", player, world.options.key_pieces.value))) | ||||
|         set_rule(multiworld.get_location("Chisps Machine", player), | ||||
|                  lambda state: state.can_reach("True Lab", "Region", player)) | ||||
|         set_rule(multiworld.get_location("Dog Sale 1", player), | ||||
| @@ -118,7 +127,7 @@ def set_rules(multiworld: MultiWorld, player: int): | ||||
|                  lambda state: state.can_reach("News Show", "Region", player) and state.has("Hot Dog...?", player, 1)) | ||||
|         set_rule(multiworld.get_location("Letter Quest", player), | ||||
|                  lambda state: state.can_reach("Last Corridor", "Region", player) and state.has("Undyne Date", player)) | ||||
|     if (not _undertale_is_route(multiworld.state, player, 2)) or _undertale_is_route(multiworld.state, player, 3): | ||||
|     if (not _undertale_is_route(world, 2)) or _undertale_is_route(world, 3): | ||||
|         set_rule(multiworld.get_location("Nicecream Punch Card", player), | ||||
|                  lambda state: state.has("Punch Card", player, 3) and state.can_reach("Waterfall", "Region", player)) | ||||
|         set_rule(multiworld.get_location("Nicecream Snowdin", player), | ||||
| @@ -129,26 +138,26 @@ def set_rules(multiworld: MultiWorld, player: int): | ||||
|                  lambda state: state.can_reach("Waterfall", "Region", player)) | ||||
|         set_rule(multiworld.get_location("Apron Hidden", player), | ||||
|                  lambda state: state.can_reach("Cooking Show", "Region", player)) | ||||
|     if _undertale_is_route(multiworld.state, player, 2) and \ | ||||
|             (bool(multiworld.rando_love[player].value) or bool(multiworld.rando_stats[player].value)): | ||||
|     if _undertale_is_route(world, 2) and \ | ||||
|             (bool(world.options.rando_love.value) or bool(world.options.rando_stats.value)): | ||||
|         maxlv = 1 | ||||
|         exp = 190 | ||||
|         curarea = "Old Home" | ||||
|  | ||||
|         while maxlv < 20: | ||||
|             maxlv += 1 | ||||
|             if multiworld.rando_love[player]: | ||||
|             if world.options.rando_love: | ||||
|                 set_rule(multiworld.get_location(("LOVE " + str(maxlv)), player), lambda state: False) | ||||
|             if multiworld.rando_stats[player]: | ||||
|             if world.options.rando_stats: | ||||
|                 set_rule(multiworld.get_location(("ATK "+str(maxlv)), player), lambda state: False) | ||||
|                 set_rule(multiworld.get_location(("HP "+str(maxlv)), player), lambda state: False) | ||||
|                 if maxlv in {5, 9, 13, 17}: | ||||
|                     set_rule(multiworld.get_location(("DEF "+str(maxlv)), player), lambda state: False) | ||||
|         maxlv = 1 | ||||
|         while maxlv < 20: | ||||
|             while _undertale_can_level(multiworld.state, exp, maxlv): | ||||
|             while _undertale_can_level(exp, maxlv): | ||||
|                 maxlv += 1 | ||||
|                 if multiworld.rando_stats[player]: | ||||
|                 if world.options.rando_stats: | ||||
|                     if curarea == "Old Home": | ||||
|                         add_rule(multiworld.get_location(("ATK "+str(maxlv)), player), | ||||
|                                  lambda state: (state.can_reach("Old Home", "Region", player)), combine="or") | ||||
| @@ -197,7 +206,7 @@ def set_rules(multiworld: MultiWorld, player: int): | ||||
|                         if maxlv == 5 or maxlv == 9 or maxlv == 13 or maxlv == 17: | ||||
|                             add_rule(multiworld.get_location(("DEF "+str(maxlv)), player), | ||||
|                                      lambda state: (state.can_reach("New Home Exit", "Entrance", player)), combine="or") | ||||
|                 if multiworld.rando_love[player]: | ||||
|                 if world.options.rando_love: | ||||
|                     if curarea == "Old Home": | ||||
|                         add_rule(multiworld.get_location(("LOVE "+str(maxlv)), player), | ||||
|                                  lambda state: (state.can_reach("Old Home", "Region", player)), combine="or") | ||||
| @@ -307,9 +316,9 @@ def set_rules(multiworld: MultiWorld, player: int): | ||||
|  | ||||
|  | ||||
| # Sets rules on completion condition | ||||
| def set_completion_rules(multiworld: MultiWorld, player: int): | ||||
|     completion_requirements = lambda state: state.can_reach("Barrier", "Region", player) | ||||
|     if _undertale_is_route(multiworld.state, player, 1): | ||||
|         completion_requirements = lambda state: state.can_reach("True Lab", "Region", player) | ||||
|  | ||||
|     multiworld.completion_condition[player] = lambda state: completion_requirements(state) | ||||
| def set_completion_rules(world: "UndertaleWorld"): | ||||
|     player = world.player | ||||
|     multiworld = world.multiworld | ||||
|     multiworld.completion_condition[player] = lambda state: state.can_reach("Barrier", "Region", player) | ||||
|     if _undertale_is_route(world, 1): | ||||
|         multiworld.completion_condition[player] = lambda state: state.can_reach("True Lab", "Region", player) | ||||
|   | ||||
| @@ -5,9 +5,9 @@ from .Regions import undertale_regions, link_undertale_areas | ||||
| from .Rules import set_rules, set_completion_rules | ||||
| from worlds.generic.Rules import exclusion_rules | ||||
| from BaseClasses import Region, Entrance, Tutorial, Item | ||||
| from .Options import undertale_options | ||||
| from .Options import UndertaleOptions | ||||
| from worlds.AutoWorld import World, WebWorld | ||||
| from worlds.LauncherComponents import Component, components, Type | ||||
| from worlds.LauncherComponents import Component, components | ||||
| from multiprocessing import Process | ||||
|  | ||||
|  | ||||
| @@ -46,7 +46,8 @@ class UndertaleWorld(World): | ||||
|     from their underground prison. | ||||
|     """ | ||||
|     game = "Undertale" | ||||
|     option_definitions = undertale_options | ||||
|     options_dataclass = UndertaleOptions | ||||
|     options: UndertaleOptions | ||||
|     web = UndertaleWeb() | ||||
|  | ||||
|     item_name_to_id = {name: data.code for name, data in item_table.items()} | ||||
| @@ -54,39 +55,55 @@ class UndertaleWorld(World): | ||||
|  | ||||
|     def _get_undertale_data(self): | ||||
|         return { | ||||
|             "world_seed": self.multiworld.per_slot_randoms[self.player].getrandbits(32), | ||||
|             "world_seed": self.random.getrandbits(32), | ||||
|             "seed_name": self.multiworld.seed_name, | ||||
|             "player_name": self.multiworld.get_player_name(self.player), | ||||
|             "player_id": self.player, | ||||
|             "client_version": self.required_client_version, | ||||
|             "race": self.multiworld.is_race, | ||||
|             "route": self.multiworld.route_required[self.player].current_key, | ||||
|             "starting_area": self.multiworld.starting_area[self.player].current_key, | ||||
|             "temy_armor_include": bool(self.multiworld.temy_include[self.player].value), | ||||
|             "only_flakes": bool(self.multiworld.only_flakes[self.player].value), | ||||
|             "no_equips": bool(self.multiworld.no_equips[self.player].value), | ||||
|             "key_hunt": bool(self.multiworld.key_hunt[self.player].value), | ||||
|             "key_pieces": self.multiworld.key_pieces[self.player].value, | ||||
|             "rando_love": bool(self.multiworld.rando_love[self.player].value), | ||||
|             "rando_stats": bool(self.multiworld.rando_stats[self.player].value), | ||||
|             "prog_armor": bool(self.multiworld.prog_armor[self.player].value), | ||||
|             "prog_weapons": bool(self.multiworld.prog_weapons[self.player].value), | ||||
|             "rando_item_button": bool(self.multiworld.rando_item_button[self.player].value) | ||||
|             "route": self.options.route_required.current_key, | ||||
|             "starting_area": self.options.starting_area.current_key, | ||||
|             "temy_armor_include": bool(self.options.temy_include.value), | ||||
|             "only_flakes": bool(self.options.only_flakes.value), | ||||
|             "no_equips": bool(self.options.no_equips.value), | ||||
|             "key_hunt": bool(self.options.key_hunt.value), | ||||
|             "key_pieces": self.options.key_pieces.value, | ||||
|             "rando_love": bool(self.options.rando_love.value), | ||||
|             "rando_stats": bool(self.options.rando_stats.value), | ||||
|             "prog_armor": bool(self.options.prog_armor.value), | ||||
|             "prog_weapons": bool(self.options.prog_weapons.value), | ||||
|             "rando_item_button": bool(self.options.rando_item_button.value) | ||||
|         } | ||||
|  | ||||
|     def get_filler_item_name(self): | ||||
|         if self.options.route_required == "all_routes": | ||||
|             junk_pool = junk_weights_all | ||||
|         elif self.options.route_required == "genocide": | ||||
|             junk_pool = junk_weights_genocide | ||||
|         elif self.options.route_required == "neutral": | ||||
|             junk_pool = junk_weights_neutral | ||||
|         elif self.options.route_required == "pacifist": | ||||
|             junk_pool = junk_weights_pacifist | ||||
|         else: | ||||
|             junk_pool = junk_weights_all | ||||
|         if not self.options.only_flakes: | ||||
|             return self.random.choices(list(junk_pool.keys()), weights=list(junk_pool.values()))[0] | ||||
|         else: | ||||
|             return "Temmie Flakes" | ||||
|  | ||||
|     def create_items(self): | ||||
|         self.multiworld.get_location("Undyne Date", self.player).place_locked_item(self.create_item("Undyne Date")) | ||||
|         self.multiworld.get_location("Alphys Date", self.player).place_locked_item(self.create_item("Alphys Date")) | ||||
|         self.multiworld.get_location("Papyrus Date", self.player).place_locked_item(self.create_item("Papyrus Date")) | ||||
|         # Generate item pool | ||||
|         itempool = [] | ||||
|         if self.multiworld.route_required[self.player] == "all_routes": | ||||
|         if self.options.route_required == "all_routes": | ||||
|             junk_pool = junk_weights_all.copy() | ||||
|         elif self.multiworld.route_required[self.player] == "genocide": | ||||
|         elif self.options.route_required == "genocide": | ||||
|             junk_pool = junk_weights_genocide.copy() | ||||
|         elif self.multiworld.route_required[self.player] == "neutral": | ||||
|         elif self.options.route_required == "neutral": | ||||
|             junk_pool = junk_weights_neutral.copy() | ||||
|         elif self.multiworld.route_required[self.player] == "pacifist": | ||||
|         elif self.options.route_required == "pacifist": | ||||
|             junk_pool = junk_weights_pacifist.copy() | ||||
|         else: | ||||
|             junk_pool = junk_weights_all.copy() | ||||
| @@ -99,73 +116,68 @@ class UndertaleWorld(World): | ||||
|             itempool += [name] * num | ||||
|         for name, num in non_key_items.items(): | ||||
|             itempool += [name] * num | ||||
|         if self.multiworld.rando_item_button[self.player]: | ||||
|         if self.options.rando_item_button: | ||||
|             itempool += ["ITEM"] | ||||
|         else: | ||||
|             self.multiworld.push_precollected(self.create_item("ITEM")) | ||||
|         self.multiworld.push_precollected(self.create_item("FIGHT")) | ||||
|         self.multiworld.push_precollected(self.create_item("ACT")) | ||||
|         self.multiworld.push_precollected(self.create_item("MERCY")) | ||||
|         if self.multiworld.route_required[self.player] == "genocide": | ||||
|         if self.options.route_required == "genocide": | ||||
|             itempool = [item for item in itempool if item != "Popato Chisps" and item != "Stained Apron" and | ||||
|                         item != "Nice Cream" and item != "Hot Cat" and item != "Hot Dog...?" and item != "Punch Card"] | ||||
|         elif self.multiworld.route_required[self.player] == "neutral": | ||||
|         elif self.options.route_required == "neutral": | ||||
|             itempool = [item for item in itempool if item != "Popato Chisps" and item != "Hot Cat" and | ||||
|                         item != "Hot Dog...?"] | ||||
|         if self.multiworld.route_required[self.player] == "pacifist" or \ | ||||
|                 self.multiworld.route_required[self.player] == "all_routes": | ||||
|         if self.options.route_required == "pacifist" or self.options.route_required == "all_routes": | ||||
|             itempool += ["Undyne Letter EX"] | ||||
|         else: | ||||
|             itempool.remove("Complete Skeleton") | ||||
|             itempool.remove("Fish") | ||||
|             itempool.remove("DT Extractor") | ||||
|             itempool.remove("Hush Puppy") | ||||
|         if self.multiworld.key_hunt[self.player]: | ||||
|             itempool += ["Key Piece"] * self.multiworld.key_pieces[self.player].value | ||||
|         if self.options.key_hunt: | ||||
|             itempool += ["Key Piece"] * self.options.key_pieces.value | ||||
|         else: | ||||
|             itempool += ["Left Home Key"] | ||||
|             itempool += ["Right Home Key"] | ||||
|         if not self.multiworld.rando_love[self.player] or \ | ||||
|                 (self.multiworld.route_required[self.player] != "genocide" and | ||||
|                  self.multiworld.route_required[self.player] != "all_routes"): | ||||
|         if not self.options.rando_love or \ | ||||
|                 (self.options.route_required != "genocide" and self.options.route_required != "all_routes"): | ||||
|             itempool = [item for item in itempool if not item == "LOVE"] | ||||
|         if not self.multiworld.rando_stats[self.player] or \ | ||||
|                 (self.multiworld.route_required[self.player] != "genocide" and | ||||
|                  self.multiworld.route_required[self.player] != "all_routes"): | ||||
|         if not self.options.rando_stats or \ | ||||
|                 (self.options.route_required != "genocide" and self.options.route_required != "all_routes"): | ||||
|             itempool = [item for item in itempool if not (item == "ATK Up" or item == "DEF Up" or item == "HP Up")] | ||||
|         if self.multiworld.temy_include[self.player]: | ||||
|         if self.options.temy_include: | ||||
|             itempool += ["temy armor"] | ||||
|         if self.multiworld.no_equips[self.player]: | ||||
|         if self.options.no_equips: | ||||
|             itempool = [item for item in itempool if item not in required_armor and item not in required_weapons] | ||||
|         else: | ||||
|             if self.multiworld.prog_armor[self.player]: | ||||
|             if self.options.prog_armor: | ||||
|                 itempool = [item if (item not in required_armor and not item == "temy armor") else | ||||
|                             "Progressive Armor" for item in itempool] | ||||
|             if self.multiworld.prog_weapons[self.player]: | ||||
|             if self.options.prog_weapons: | ||||
|                 itempool = [item if item not in required_weapons else "Progressive Weapons" for item in itempool] | ||||
|         if self.multiworld.route_required[self.player] == "genocide" or \ | ||||
|                 self.multiworld.route_required[self.player] == "all_routes": | ||||
|             if not self.multiworld.only_flakes[self.player]: | ||||
|         if self.options.route_required == "genocide" or \ | ||||
|                 self.options.route_required == "all_routes": | ||||
|             if not self.options.only_flakes: | ||||
|                 itempool += ["Snowman Piece"] * 2 | ||||
|             if not self.multiworld.no_equips[self.player]: | ||||
|             if not self.options.no_equips: | ||||
|                 itempool = ["Real Knife" if item == "Worn Dagger" else "The Locket" | ||||
|                             if item == "Heart Locket" else item for item in itempool] | ||||
|         if self.multiworld.only_flakes[self.player]: | ||||
|         if self.options.only_flakes: | ||||
|             itempool = [item for item in itempool if item not in non_key_items] | ||||
|  | ||||
|         starting_key = self.multiworld.starting_area[self.player].current_key.title() + " Key" | ||||
|         starting_key = self.options.starting_area.current_key.title() + " Key" | ||||
|         itempool.remove(starting_key) | ||||
|         self.multiworld.push_precollected(self.create_item(starting_key)) | ||||
|         # Choose locations to automatically exclude based on settings | ||||
|         exclusion_pool = set() | ||||
|         exclusion_pool.update(exclusion_table[self.multiworld.route_required[self.player].current_key]) | ||||
|         if not self.multiworld.rando_love[self.player] or \ | ||||
|                 (self.multiworld.route_required[self.player] != "genocide" and | ||||
|                  self.multiworld.route_required[self.player] != "all_routes"): | ||||
|         exclusion_pool.update(exclusion_table[self.options.route_required.current_key]) | ||||
|         if not self.options.rando_love or \ | ||||
|                 (self.options.route_required != "genocide" and self.options.route_required != "all_routes"): | ||||
|             exclusion_pool.update(exclusion_table["NoLove"]) | ||||
|         if not self.multiworld.rando_stats[self.player] or \ | ||||
|                 (self.multiworld.route_required[self.player] != "genocide" and | ||||
|                  self.multiworld.route_required[self.player] != "all_routes"): | ||||
|         if not self.options.rando_stats or \ | ||||
|                 (self.options.route_required != "genocide" and self.options.route_required != "all_routes"): | ||||
|             exclusion_pool.update(exclusion_table["NoStats"]) | ||||
|  | ||||
|         # Choose locations to automatically exclude based on settings | ||||
| @@ -173,36 +185,33 @@ class UndertaleWorld(World): | ||||
|         exclusion_checks.update(["Nicecream Punch Card", "Hush Trade"]) | ||||
|         exclusion_rules(self.multiworld, self.player, exclusion_checks) | ||||
|  | ||||
|         # Fill remaining items with randomly generated junk or Temmie Flakes | ||||
|         if not self.multiworld.only_flakes[self.player]: | ||||
|             itempool += self.multiworld.random.choices(list(junk_pool.keys()), weights=list(junk_pool.values()), | ||||
|                                                        k=len(self.location_names)-len(itempool)-len(exclusion_pool)) | ||||
|         else: | ||||
|             itempool += ["Temmie Flakes"] * (len(self.location_names) - len(itempool) - len(exclusion_pool)) | ||||
|         # Convert itempool into real items | ||||
|         itempool = [item for item in map(lambda name: self.create_item(name), itempool)] | ||||
|         # Fill remaining items with randomly generated junk or Temmie Flakes | ||||
|         while len(itempool) < len(self.multiworld.get_unfilled_locations(self.player)): | ||||
|             itempool.append(self.create_filler()) | ||||
|  | ||||
|         self.multiworld.itempool += itempool | ||||
|  | ||||
|     def set_rules(self): | ||||
|         set_rules(self.multiworld, self.player) | ||||
|         set_completion_rules(self.multiworld, self.player) | ||||
|         set_rules(self) | ||||
|         set_completion_rules(self) | ||||
|  | ||||
|     def create_regions(self): | ||||
|         def UndertaleRegion(region_name: str, exits=[]): | ||||
|             ret = Region(region_name, self.player, self.multiworld) | ||||
|             ret.locations += [UndertaleAdvancement(self.player, loc_name, loc_data.id, ret) | ||||
|                              for loc_name, loc_data in advancement_table.items() | ||||
|                              if loc_data.region == region_name and | ||||
|                              (loc_name not in exclusion_table["NoStats"] or | ||||
|                               (self.multiworld.rando_stats[self.player] and | ||||
|                                (self.multiworld.route_required[self.player] == "genocide" or | ||||
|                                 self.multiworld.route_required[self.player] == "all_routes"))) and | ||||
|                              (loc_name not in exclusion_table["NoLove"] or | ||||
|                               (self.multiworld.rando_love[self.player] and | ||||
|                                (self.multiworld.route_required[self.player] == "genocide" or | ||||
|                                 self.multiworld.route_required[self.player] == "all_routes"))) and | ||||
|                              loc_name not in exclusion_table[self.multiworld.route_required[self.player].current_key]] | ||||
|                               for loc_name, loc_data in advancement_table.items() | ||||
|                               if loc_data.region == region_name and | ||||
|                               (loc_name not in exclusion_table["NoStats"] or | ||||
|                               (self.options.rando_stats and | ||||
|                                (self.options.route_required == "genocide" or | ||||
|                                 self.options.route_required == "all_routes"))) and | ||||
|                               (loc_name not in exclusion_table["NoLove"] or | ||||
|                               (self.options.rando_love and | ||||
|                                (self.options.route_required == "genocide" or | ||||
|                                 self.options.route_required == "all_routes"))) and | ||||
|                               loc_name not in exclusion_table[self.options.route_required.current_key]] | ||||
|             for exit in exits: | ||||
|                 ret.exits.append(Entrance(self.player, exit, ret)) | ||||
|             return ret | ||||
| @@ -212,11 +221,11 @@ class UndertaleWorld(World): | ||||
|  | ||||
|     def fill_slot_data(self): | ||||
|         slot_data = self._get_undertale_data() | ||||
|         for option_name in undertale_options: | ||||
|         for option_name in self.options.as_dict(): | ||||
|             option = getattr(self.multiworld, option_name)[self.player] | ||||
|             if (option_name == "rando_love" or option_name == "rando_stats") and \ | ||||
|                     self.multiworld.route_required[self.player] != "genocide" and \ | ||||
|                     self.multiworld.route_required[self.player] != "all_routes": | ||||
|                     self.options.route_required != "genocide" and \ | ||||
|                     self.options.route_required != "all_routes": | ||||
|                 option.value = False | ||||
|             if slot_data.get(option_name, None) is None and type(option.value) in {str, int}: | ||||
|                 slot_data[option_name] = int(option.value) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Mewlif
					Mewlif