Archipelago/worlds/overcooked2/Overcooked2Levels.py

375 lines
16 KiB
Python
Raw Normal View History

from enum import Enum
from typing import List
class Overcooked2Dlc(Enum):
STORY = "Story"
SURF_N_TURF = "Surf 'n' Turf"
CAMPFIRE_COOK_OFF = "Campfire Cook Off"
NIGHT_OF_THE_HANGRY_HORDE = "Night of the Hangry Horde"
CARNIVAL_OF_CHAOS = "Carnival of Chaos"
SEASONAL = "Seasonal"
# CHRISTMAS = "Christmas"
# CHINESE_NEW_YEAR = "Chinese New Year"
# WINTER_WONDERLAND = "Winter Wonderland"
# MOON_HARVEST = "Moon Harvest"
# SPRING_FRESTIVAL = "Spring Festival"
# SUNS_OUT_BUNS_OUT = "Sun's Out Buns Out"
def __int__(self) -> int:
if self == Overcooked2Dlc.STORY:
return 0
if self == Overcooked2Dlc.SURF_N_TURF:
return 1
if self == Overcooked2Dlc.CAMPFIRE_COOK_OFF:
return 2
if self == Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE:
return 3
if self == Overcooked2Dlc.CARNIVAL_OF_CHAOS:
return 4
if self == Overcooked2Dlc.SEASONAL:
return 5
assert False
# inclusive
@property
def start_level_id(self) -> int:
return 0
# exclusive
@property
def end_level_id(self) -> int:
id = None
if self == Overcooked2Dlc.STORY:
id = 1 + 6*6 + 8 # tutorial + world_count*level_count + kevin count
if self == Overcooked2Dlc.SURF_N_TURF:
id = 3*4 + 1
if self == Overcooked2Dlc.CAMPFIRE_COOK_OFF:
id = 3*4 + 3
if self == Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE:
id = 3*3 + 3 + 8
if self == Overcooked2Dlc.CARNIVAL_OF_CHAOS:
id = 3*4 + 3
if self == Overcooked2Dlc.SEASONAL:
id = 31 + 1
return self.start_level_id + id
# Tutorial + Horde Levels + Endgame
def excluded_levels(self) -> List[int]:
if self == Overcooked2Dlc.STORY:
return [0, 36]
return []
def horde_levels(self) -> List[int]:
if self == Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE:
return [12, 13, 14, 15, 16, 17, 18, 19]
if self == Overcooked2Dlc.SEASONAL:
return [13, 15]
return []
def prep_levels(self) -> List[int]:
if self == Overcooked2Dlc.STORY:
return [1, 2, 5, 10, 12, 13, 28, 31]
if self == Overcooked2Dlc.SURF_N_TURF:
return [0, 4]
if self == Overcooked2Dlc.CAMPFIRE_COOK_OFF:
return [0, 2, 4, 9]
if self == Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE:
return [0, 1, 4]
if self == Overcooked2Dlc.CARNIVAL_OF_CHAOS:
return [0, 1, 3, 4, 5]
if self == Overcooked2Dlc.SEASONAL:
# moon 1-1 is a prep level for 1P only, but we can't make that assumption here
return [0, 1, 5, 6, 12, 14, 16, 17, 18, 22, 23, 24, 27, 29]
return []
def exclusive_items(self) -> List[str]:
"""Returns list of items exclusive to this DLC"""
if self == Overcooked2Dlc.SURF_N_TURF:
return ["Bellows"]
if self == Overcooked2Dlc.CAMPFIRE_COOK_OFF:
return ["Wood"]
if self == Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE:
return ["Coal Bucket"]
if self == Overcooked2Dlc.CARNIVAL_OF_CHAOS:
return ["Faster Condiment/Drink Switch"]
if self == Overcooked2Dlc.SEASONAL:
return ["Wok Wheels"]
return []
ITEMS_TO_EXCLUDE_IF_NO_DLC = [
"Wood",
"Coal Bucket",
"Bellows",
"Coin Purse",
"Wok Wheels",
"Lightweight Backpack",
"Faster Condiment/Drink Switch",
"Calmer Unbread",
]
class Overcooked2GameWorld(Enum):
ONE = 1
TWO = 2
THREE = 3
FOUR = 4
FIVE = 5
SIX = 6
KEVIN = 7
@property
def as_str(self) -> str:
if self == Overcooked2GameWorld.KEVIN:
return "Kevin"
return str(int(self.value))
@property
def sublevel_count(self) -> int:
if self == Overcooked2GameWorld.KEVIN:
return 8
return 6
@property
def base_id(self) -> int:
if self == Overcooked2GameWorld.ONE:
return 1
prev = Overcooked2GameWorld(self.value - 1)
return prev.base_id + prev.sublevel_count
@property
def name(self) -> str:
if self == Overcooked2GameWorld.KEVIN:
return "Kevin"
return "World " + self.as_str
class Overcooked2GenericLevel():
dlc: Overcooked2Dlc
level_id: int
def __init__(self, level_id: int, dlc: Overcooked2Dlc = Overcooked2Dlc("Story")):
self.dlc = dlc
self.level_id = level_id
def __str__(self) -> str:
return f"{self.dlc.value}|{self.level_id}"
def __repr__(self) -> str:
return f"{self}"
@property
def shortname(self) -> str:
return level_id_to_shortname[(self.dlc, self.level_id)]
@property
def is_horde(self) -> bool:
return self.level_id in self.dlc.horde_levels()
class Overcooked2Level:
"""
Abstraction for a playable levels in Overcooked 2. By default constructor
it can be used as an iterator for all locations in the Story map.
"""
world: Overcooked2GameWorld
sublevel: int
def __init__(self):
self.world = Overcooked2GameWorld.ONE
self.sublevel = 0
def __iter__(self):
return self
def __next__(self):
self.sublevel += 1
if self.sublevel > self.world.sublevel_count:
if self.world == Overcooked2GameWorld.KEVIN:
raise StopIteration
self.world = Overcooked2GameWorld(self.world.value + 1)
self.sublevel = 1
return self
@property
def level_id(self) -> int:
return self.world.base_id + (self.sublevel - 1)
@property
def level_name(self) -> str:
return self.world.as_str + "-" + str(self.sublevel)
@property
def location_name_item(self) -> str:
return self.level_name + " Completed"
@property
def location_name_level_complete(self) -> str:
return self.level_name + " Level Completed"
@property
def event_name_level_complete(self) -> str:
return self.level_name + " Level Complete"
def location_name_star_event(self, stars: int) -> str:
return "%s (%d-Star)" % (self.level_name, stars)
@property
def as_generic_level(self) -> Overcooked2GenericLevel:
return Overcooked2GenericLevel(self.level_id)
# Note that there are valid levels beyond what is listed here, but they are all
# Onion King Dialogs
level_id_to_shortname = {
(Overcooked2Dlc.STORY , 0 ): "Tutorial" ,
(Overcooked2Dlc.STORY , 1 ): "Story 1-1" ,
(Overcooked2Dlc.STORY , 2 ): "Story 1-2" ,
(Overcooked2Dlc.STORY , 3 ): "Story 1-3" ,
(Overcooked2Dlc.STORY , 4 ): "Story 1-4" ,
(Overcooked2Dlc.STORY , 5 ): "Story 1-5" ,
(Overcooked2Dlc.STORY , 6 ): "Story 1-6" ,
(Overcooked2Dlc.STORY , 7 ): "Story 2-1" ,
(Overcooked2Dlc.STORY , 8 ): "Story 2-2" ,
(Overcooked2Dlc.STORY , 9 ): "Story 2-3" ,
(Overcooked2Dlc.STORY , 10 ): "Story 2-4" ,
(Overcooked2Dlc.STORY , 11 ): "Story 2-5" ,
(Overcooked2Dlc.STORY , 12 ): "Story 2-6" ,
(Overcooked2Dlc.STORY , 13 ): "Story 3-1" ,
(Overcooked2Dlc.STORY , 14 ): "Story 3-2" ,
(Overcooked2Dlc.STORY , 15 ): "Story 3-3" ,
(Overcooked2Dlc.STORY , 16 ): "Story 3-4" ,
(Overcooked2Dlc.STORY , 17 ): "Story 3-5" ,
(Overcooked2Dlc.STORY , 18 ): "Story 3-6" ,
(Overcooked2Dlc.STORY , 19 ): "Story 4-1" ,
(Overcooked2Dlc.STORY , 20 ): "Story 4-2" ,
(Overcooked2Dlc.STORY , 21 ): "Story 4-3" ,
(Overcooked2Dlc.STORY , 22 ): "Story 4-4" ,
(Overcooked2Dlc.STORY , 23 ): "Story 4-5" ,
(Overcooked2Dlc.STORY , 24 ): "Story 4-6" ,
(Overcooked2Dlc.STORY , 25 ): "Story 5-1" ,
(Overcooked2Dlc.STORY , 26 ): "Story 5-2" ,
(Overcooked2Dlc.STORY , 27 ): "Story 5-3" ,
(Overcooked2Dlc.STORY , 28 ): "Story 5-4" ,
(Overcooked2Dlc.STORY , 29 ): "Story 5-5" ,
(Overcooked2Dlc.STORY , 30 ): "Story 5-6" ,
(Overcooked2Dlc.STORY , 31 ): "Story 6-1" ,
(Overcooked2Dlc.STORY , 32 ): "Story 6-2" ,
(Overcooked2Dlc.STORY , 33 ): "Story 6-3" ,
(Overcooked2Dlc.STORY , 34 ): "Story 6-4" ,
(Overcooked2Dlc.STORY , 35 ): "Story 6-5" ,
(Overcooked2Dlc.STORY , 36 ): "Story 6-6" ,
(Overcooked2Dlc.STORY , 37 ): "Story K-1" ,
(Overcooked2Dlc.STORY , 38 ): "Story K-2" ,
(Overcooked2Dlc.STORY , 39 ): "Story K-3" ,
(Overcooked2Dlc.STORY , 40 ): "Story K-4" ,
(Overcooked2Dlc.STORY , 41 ): "Story K-5" ,
(Overcooked2Dlc.STORY , 42 ): "Story K-6" ,
(Overcooked2Dlc.STORY , 43 ): "Story K-7" ,
(Overcooked2Dlc.STORY , 44 ): "Story K-8" ,
(Overcooked2Dlc.SURF_N_TURF , 0 ): "Surf 1-1" ,
(Overcooked2Dlc.SURF_N_TURF , 1 ): "Surf 1-2" ,
(Overcooked2Dlc.SURF_N_TURF , 2 ): "Surf 1-3" ,
(Overcooked2Dlc.SURF_N_TURF , 3 ): "Surf 1-4" ,
(Overcooked2Dlc.SURF_N_TURF , 4 ): "Surf 2-1" ,
(Overcooked2Dlc.SURF_N_TURF , 5 ): "Surf 2-2" ,
(Overcooked2Dlc.SURF_N_TURF , 6 ): "Surf 2-3" ,
(Overcooked2Dlc.SURF_N_TURF , 7 ): "Surf 2-4" ,
(Overcooked2Dlc.SURF_N_TURF , 8 ): "Surf 3-1" ,
(Overcooked2Dlc.SURF_N_TURF , 9 ): "Surf 3-2" ,
(Overcooked2Dlc.SURF_N_TURF , 10 ): "Surf 3-3" ,
(Overcooked2Dlc.SURF_N_TURF , 11 ): "Surf 3-4" ,
(Overcooked2Dlc.SURF_N_TURF , 12 ): "Surf K-1" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 0 ): "Campfire 1-1" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 1 ): "Campfire 1-2" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 2 ): "Campfire 1-3" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 3 ): "Campfire 1-4" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 4 ): "Campfire 2-1" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 5 ): "Campfire 2-2" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 6 ): "Campfire 2-3" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 7 ): "Campfire 2-4" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 8 ): "Campfire 3-1" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 9 ): "Campfire 3-2" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 10 ): "Campfire 3-3" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 11 ): "Campfire 3-4" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 12 ): "Campfire K-1" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 13 ): "Campfire K-2" ,
(Overcooked2Dlc.CAMPFIRE_COOK_OFF , 14 ): "Campfire K-3" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 0 ): "Carnival 1-1" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 1 ): "Carnival 1-2" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 2 ): "Carnival 1-3" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 3 ): "Carnival 1-4" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 4 ): "Carnival 2-1" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 5 ): "Carnival 2-2" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 6 ): "Carnival 2-3" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 7 ): "Carnival 2-4" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 8 ): "Carnival 3-1" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 9 ): "Carnival 3-2" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 10 ): "Carnival 3-3" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 11 ): "Carnival 3-4" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 12 ): "Carnival K-1" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 13 ): "Carnival K-2" ,
(Overcooked2Dlc.CARNIVAL_OF_CHAOS , 14 ): "Carnival K-3" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 0 ): "Horde 1-1" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 1 ): "Horde 1-2" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 2 ): "Horde 1-3" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 3 ): "Horde 2-1" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 4 ): "Horde 2-2" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 5 ): "Horde 2-3" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 6 ): "Horde 3-1" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 7 ): "Horde 3-2" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 8 ): "Horde 3-3" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 9 ): "Horde K-1" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 10 ): "Horde K-2" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 11 ): "Horde K-3" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 12 ): "Horde H-1" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 13 ): "Horde H-2" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 14 ): "Horde H-3" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 15 ): "Horde H-4" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 16 ): "Horde H-5" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 17 ): "Horde H-6" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 18 ): "Horde H-7" ,
(Overcooked2Dlc.NIGHT_OF_THE_HANGRY_HORDE , 19 ): "Horde H-8" ,
(Overcooked2Dlc.SEASONAL , 0 ): "Christmas 1-1" ,
(Overcooked2Dlc.SEASONAL , 1 ): "Christmas 1-2" ,
(Overcooked2Dlc.SEASONAL , 2 ): "Christmas 1-3" ,
(Overcooked2Dlc.SEASONAL , 3 ): "Christmas 1-4" ,
(Overcooked2Dlc.SEASONAL , 4 ): "Christmas 1-5" ,
(Overcooked2Dlc.SEASONAL , 5 ): "Chinese 1-1" ,
(Overcooked2Dlc.SEASONAL , 6 ): "Chinese 1-2" ,
(Overcooked2Dlc.SEASONAL , 7 ): "Chinese 1-3" ,
(Overcooked2Dlc.SEASONAL , 8 ): "Chinese 1-4" ,
(Overcooked2Dlc.SEASONAL , 9 ): "Chinese 1-5" ,
(Overcooked2Dlc.SEASONAL , 10 ): "Chinese 1-6" ,
(Overcooked2Dlc.SEASONAL , 11 ): "Chinese 1-7" ,
(Overcooked2Dlc.SEASONAL , 12 ): "Winter 1-1" ,
(Overcooked2Dlc.SEASONAL , 13 ): "Winter H-2" ,
(Overcooked2Dlc.SEASONAL , 14 ): "Winter 1-3" ,
(Overcooked2Dlc.SEASONAL , 15 ): "Winter H-4" ,
(Overcooked2Dlc.SEASONAL , 16 ): "Winter 1-5" ,
(Overcooked2Dlc.SEASONAL , 17 ): "Spring 1-1" ,
(Overcooked2Dlc.SEASONAL , 18 ): "Spring 1-2" ,
(Overcooked2Dlc.SEASONAL , 19 ): "Spring 1-3" ,
(Overcooked2Dlc.SEASONAL , 20 ): "Spring 1-4" ,
(Overcooked2Dlc.SEASONAL , 21 ): "Spring 1-5" ,
(Overcooked2Dlc.SEASONAL , 22 ): "SOBO 1-1" ,
(Overcooked2Dlc.SEASONAL , 23 ): "SOBO 1-2" ,
(Overcooked2Dlc.SEASONAL , 24 ): "SOBO 1-3" ,
(Overcooked2Dlc.SEASONAL , 25 ): "SOBO 1-4" ,
(Overcooked2Dlc.SEASONAL , 26 ): "SOBO 1-5" ,
(Overcooked2Dlc.SEASONAL , 27 ): "Moon 1-1" ,
(Overcooked2Dlc.SEASONAL , 28 ): "Moon 1-2" ,
(Overcooked2Dlc.SEASONAL , 29 ): "Moon 1-3" ,
(Overcooked2Dlc.SEASONAL , 30 ): "Moon 1-4" ,
(Overcooked2Dlc.SEASONAL , 31 ): "Moon 1-5" ,
}