from worlds.generic.Rules import set_rule, add_rule from BaseClasses import CollectionState from typing import Dict from .Regions import Stages def graffitiM(state: CollectionState, player: int, limit: bool, spots: int) -> bool: return state.count_group_unique("graffitim", player) * 7 >= spots if limit \ else state.has_group("graffitim", player) def graffitiL(state: CollectionState, player: int, limit: bool, spots: int) -> bool: return state.count_group_unique("graffitil", player) * 6 >= spots if limit \ else state.has_group("graffitil", player) def graffitiXL(state: CollectionState, player: int, limit: bool, spots: int) -> bool: return state.count_group_unique("graffitixl", player) * 4 >= spots if limit \ else state.has_group("graffitixl", player) def skateboard(state: CollectionState, player: int, movestyle: int) -> bool: return True if movestyle == 2 else state.has_group("skateboard", player) def inline_skates(state: CollectionState, player: int, movestyle: int) -> bool: return True if movestyle == 3 else state.has_group("skates", player) def bmx(state: CollectionState, player: int, movestyle: int) -> bool: return True if movestyle == 1 else state.has_group("bmx", player) def camera(state: CollectionState, player: int) -> bool: return state.has("Camera App", player) def is_girl(state: CollectionState, player: int) -> bool: return state.has_group("girl", player) def current_chapter(state: CollectionState, player: int, chapter: int) -> bool: return state.has("Chapter Completed", player, chapter-1) def versum_hill_entrance(state: CollectionState, player: int) -> bool: return rep(state, player, 20) def versum_hill_ch1_roadblock(state: CollectionState, player: int, limit: bool) -> bool: return graffitiL(state, player, limit, 10) def versum_hill_challenge1(state: CollectionState, player: int) -> bool: return rep(state, player, 50) def versum_hill_challenge2(state: CollectionState, player: int) -> bool: return rep(state, player, 58) def versum_hill_challenge3(state: CollectionState, player: int) -> bool: return rep(state, player, 65) def versum_hill_all_challenges(state: CollectionState, player: int) -> bool: return versum_hill_challenge3(state, player) def versum_hill_basketball_court(state: CollectionState, player: int) -> bool: return rep(state, player, 90) def versum_hill_oldhead(state: CollectionState, player: int) -> bool: return rep(state, player, 120) def versum_hill_crew_battle(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( rep(state, player, 90) and graffitiM(state, player, limit, 98) ) else: return ( rep(state, player, 90) and graffitiM(state, player, limit, 27) ) def versum_hill_rietveld(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( current_chapter(state, player, 2) and graffitiM(state, player, limit, 114) ) else: return ( current_chapter(state, player, 2) and graffitiM(state, player, limit, 67) ) def versum_hill_rave(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: if current_chapter(state, player, 4): return ( graffitiL(state, player, limit, 90) and graffitiXL(state, player, limit, 51) ) elif current_chapter(state, player, 3): return ( graffitiL(state, player, limit, 89) and graffitiXL(state, player, limit, 51) ) else: return ( graffitiL(state, player, limit, 85) and graffitiXL(state, player, limit, 48) ) else: return ( graffitiL(state, player, limit, 26) and graffitiXL(state, player, limit, 10) ) def millennium_square_entrance(state: CollectionState, player: int) -> bool: return current_chapter(state, player, 2) def brink_terminal_entrance(state: CollectionState, player: int) -> bool: return ( is_girl(state, player) and rep(state, player, 180) and current_chapter(state, player, 2) ) def brink_terminal_challenge1(state: CollectionState, player: int) -> bool: return rep(state, player, 188) def brink_terminal_challenge2(state: CollectionState, player: int) -> bool: return rep(state, player, 200) def brink_terminal_challenge3(state: CollectionState, player: int) -> bool: return rep(state, player, 220) def brink_terminal_all_challenges(state: CollectionState, player: int) -> bool: return brink_terminal_challenge3(state, player) def brink_terminal_plaza(state: CollectionState, player: int) -> bool: return brink_terminal_all_challenges(state, player) def brink_terminal_tower(state: CollectionState, player: int) -> bool: return rep(state, player, 280) def brink_terminal_oldhead_underground(state: CollectionState, player: int) -> bool: return rep(state, player, 250) def brink_terminal_oldhead_dock(state: CollectionState, player: int) -> bool: return rep(state, player, 320) def brink_terminal_crew_battle(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( rep(state, player, 280) and graffitiL(state, player, limit, 103) ) else: return ( rep(state, player, 280) and graffitiL(state, player, limit, 62) ) def brink_terminal_mesh(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( graffitiM(state, player, limit, 114) and graffitiXL(state, player, limit, 45) ) else: return ( graffitiM(state, player, limit, 67) and graffitiXL(state, player, limit, 45) ) def millennium_mall_entrance(state: CollectionState, player: int) -> bool: return ( rep(state, player, 380) and current_chapter(state, player, 3) ) def millennium_mall_oldhead_ceiling(state: CollectionState, player: int, limit: bool) -> bool: return ( rep(state, player, 580) or millennium_mall_theater(state, player, limit) ) def millennium_mall_switch(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( graffitiM(state, player, limit, 114) and current_chapter(state, player, 3) ) else: return ( graffitiM(state, player, limit, 72) and current_chapter(state, player, 3) ) def millennium_mall_big(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: return millennium_mall_switch(state, player, limit, glitched) def millennium_mall_oldhead_race(state: CollectionState, player: int) -> bool: return rep(state, player, 530) def millennium_mall_challenge1(state: CollectionState, player: int) -> bool: return rep(state, player, 434) def millennium_mall_challenge2(state: CollectionState, player: int) -> bool: return rep(state, player, 442) def millennium_mall_challenge3(state: CollectionState, player: int) -> bool: return rep(state, player, 450) def millennium_mall_challenge4(state: CollectionState, player: int) -> bool: return rep(state, player, 458) def millennium_mall_all_challenges(state: CollectionState, player: int) -> bool: return millennium_mall_challenge4(state, player) def millennium_mall_theater(state: CollectionState, player: int, limit: bool) -> bool: return ( rep(state, player, 491) and graffitiM(state, player, limit, 78) ) def millennium_mall_crew_battle(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( rep(state, player, 491) and graffitiM(state, player, limit, 114) and graffitiL(state, player, limit, 107) ) else: return ( rep(state, player, 491) and graffitiM(state, player, limit, 78) and graffitiL(state, player, limit, 80) ) def pyramid_island_entrance(state: CollectionState, player: int) -> bool: return current_chapter(state, player, 4) def pyramid_island_gate(state: CollectionState, player: int) -> bool: return rep(state, player, 620) def pyramid_island_oldhead(state: CollectionState, player: int) -> bool: return rep(state, player, 780) def pyramid_island_challenge1(state: CollectionState, player: int) -> bool: return ( rep(state, player, 630) and current_chapter(state, player, 4) ) def pyramid_island_race(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( pyramid_island_challenge1(state, player) and graffitiL(state, player, limit, 108) ) else: return ( pyramid_island_challenge1(state, player) and graffitiL(state, player, limit, 93) ) def pyramid_island_challenge2(state: CollectionState, player: int) -> bool: return rep(state, player, 650) def pyramid_island_challenge3(state: CollectionState, player: int) -> bool: return rep(state, player, 660) def pyramid_island_all_challenges(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( graffitiM(state, player, limit, 114) and rep(state, player, 660) ) else: return ( graffitiM(state, player, limit, 88) and rep(state, player, 660) ) def pyramid_island_upper_half(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: return pyramid_island_all_challenges(state, player, limit, glitched) def pyramid_island_crew_battle(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( rep(state, player, 730) and graffitiL(state, player, limit, 108) ) else: return ( rep(state, player, 730) and graffitiL(state, player, limit, 97) ) def pyramid_island_top(state: CollectionState, player: int) -> bool: return current_chapter(state, player, 5) def mataan_entrance(state: CollectionState, player: int) -> bool: return current_chapter(state, player, 2) def mataan_smoke_wall(state: CollectionState, player: int) -> bool: return ( current_chapter(state, player, 5) and rep(state, player, 850) ) def mataan_challenge1(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( current_chapter(state, player, 5) and rep(state, player, 864) and graffitiL(state, player, limit, 108) ) else: return ( current_chapter(state, player, 5) and rep(state, player, 864) and graffitiL(state, player, limit, 98) ) def mataan_deep_city(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: return mataan_challenge1(state, player, limit, glitched) def mataan_oldhead(state: CollectionState, player: int) -> bool: return rep(state, player, 935) def mataan_challenge2(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( rep(state, player, 880) and graffitiXL(state, player, limit, 59) ) else: return ( rep(state, player, 880) and graffitiXL(state, player, limit, 57) ) def mataan_challenge3(state: CollectionState, player: int) -> bool: return rep(state, player, 920) def mataan_all_challenges(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: return ( mataan_challenge2(state, player, limit, glitched) and mataan_challenge3(state, player) ) def mataan_smoke_wall2(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: return ( mataan_all_challenges(state, player, limit, glitched) and rep(state, player, 960) ) def mataan_crew_battle(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: if glitched: return ( mataan_smoke_wall2(state, player, limit, glitched) and graffitiM(state, player, limit, 122) and graffitiXL(state, player, limit, 59) ) else: return ( mataan_smoke_wall2(state, player, limit, glitched) and graffitiM(state, player, limit, 117) and graffitiXL(state, player, limit, 57) ) def mataan_deepest(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: return mataan_crew_battle(state, player, limit, glitched) def mataan_faux(state: CollectionState, player: int, limit: bool, glitched: bool) -> bool: return ( mataan_deepest(state, player, limit, glitched) and graffitiM(state, player, limit, 122) ) def spots_s_glitchless(state: CollectionState, player: int, limit: bool, access_cache: Dict[str, bool]) -> int: total: int = 10 conditions: Dict[str, int] = { "versum_hill_entrance": 1, "versum_hill_ch1_roadblock": 11, "chapter2": 12, "versum_hill_oldhead": 1, "brink_terminal_entrance": 9, "brink_terminal_plaza": 3, "brink_terminal_tower": 0, "chapter3": 6, "brink_terminal_oldhead_dock": 1, "millennium_mall_entrance": 3, "millennium_mall_switch": 4, "millennium_mall_theater": 3, "chapter4": 2, "pyramid_island_gate": 5, "pyramid_island_upper_half": 8, "pyramid_island_oldhead": 2, "mataan_smoke_wall": 3, "mataan_deep_city": 5, "mataan_oldhead": 3, "mataan_deepest": 2 } for access_name, graffiti_count in conditions.items(): if access_cache[access_name]: total += graffiti_count else: break if limit: sprayable: int = 5 + (state.count_group_unique("characters", player) * 5) if total <= sprayable: return total else: return sprayable else: return total def spots_s_glitched(state: CollectionState, player: int, limit: bool, access_cache: Dict[str, bool]) -> int: total: int = 75 conditions: Dict[str, int] = { "brink_terminal_entrance": 13, "chapter3": 6 } for access_name, graffiti_count in conditions.items(): if access_cache[access_name]: total += graffiti_count else: break if limit: sprayable: int = 5 + (state.count_group_unique("characters", player) * 5) if total <= sprayable: return total else: return sprayable else: return total def spots_m_glitchless(state: CollectionState, player: int, limit: bool, access_cache: Dict[str, bool]) -> int: total: int = 4 conditions: Dict[str, int] = { "versum_hill_entrance": 3, "versum_hill_ch1_roadblock": 13, "versum_hill_all_challenges": 3, "chapter2": 16, "versum_hill_oldhead": 4, "brink_terminal_entrance": 13, "brink_terminal_plaza": 4, "brink_terminal_tower": 0, "chapter3": 3, "brink_terminal_oldhead_dock": 4, "millennium_mall_entrance": 5, "millennium_mall_big": 6, "millennium_mall_theater": 4, "chapter4": 2, "millennium_mall_oldhead_ceiling": 1, "pyramid_island_gate": 3, "pyramid_island_upper_half": 8, "chapter5": 2, "pyramid_island_oldhead": 5, "mataan_deep_city": 7, "skateboard": 1, "mataan_oldhead": 1, "mataan_smoke_wall2": 1, "mataan_deepest": 10 } for access_name, graffiti_count in conditions.items(): if access_cache[access_name]: total += graffiti_count elif access_name != "skateboard": break if limit: sprayable: int = state.count_group_unique("graffitim", player) * 7 if total <= sprayable: return total else: return sprayable else: if state.has_group("graffitim", player): return total else: return 0 def spots_m_glitched(state: CollectionState, player: int, limit: bool, access_cache: Dict[str, bool]) -> int: total: int = 99 conditions: Dict[str, int] = { "brink_terminal_entrance": 21, "chapter3": 3 } for access_name, graffiti_count in conditions.items(): if access_cache[access_name]: total += graffiti_count else: break if limit: sprayable: int = state.count_group_unique("graffitim", player) * 7 if total <= sprayable: return total else: return sprayable else: if state.has_group("graffitim", player): return total else: return 0 def spots_l_glitchless(state: CollectionState, player: int, limit: bool, access_cache: Dict[str, bool]) -> int: total: int = 7 conditions: Dict[str, int] = { "inline_skates": 1, "versum_hill_entrance": 2, "versum_hill_ch1_roadblock": 13, "versum_hill_all_challenges": 1, "chapter2": 14, "versum_hill_oldhead": 2, "brink_terminal_entrance": 10, "brink_terminal_plaza": 2, "brink_terminal_oldhead_underground": 1, "brink_terminal_tower": 1, "chapter3": 4, "brink_terminal_oldhead_dock": 4, "millennium_mall_entrance": 3, "millennium_mall_big": 8, "millennium_mall_theater": 4, "chapter4": 5, "millennium_mall_oldhead_ceiling": 3, "pyramid_island_gate": 4, "pyramid_island_upper_half": 5, "pyramid_island_crew_battle": 1, "chapter5": 1, "pyramid_island_oldhead": 2, "mataan_smoke_wall": 1, "mataan_deep_city": 2, "skateboard": 1, "mataan_oldhead": 2, "mataan_deepest": 7 } for access_name, graffiti_count in conditions.items(): if access_cache[access_name]: total += graffiti_count elif not (access_name == "inline_skates" or access_name == "skateboard"): break if limit: sprayable: int = state.count_group_unique("graffitil", player) * 6 if total <= sprayable: return total else: return sprayable else: if state.has_group("graffitil", player): return total else: return 0 def spots_l_glitched(state: CollectionState, player: int, limit: bool, access_cache: Dict[str, bool]) -> int: total: int = 88 conditions: Dict[str, int] = { "brink_terminal_entrance": 18, "chapter3": 4, "chapter4": 1 } for access_name, graffiti_count in conditions.items(): if access_cache[access_name]: total += graffiti_count else: break if limit: sprayable: int = state.count_group_unique("graffitil", player) * 6 if total <= sprayable: return total else: return sprayable else: if state.has_group("graffitil", player): return total else: return 0 def spots_xl_glitchless(state: CollectionState, player: int, limit: bool, access_cache: Dict[str, bool]) -> int: total: int = 3 conditions: Dict[str, int] = { "versum_hill_ch1_roadblock": 6, "versum_hill_basketball_court": 1, "chapter2": 9, "brink_terminal_entrance": 3, "brink_terminal_plaza": 1, "brink_terminal_oldhead_underground": 1, "brink_terminal_tower": 1, "chapter3": 3, "brink_terminal_oldhead_dock": 2, "millennium_mall_entrance": 2, "millennium_mall_big": 5, "millennium_mall_theater": 5, "chapter4": 3, "millennium_mall_oldhead_ceiling": 1, "pyramid_island_upper_half": 5, "pyramid_island_oldhead": 3, "mataan_smoke_wall": 2, "mataan_deep_city": 2, "mataan_oldhead": 2, "mataan_deepest": 2 } for access_name, graffiti_count in conditions.items(): if access_cache[access_name]: total += graffiti_count else: break if limit: sprayable: int = state.count_group_unique("graffitixl", player) * 4 if total <= sprayable: return total else: return sprayable else: if state.has_group("graffitixl", player): return total else: return 0 def spots_xl_glitched(state: CollectionState, player: int, limit: bool, access_cache: Dict[str, bool]) -> int: total: int = 51 conditions: Dict[str, int] = { "brink_terminal_entrance": 7, "chapter3": 3, "chapter4": 1 } for access_name, graffiti_count in conditions.items(): if access_cache[access_name]: total += graffiti_count else: break if limit: sprayable: int = state.count_group_unique("graffitixl", player) * 4 if total <= sprayable: return total else: return sprayable else: if state.has_group("graffitixl", player): return total else: return 0 def build_access_cache(state: CollectionState, player: int, movestyle: int, limit: bool, glitched: bool) -> Dict[str, bool]: funcs: Dict[str, tuple] = { "versum_hill_entrance": (state, player), "versum_hill_ch1_roadblock": (state, player, limit), "versum_hill_oldhead": (state, player), "versum_hill_all_challenges": (state, player), "versum_hill_basketball_court": (state, player), "brink_terminal_entrance": (state, player), "brink_terminal_oldhead_underground": (state, player), "brink_terminal_oldhead_dock": (state, player), "brink_terminal_plaza": (state, player), "brink_terminal_tower": (state, player), "millennium_mall_entrance": (state, player), "millennium_mall_switch": (state, player, limit, glitched), "millennium_mall_oldhead_ceiling": (state, player, limit), "millennium_mall_big": (state, player, limit, glitched), "millennium_mall_theater": (state, player, limit), "pyramid_island_gate": (state, player), "pyramid_island_oldhead": (state, player), "pyramid_island_upper_half": (state, player, limit, glitched), "pyramid_island_crew_battle": (state, player, limit, glitched), "mataan_smoke_wall": (state, player), "mataan_deep_city": (state, player, limit, glitched), "mataan_oldhead": (state, player), "mataan_smoke_wall2": (state, player, limit, glitched), "mataan_deepest": (state, player, limit, glitched) } access_cache: Dict[str, bool] = { "skateboard": skateboard(state, player, movestyle), "inline_skates": inline_skates(state, player, movestyle), "chapter2": current_chapter(state, player, 2), "chapter3": current_chapter(state, player, 3), "chapter4": current_chapter(state, player, 4), "chapter5": current_chapter(state, player, 5) } stop: bool = False for fname, fvars in funcs.items(): if stop: access_cache[fname] = False continue func = globals()[fname] access: bool = func(*fvars) access_cache[fname] = access if not access and "oldhead" not in fname: stop = True return access_cache def graffiti_spots(state: CollectionState, player: int, movestyle: int, limit: bool, glitched: bool, spots: int) -> bool: access_cache = build_access_cache(state, player, movestyle, limit, glitched) total: int = 0 if glitched: total = spots_s_glitched(state, player, limit, access_cache) \ + spots_m_glitched(state, player, limit, access_cache) \ + spots_l_glitched(state, player, limit, access_cache) \ + spots_xl_glitched(state, player, limit, access_cache) else: total = spots_s_glitchless(state, player, limit, access_cache) \ + spots_m_glitchless(state, player, limit, access_cache) \ + spots_l_glitchless(state, player, limit, access_cache) \ + spots_xl_glitchless(state, player, limit, access_cache) return total >= spots def rep(state: CollectionState, player: int, required: int) -> bool: return state.has("rep", player, required) def rules(brcworld): multiworld = brcworld.multiworld player = brcworld.player movestyle = brcworld.options.starting_movestyle limit = brcworld.options.limited_graffiti glitched = brcworld.options.logic extra = brcworld.options.extra_rep_required photos = not brcworld.options.skip_polo_photos # entrances for e in multiworld.get_region(Stages.BT1, player).entrances: set_rule(e, lambda state: brink_terminal_entrance(state, player)) if not glitched: # versum hill for e in multiworld.get_region(Stages.VH1, player).entrances: set_rule(e, lambda state: versum_hill_entrance(state, player)) for e in multiworld.get_region(Stages.VH2, player).entrances: set_rule(e, lambda state: versum_hill_ch1_roadblock(state, player, limit)) for e in multiworld.get_region(Stages.VHO, player).entrances: set_rule(e, lambda state: versum_hill_oldhead(state, player)) for e in multiworld.get_region(Stages.VH3, player).entrances: set_rule(e, lambda state: versum_hill_all_challenges(state, player)) for e in multiworld.get_region(Stages.VH4, player).entrances: set_rule(e, lambda state: versum_hill_basketball_court(state, player)) # millennium square for e in multiworld.get_region(Stages.MS, player).entrances: set_rule(e, lambda state: millennium_square_entrance(state, player)) # brink terminal for e in multiworld.get_region(Stages.BTO1, player).entrances: set_rule(e, lambda state: brink_terminal_oldhead_underground(state, player)) for e in multiworld.get_region(Stages.BTO2, player).entrances: set_rule(e, lambda state: brink_terminal_oldhead_dock(state, player)) for e in multiworld.get_region(Stages.BT2, player).entrances: set_rule(e, lambda state: brink_terminal_plaza(state, player)) for e in multiworld.get_region(Stages.BT3, player).entrances: set_rule(e, lambda state: brink_terminal_tower(state, player)) # millennium mall for e in multiworld.get_region(Stages.MM1, player).entrances: set_rule(e, lambda state: millennium_mall_entrance(state, player)) for e in multiworld.get_region(Stages.MMO1, player).entrances: set_rule(e, lambda state: millennium_mall_oldhead_ceiling(state, player, limit)) for e in multiworld.get_region(Stages.MM2, player).entrances: set_rule(e, lambda state: millennium_mall_big(state, player, limit, glitched)) for e in multiworld.get_region(Stages.MMO2, player).entrances: set_rule(e, lambda state: millennium_mall_oldhead_race(state, player)) for e in multiworld.get_region(Stages.MM3, player).entrances: set_rule(e, lambda state: millennium_mall_theater(state, player, limit)) # pyramid island for e in multiworld.get_region(Stages.PI1, player).entrances: set_rule(e, lambda state: pyramid_island_entrance(state, player)) for e in multiworld.get_region(Stages.PI2, player).entrances: set_rule(e, lambda state: pyramid_island_gate(state, player)) for e in multiworld.get_region(Stages.PIO, player).entrances: set_rule(e, lambda state: pyramid_island_oldhead(state, player)) for e in multiworld.get_region(Stages.PI3, player).entrances: set_rule(e, lambda state: pyramid_island_upper_half(state, player, limit, glitched)) for e in multiworld.get_region(Stages.PI4, player).entrances: set_rule(e, lambda state: pyramid_island_top(state, player)) # mataan for e in multiworld.get_region(Stages.MA1, player).entrances: set_rule(e, lambda state: mataan_entrance(state, player)) for e in multiworld.get_region(Stages.MA2, player).entrances: set_rule(e, lambda state: mataan_smoke_wall(state, player)) for e in multiworld.get_region(Stages.MA3, player).entrances: set_rule(e, lambda state: mataan_deep_city(state, player, limit, glitched)) for e in multiworld.get_region(Stages.MAO, player).entrances: set_rule(e, lambda state: mataan_oldhead(state, player)) for e in multiworld.get_region(Stages.MA4, player).entrances: set_rule(e, lambda state: mataan_smoke_wall2(state, player, limit, glitched)) for e in multiworld.get_region(Stages.MA5, player).entrances: set_rule(e, lambda state: mataan_deepest(state, player, limit, glitched)) # locations # hideout set_rule(multiworld.get_location("Hideout: BMX garage skateboard", player), lambda state: bmx(state, player, movestyle)) set_rule(multiworld.get_location("Hideout: Unlock phone app", player), lambda state: current_chapter(state, player, 2)) set_rule(multiworld.get_location("Hideout: Vinyl joins the crew", player), lambda state: current_chapter(state, player, 4)) set_rule(multiworld.get_location("Hideout: Solace joins the crew", player), lambda state: current_chapter(state, player, 5)) # versum hill set_rule(multiworld.get_location("Versum Hill: Wallrunning challenge reward", player), lambda state: versum_hill_challenge1(state, player)) set_rule(multiworld.get_location("Versum Hill: Manual challenge reward", player), lambda state: versum_hill_challenge2(state, player)) set_rule(multiworld.get_location("Versum Hill: Corner challenge reward", player), lambda state: versum_hill_challenge3(state, player)) set_rule(multiworld.get_location("Versum Hill: BMX gate outfit", player), lambda state: bmx(state, player, movestyle)) set_rule(multiworld.get_location("Versum Hill: Glass floor skates", player), lambda state: inline_skates(state, player, movestyle)) set_rule(multiworld.get_location("Versum Hill: Basketball court shortcut CD", player), lambda state: current_chapter(state, player, 2)) set_rule(multiworld.get_location("Versum Hill: Rave joins the crew", player), lambda state: versum_hill_rave(state, player, limit, glitched)) set_rule(multiworld.get_location("Versum Hill: Frank joins the crew", player), lambda state: current_chapter(state, player, 2)) set_rule(multiworld.get_location("Versum Hill: Rietveld joins the crew", player), lambda state: versum_hill_rietveld(state, player, limit, glitched)) if photos: set_rule(multiworld.get_location("Versum Hill: Big Polo", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Versum Hill: Trash Polo", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Versum Hill: Fruit stand Polo", player), lambda state: camera(state, player)) # millennium square if photos: set_rule(multiworld.get_location("Millennium Square: Half pipe Polo", player), lambda state: camera(state, player)) # brink terminal set_rule(multiworld.get_location("Brink Terminal: Upside grind challenge reward", player), lambda state: brink_terminal_challenge1(state, player)) set_rule(multiworld.get_location("Brink Terminal: Manual challenge reward", player), lambda state: brink_terminal_challenge2(state, player)) set_rule(multiworld.get_location("Brink Terminal: Score challenge reward", player), lambda state: brink_terminal_challenge3(state, player)) set_rule(multiworld.get_location("Brink Terminal: BMX gate graffiti", player), lambda state: bmx(state, player, movestyle)) set_rule(multiworld.get_location("Brink Terminal: Mesh's skateboard", player), lambda state: brink_terminal_mesh(state, player, limit, glitched)) set_rule(multiworld.get_location("Brink Terminal: Rooftop glass CD", player), lambda state: inline_skates(state, player, movestyle)) set_rule(multiworld.get_location("Brink Terminal: Mesh joins the crew", player), lambda state: brink_terminal_mesh(state, player, limit, glitched)) set_rule(multiworld.get_location("Brink Terminal: Eclipse joins the crew", player), lambda state: current_chapter(state, player, 3)) if photos: set_rule(multiworld.get_location("Brink Terminal: Behind glass Polo", player), lambda state: camera(state, player)) # millennium mall set_rule(multiworld.get_location("Millennium Mall: Glass cylinder CD", player), lambda state: inline_skates(state, player, movestyle)) set_rule(multiworld.get_location("Millennium Mall: Trick challenge reward", player), lambda state: millennium_mall_challenge1(state, player)) set_rule(multiworld.get_location("Millennium Mall: Slide challenge reward", player), lambda state: millennium_mall_challenge2(state, player)) set_rule(multiworld.get_location("Millennium Mall: Fish challenge reward", player), lambda state: millennium_mall_challenge3(state, player)) set_rule(multiworld.get_location("Millennium Mall: Score challenge reward", player), lambda state: millennium_mall_challenge4(state, player)) set_rule(multiworld.get_location("Millennium Mall: Atrium BMX gate BMX", player), lambda state: bmx(state, player, movestyle)) set_rule(multiworld.get_location("Millennium Mall: Shine joins the crew", player), lambda state: current_chapter(state, player, 4)) set_rule(multiworld.get_location("Millennium Mall: DOT.EXE joins the crew", player), lambda state: current_chapter(state, player, 4)) # pyramid island set_rule(multiworld.get_location("Pyramid Island: BMX gate BMX", player), lambda state: bmx(state, player, movestyle)) set_rule(multiworld.get_location("Pyramid Island: Score challenge reward", player), lambda state: pyramid_island_challenge1(state, player)) set_rule(multiworld.get_location("Pyramid Island: Score challenge 2 reward", player), lambda state: pyramid_island_challenge2(state, player)) set_rule(multiworld.get_location("Pyramid Island: Quarter pipe challenge reward", player), lambda state: pyramid_island_challenge3(state, player)) set_rule(multiworld.get_location("Pyramid Island: Shortcut glass CD", player), lambda state: inline_skates(state, player, movestyle)) set_rule(multiworld.get_location("Pyramid Island: Maze outfit", player), lambda state: skateboard(state, player, movestyle)) if not glitched: add_rule(multiworld.get_location("Pyramid Island: Rise joins the crew", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Devil Theory joins the crew", player), lambda state: current_chapter(state, player, 5)) if photos: set_rule(multiworld.get_location("Pyramid Island: Polo pile 1", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Polo pile 2", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Polo pile 3", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Polo pile 4", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Maze glass Polo", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Maze classroom Polo", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Maze vent Polo", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Big maze Polo", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Maze desk Polo", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Pyramid Island: Maze forklift Polo", player), lambda state: camera(state, player)) # mataan set_rule(multiworld.get_location("Mataan: Race challenge reward", player), lambda state: mataan_challenge1(state, player, limit, glitched)) set_rule(multiworld.get_location("Mataan: Wallrunning challenge reward", player), lambda state: mataan_challenge2(state, player, limit, glitched)) set_rule(multiworld.get_location("Mataan: Score challenge reward", player), lambda state: mataan_challenge3(state, player)) set_rule(multiworld.get_location("Mataan: Coil joins the crew", player), lambda state: mataan_deepest(state, player, limit, glitched)) if photos: set_rule(multiworld.get_location("Mataan: Trash Polo", player), lambda state: camera(state, player)) set_rule(multiworld.get_location("Mataan: Shopping Polo", player), lambda state: camera(state, player)) # events set_rule(multiworld.get_location("Versum Hill: Complete Chapter 1", player), lambda state: versum_hill_crew_battle(state, player, limit, glitched)) set_rule(multiworld.get_location("Brink Terminal: Complete Chapter 2", player), lambda state: brink_terminal_crew_battle(state, player, limit, glitched)) set_rule(multiworld.get_location("Millennium Mall: Complete Chapter 3", player), lambda state: millennium_mall_crew_battle(state, player, limit, glitched)) set_rule(multiworld.get_location("Pyramid Island: Complete Chapter 4", player), lambda state: pyramid_island_crew_battle(state, player, limit, glitched)) set_rule(multiworld.get_location("Defeat Faux", player), lambda state: mataan_faux(state, player, limit, glitched)) if extra: add_rule(multiworld.get_location("Defeat Faux", player), lambda state: rep(state, player, 1000)) # graffiti spots spots: int = 0 while spots < 385: spots += 5 set_rule(multiworld.get_location(f"Tagged {spots} Graffiti Spots", player), lambda state, spot_count=spots: graffiti_spots(state, player, movestyle, limit, glitched, spot_count)) set_rule(multiworld.get_location("Tagged 389 Graffiti Spots", player), lambda state: graffiti_spots(state, player, movestyle, limit, glitched, 389))