Files
APSly3/Sly3Rules.py
2025-12-13 21:53:24 +01:00

101 lines
3.3 KiB
Python

import typing
from math import ceil
from BaseClasses import CollectionState
from worlds.generic.Rules import add_rule
from .data.Constants import EPISODES, CHALLENGES, REQUIREMENTS
if typing.TYPE_CHECKING:
from . import Sly3World
def set_rules_sly3(world: "Sly3World"):
player = world.player
thiefnet_items = world.options.thiefnet_locations.value
# Putting ThiefNet stuff out of logic, to make early game less slow.
# Divides the items into groups that require a number of episode and crew
# items to be in logic
for i in range(1,thiefnet_items):
divisor = ceil(thiefnet_items/12)
episode_items_n = ceil(i/divisor)
add_rule(
world.get_location(f"ThiefNet {i:02}"),
lambda state, n=episode_items_n: (
(
state.count_group("Episode", player) +
state.count_group("Crew", player)
) >= n
)
)
def require(location: str, item: str|list[str]):
add_rule(
world.get_location(location),
lambda state, i=item: (
all(state.has(j, player) for j in i)
)
)
### Job requirements
for episode, sections in EPISODES.items():
if episode == "Honor Among Thieves":
continue
for i, s in enumerate(sections):
for j, job in enumerate(s):
reqs = REQUIREMENTS["Jobs"][episode][i][j]
add_rule(
world.get_location(f"{episode} - {job}"),
lambda state, items=reqs: (
all(state.has(item, player) for item in items)
)
)
### Challenge requirements
for episode, sections in CHALLENGES.items():
if episode == "Honor Among Thieves":
continue
for i, s in enumerate(sections):
for j, challenge in enumerate(s):
reqs = REQUIREMENTS["Challenges"][episode][i][j]
add_rule(
world.get_location(f"{episode} - {challenge}"),
lambda state, items=reqs: (
all(state.has(item, player) for item in items)
)
)
if world.options.goal.value < 6:
victory_condition = [
"An Opera of Fear - Operation: Tar-Be Gone!",
"Rumble Down Under - Operation: Moon Crash",
"Flight of Fancy - Operation: Turbo Dominant Eagle",
"A Cold Alliance - Operation: Wedding Crasher",
"Dead Men Tell No Tales - Operation: Reverse Double-Cross",
"Honor Among Thieves - Final Legacy"
][world.options.goal.value]
victory_location = world.multiworld.get_location(victory_condition, world.player)
victory_location.address = None
victory_location.place_locked_item(world.create_event("Victory"))
world.multiworld.completion_condition[world.player] = lambda state: state.has("Victory", world.player)
elif world.options.goal.value == 6:
def access_rule(state: CollectionState):
victory_conditions = [
"An Opera of Fear - Operation: Tar-Be Gone!",
"Rumble Down Under - Operation: Moon Crash",
"Flight of Fancy - Operation: Turbo Dominant Eagle",
"A Cold Alliance - Operation: Wedding Crasher",
"Dead Men Tell No Tales - Operation: Reverse Double-Cross",
"Honor Among Thieves - Final Legacy"
]
return all(
world.multiworld.get_location(cond,world.player).access_rule(state)
for cond in victory_conditions
)
world.multiworld.completion_condition[world.player] = access_rule