Skip to content

Commit 20b7e2e

Browse files
committed
Cleanup, v0.1.0
1 parent 7cace70 commit 20b7e2e

File tree

11 files changed

+778
-582
lines changed

11 files changed

+778
-582
lines changed

worlds/sneak_king/Items.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ class SneakKingItem(Item):
1818
items: list[ItemData] = []
1919
index = 0
2020
for level in ["Sawmill", "Cul-De-Sac", "Construction", "Downtown"]:
21-
items += [ItemData(f"{level} Mission {i} Unlock", i + index, ItemClassification.progression) for i in range(2, 21)] # start at 2
21+
items += [ItemData(f"{level} Mission {i} Unlock", i + index, ItemClassification.progression) for i in range(2, 21)]
2222
index += 20
2323
items += [
2424
ItemData("Sawmill Unlock", 81, ItemClassification.progression),
2525
ItemData("Cul-De-Sac Unlock", 82, ItemClassification.progression),
2626
ItemData("Construction Unlock", 83, ItemClassification.progression),
2727
ItemData("Downtown Unlock", 84, ItemClassification.progression),
28-
ItemData("Progressive Flourish", 85, ItemClassification.progression, 3),
29-
ItemData("Progressive Chain", 86, ItemClassification.progression, 3),
28+
ItemData("Progressive Flourish", 85, ItemClassification.progression, 0),
29+
ItemData("Progressive Chain", 86, ItemClassification.progression, 0),
3030
ItemData("Nothing", 87, ItemClassification.filler, 0),
3131
]
3232

worlds/sneak_king/Locations.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ def __init__(self, name: str, id: int, tags: list[str]):
99
all_locations: list[LocationData] = []
1010
index = 0
1111

12-
# Mission rank locations
1312
for level in ["Sawmill", "Cul-De-Sac", "Construction", "Downtown"]:
1413
for rank in ["C", "B", "A"]:
1514
all_locations += [LocationData(f"{level}: Mission {i} Rank {rank}", index + i, [level, rank, "mission"]) for i in range(1, 21)]
1615
index += 20
1716

18-
# Interactable object locations
1917
interactable_objects: dict[str, list[tuple[str, str]]] = {
2018
"Sawmill": [
2119
("1A_Int_Door01", "Door 1"),
@@ -122,8 +120,8 @@ def __init__(self, name: str, id: int, tags: list[str]):
122120
("3A_Crate07", "Crate 7"),
123121
("3A_DiggerScoop", "Raised Truck Scoop"),
124122
("3A_Door01", "Door 1"),
125-
("3A_Door02_knocker", "Knock on Door 1"),
126-
("3A_Door03_knocker", "Knock on Door 2"),
123+
("3A_Door02_knocker", "Knock on Door 2"),
124+
("3A_Door03_knocker", "Knock on Door 3"),
127125
("3A_Door_Portaloo", "Porta-Potty"),
128126
("3A_LadderBase", "Ladder"),
129127
("3A_Manhole1", "Manhole 1"),
@@ -166,8 +164,6 @@ def __init__(self, name: str, id: int, tags: list[str]):
166164
],
167165
}
168166

169-
# Mission IDs used: index+1 through index+20 per batch, so max mission ID = index
170-
# Interactable IDs start after
171167
index += 1
172168

173169
for level, objects in interactable_objects.items():

worlds/sneak_king/Options.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,25 @@
44

55

66
class Goal(Choice):
7+
"""The win condition for the game.
8+
Complete X Missions: complete the required number of missions at any rank.
9+
Complete X A-Ranks: earn A-rank on the required number of missions."""
710
display_name = "Goal"
811
option_complete_x_missions = 0
912
option_complete_x_a_ranks = 1
1013
default = 0
1114

1215

1316
class GoalRange(Range):
17+
"""The number of missions or A-ranks required to complete the goal."""
1418
display_name = "Goal Range"
1519
range_start = 10
1620
range_end = 80
17-
default = 20
21+
default = 40
1822

1923

2024
class StartingLevel(Choice):
25+
"""The level you start with access to. All other levels must be unlocked."""
2126
display_name = "Starting Level"
2227
option_sawmill = 0
2328
option_cul_de_sac = 1
@@ -27,44 +32,56 @@ class StartingLevel(Choice):
2732

2833

2934
class EnabledRanks(OptionSet):
35+
"""Which rank tiers count as locations. Disabling a rank removes those checks from the pool."""
3036
display_name = "Enabled Ranks"
3137
valid_keys = ["C", "B", "A"]
3238
default = ["C", "B", "A"]
3339

3440

3541
class LevelUnlockMethod(Choice):
42+
"""How non-starting levels are unlocked.
43+
Unlock Item: each level requires a specific unlock item from the item pool.
44+
X Missions: each level unlocks after completing a set number of missions in the previous level."""
3645
display_name = "Level Unlock Method"
3746
option_x_missions = 0
3847
option_unlock_item = 1
3948
default = 1
4049

4150

