DLCQuest : implement new game (#1628)

adding DLC Quest as a new game
This commit is contained in:
axe-y 2023-04-09 15:06:59 -04:00 committed by GitHub
parent 8e7bbb4ea8
commit bbef7a4cbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 1305 additions and 0 deletions

133
worlds/dlcquest/Items.py Normal file
View File

@ -0,0 +1,133 @@
import csv
import enum
import math
from typing import Protocol, Union, Dict, List
from BaseClasses import Item, ItemClassification
from . import Options, data
from dataclasses import dataclass, field
from random import Random
class DLCQuestItem(Item):
game: str = "DLCQuest"
offset = 120_000
class Group(enum.Enum):
DLC = enum.auto()
DLCQuest = enum.auto()
Freemium = enum.auto()
Item = enum.auto()
Coin = enum.auto()
Trap = enum.auto()
@dataclass(frozen=True)
class ItemData:
code_without_offset: offset
name: str
classification: ItemClassification
groups: set[Group] = field(default_factory=frozenset)
def __post_init__(self):
if not isinstance(self.groups, frozenset):
super().__setattr__("groups", frozenset(self.groups))
@property
def code(self):
return offset + self.code_without_offset if self.code_without_offset is not None else None
def has_any_group(self, *group: Group) -> bool:
groups = set(group)
return bool(groups.intersection(self.groups))
def load_item_csv():
try:
from importlib.resources import files
except ImportError:
from importlib_resources import files # noqa
items = []
with files(data).joinpath("items.csv").open() as file:
item_reader = csv.DictReader(file)
for item in item_reader:
id = int(item["id"]) if item["id"] else None
classification = ItemClassification[item["classification"]]
groups = {Group[group] for group in item["groups"].split(",") if group}
items.append(ItemData(id, item["name"], classification, groups))
return items
all_items: List[ItemData] = load_item_csv()
item_table: Dict[str, ItemData] = {}
items_by_group: Dict[Group, List[ItemData]] = {}
def initialize_item_table():
item_table.update({item.name: item for item in all_items})
def initialize_groups():
for item in all_items:
for group in item.groups:
item_group = items_by_group.get(group, list())
item_group.append(item)
items_by_group[group] = item_group
initialize_item_table()
initialize_groups()
def create_trap_items(world, World_Options: Options.DLCQuestOptions, trap_needed: int, random: Random) -> List[Item]:
traps = []
for i in range(trap_needed):
trap = random.choice(items_by_group[Group.Trap])
traps.append(world.create_item(trap))
return traps
def create_items(world, World_Options: Options.DLCQuestOptions, locations_count: int, random: Random):
created_items = []
if World_Options[Options.Campaign] == Options.Campaign.option_basic or World_Options[
Options.Campaign] == Options.Campaign.option_both:
for item in items_by_group[Group.DLCQuest]:
if item.has_any_group(Group.DLC):
created_items.append(world.create_item(item))
if item.has_any_group(Group.Item) and World_Options[
Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
created_items.append(world.create_item(item))
if World_Options[Options.CoinSanity] == Options.CoinSanity.option_coin:
coin_bundle_needed = math.floor(825 / World_Options[Options.CoinSanityRange])
for item in items_by_group[Group.DLCQuest]:
if item.has_any_group(Group.Coin):
for i in range(coin_bundle_needed):
created_items.append(world.create_item(item))
if 825 % World_Options[Options.CoinSanityRange] != 0:
created_items.append(world.create_item(item))
if World_Options[Options.Campaign] == Options.Campaign.option_live_freemium_or_die or World_Options[
Options.Campaign] == Options.Campaign.option_both:
for item in items_by_group[Group.Freemium]:
if item.has_any_group(Group.DLC):
created_items.append(world.create_item(item))
if item.has_any_group(Group.Item) and World_Options[
Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
created_items.append(world.create_item(item))
if World_Options[Options.CoinSanity] == Options.CoinSanity.option_coin:
coin_bundle_needed = math.floor(889 / World_Options[Options.CoinSanityRange])
for item in items_by_group[Group.Freemium]:
if item.has_any_group(Group.Coin):
for i in range(coin_bundle_needed):
created_items.append(world.create_item(item))
if 889 % World_Options[Options.CoinSanityRange] != 0:
created_items.append(world.create_item(item))
trap_items = create_trap_items(world, World_Options, locations_count - len(created_items), random)
created_items += trap_items
return created_items

View File

@ -0,0 +1,79 @@
from BaseClasses import Location, MultiWorld
from . import Options
class DLCQuestLocation(Location):
game: str = "DLCQuest"
offset = 120_000
location_table = {
"Movement Pack": offset + 0,
"Animation Pack": offset + 1,
"Audio Pack": offset + 2,
"Pause Menu Pack": offset + 3,
"Time is Money Pack": offset + 4,
"Double Jump Pack": offset + 5,
"Pet Pack": offset + 6,
"Sexy Outfits Pack": offset + 7,
"Top Hat Pack": offset + 8,
"Map Pack": offset + 9,
"Gun Pack": offset + 10,
"The Zombie Pack": offset + 11,
"Night Map Pack": offset + 12,
"Psychological Warfare Pack": offset + 13,
"Armor for your Horse Pack": offset + 14,
"Finish the Fight Pack": offset + 15,
"Particles Pack": offset + 16,
"Day One Patch Pack": offset + 17,
"Checkpoint Pack": offset + 18,
"Incredibly Important Pack": offset + 19,
"Wall Jump Pack": offset + 20,
"Health Bar Pack": offset + 21,
"Parallax Pack": offset + 22,
"Harmless Plants Pack": offset + 23,
"Death of Comedy Pack": offset + 24,
"Canadian Dialog Pack": offset + 25,
"DLC NPC Pack": offset + 26,
"Cut Content Pack": offset + 27,
"Name Change Pack": offset + 28,
"Season Pass": offset + 29,
"High Definition Next Gen Pack": offset + 30,
"Increased HP Pack": offset + 31,
"Remove Ads Pack": offset + 32,
"Big Sword Pack": offset + 33,
"Really Big Sword Pack": offset + 34,
"Unfathomable Sword Pack": offset + 35,
"Pickaxe": offset + 36,
"Gun": offset + 37,
"Sword": offset + 38,
"Wooden Sword": offset + 39,
"Box of Various Supplies": offset + 40,
"Humble Indie Bindle": offset + 41,
"Double Jump Alcove Sheep": offset + 42,
"Double Jump Floating Sheep": offset + 43,
"Sexy Outfits Sheep": offset + 44,
"Forest High Sheep": offset + 45,
"Forest Low Sheep": offset + 46,
"Between Trees Sheep": offset + 47,
"Hole in the Wall Sheep": offset + 48,
"Shepherd Sheep": offset + 49,
"Top Hat Sheep": offset + 50,
"North West Ceiling Sheep": offset + 51,
"North West Alcove Sheep": offset + 52,
"West Cave Sheep": offset + 53,
"Cutscene Sheep": offset + 54,
"Not Exactly Noble": offset + 55,
"Story is Important": offset + 56,
"Nice Try": offset + 57,
"I Get That Reference!": offset + 58,
}
for i in range(1, 826):
item_coin = f"DLC Quest: {i} Coin"
location_table[item_coin] = offset + 58 + i
for i in range(1, 890):
item_coin_freemium = f"Live Freemium or Die: {i} Coin"
location_table[item_coin_freemium] = offset + 825 + 58 + i

114
worlds/dlcquest/Options.py Normal file
View File

@ -0,0 +1,114 @@
from typing import Union, Dict, runtime_checkable, Protocol
from Options import Option, DeathLink, Choice, Toggle, SpecialRange
from dataclasses import dataclass
@runtime_checkable
class DLCQuestOption(Protocol):
internal_name: str
@dataclass
class DLCQuestOptions:
options: Dict[str, Union[bool, int]]
def __getitem__(self, item: Union[str, DLCQuestOption]) -> Union[bool, int]:
if isinstance(item, DLCQuestOption):
item = item.internal_name
return self.options.get(item, None)
class FalseDoubleJump(Choice):
"""If you can do a double jump without the pack for it (glitch)."""
internal_name = "double_jump_glitch"
display_name = "Double Jump glitch"
option_none = 0
option_simple = 1
option_all = 2
default = 0
class TimeIsMoney(Choice):
"""Is your time worth the money, are you ready to grind your sword by hand?"""
internal_name = "time_is_money"
display_name = "Time Is Money"
option_required = 0
option_optional = 1
default = 0
class CoinSanity(Choice):
"""This is for the insane it can be 825 check, it is coin sanity"""
internal_name = "coinsanity"
display_name = "CoinSanity"
option_none = 0
option_coin = 1
default = 0
class CoinSanityRange(SpecialRange):
"""This is the amount of coin in a coin bundle"""
internal_name = "coinbundlequantity"
display_name = "Coin Bundle Quantity"
range_start = 1
range_end = 100
default = 20
class EndingChoice(Choice):
"""This is for the ending type of the basic game"""
internal_name = "ending_choice"
display_name = "Ending Choice"
option_any = 0
option_true = 1
default = 1
class Campaign(Choice):
"""Whitch game you wana play to end"""
internal_name = "campaign"
display_name = "Campaign"
option_basic = 0
option_live_freemium_or_die = 1
option_both = 2
default = 0
class ItemShuffle(Choice):
"""Should Inventory Items be separate from their DLCs and shuffled in the item pool"""
internal_name = "item_shuffle"
display_name = "Item Shuffle"
option_disabled = 0
option_shuffled = 1
default = 0
DLCQuest_options: Dict[str, type(Option)] = {
option.internal_name: option
for option in [
FalseDoubleJump,
CoinSanity,
CoinSanityRange,
TimeIsMoney,
EndingChoice,
Campaign,
ItemShuffle,
]
}
default_options = {option.internal_name: option.default for option in DLCQuest_options.values()}
DLCQuest_options["death_link"] = DeathLink
def fetch_options(world, player: int) -> DLCQuestOptions:
return DLCQuestOptions({option: get_option_value(world, player, option) for option in DLCQuest_options})
def get_option_value(world, player: int, name: str) -> Union[bool, int]:
assert name in DLCQuest_options, f"{name} is not a valid option for DLC Quest."
value = getattr(world, name)
if issubclass(DLCQuest_options[name], Toggle):
return bool(value[player].value)
return value[player].value

325
worlds/dlcquest/Regions.py Normal file
View File

@ -0,0 +1,325 @@
import math
from BaseClasses import MultiWorld, Region, Location, Entrance, ItemClassification
from .Locations import DLCQuestLocation, location_table
from .Rules import create_event
from . import Options
DLCQuestRegion = ["Movement Pack", "Behind Tree", "Psychological Warfare", "Double Jump Left",
"Double Jump Behind the Tree", "The Forest", "Final Room"]
def add_coin_freemium(region: Region, Coin: int, player: int):
number_coin = f"{Coin} coins freemium"
location_coin = f"{region.name} coins freemium"
location = DLCQuestLocation(player, location_coin, None, region)
region.locations.append(location)
location.place_locked_item(create_event(player, number_coin))
def add_coin_dlcquest(region: Region, Coin: int, player: int):
number_coin = f"{Coin} coins"
location_coin = f"{region.name} coins"
location = DLCQuestLocation(player, location_coin, None, region)
region.locations.append(location)
location.place_locked_item(create_event(player, number_coin))
def create_regions(world: MultiWorld, player: int, World_Options: Options.DLCQuestOptions):
Regmenu = Region("Menu", player, world)
if World_Options[Options.Campaign] == Options.Campaign.option_basic or World_Options[
Options.Campaign] == Options.Campaign.option_both:
Regmenu.exits += [Entrance(player, "DLC Quest Basic", Regmenu)]
if World_Options[Options.Campaign] == Options.Campaign.option_live_freemium_or_die or World_Options[
Options.Campaign] == Options.Campaign.option_both:
Regmenu.exits += [Entrance(player, "Live Freemium or Die", Regmenu)]
world.regions.append(Regmenu)
if World_Options[Options.Campaign] == Options.Campaign.option_basic or World_Options[
Options.Campaign] == Options.Campaign.option_both:
Regmoveright = Region("Move Right", player, world, "Start of the basic game")
Locmoveright_name = ["Movement Pack", "Animation Pack", "Audio Pack", "Pause Menu Pack"]
Regmoveright.exits = [Entrance(player, "Moving", Regmoveright)]
Regmoveright.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regmoveright) for
loc_name in Locmoveright_name]
add_coin_dlcquest(Regmoveright, 4, player)
if World_Options[Options.CoinSanity] == Options.CoinSanity.option_coin:
coin_bundle_needed = math.floor(825 / World_Options[Options.CoinSanityRange])
for i in range(coin_bundle_needed):
item_coin = f"DLC Quest: {World_Options[Options.CoinSanityRange] * (i + 1)} Coin"
Regmoveright.locations += [
DLCQuestLocation(player, item_coin, location_table[item_coin], Regmoveright)]
if 825 % World_Options[Options.CoinSanityRange] != 0:
Regmoveright.locations += [
DLCQuestLocation(player, "DLC Quest: 825 Coin", location_table["DLC Quest: 825 Coin"],
Regmoveright)]
world.regions.append(Regmoveright)
Regmovpack = Region("Movement Pack", player, world)
Locmovpack_name = ["Time is Money Pack", "Psychological Warfare Pack", "Armor for your Horse Pack",
"Shepherd Sheep"]
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
Locmovpack_name += ["Sword"]
Regmovpack.exits = [Entrance(player, "Tree", Regmovpack), Entrance(player, "Cloud", Regmovpack)]
Regmovpack.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regmovpack) for loc_name
in Locmovpack_name]
add_coin_dlcquest(Regmovpack, 46, player)
world.regions.append(Regmovpack)
Regbtree = Region("Behind Tree", player, world)
Locbtree_name = ["Double Jump Pack", "Map Pack", "Between Trees Sheep", "Hole in the Wall Sheep"]
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
Locbtree_name += ["Gun"]
Regbtree.exits = [Entrance(player, "Behind Tree Double Jump", Regbtree),
Entrance(player, "Forest Entrance", Regbtree)]
Regbtree.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regbtree) for loc_name in
Locbtree_name]
add_coin_dlcquest(Regbtree, 60, player)
world.regions.append(Regbtree)
Regpsywarfare = Region("Psychological Warfare", player, world)
Locpsywarfare_name = ["West Cave Sheep"]
Regpsywarfare.exits = [Entrance(player, "Cloud Double Jump", Regpsywarfare)]
Regpsywarfare.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regpsywarfare) for
loc_name in Locpsywarfare_name]
add_coin_dlcquest(Regpsywarfare, 100, player)
world.regions.append(Regpsywarfare)
Regdoubleleft = Region("Double Jump Total Left", player, world)
Locdoubleleft_name = ["Pet Pack", "Top Hat Pack", "North West Alcove Sheep"]
Regdoubleleft.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regdoubleleft) for
loc_name in
Locdoubleleft_name]
Regdoubleleft.exits = [Entrance(player, "Cave Tree", Regdoubleleft),
Entrance(player, "Cave Roof", Regdoubleleft)]
add_coin_dlcquest(Regdoubleleft, 50, player)
world.regions.append(Regdoubleleft)
Regdoubleleftcave = Region("Double Jump Total Left Cave", player, world)
Locdoubleleftcave_name = ["Top Hat Sheep"]
Regdoubleleftcave.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regdoubleleftcave)
for loc_name in Locdoubleleftcave_name]
add_coin_dlcquest(Regdoubleleftcave, 9, player)
world.regions.append(Regdoubleleftcave)
Regdoubleleftroof = Region("Double Jump Total Left Roof", player, world)
Locdoubleleftroof_name = ["North West Ceiling Sheep"]
Regdoubleleftroof.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regdoubleleftroof)
for loc_name in Locdoubleleftroof_name]
add_coin_dlcquest(Regdoubleleftroof, 10, player)
world.regions.append(Regdoubleleftroof)
Regdoubletree = Region("Double Jump Behind Tree", player, world)
Locdoubletree_name = ["Sexy Outfits Pack", "Double Jump Alcove Sheep", "Sexy Outfits Sheep"]
Regdoubletree.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regdoubletree) for
loc_name in
Locdoubletree_name]
Regdoubletree.exits = [Entrance(player, "True Double Jump", Regdoubletree)]
add_coin_dlcquest(Regdoubletree, 89, player)
world.regions.append(Regdoubletree)
Regtruedoublejump = Region("True Double Jump Behind Tree", player, world)
Loctruedoublejump_name = ["Double Jump Floating Sheep", "Cutscene Sheep"]
Regtruedoublejump.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regtruedoublejump)
for loc_name in Loctruedoublejump_name]
add_coin_dlcquest(Regtruedoublejump, 7, player)
world.regions.append(Regtruedoublejump)
Regforest = Region("The Forest", player, world)
Locforest_name = ["Gun Pack", "Night Map Pack"]
Regforest.exits = [Entrance(player, "Behind Ogre", Regforest),
Entrance(player, "Forest Double Jump", Regforest)]
Regforest.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regforest) for loc_name in
Locforest_name]
add_coin_dlcquest(Regforest, 169, player)
world.regions.append(Regforest)
Regforestdoublejump = Region("The Forest whit double Jump", player, world)
Locforestdoublejump_name = ["The Zombie Pack", "Forest Low Sheep"]
Regforestdoublejump.exits = [Entrance(player, "Forest True Double Jump", Regforestdoublejump)]
Regforestdoublejump.locations += [
DLCQuestLocation(player, loc_name, location_table[loc_name], Regforestdoublejump) for loc_name in
Locforestdoublejump_name]
add_coin_dlcquest(Regforestdoublejump, 76, player)
world.regions.append(Regforestdoublejump)
Regforesttruedoublejump = Region("The Forest whit double Jump Part 2", player, world)
Locforesttruedoublejump_name = ["Forest High Sheep"]
Regforesttruedoublejump.locations += [
DLCQuestLocation(player, loc_name, location_table[loc_name], Regforesttruedoublejump)
for loc_name in Locforesttruedoublejump_name]
add_coin_dlcquest(Regforesttruedoublejump, 203, player)
world.regions.append(Regforesttruedoublejump)
Regfinalroom = Region("The Final Boss Room", player, world)
Locfinalroom_name = ["Finish the Fight Pack"]
Regfinalroom.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regfinalroom) for
loc_name in
Locfinalroom_name]
world.regions.append(Regfinalroom)
loc_win = DLCQuestLocation(player, "Winning Basic", None, world.get_region("The Final Boss Room", player))
world.get_region("The Final Boss Room", player).locations.append(loc_win)
loc_win.place_locked_item(create_event(player, "Victory Basic"))
world.get_entrance("DLC Quest Basic", player).connect(world.get_region("Move Right", player))
world.get_entrance("Moving", player).connect(world.get_region("Movement Pack", player))
world.get_entrance("Tree", player).connect(world.get_region("Behind Tree", player))
world.get_entrance("Cloud", player).connect(world.get_region("Psychological Warfare", player))
world.get_entrance("Cloud Double Jump", player).connect(world.get_region("Double Jump Total Left", player))
world.get_entrance("Cave Tree", player).connect(world.get_region("Double Jump Total Left Cave", player))
world.get_entrance("Cave Roof", player).connect(world.get_region("Double Jump Total Left Roof", player))
world.get_entrance("Forest Entrance", player).connect(world.get_region("The Forest", player))
world.get_entrance("Behind Tree Double Jump", player).connect(
world.get_region("Double Jump Behind Tree", player))
world.get_entrance("Behind Ogre", player).connect(world.get_region("The Final Boss Room", player))
world.get_entrance("Forest Double Jump", player).connect(
world.get_region("The Forest whit double Jump", player))
world.get_entrance("Forest True Double Jump", player).connect(
world.get_region("The Forest whit double Jump Part 2", player))
world.get_entrance("True Double Jump", player).connect(world.get_region("True Double Jump Behind Tree", player))
if World_Options[Options.Campaign] == Options.Campaign.option_live_freemium_or_die or World_Options[
Options.Campaign] == Options.Campaign.option_both:
Regfreemiumstart = Region("Freemium Start", player, world)
Locfreemiumstart_name = ["Particles Pack", "Day One Patch Pack", "Checkpoint Pack", "Incredibly Important Pack",
"Nice Try", "Story is Important", "I Get That Reference!"]
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
Locfreemiumstart_name += ["Wooden Sword"]
Regfreemiumstart.exits = [Entrance(player, "Vines", Regfreemiumstart)]
Regfreemiumstart.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regfreemiumstart)
for loc_name in
Locfreemiumstart_name]
add_coin_freemium(Regfreemiumstart, 50, player)
if World_Options[Options.CoinSanity] == Options.CoinSanity.option_coin:
coin_bundle_needed = math.floor(889 / World_Options[Options.CoinSanityRange])
for i in range(coin_bundle_needed):
item_coin_freemium = f"Live Freemium or Die: {World_Options[Options.CoinSanityRange] * (i + 1)} Coin"
Regfreemiumstart.locations += [
DLCQuestLocation(player, item_coin_freemium, location_table[item_coin_freemium],
Regfreemiumstart)]
if 889 % World_Options[Options.CoinSanityRange] != 0:
Regfreemiumstart.locations += [
DLCQuestLocation(player, "Live Freemium or Die: 889 Coin",
location_table["Live Freemium or Die: 889 Coin"],
Regfreemiumstart)]
world.regions.append(Regfreemiumstart)
Regbehindvine = Region("Behind the Vines", player, world)
Locbehindvine_name = ["Wall Jump Pack", "Health Bar Pack", "Parallax Pack"]
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
Locbehindvine_name += ["Pickaxe"]
Regbehindvine.exits = [Entrance(player, "Wall Jump Entrance", Regbehindvine)]
Regbehindvine.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regbehindvine) for
loc_name in Locbehindvine_name]
add_coin_freemium(Regbehindvine, 95, player)
world.regions.append(Regbehindvine)
Regwalljump = Region("Wall Jump", player, world)
Locwalljump_name = ["Harmless Plants Pack", "Death of Comedy Pack", "Canadian Dialog Pack", "DLC NPC Pack"]
Regwalljump.exits = [Entrance(player, "Harmless Plants", Regwalljump),
Entrance(player, "Pickaxe Hard Cave", Regwalljump)]
Regwalljump.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regwalljump) for
loc_name in Locwalljump_name]
add_coin_freemium(Regwalljump, 150, player)
world.regions.append(Regwalljump)
Regfakeending = Region("Fake Ending", player, world)
Locfakeending_name = ["Cut Content Pack", "Name Change Pack"]
Regfakeending.exits = [Entrance(player, "Name Change Entrance", Regfakeending),
Entrance(player, "Cut Content Entrance", Regfakeending)]
Regfakeending.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regfakeending) for
loc_name in Locfakeending_name]
world.regions.append(Regfakeending)
Reghardcave = Region("Hard Cave", player, world)
add_coin_freemium(Reghardcave, 20, player)
Reghardcave.exits = [Entrance(player, "Hard Cave Wall Jump", Reghardcave)]
world.regions.append(Reghardcave)
Reghardcavewalljump = Region("Hard Cave Wall Jump", player, world)
Lochardcavewalljump_name = ["Increased HP Pack"]
Reghardcavewalljump.locations += [
DLCQuestLocation(player, loc_name, location_table[loc_name], Reghardcavewalljump) for
loc_name in Lochardcavewalljump_name]
add_coin_freemium(Reghardcavewalljump, 130, player)
world.regions.append(Reghardcavewalljump)
Regcutcontent = Region("Cut Content", player, world)
Loccutcontent_name = []
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
Loccutcontent_name += ["Humble Indie Bindle"]
Regcutcontent.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regcutcontent) for
loc_name in Loccutcontent_name]
add_coin_freemium(Regcutcontent, 200, player)
world.regions.append(Regcutcontent)
Regnamechange = Region("Name Change", player, world)
Locnamechange_name = []
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
Locnamechange_name += ["Box of Various Supplies"]
Regnamechange.exits = [Entrance(player, "Behind Rocks", Regnamechange)]
Regnamechange.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regnamechange) for
loc_name in Locnamechange_name]
world.regions.append(Regnamechange)
Regtopright = Region("Top Right", player, world)
Loctopright_name = ["Season Pass", "High Definition Next Gen Pack"]
Regtopright.exits = [Entrance(player, "Blizzard", Regtopright)]
Regtopright.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regtopright) for
loc_name in Loctopright_name]
add_coin_freemium(Regtopright, 90, player)
world.regions.append(Regtopright)
Regseason = Region("Season", player, world)
Locseason_name = ["Remove Ads Pack", "Not Exactly Noble"]
Regseason.exits = [Entrance(player, "Boss Door", Regseason)]
Regseason.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regseason) for
loc_name in Locseason_name]
add_coin_freemium(Regseason, 154, player)
world.regions.append(Regseason)
Regfinalboss = Region("Final Boss", player, world)
Locfinalboss_name = ["Big Sword Pack", "Really Big Sword Pack", "Unfathomable Sword Pack"]
Regfinalboss.locations += [DLCQuestLocation(player, loc_name, location_table[loc_name], Regfinalboss) for
loc_name in Locfinalboss_name]
world.regions.append(Regfinalboss)
loc_wining = DLCQuestLocation(player, "Winning Freemium", None, world.get_region("Final Boss", player))
world.get_region("Final Boss", player).locations.append(loc_wining)
loc_wining.place_locked_item(create_event(player, "Victory Freemium"))
world.get_entrance("Live Freemium or Die", player).connect(world.get_region("Freemium Start", player))
world.get_entrance("Vines", player).connect(world.get_region("Behind the Vines", player))
world.get_entrance("Wall Jump Entrance", player).connect(world.get_region("Wall Jump", player))
world.get_entrance("Harmless Plants", player).connect(world.get_region("Fake Ending", player))
world.get_entrance("Pickaxe Hard Cave", player).connect(world.get_region("Hard Cave", player))
world.get_entrance("Hard Cave Wall Jump", player).connect(world.get_region("Hard Cave Wall Jump", player))
world.get_entrance("Name Change Entrance", player).connect(world.get_region("Name Change", player))
world.get_entrance("Cut Content Entrance", player).connect(world.get_region("Cut Content", player))
world.get_entrance("Behind Rocks", player).connect(world.get_region("Top Right", player))
world.get_entrance("Blizzard", player).connect(world.get_region("Season", player))
world.get_entrance("Boss Door", player).connect(world.get_region("Final Boss", player))

