Subnautica: add creature scans
This commit is contained in:
parent
b3ad766680
commit
e1ef820184
|
@ -0,0 +1,82 @@
|
||||||
|
from typing import Dict, Set, List
|
||||||
|
|
||||||
|
# EN Locale Creature Name to rough depth in meters found at
|
||||||
|
all_creatures: Dict[str, int] = {
|
||||||
|
"Gasopod": 0,
|
||||||
|
"Bladderfish": 0,
|
||||||
|
"Ancient Floater": 0,
|
||||||
|
"Skyray": 0,
|
||||||
|
"Garryfish": 0,
|
||||||
|
"Peeper": 0,
|
||||||
|
"Shuttlebug": 0,
|
||||||
|
"Rabbit Ray": 0,
|
||||||
|
"Stalker": 0,
|
||||||
|
"Floater": 0,
|
||||||
|
"Holefish": 0,
|
||||||
|
"Cave Crawler": 0,
|
||||||
|
"Hoopfish": 0,
|
||||||
|
"Crashfish": 0,
|
||||||
|
"Hoverfish": 0,
|
||||||
|
"Spadefish": 0,
|
||||||
|
"Reefback Leviathan": 0,
|
||||||
|
"Reaper Leviathan": 0,
|
||||||
|
"Warper": 0,
|
||||||
|
"Boomerang": 0,
|
||||||
|
"Biter": 200,
|
||||||
|
"Sand Shark": 200,
|
||||||
|
"Bleeder": 200,
|
||||||
|
"Crabsnake": 300,
|
||||||
|
"Jellyray": 300,
|
||||||
|
"Oculus": 300,
|
||||||
|
"Mesmer": 300,
|
||||||
|
"Eyeye": 300,
|
||||||
|
"Reginald": 400,
|
||||||
|
"Sea Treader Leviathan": 400,
|
||||||
|
"Crabsquid": 400,
|
||||||
|
"Ampeel": 400,
|
||||||
|
"Boneshark": 400,
|
||||||
|
"Rockgrub": 400,
|
||||||
|
"Ghost Leviathan": 500,
|
||||||
|
"Ghost Leviathan Juvenile": 500,
|
||||||
|
"Spinefish": 600,
|
||||||
|
"Blighter": 600,
|
||||||
|
"Blood Crawler": 600,
|
||||||
|
"Ghostray": 1000,
|
||||||
|
"Amoeboid": 1000,
|
||||||
|
"River Prowler": 1000,
|
||||||
|
"Red Eyeye": 1300,
|
||||||
|
"Magmarang": 1300,
|
||||||
|
"Crimson Ray": 1300,
|
||||||
|
"Lava Larva": 1300,
|
||||||
|
"Lava Lizard": 1300,
|
||||||
|
"Sea Dragon Leviathan": 1300,
|
||||||
|
"Sea Emperor Leviathan": 1700,
|
||||||
|
"Sea Emperor Juvenile": 1700,
|
||||||
|
|
||||||
|
# "Cuddlefish": 300, # maybe at some point, needs hatching in containment chamber (20 real-life minutes)
|
||||||
|
}
|
||||||
|
|
||||||
|
# be nice and make these require Stasis Rifle
|
||||||
|
aggressive: Set[str] = {
|
||||||
|
"Cave Crawler", # is very easy without Stasis Rifle, but included for consistency
|
||||||
|
"Crashfish",
|
||||||
|
"Bleeder",
|
||||||
|
"Mesmer",
|
||||||
|
"Reaper Leviathan",
|
||||||
|
"Crabsquid",
|
||||||
|
"Warper",
|
||||||
|
"Crabsnake",
|
||||||
|
"Ampeel",
|
||||||
|
"Boneshark",
|
||||||
|
"Lava Lizard",
|
||||||
|
"Sea Dragon Leviathan",
|
||||||
|
"River Prowler",
|
||||||
|
}
|
||||||
|
|
||||||
|
suffix: str = " Scan"
|
||||||
|
|
||||||
|
creature_locations: Dict[str, int] = {
|
||||||
|
creature+suffix: creature_id for creature_id, creature in enumerate(all_creatures, start=34000)
|
||||||
|
}
|
||||||
|
|
||||||
|
all_creatures_presorted: List[str] = sorted(all_creatures)
|
|
@ -166,7 +166,7 @@ item_table: Dict[int, ItemDict] = {
|
||||||
'count': 5,
|
'count': 5,
|
||||||
'name': 'Seamoth Fragment',
|
'name': 'Seamoth Fragment',
|
||||||
'tech_type': 'SeamothFragment'},
|
'tech_type': 'SeamothFragment'},
|
||||||
35039: {'classification': ItemClassification.useful,
|
35039: {'classification': ItemClassification.progression,
|
||||||
'count': 2,
|
'count': 2,
|
||||||
'name': 'Stasis Rifle Fragment',
|
'name': 'Stasis Rifle Fragment',
|
||||||
'tech_type': 'StasisRifleFragment'},
|
'tech_type': 'StasisRifleFragment'},
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from Options import Choice
|
from Options import Choice, Range
|
||||||
|
from .Creatures import all_creatures
|
||||||
|
|
||||||
|
|
||||||
class ItemPool(Choice):
|
class ItemPool(Choice):
|
||||||
|
@ -31,7 +32,15 @@ class Goal(Choice):
|
||||||
}[self.value]
|
}[self.value]
|
||||||
|
|
||||||
|
|
||||||
|
class CreatureScans(Range):
|
||||||
|
"""Place items on specific creature scans.
|
||||||
|
Warning: Includes aggressive Leviathans."""
|
||||||
|
display_name = "Creature Scans"
|
||||||
|
range_end = len(all_creatures)
|
||||||
|
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
"item_pool": ItemPool,
|
"item_pool": ItemPool,
|
||||||
"goal": Goal,
|
"goal": Goal,
|
||||||
|
"creature_scans": CreatureScans
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,112 +1,122 @@
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from worlds.generic.Rules import set_rule
|
from worlds.generic.Rules import set_rule
|
||||||
from .Locations import location_table, LocationDict
|
from .Locations import location_table, LocationDict
|
||||||
|
from .Creatures import all_creatures, aggressive, suffix
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from . import SubnauticaWorld
|
||||||
|
|
||||||
def has_seaglide(state, player):
|
|
||||||
|
def has_seaglide(state, player: int):
|
||||||
return state.has("Seaglide Fragment", player, 2)
|
return state.has("Seaglide Fragment", player, 2)
|
||||||
|
|
||||||
|
|
||||||
def has_modification_station(state, player):
|
def has_modification_station(state, player: int):
|
||||||
return state.has("Modification Station Fragment", player, 3)
|
return state.has("Modification Station Fragment", player, 3)
|
||||||
|
|
||||||
|
|
||||||
def has_mobile_vehicle_bay(state, player):
|
def has_mobile_vehicle_bay(state, player: int):
|
||||||
return state.has("Mobile Vehicle Bay Fragment", player, 3)
|
return state.has("Mobile Vehicle Bay Fragment", player, 3)
|
||||||
|
|
||||||
|
|
||||||
def has_moonpool(state, player):
|
def has_moonpool(state, player: int):
|
||||||
return state.has("Moonpool Fragment", player, 2)
|
return state.has("Moonpool Fragment", player, 2)
|
||||||
|
|
||||||
|
|
||||||
def has_vehicle_upgrade_console(state, player):
|
def has_vehicle_upgrade_console(state, player: int):
|
||||||
return state.has("Vehicle Upgrade Console", player) and \
|
return state.has("Vehicle Upgrade Console", player) and \
|
||||||
has_moonpool(state, player)
|
has_moonpool(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_seamoth(state, player):
|
def has_seamoth(state, player: int):
|
||||||
return state.has("Seamoth Fragment", player, 3) and \
|
return state.has("Seamoth Fragment", player, 3) and \
|
||||||
has_mobile_vehicle_bay(state, player)
|
has_mobile_vehicle_bay(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_seamoth_depth_module_mk1(state, player):
|
def has_seamoth_depth_module_mk1(state, player: int):
|
||||||
return has_vehicle_upgrade_console(state, player)
|
return has_vehicle_upgrade_console(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_seamoth_depth_module_mk2(state, player):
|
def has_seamoth_depth_module_mk2(state, player: int):
|
||||||
return has_seamoth_depth_module_mk1(state, player) and \
|
return has_seamoth_depth_module_mk1(state, player) and \
|
||||||
has_modification_station(state, player)
|
has_modification_station(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_seamoth_depth_module_mk3(state, player):
|
def has_seamoth_depth_module_mk3(state, player: int):
|
||||||
return has_seamoth_depth_module_mk2(state, player) and \
|
return has_seamoth_depth_module_mk2(state, player) and \
|
||||||
has_modification_station(state, player)
|
has_modification_station(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_cyclops_bridge(state, player):
|
def has_cyclops_bridge(state, player: int):
|
||||||
return state.has("Cyclops Bridge Fragment", player, 3)
|
return state.has("Cyclops Bridge Fragment", player, 3)
|
||||||
|
|
||||||
|
|
||||||
def has_cyclops_engine(state, player):
|
def has_cyclops_engine(state, player: int):
|
||||||
return state.has("Cyclops Engine Fragment", player, 3)
|
return state.has("Cyclops Engine Fragment", player, 3)
|
||||||
|
|
||||||
|
|
||||||
def has_cyclops_hull(state, player):
|
def has_cyclops_hull(state, player: int):
|
||||||
return state.has("Cyclops Hull Fragment", player, 3)
|
return state.has("Cyclops Hull Fragment", player, 3)
|
||||||
|
|
||||||
|
|
||||||
def has_cyclops(state, player):
|
def has_cyclops(state, player: int):
|
||||||
return has_cyclops_bridge(state, player) and \
|
return has_cyclops_bridge(state, player) and \
|
||||||
has_cyclops_engine(state, player) and \
|
has_cyclops_engine(state, player) and \
|
||||||
has_cyclops_hull(state, player) and \
|
has_cyclops_hull(state, player) and \
|
||||||
has_mobile_vehicle_bay(state, player)
|
has_mobile_vehicle_bay(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_cyclops_depth_module_mk1(state, player):
|
def has_cyclops_depth_module_mk1(state, player: int):
|
||||||
return state.has("Cyclops Depth Module MK1", player) and \
|
return state.has("Cyclops Depth Module MK1", player) and \
|
||||||
has_modification_station(state, player)
|
has_modification_station(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_cyclops_depth_module_mk2(state, player):
|
def has_cyclops_depth_module_mk2(state, player: int):
|
||||||
return has_cyclops_depth_module_mk1(state, player) and \
|
return has_cyclops_depth_module_mk1(state, player) and \
|
||||||
has_modification_station(state, player)
|
has_modification_station(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_cyclops_depth_module_mk3(state, player):
|
def has_cyclops_depth_module_mk3(state, player: int):
|
||||||
return has_cyclops_depth_module_mk2(state, player) and \
|
return has_cyclops_depth_module_mk2(state, player) and \
|
||||||
has_modification_station(state, player)
|
has_modification_station(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_prawn(state, player):
|
def has_prawn(state, player: int):
|
||||||
return state.has("Prawn Suit Fragment", player, 4) and \
|
return state.has("Prawn Suit Fragment", player, 4) and \
|
||||||
has_mobile_vehicle_bay(state, player)
|
has_mobile_vehicle_bay(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_praw_propulsion_arm(state, player):
|
def has_praw_propulsion_arm(state, player: int):
|
||||||
return state.has("Prawn Suit Propulsion Cannon Fragment", player, 2) and \
|
return state.has("Prawn Suit Propulsion Cannon Fragment", player, 2) and \
|
||||||
has_vehicle_upgrade_console(state, player)
|
has_vehicle_upgrade_console(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_prawn_depth_module_mk1(state, player):
|
def has_prawn_depth_module_mk1(state, player: int):
|
||||||
return has_vehicle_upgrade_console(state, player)
|
return has_vehicle_upgrade_console(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_prawn_depth_module_mk2(state, player):
|
def has_prawn_depth_module_mk2(state, player: int):
|
||||||
return has_prawn_depth_module_mk1(state, player) and \
|
return has_prawn_depth_module_mk1(state, player) and \
|
||||||
has_modification_station(state, player)
|
has_modification_station(state, player)
|
||||||
|
|
||||||
|
|
||||||
def has_laser_cutter(state, player):
|
def has_laser_cutter(state, player: int):
|
||||||
return state.has("Laser Cutter Fragment", player, 3)
|
return state.has("Laser Cutter Fragment", player, 3)
|
||||||
|
|
||||||
|
|
||||||
|
def has_stasis_rile(state, player: int):
|
||||||
|
return state.has("Stasis Rifle Fragment", player, 2)
|
||||||
|
|
||||||
|
|
||||||
# Either we have propulsion cannon, or prawn + propulsion cannon arm
|
# Either we have propulsion cannon, or prawn + propulsion cannon arm
|
||||||
def has_propulsion_cannon(state, player):
|
def has_propulsion_cannon(state, player: int):
|
||||||
return state.has("Propulsion Cannon Fragment", player, 2) or \
|
return state.has("Propulsion Cannon Fragment", player, 2) or \
|
||||||
(has_prawn(state, player) and has_praw_propulsion_arm(state, player))
|
(has_prawn(state, player) and has_praw_propulsion_arm(state, player))
|
||||||
|
|
||||||
|
|
||||||
def has_cyclops_shield(state, player):
|
def has_cyclops_shield(state, player: int):
|
||||||
return has_cyclops(state, player) and \
|
return has_cyclops(state, player) and \
|
||||||
state.has("Cyclops Shield Generator", player)
|
state.has("Cyclops Shield Generator", player)
|
||||||
|
|
||||||
|
@ -119,7 +129,7 @@ def has_cyclops_shield(state, player):
|
||||||
# negligeable with from high capacity tank. 430m -> 460m
|
# negligeable with from high capacity tank. 430m -> 460m
|
||||||
# Fins are not used when using seaglide
|
# Fins are not used when using seaglide
|
||||||
#
|
#
|
||||||
def get_max_swim_depth(state, player):
|
def get_max_swim_depth(state, player: int):
|
||||||
# TODO, Make this a difficulty setting.
|
# TODO, Make this a difficulty setting.
|
||||||
# Only go up to 200m without any submarines for now.
|
# Only go up to 200m without any submarines for now.
|
||||||
return 200
|
return 200
|
||||||
|
@ -130,7 +140,7 @@ def get_max_swim_depth(state, player):
|
||||||
# has_ultra_glide_fins = state.has("Ultra Glide Fins", player)
|
# has_ultra_glide_fins = state.has("Ultra Glide Fins", player)
|
||||||
|
|
||||||
# max_depth = 400 # More like 430m. Give some room
|
# max_depth = 400 # More like 430m. Give some room
|
||||||
# if has_seaglide(state, player):
|
# if has_seaglide(state, player: int):
|
||||||
# if has_ultra_high_capacity_tank:
|
# if has_ultra_high_capacity_tank:
|
||||||
# max_depth = 750 # It's about 50m more. Give some room
|
# max_depth = 750 # It's about 50m more. Give some room
|
||||||
# else:
|
# else:
|
||||||
|
@ -146,7 +156,7 @@ def get_max_swim_depth(state, player):
|
||||||
# return max_depth
|
# return max_depth
|
||||||
|
|
||||||
|
|
||||||
def get_seamoth_max_depth(state, player):
|
def get_seamoth_max_depth(state, player: int):
|
||||||
if has_seamoth(state, player):
|
if has_seamoth(state, player):
|
||||||
if has_seamoth_depth_module_mk3(state, player):
|
if has_seamoth_depth_module_mk3(state, player):
|
||||||
return 900
|
return 900
|
||||||
|
@ -186,7 +196,7 @@ def get_prawn_max_depth(state, player):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def get_max_depth(state, player):
|
def get_max_depth(state, player: int):
|
||||||
# TODO, Difficulty option, we can add vehicle depth + swim depth
|
# TODO, Difficulty option, we can add vehicle depth + swim depth
|
||||||
# But at this point, we have to consider traver distance in caves, not
|
# But at this point, we have to consider traver distance in caves, not
|
||||||
# just depth
|
# just depth
|
||||||
|
@ -196,7 +206,7 @@ def get_max_depth(state, player):
|
||||||
get_prawn_max_depth(state, player))
|
get_prawn_max_depth(state, player))
|
||||||
|
|
||||||
|
|
||||||
def can_access_location(state, player: int, loc: LocationDict):
|
def can_access_location(state, player: int, loc: LocationDict) -> bool:
|
||||||
need_laser_cutter = loc.get("need_laser_cutter", False)
|
need_laser_cutter = loc.get("need_laser_cutter", False)
|
||||||
if need_laser_cutter and not has_laser_cutter(state, player):
|
if need_laser_cutter and not has_laser_cutter(state, player):
|
||||||
return False
|
return False
|
||||||
|
@ -225,17 +235,33 @@ def can_access_location(state, player: int, loc: LocationDict):
|
||||||
return get_max_depth(state, player) >= depth
|
return get_max_depth(state, player) >= depth
|
||||||
|
|
||||||
|
|
||||||
def set_location_rule(world, player, loc):
|
def set_location_rule(world, player: int, loc: LocationDict):
|
||||||
set_rule(world.get_location(loc["name"], player), lambda state: can_access_location(state, player, loc))
|
set_rule(world.get_location(loc["name"], player), lambda state: can_access_location(state, player, loc))
|
||||||
|
|
||||||
|
|
||||||
def set_rules(subnautica_world):
|
def can_scan_creature(state, player: int, creature: str) -> bool:
|
||||||
|
if not has_seaglide(state, player):
|
||||||
|
return False
|
||||||
|
if creature in aggressive and not has_stasis_rile(state, player):
|
||||||
|
return False
|
||||||
|
return get_max_depth(state, player) >= all_creatures[creature]
|
||||||
|
|
||||||
|
|
||||||
|
def set_creature_rule(world, player, creature_name: str):
|
||||||
|
set_rule(world.get_location(creature_name + suffix, player),
|
||||||
|
lambda state: can_scan_creature(state, player, creature_name))
|
||||||
|
|
||||||
|
|
||||||
|
def set_rules(subnautica_world: "SubnauticaWorld"):
|
||||||
player = subnautica_world.player
|
player = subnautica_world.player
|
||||||
world = subnautica_world.world
|
world = subnautica_world.world
|
||||||
|
|
||||||
for loc in location_table.values():
|
for loc in location_table.values():
|
||||||
set_location_rule(world, player, loc)
|
set_location_rule(world, player, loc)
|
||||||
|
|
||||||
|
for creature_name in subnautica_world.creatures_to_scan:
|
||||||
|
set_creature_rule(world, player, creature_name)
|
||||||
|
|
||||||
# Victory locations
|
# Victory locations
|
||||||
set_rule(world.get_location("Neptune Launch", player), lambda state:
|
set_rule(world.get_location("Neptune Launch", player), lambda state:
|
||||||
get_max_depth(state, player) >= 1444 and
|
get_max_depth(state, player) >= 1444 and
|
||||||
|
|
|
@ -5,6 +5,7 @@ from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassifi
|
||||||
from worlds.AutoWorld import World, WebWorld
|
from worlds.AutoWorld import World, WebWorld
|
||||||
from . import Items
|
from . import Items
|
||||||
from . import Locations
|
from . import Locations
|
||||||
|
from . import Creatures
|
||||||
from . import Options
|
from . import Options
|
||||||
from .Items import item_table
|
from .Items import item_table
|
||||||
from .Rules import set_rules
|
from .Rules import set_rules
|
||||||
|
@ -23,6 +24,10 @@ class SubnaticaWeb(WebWorld):
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
|
||||||
|
all_locations = {data["name"]: loc_id for loc_id, data in Locations.location_table.items()}
|
||||||
|
all_locations.update(Creatures.creature_locations)
|
||||||
|
|
||||||
|
|
||||||
class SubnauticaWorld(World):
|
class SubnauticaWorld(World):
|
||||||
"""
|
"""
|
||||||
Subnautica is an undersea exploration game. Stranded on an alien world, you become infected by
|
Subnautica is an undersea exploration game. Stranded on an alien world, you become infected by
|
||||||
|
@ -33,25 +38,30 @@ class SubnauticaWorld(World):
|
||||||
web = SubnaticaWeb()
|
web = SubnaticaWeb()
|
||||||
|
|
||||||
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
|
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
|
||||||
location_name_to_id = {data["name"]: loc_id for loc_id, data in Locations.location_table.items()}
|
location_name_to_id = all_locations
|
||||||
options = Options.options
|
options = Options.options
|
||||||
|
|
||||||
data_version = 2
|
data_version = 3
|
||||||
required_client_version = (0, 3, 3)
|
required_client_version = (0, 3, 3)
|
||||||
|
|
||||||
prefill_items: List[Item]
|
prefill_items: List[Item]
|
||||||
|
creatures_to_scan: List[str]
|
||||||
|
|
||||||
def generate_early(self) -> None:
|
def generate_early(self) -> None:
|
||||||
self.prefill_items = [
|
self.prefill_items = [
|
||||||
self.create_item("Seaglide Fragment"),
|
self.create_item("Seaglide Fragment"),
|
||||||
self.create_item("Seaglide Fragment")
|
self.create_item("Seaglide Fragment")
|
||||||
]
|
]
|
||||||
|
self.creatures_to_scan = self.world.random.sample(Creatures.all_creatures_presorted,
|
||||||
|
self.world.creature_scans[self.player].value)
|
||||||
|
|
||||||
def create_regions(self):
|
def create_regions(self):
|
||||||
self.world.regions += [
|
self.world.regions += [
|
||||||
self.create_region("Menu", None, ["Lifepod 5"]),
|
self.create_region("Menu", None, ["Lifepod 5"]),
|
||||||
self.create_region("Planet 4546B",
|
self.create_region("Planet 4546B",
|
||||||
Locations.events + [location["name"] for location in Locations.location_table.values()])
|
Locations.events +
|
||||||
|
[location["name"] for location in Locations.location_table.values()] +
|
||||||
|
[creature+Creatures.suffix for creature in self.creatures_to_scan])
|
||||||
]
|
]
|
||||||
|
|
||||||
# refer to Rules.py
|
# refer to Rules.py
|
||||||
|
@ -64,7 +74,7 @@ class SubnauticaWorld(World):
|
||||||
# Generate item pool
|
# Generate item pool
|
||||||
pool = []
|
pool = []
|
||||||
neptune_launch_platform = None
|
neptune_launch_platform = None
|
||||||
extras = 0
|
extras = self.world.creature_scans[self.player].value
|
||||||
valuable = self.world.item_pool[self.player] == Options.ItemPool.option_valuable
|
valuable = self.world.item_pool[self.player] == Options.ItemPool.option_valuable
|
||||||
for item in item_table.values():
|
for item in item_table.values():
|
||||||
for i in range(item["count"]):
|
for i in range(item["count"]):
|
||||||
|
@ -105,6 +115,7 @@ class SubnauticaWorld(World):
|
||||||
slot_data: Dict[str, Any] = {
|
slot_data: Dict[str, Any] = {
|
||||||
"goal": goal.current_key,
|
"goal": goal.current_key,
|
||||||
"vanilla_tech": vanilla_tech,
|
"vanilla_tech": vanilla_tech,
|
||||||
|
"creatures_to_scan": self.creatures_to_scan
|
||||||
}
|
}
|
||||||
|
|
||||||
return slot_data
|
return slot_data
|
||||||
|
|
Loading…
Reference in New Issue