4251
class LevelUnlockRange(Range):
52+
"""When using the X Missions unlock method, the number of missions that must be completed
53+
in a level before the next level in the chain becomes accessible."""
4354
display_Name = "Level Unlock Mission Count"
4455
range_start = 5
4556
range_end = 20
46-
default = 20
57+
default = 10
4758

4859

4960
class LevelShuffle(DefaultOnToggle):
61+
"""Randomize the order in which levels appear in the unlock chain.
62+
When disabled, the unlock order is Sawmill -> Cul-De-Sac -> Construction -> Downtown.
63+
Only has an effect if the Level Unlock Method is set to X Missions."""
5064
display_name = "Level Shuffle"
5165

5266

5367
class KingSpeedMultiplier(Range):
68+
"""Multiplier applied to the King's movement speed."""
5469
display_name = "King Speed Multiplier"
5570
range_start = 1
5671
range_end = 2
5772
default = 1
5873

5974

6075
class CivilianSpeedMultiplier(Range):
76+
"""Multiplier applied to civilian movement speed."""
6177
display_name = "Civilian Speed Multiplier"
6278
range_start = 1
6379
range_end = 2
6480
default = 1
6581

6682

6783
class TrapPercentage(Range):
84+
"""Percentage of filler items replaced with traps."""
6885
display_name = "Trap Percentage"
6986
range_start = 0
7087
range_end = 100

worlds/sneak_king/Regions.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
region_names = ["Sawmill", "Cul-De-Sac", "Construction", "Downtown"]
1212

1313
def create_regions(world: "SneakKingWorld"):
14-
# Create menu region (always included)
1514
menu_region = Region("Menu", world.player, world.multiworld)
1615
world.multiworld.regions.append(menu_region)
1716

18-
# Create other regions from dictionary, excluding any in disabled_regions
1917
regions_dict = get_regions_dict()
2018
for name, locations in regions_dict.items():
2119
if name not in world.disabled_regions:
@@ -35,13 +33,10 @@ def connect_regions(world: "SneakKingWorld"):
3533
connections_dict = get_region_connections_dict(world)
3634
names: typing.Dict[str, int] = {}
3735

38-
# Connect regions based on the connections dictionary, excluding any with excluded regions
3936
for (source, target), rule in connections_dict.items():
40-
# Skip connections where either the source or target is in excluded_regions
4137
if source in world.disabled_regions or target in world.disabled_regions:
4238
continue
4339

44-
# Verify that both regions exist before trying to connect them
4540
try:
4641
world.multiworld.get_region(source, world.player)
4742
world.multiworld.get_region(target, world.player)
@@ -74,16 +69,13 @@ def get_level_order(world: "SneakKingWorld") -> list[str]:
7469
def get_region_connections_dict(world: "SneakKingWorld"):
7570
level_order = world.level_order
7671
connections = {
77-
("Menu", level_order[0]): None, # Starting region is always accessible
72+
("Menu", level_order[0]): None,
7873
}
7974

8075
if world.options.level_unlock_method == LevelUnlockMethod.option_unlock_item:
81-
# All non-starting regions connect from Menu with their unlock item
8276
for region in level_order[1:]:
8377
connections[("Menu", region)] = Has(f"{region} Unlock")
8478
else:
85-
# x_missions: linear chain where completing X missions in region N unlocks region N+1
86-
# Mission 1 is always available (no unlock needed), so we need X-1 unlock items
8779
required_unlocks = world.options.level_unlock_range.value - 1
8880
for i in range(1, len(level_order)):
8981
prev_region = level_order[i - 1]

worlds/sneak_king/Rules.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,24 @@
2222
mission_rules[location.name] = Has(item_name)
2323

2424
def set_rules(world: "SneakKingWorld"):
25-
# Set mission unlock rules
2625
for location_name, rule in mission_rules.items():
2726
if location_name not in world.disabled_locations:
2827
world.set_rule(world.get_location(location_name), rule)
2928

3029
starting_region = region_names[world.options.starting_level.value]
3130

3231
if world.options.level_unlock_method == LevelUnlockMethod.option_unlock_item:
33-
# Prevent region unlock items from being placed in their own region
3432
for region_name in region_names:
3533
if region_name == starting_region:
36-
continue # Starting region unlock doesn't exist in item pool
34+
continue
3735

3836
region_unlock_item = f"{region_name} Unlock"
3937
region = world.multiworld.get_region(region_name, world.player)
4038
for location in region.locations:
4139
forbid_item(location, region_unlock_item, world.player)
4240
else:
43-
# x_missions chain mode: Region[0] -> Region[1] -> Region[2] -> Region[3]
44-
# Completing X missions in Region[i] unlocks Region[i+1].
45-
# Forbid Region[i]'s mission unlocks from regions that come AFTER Region[i+1]
46-
# in the chain, since those regions can't be reached without first completing
47-
# Region[i]'s missions. This helps the fill algorithm avoid dead ends.
4841
level_order = world.level_order
4942
for i, source_region in enumerate(level_order):
50-
# Regions after the one this source unlocks
5143
forbidden_regions = level_order[i + 2:] if i + 2 < len(level_order) else []
5244
if not forbidden_regions:
5345
continue

0 commit comments

Comments
 (0)