370
worlds/dlcquest/Rules.py Normal file
View File

@ -0,0 +1,370 @@
import math
import re
from .Locations import DLCQuestLocation
from ..generic.Rules import add_rule, set_rule
from .Items import DLCQuestItem
from BaseClasses import ItemClassification
from . import Options
def create_event(player, event: str):
return DLCQuestItem(event, ItemClassification.progression, None, player)
def set_rules(world, player, World_Options: Options.DLCQuestOptions):
def has_enough_coin(player: int, coin: int):
def has_coin(state, player: int, coins: int):
coin_possessed = 0
for i in [4, 7, 9, 10, 46, 50, 60, 76, 89, 100, 169, 203]:
name_coin = f"{i} coins"
if state.has(name_coin, player):
coin_possessed += i
return coin_possessed >= coins
return lambda state: has_coin(state, player, coin)
def has_enough_coin_freemium(player: int, coin: int):
def has_coin(state, player: int, coins: int):
coin_possessed = 0
for i in [20, 50, 90, 95, 130, 150, 154, 200]:
name_coin = f"{i} coins freemium"
if state.has(name_coin, player):
coin_possessed += i
return coin_possessed >= coins
return lambda state: has_coin(state, player, coin)
if World_Options[Options.Campaign] == Options.Campaign.option_basic or World_Options[
Options.Campaign] == Options.Campaign.option_both:
set_rule(world.get_entrance("Moving", player),
lambda state: state.has("Movement Pack", player))
set_rule(world.get_entrance("Cloud", player),
lambda state: state.has("Psychological Warfare Pack", player))
set_rule(world.get_entrance("Forest Entrance", player),
lambda state: state.has("Map Pack", player))
set_rule(world.get_entrance("Forest True Double Jump", player),
lambda state: state.has("Double Jump Pack", player))
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_disabled:
set_rule(world.get_entrance("Behind Ogre", player),
lambda state: state.has("Gun Pack", player))
if World_Options[Options.TimeIsMoney] == Options.TimeIsMoney.option_required:
set_rule(world.get_entrance("Tree", player),
lambda state: state.has("Time is Money Pack", player))
set_rule(world.get_entrance("Cave Tree", player),
lambda state: state.has("Time is Money Pack", player))
set_rule(world.get_location("Shepherd Sheep", player),
lambda state: state.has("Time is Money Pack", player))
set_rule(world.get_location("North West Ceiling Sheep", player),
lambda state: state.has("Time is Money Pack", player))
set_rule(world.get_location("North West Alcove Sheep", player),
lambda state: state.has("Time is Money Pack", player))
set_rule(world.get_location("West Cave Sheep", player),
lambda state: state.has("Time is Money Pack", player))
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
set_rule(world.get_entrance("Behind Ogre", player),
lambda state: state.has("Gun", player))
set_rule(world.get_entrance("Tree", player),
lambda state: state.has("Sword", player) or state.has("Gun", player))
set_rule(world.get_entrance("Cave Tree", player),
lambda state: state.has("Sword", player) or state.has("Gun", player))
set_rule(world.get_entrance("True Double Jump", player),
lambda state: state.has("Double Jump Pack", player))
set_rule(world.get_location("Shepherd Sheep", player),
lambda state: state.has("Sword", player) or state.has("Gun", player))
set_rule(world.get_location("North West Ceiling Sheep", player),
lambda state: state.has("Sword", player) or state.has("Gun", player))
set_rule(world.get_location("North West Alcove Sheep", player),
lambda state: state.has("Sword", player) or state.has("Gun", player))
set_rule(world.get_location("West Cave Sheep", player),
lambda state: state.has("Sword", player) or state.has("Gun", player))
if World_Options[Options.TimeIsMoney] == Options.TimeIsMoney.option_required:
set_rule(world.get_location("Sword", player),
lambda state: state.has("Time is Money Pack", player))
if World_Options[Options.FalseDoubleJump] == Options.FalseDoubleJump.option_none:
set_rule(world.get_entrance("Cloud Double Jump", player),
lambda state: state.has("Double Jump Pack", player))
set_rule(world.get_entrance("Forest Double Jump", player),
lambda state: state.has("Double Jump Pack", player))
if World_Options[Options.FalseDoubleJump] == Options.FalseDoubleJump.option_none or World_Options[
Options.FalseDoubleJump] == Options.FalseDoubleJump.option_simple:
set_rule(world.get_entrance("Behind Tree Double Jump", player),
lambda state: state.has("Double Jump Pack", player))
set_rule(world.get_entrance("Cave Roof", player),
lambda state: state.has("Double Jump Pack", player))
if World_Options[Options.CoinSanity] == Options.CoinSanity.option_coin:
number_of_bundle = math.floor(825 / World_Options[Options.CoinSanityRange])
for i in range(number_of_bundle):
item_coin = "DLC Quest: number Coin"
item_coin_loc = re.sub("number", str(World_Options[Options.CoinSanityRange] * (i + 1)), item_coin)
set_rule(world.get_location(item_coin_loc, player),
has_enough_coin(player, World_Options[Options.CoinSanityRange] * (i + 1)))
if 825 % World_Options[Options.CoinSanityRange] != 0:
set_rule(world.get_location("DLC Quest: 825 Coin", player),
has_enough_coin(player, 825))
set_rule(world.get_location("Movement Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(4 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Animation Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Audio Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Pause Menu Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Time is Money Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(20 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Double Jump Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(100 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Pet Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Sexy Outfits Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Top Hat Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Map Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(140 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Gun Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(75 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("The Zombie Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Night Map Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(75 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Psychological Warfare Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(50 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Armor for your Horse Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(250 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Finish the Fight Pack", player),
lambda state: state.has("DLC Quest: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
if World_Options[Options.CoinSanity] == Options.CoinSanity.option_none:
set_rule(world.get_location("Movement Pack", player),
has_enough_coin(player, 4))
set_rule(world.get_location("Animation Pack", player),
has_enough_coin(player, 5))
set_rule(world.get_location("Audio Pack", player),
has_enough_coin(player, 5))
set_rule(world.get_location("Pause Menu Pack", player),
has_enough_coin(player, 5))
set_rule(world.get_location("Time is Money Pack", player),
has_enough_coin(player, 20))
set_rule(world.get_location("Double Jump Pack", player),
has_enough_coin(player, 100))
set_rule(world.get_location("Pet Pack", player),
has_enough_coin(player, 5))
set_rule(world.get_location("Sexy Outfits Pack", player),
has_enough_coin(player, 5))
set_rule(world.get_location("Top Hat Pack", player),
has_enough_coin(player, 5))
set_rule(world.get_location("Map Pack", player),
has_enough_coin(player, 140))
set_rule(world.get_location("Gun Pack", player),
has_enough_coin(player, 75))
set_rule(world.get_location("The Zombie Pack", player),
has_enough_coin(player, 5))
set_rule(world.get_location("Night Map Pack", player),
has_enough_coin(player, 75))
set_rule(world.get_location("Psychological Warfare Pack", player),
has_enough_coin(player, 50))
set_rule(world.get_location("Armor for your Horse Pack", player),
has_enough_coin(player, 250))
set_rule(world.get_location("Finish the Fight Pack", player),
has_enough_coin(player, 5))
if World_Options[Options.EndingChoice] == Options.EndingChoice.option_any:
set_rule(world.get_location("Winning Basic", player),
lambda state: state.has("Finish the Fight Pack", player))
if World_Options[Options.EndingChoice] == Options.EndingChoice.option_true:
set_rule(world.get_location("Winning Basic", player),
lambda state: state.has("Armor for your Horse Pack", player) and state.has("Finish the Fight Pack",
player))
if World_Options[Options.Campaign] == Options.Campaign.option_live_freemium_or_die or World_Options[
Options.Campaign] == Options.Campaign.option_both:
set_rule(world.get_entrance("Wall Jump Entrance", player),
lambda state: state.has("Wall Jump Pack", player))
set_rule(world.get_entrance("Harmless Plants", player),
lambda state: state.has("Harmless Plants Pack", player))
set_rule(world.get_entrance("Pickaxe Hard Cave", player),
lambda state: state.has("Pickaxe", player))
set_rule(world.get_entrance("Name Change Entrance", player),
lambda state: state.has("Name Change Pack", player))
set_rule(world.get_entrance("Cut Content Entrance", player),
lambda state: state.has("Cut Content Pack", player))
set_rule(world.get_entrance("Blizzard", player),
lambda state: state.has("Season Pass", player))
set_rule(world.get_entrance("Boss Door", player),
lambda state: state.has("Big Sword Pack", player) and state.has("Really Big Sword Pack",
player) and state.has(
"Unfathomable Sword Pack", player))
set_rule(world.get_location("I Get That Reference!", player),
lambda state: state.has("Death of Comedy Pack", player))
set_rule(world.get_location("Story is Important", player),
lambda state: state.has("DLC NPC Pack", player))
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_disabled:
set_rule(world.get_entrance("Vines", player),
lambda state: state.has("Incredibly Important Pack", player))
set_rule(world.get_entrance("Behind Rocks", player),
lambda state: state.can_reach("Cut Content", 'region', player))
if World_Options[Options.ItemShuffle] == Options.ItemShuffle.option_shuffled:
set_rule(world.get_entrance("Vines", player),
lambda state: state.has("Wooden Sword", player) or state.has("Pickaxe", player))
set_rule(world.get_entrance("Behind Rocks", player),
lambda state: state.has("Pickaxe", player))
set_rule(world.get_location("Wooden Sword", player),
lambda state: state.has("Incredibly Important Pack", player))
set_rule(world.get_location("Pickaxe", player),
lambda state: state.has("Humble Indie Bindle", player))
set_rule(world.get_location("Humble Indie Bindle", player),
lambda state: state.has("Box of Various Supplies", player) and state.can_reach("Cut Content",
'region', player))
set_rule(world.get_location("Box of Various Supplies", player),
lambda state: state.can_reach("Cut Content", 'region', player))
if World_Options[Options.CoinSanity] == Options.CoinSanity.option_coin:
number_of_bundle = math.floor(889 / World_Options[Options.CoinSanityRange])
for i in range(number_of_bundle):
item_coin_freemium = "Live Freemium or Die: number Coin"
item_coin_loc_freemium = re.sub("number", str(World_Options[Options.CoinSanityRange] * (i + 1)),
item_coin_freemium)
set_rule(world.get_location(item_coin_loc_freemium, player),
has_enough_coin_freemium(player, World_Options[Options.CoinSanityRange] * (i + 1)))
if 889 % World_Options[Options.CoinSanityRange] != 0:
set_rule(world.get_location("Live Freemium or Die: 889 Coin", player),
has_enough_coin_freemium(player, 889))
set_rule(world.get_entrance("Boss Door", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(889 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Particles Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Day One Patch Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Checkpoint Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Incredibly Important Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(15 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Wall Jump Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(35 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Health Bar Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Parallax Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(5 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Harmless Plants Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(130 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Death of Comedy Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(15 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Canadian Dialog Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(10 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("DLC NPC Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(15 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Cut Content Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(40 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Name Change Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(150 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Season Pass", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(199 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("High Definition Next Gen Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(20 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Increased HP Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(10 / World_Options[Options.CoinSanityRange])))
set_rule(world.get_location("Remove Ads Pack", player),
lambda state: state.has("Live Freemium or Die: Coin Bundle", player,
math.ceil(25 / World_Options[Options.CoinSanityRange])))
if World_Options[Options.CoinSanity] == Options.CoinSanity.option_none:
set_rule(world.get_entrance("Boss Door", player),
has_enough_coin_freemium(player, 889))
set_rule(world.get_location("Particles Pack", player),
has_enough_coin_freemium(player, 5))
set_rule(world.get_location("Day One Patch Pack", player),
has_enough_coin_freemium(player, 5))
set_rule(world.get_location("Checkpoint Pack", player),
has_enough_coin_freemium(player, 5))
set_rule(world.get_location("Incredibly Important Pack", player),
has_enough_coin_freemium(player, 15))
set_rule(world.get_location("Wall Jump Pack", player),
has_enough_coin_freemium(player, 35))
set_rule(world.get_location("Health Bar Pack", player),
has_enough_coin_freemium(player, 5))
set_rule(world.get_location("Parallax Pack", player),
has_enough_coin_freemium(player, 5))
set_rule(world.get_location("Harmless Plants Pack", player),
has_enough_coin_freemium(player, 130))
set_rule(world.get_location("Death of Comedy Pack", player),
has_enough_coin_freemium(player, 15))
set_rule(world.get_location("Canadian Dialog Pack", player),
has_enough_coin_freemium(player, 10))
set_rule(world.get_location("DLC NPC Pack", player),
has_enough_coin_freemium(player, 15))
set_rule(world.get_location("Cut Content Pack", player),
has_enough_coin_freemium(player, 40))
set_rule(world.get_location("Name Change Pack", player),
has_enough_coin_freemium(player, 150))
set_rule(world.get_location("Season Pass", player),
has_enough_coin_freemium(player, 199))
set_rule(world.get_location("High Definition Next Gen Pack", player),
has_enough_coin_freemium(player, 20))
set_rule(world.get_location("Increased HP Pack", player),
has_enough_coin_freemium(player, 10))
set_rule(world.get_location("Remove Ads Pack", player),
has_enough_coin_freemium(player, 25))
if World_Options[Options.Campaign] == Options.Campaign.option_basic:
world.completion_condition[player] = lambda state: state.has("Victory Basic", player)
if World_Options[Options.Campaign] == Options.Campaign.option_live_freemium_or_die:
world.completion_condition[player] = lambda state: state.has("Victory Freemium", player)
if World_Options[Options.Campaign] == Options.Campaign.option_both:
world.completion_condition[player] = lambda state: state.has("Victory Basic", player) and state.has(
"Victory Freemium", player)

View File

View File

@ -0,0 +1,26 @@
"""Items export script
This script can be used to export all the AP items into a json file in the output folder. This file is used by the tests
of the mod to ensure it can handle all possible items.
To run the script, use `python -m worlds.dlcquest.Script.export_items` from the repository root.
"""
import json
import os.path
from worlds.dlcquest import item_table
if not os.path.isdir("output"):
os.mkdir("output")
if __name__ == "__main__":
with open("output/dlc_quest_item_table.json", "w+") as f:
items = {
item.name: {
"code": item.code,
"classification": item.classification.name
}
for item in item_table.values()
if item.code is not None
}
json.dump({"items": items}, f)

View File

@ -0,0 +1,20 @@
"""Locations export script
This script can be used to export all the AP locations into a json file in the output folder. This file is used by the
tests of the mod to ensure it can handle all possible locations.
To run the script, use `python -m worlds.stardew_valley.scripts.export_locations` from the repository root.
"""
import json
import os
from worlds.dlcquest import location_table
if not os.path.isdir("output"):
os.mkdir("output")
if __name__ == "__main__":
with open("output/dlc_quest_location_table.json", "w+") as f:
locations = location_table
json.dump({"locations": locations}, f)

View File

@ -0,0 +1,82 @@
from typing import Dict, Any, Iterable, Optional, Union
from BaseClasses import Tutorial
from worlds.AutoWorld import World, WebWorld
from .Items import DLCQuestItem, item_table, ItemData, create_items
from .Locations import location_table, DLCQuestLocation
from .Options import DLCQuest_options, DLCQuestOptions, fetch_options
from .Rules import set_rules
from .Regions import create_regions
client_version = 0
class DLCqwebworld(WebWorld):
tutorials = [Tutorial(
"Multiworld Setup Tutorial",
"A guide to setting up the Archipelago DLCQuest game on your computer.",
"English",
"setup_en.md",
"setup/en",
["axe_y"]
)]
class DLCqworld(World):
"""
DLCQuest is a metroid ish game where everything is an in-game dlc.
"""
game = "DLCQuest"
topology_present = False
web = DLCqwebworld()
item_name_to_id = {name: data.code for name, data in item_table.items()}
location_name_to_id = location_table
data_version = 0
option_definitions = DLCQuest_options
def generate_early(self):
self.options = fetch_options(self.multiworld, self.player)
def create_regions(self):
create_regions(self.multiworld, self.player, self.options)
def set_rules(self):
set_rules(self.multiworld, self.player, self.options)
def create_event(self, event: str):
return DLCQuestItem(event, True, None, self.player)
def create_items(self):
locations_count = len([location
for location in self.multiworld.get_locations(self.player)
if not location.event])
items_to_exclude = [excluded_items
for excluded_items in self.multiworld.precollected_items[self.player]]
created_items = create_items(self, self.options, locations_count + len(items_to_exclude), self.multiworld.random)
self.multiworld.itempool += created_items
for item in items_to_exclude:
if item in self.multiworld.itempool:
self.multiworld.itempool.remove(item)
def create_item(self, item: Union[str, ItemData]) -> DLCQuestItem:
if isinstance(item, str):
item = item_table[item]
return DLCQuestItem(item.name, item.classification, item.code, self.player)
def fill_slot_data(self):
return {
"death_link": self.multiworld.death_link[self.player].value,
"ending_choice": self.multiworld.ending_choice[self.player].value,
"campaign": self.multiworld.campaign[self.player].value,
"coinsanity": self.multiworld.coinsanity[self.player].value,
"coinbundlerange": self.multiworld.coinbundlequantity[self.player].value,
"item_shuffle": self.multiworld.item_shuffle[self.player].value,
"seed": self.multiworld.per_slot_randoms[self.player].randrange(99999999)
}

View File

@ -0,0 +1,48 @@
id,name,classification,groups
0,Movement Pack,progression,"DLC,DLCQuest"
1,Animation Pack,filler,"DLC,DLCQuest"
2,Audio Pack,filler,"DLC,DLCQuest"
3,Pause Menu Pack,useful,"DLC,DLCQuest"
4,Time is Money Pack,progression,"DLC,DLCQuest"
5,Double Jump Pack,progression,"DLC,DLCQuest"
6,Pet Pack,filler,"DLC,DLCQuest"
7,Sexy Outfits Pack,filler,"DLC,DLCQuest"
8,Top Hat Pack,filler,"DLC,DLCQuest"
9,Map Pack,progression,"DLC,DLCQuest"
10,Gun Pack,progression,"DLC,DLCQuest"
11,The Zombie Pack,filler,"DLC,DLCQuest"
12,Night Map Pack,useful,"DLC,DLCQuest"
13,Psychological Warfare Pack,progression,"DLC,DLCQuest"
14,Armor for your Horse Pack,progression,"DLC,DLCQuest"
15,Finish the Fight Pack,progression,"DLC,DLCQuest"
16,Particles Pack,filler,"DLC,Freemium"
17,Day One Patch Pack,useful,"DLC,Freemium"
18,Checkpoint Pack,useful,"DLC,Freemium"
19,Incredibly Important Pack,progression,"DLC,Freemium"
20,Wall Jump Pack,progression,"DLC,Freemium"
21,Health Bar Pack,useful,"DLC,Freemium"
22,Parallax Pack,filler,"DLC,Freemium"
23,Harmless Plants Pack,progression,"DLC,Freemium"
24,Death of Comedy Pack,progression,"DLC,Freemium"
25,Canadian Dialog Pack,filler,"DLC,Freemium"
26,DLC NPC Pack,progression,"DLC,Freemium"
27,Cut Content Pack,progression,"DLC,Freemium"
28,Name Change Pack,progression,"DLC,Freemium"
29,Pickaxe,progression,"Item,Freemium"
30,Season Pass,progression,"DLC,Freemium"
31,High Definition Next Gen Pack,filler,"DLC,Freemium"
32,Increased HP Pack,useful,"DLC,Freemium"
33,Removed Ads Pack,filler,"DLC,Freemium"
34,Big Sword Pack,progression,"DLC,Freemium"
35,Really Big Sword Pack,progression,"DLC,Freemium"
36,Unfathomable Sword Pack,progression,"DLC,Freemium"
37,Gun,progression,"Item,DLCQuest"
38,Sword,progression,"Item,DLCQuest"
39,Wooden Sword,progression,"Item,Freemium"
40,Box of Various Supplies,progression,"Item,Freemium"
41,Humble Indie Bindle,progression,"Item,Freemium"
42,DLC Quest: Coin Bundle,progression,"Coin,DLCQuest"
43,Live Freemium or Die: Coin Bundle,progression,"Coin,Freemium"
44,Zombie Sheep,trap,Trap
45,Temporary Spike,trap,Trap
46,Loading Screen,trap,Trap
1 id name classification groups
2 0 Movement Pack progression DLC,DLCQuest
3 1 Animation Pack filler DLC,DLCQuest
4 2 Audio Pack filler DLC,DLCQuest
5 3 Pause Menu Pack useful DLC,DLCQuest
6 4 Time is Money Pack progression DLC,DLCQuest
7 5 Double Jump Pack progression DLC,DLCQuest
8 6 Pet Pack filler DLC,DLCQuest
9 7 Sexy Outfits Pack filler DLC,DLCQuest
10 8 Top Hat Pack filler DLC,DLCQuest
11 9 Map Pack progression DLC,DLCQuest
12 10 Gun Pack progression DLC,DLCQuest
13 11 The Zombie Pack filler DLC,DLCQuest
14 12 Night Map Pack useful DLC,DLCQuest
15 13 Psychological Warfare Pack progression DLC,DLCQuest
16 14 Armor for your Horse Pack progression DLC,DLCQuest
17 15 Finish the Fight Pack progression DLC,DLCQuest
18 16 Particles Pack filler DLC,Freemium
19 17 Day One Patch Pack useful DLC,Freemium
20 18 Checkpoint Pack useful DLC,Freemium
21 19 Incredibly Important Pack progression DLC,Freemium
22 20 Wall Jump Pack progression DLC,Freemium
23 21 Health Bar Pack useful DLC,Freemium
24 22 Parallax Pack filler DLC,Freemium
25 23 Harmless Plants Pack progression DLC,Freemium
26 24 Death of Comedy Pack progression DLC,Freemium
27 25 Canadian Dialog Pack filler DLC,Freemium
28 26 DLC NPC Pack progression DLC,Freemium
29 27 Cut Content Pack progression DLC,Freemium
30 28 Name Change Pack progression DLC,Freemium
31 29 Pickaxe progression Item,Freemium
32 30 Season Pass progression DLC,Freemium
33 31 High Definition Next Gen Pack filler DLC,Freemium
34 32 Increased HP Pack useful DLC,Freemium
35 33 Removed Ads Pack filler DLC,Freemium
36 34 Big Sword Pack progression DLC,Freemium
37 35 Really Big Sword Pack progression DLC,Freemium
38 36 Unfathomable Sword Pack progression DLC,Freemium
39 37 Gun progression Item,DLCQuest
40 38 Sword progression Item,DLCQuest
41 39 Wooden Sword progression Item,Freemium
42 40 Box of Various Supplies progression Item,Freemium
43 41 Humble Indie Bindle progression Item,Freemium
44 42 DLC Quest: Coin Bundle progression Coin,DLCQuest
45 43 Live Freemium or Die: Coin Bundle progression Coin,Freemium
46 44 Zombie Sheep trap Trap
47 45 Temporary Spike trap Trap
48 46 Loading Screen trap Trap

View File

@ -0,0 +1,51 @@
# DLC Quest
## Where is the settings page?
The [player settings page for this game](../player-settings) contains all the options you need to configure and export a
config file.
## What does randomization do to this game?
DLCs are obtained as checks for the multiworld. There are also some other optional checks in DLC Quest
## What is the goal of DLC Quest?
DLC Quest has two campaigns, and the player can choose which one they will play for their slot.
They can also choose to do both campaigns.
## What are location checks in DLC Quest?
Location checks in DLC Quest always include:
- DLC Purchases from the shopkeeper
- Awardment-related objectives
- Killing Sheep in DLC Quest
- Specific Awardment objectives in Live Freemium or Die
There also are a number of location checks that are optional, and individual players choose to include them or not in their shuffling:
- Items that your character can obtain in various ways
- Swords
- Gun
- Box of Various Supplies
- Humble Indie Bindle
- Pickaxe
- Coinsanity: Coins, either individually or as custom-sized bundles
## Which items can be in another player's world?
Every DLC in the game is shuffled in the item pool. The items related to the optional checks described above are also in the pool
There are also some brand new trap items, used as filler, based on vanilla game annoyances
- Zombie Sheep
- Loading Screens
- Temporary Spikes
## When the player receives an item, what happens?
Every time an item is received while online, a notification appears on screen informing the player of it.
Some items also include an animation or cutscene that will play immediately upon receiving it.
Items that are received while offline will not play any animation or cutscene, and simply be active when logging in.

View File

@ -0,0 +1,57 @@
# Stardew Valley Randomizer Setup Guide
## Required Software
- DLC Quest on PC (Recommended: [Steam version](https://store.steampowered.com/app/230050/DLC_Quest/))
- [DLCQuestipelago](https://github.com/agilbert1412/DLCQuestipelago/releases)
- BepinEx (Used as a modloader for DLCQuest. The Mod release above includes BepInEx if you pick the full installer version)
## Optional Software
- Archipelago from the [Archipelago Releases Page](https://github.com/ArchipelagoMW/Archipelago/releases)
- (Only for the TextClient)
## Configuring your YAML file
### What is a YAML file and why do I need one?
See the guide on setting up a basic YAML at the Archipelago setup
guide: [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en)
### Where do I get a YAML file?
You can customize your settings by visiting the [DLC Quest Player Settings Page](../player-settings)
## Joining a MultiWorld Game
### Installing the mod
- Download the [DLCQuestipelago mod release](https://github.com/agilbert1412/DLCQuestipelago/releases). If this is your first time installing the mod, or if you are not comfortable with manually editing files, you should pick the Installer. It will handle most of the work for you
- Extract the .zip archive to a location of your choice
- Run "DLCQuestipelagoInstaller.exe"
![image](https://i.imgur.com/2sPhMgs.png)
- The installer should describe what it is doing each step of the way, and will ask for your input when necessary.
- It will allow you to choose where to install your modded game, and offer a default location
- It will **try** to find your DLCQuest game on your computer, and should it fail, it will ask you to input the path to it
- It will offer the choice of creating a desktop shortcut for the modded launcher
### Connect to the MultiServer
- Locate the file "ArchipelagoConnectionInfo.json", at the root of your modded installation. You can edit this file with any text editor, and you need to enter the server ip address, port and your slotname into the relevant fields.
- Run BepInEx.NET.Framework.Launcher.exe. If you opted for a desktop shortcut, you will find it with an icon and a more recognizable name.
- ![image](https://i.imgur.com/ZUiFrhf.png)
- Your game should launch alongside a modloader console, which will contain important debugging information if you run into problems.
- The game should automatically connect, and attempt reconnecting if your internet or the server fails, during your playthrough.
### Interacting with the MultiWorld from in-game
You cannot send commands to the server or chat with the other players from DLC Quest, as the game lacks a proper way to input text.
You can keep track of the server activity in your BepInEx console, as Archipelago chat messages will be displayed in it.
You will need to use an [Archipelago Text Client](https://github.com/ArchipelagoMW/Archipelago/releases) if you want to send commands.