DOOM II: implement new game (#2255)
This commit is contained in:
parent
530e792c3c
commit
c5b0330223
|
@ -53,6 +53,8 @@ Currently, the following games are supported:
|
|||
* Terraria
|
||||
* Lingo
|
||||
* Pokémon Emerald
|
||||
* DOOM II
|
||||
|
||||
|
||||
For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/).
|
||||
Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,39 @@
|
|||
# This file is auto generated. More info: https://github.com/Daivuk/apdoom
|
||||
|
||||
from typing import List
|
||||
|
||||
|
||||
map_names: List[str] = [
|
||||
'Entryway (MAP01)',
|
||||
'Underhalls (MAP02)',
|
||||
'The Gantlet (MAP03)',
|
||||
'The Focus (MAP04)',
|
||||
'The Waste Tunnels (MAP05)',
|
||||
'The Crusher (MAP06)',
|
||||
'Dead Simple (MAP07)',
|
||||
'Tricks and Traps (MAP08)',
|
||||
'The Pit (MAP09)',
|
||||
'Refueling Base (MAP10)',
|
||||
'Circle of Death (MAP11)',
|
||||
'The Factory (MAP12)',
|
||||
'Downtown (MAP13)',
|
||||
'The Inmost Dens (MAP14)',
|
||||
'Industrial Zone (MAP15)',
|
||||
'Suburbs (MAP16)',
|
||||
'Tenements (MAP17)',
|
||||
'The Courtyard (MAP18)',
|
||||
'The Citadel (MAP19)',
|
||||
'Gotcha! (MAP20)',
|
||||
'Nirvana (MAP21)',
|
||||
'The Catacombs (MAP22)',
|
||||
'Barrels o Fun (MAP23)',
|
||||
'The Chasm (MAP24)',
|
||||
'Bloodfalls (MAP25)',
|
||||
'The Abandoned Mines (MAP26)',
|
||||
'Monster Condo (MAP27)',
|
||||
'The Spirit World (MAP28)',
|
||||
'The Living End (MAP29)',
|
||||
'Icon of Sin (MAP30)',
|
||||
'Wolfenstein2 (MAP31)',
|
||||
'Grosse2 (MAP32)',
|
||||
]
|
|
@ -0,0 +1,150 @@
|
|||
import typing
|
||||
|
||||
from Options import PerGameCommonOptions, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
class Difficulty(Choice):
|
||||
"""
|
||||
Choose the difficulty option. Those match DOOM's difficulty options.
|
||||
baby (I'm too young to die.) double ammos, half damage, less monsters or strength.
|
||||
easy (Hey, not too rough.) less monsters or strength.
|
||||
medium (Hurt me plenty.) Default.
|
||||
hard (Ultra-Violence.) More monsters or strength.
|
||||
nightmare (Nightmare!) Monsters attack more rapidly and respawn.
|
||||
"""
|
||||
display_name = "Difficulty"
|
||||
option_baby = 0
|
||||
option_easy = 1
|
||||
option_medium = 2
|
||||
option_hard = 3
|
||||
option_nightmare = 4
|
||||
default = 2
|
||||
|
||||
|
||||
class RandomMonsters(Choice):
|
||||
"""
|
||||
Choose how monsters are randomized.
|
||||
vanilla: No randomization
|
||||
shuffle: Monsters are shuffled within the level
|
||||
random_balanced: Monsters are completely randomized, but balanced based on existing ratio in the level. (Small monsters vs medium vs big)
|
||||
random_chaotic: Monsters are completely randomized, but balanced based on existing ratio in the entire game.
|
||||
"""
|
||||
display_name = "Random Monsters"
|
||||
option_vanilla = 0
|
||||
option_shuffle = 1
|
||||
option_random_balanced = 2
|
||||
option_random_chaotic = 3
|
||||
default = 2
|
||||
|
||||
|
||||
class RandomPickups(Choice):
|
||||
"""
|
||||
Choose how pickups are randomized.
|
||||
vanilla: No randomization
|
||||
shuffle: Pickups are shuffled within the level
|
||||
random_balanced: Pickups are completely randomized, but balanced based on existing ratio in the level. (Small pickups vs Big)
|
||||
"""
|
||||
display_name = "Random Pickups"
|
||||
option_vanilla = 0
|
||||
option_shuffle = 1
|
||||
option_random_balanced = 2
|
||||
default = 1
|
||||
|
||||
|
||||
class RandomMusic(Choice):
|
||||
"""
|
||||
Level musics will be randomized.
|
||||
vanilla: No randomization
|
||||
shuffle_selected: Selected episodes' levels will be shuffled
|
||||
shuffle_game: All the music will be shuffled
|
||||
"""
|
||||
display_name = "Random Music"
|
||||
option_vanilla = 0
|
||||
option_shuffle_selected = 1
|
||||
option_shuffle_game = 2
|
||||
default = 0
|
||||
|
||||
|
||||
class FlipLevels(Choice):
|
||||
"""
|
||||
Flip levels on one axis.
|
||||
vanilla: No flipping
|
||||
flipped: All levels are flipped
|
||||
random: Random levels are flipped
|
||||
"""
|
||||
display_name = "Flip Levels"
|
||||
option_vanilla = 0
|
||||
option_flipped = 1
|
||||
option_randomly_flipped = 2
|
||||
default = 0
|
||||
|
||||
|
||||
class AllowDeathLogic(Toggle):
|
||||
"""Some locations require a timed puzzle that can only be tried once.
|
||||
After which, if the player failed to get it, the location cannot be checked anymore.
|
||||
By default, no progression items are placed here. There is a way, hovewer, to still get them:
|
||||
Get killed in the current map. The map will reset, you can now attempt the puzzle again."""
|
||||
display_name = "Allow Death Logic"
|
||||
|
||||
|
||||
class Pro(Toggle):
|
||||
"""Include difficult tricks into rules. Mostly employed by speed runners.
|
||||
i.e.: Leaps across to a locked area, trigger a switch behind a window at the right angle, etc."""
|
||||
display_name = "Pro Doom"
|
||||
|
||||
|
||||
class StartWithComputerAreaMaps(Toggle):
|
||||
"""Give the player all Computer Area Map items from the start."""
|
||||
display_name = "Start With Computer Area Maps"
|
||||
|
||||
|
||||
class ResetLevelOnDeath(DefaultOnToggle):
|
||||
"""When dying, levels are reset and monsters respawned. But inventory and checks are kept.
|
||||
Turning this setting off is considered easy mode. Good for new players that don't know the levels well."""
|
||||
display_message="Reset level on death"
|
||||
|
||||
|
||||
class Episode1(DefaultOnToggle):
|
||||
"""Subterranean and Outpost.
|
||||
If none of the episodes are chosen, Episode 1 will be chosen by default."""
|
||||
display_name = "Episode 1"
|
||||
|
||||
|
||||
class Episode2(DefaultOnToggle):
|
||||
"""City.
|
||||
If none of the episodes are chosen, Episode 1 will be chosen by default."""
|
||||
display_name = "Episode 2"
|
||||
|
||||
|
||||
class Episode3(DefaultOnToggle):
|
||||
"""Hell.
|
||||
If none of the episodes are chosen, Episode 1 will be chosen by default."""
|
||||
display_name = "Episode 3"
|
||||
|
||||
|
||||
class SecretLevels(Toggle):
|
||||
"""Secret levels.
|
||||
This is too short to be an episode. It's additive.
|
||||
Another episode will have to be selected along with this one.
|
||||
Otherwise episode 1 will be added."""
|
||||
display_name = "Secret Levels"
|
||||
|
||||
|
||||
@dataclass
|
||||
class DOOM2Options(PerGameCommonOptions):
|
||||
start_inventory_from_pool: StartInventoryPool
|
||||
difficulty: Difficulty
|
||||
random_monsters: RandomMonsters
|
||||
random_pickups: RandomPickups
|
||||
random_music: RandomMusic
|
||||
flip_levels: FlipLevels
|
||||
allow_death_logic: AllowDeathLogic
|
||||
pro: Pro
|
||||
start_with_computer_area_maps: StartWithComputerAreaMaps
|
||||
death_link: DeathLink
|
||||
reset_level_on_death: ResetLevelOnDeath
|
||||
episode1: Episode1
|
||||
episode2: Episode2
|
||||
episode3: Episode3
|
||||
episode4: SecretLevels
|
|
@ -0,0 +1,502 @@
|
|||
# This file is auto generated. More info: https://github.com/Daivuk/apdoom
|
||||
|
||||
from typing import List
|
||||
from BaseClasses import TypedDict
|
||||
|
||||
class ConnectionDict(TypedDict, total=False):
|
||||
target: str
|
||||
pro: bool
|
||||
|
||||
class RegionDict(TypedDict, total=False):
|
||||
name: str
|
||||
connects_to_hub: bool
|
||||
episode: int
|
||||
connections: List[ConnectionDict]
|
||||
|
||||
|
||||
regions:List[RegionDict] = [
|
||||
# Entryway (MAP01)
|
||||
{"name":"Entryway (MAP01) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[]},
|
||||
|
||||
# Underhalls (MAP02)
|
||||
{"name":"Underhalls (MAP02) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[{"target":"Underhalls (MAP02) Red","pro":False}]},
|
||||
{"name":"Underhalls (MAP02) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"Underhalls (MAP02) Red","pro":False}]},
|
||||
{"name":"Underhalls (MAP02) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"Underhalls (MAP02) Blue","pro":False},
|
||||
{"target":"Underhalls (MAP02) Main","pro":False}]},
|
||||
|
||||
# The Gantlet (MAP03)
|
||||
{"name":"The Gantlet (MAP03) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Gantlet (MAP03) Blue","pro":False},
|
||||
{"target":"The Gantlet (MAP03) Blue Pro Jump","pro":True}]},
|
||||
{"name":"The Gantlet (MAP03) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Gantlet (MAP03) Main","pro":False},
|
||||
{"target":"The Gantlet (MAP03) Red","pro":False},
|
||||
{"target":"The Gantlet (MAP03) Blue Pro Jump","pro":False}]},
|
||||
{"name":"The Gantlet (MAP03) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[]},
|
||||
{"name":"The Gantlet (MAP03) Blue Pro Jump",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"The Gantlet (MAP03) Blue","pro":False}]},
|
||||
|
||||
# The Focus (MAP04)
|
||||
{"name":"The Focus (MAP04) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Focus (MAP04) Red","pro":False},
|
||||
{"target":"The Focus (MAP04) Blue","pro":False}]},
|
||||
{"name":"The Focus (MAP04) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"The Focus (MAP04) Main","pro":False}]},
|
||||
{"name":"The Focus (MAP04) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"The Focus (MAP04) Red","pro":False}]},
|
||||
{"name":"The Focus (MAP04) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Focus (MAP04) Yellow","pro":False},
|
||||
{"target":"The Focus (MAP04) Main","pro":False}]},
|
||||
|
||||
# The Waste Tunnels (MAP05)
|
||||
{"name":"The Waste Tunnels (MAP05) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Waste Tunnels (MAP05) Red","pro":False},
|
||||
{"target":"The Waste Tunnels (MAP05) Blue","pro":False}]},
|
||||
{"name":"The Waste Tunnels (MAP05) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Waste Tunnels (MAP05) Yellow","pro":False},
|
||||
{"target":"The Waste Tunnels (MAP05) Main","pro":False}]},
|
||||
{"name":"The Waste Tunnels (MAP05) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"The Waste Tunnels (MAP05) Blue","pro":False}]},
|
||||
{"name":"The Waste Tunnels (MAP05) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"The Waste Tunnels (MAP05) Main","pro":False}]},
|
||||
|
||||
# The Crusher (MAP06)
|
||||
{"name":"The Crusher (MAP06) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[{"target":"The Crusher (MAP06) Blue","pro":False}]},
|
||||
{"name":"The Crusher (MAP06) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Crusher (MAP06) Red","pro":False},
|
||||
{"target":"The Crusher (MAP06) Main","pro":False}]},
|
||||
{"name":"The Crusher (MAP06) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"The Crusher (MAP06) Red","pro":False}]},
|
||||
{"name":"The Crusher (MAP06) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Crusher (MAP06) Yellow","pro":False},
|
||||
{"target":"The Crusher (MAP06) Blue","pro":False},
|
||||
{"target":"The Crusher (MAP06) Main","pro":False}]},
|
||||
|
||||
# Dead Simple (MAP07)
|
||||
{"name":"Dead Simple (MAP07) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[]},
|
||||
|
||||
# Tricks and Traps (MAP08)
|
||||
{"name":"Tricks and Traps (MAP08) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"Tricks and Traps (MAP08) Red","pro":False},
|
||||
{"target":"Tricks and Traps (MAP08) Yellow","pro":False}]},
|
||||
{"name":"Tricks and Traps (MAP08) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"Tricks and Traps (MAP08) Main","pro":False}]},
|
||||
{"name":"Tricks and Traps (MAP08) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"Tricks and Traps (MAP08) Main","pro":False}]},
|
||||
|
||||
# The Pit (MAP09)
|
||||
{"name":"The Pit (MAP09) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"The Pit (MAP09) Yellow","pro":False},
|
||||
{"target":"The Pit (MAP09) Blue","pro":False}]},
|
||||
{"name":"The Pit (MAP09) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[]},
|
||||
{"name":"The Pit (MAP09) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"The Pit (MAP09) Main","pro":False}]},
|
||||
|
||||
# Refueling Base (MAP10)
|
||||
{"name":"Refueling Base (MAP10) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[{"target":"Refueling Base (MAP10) Yellow","pro":False}]},
|
||||
{"name":"Refueling Base (MAP10) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"Refueling Base (MAP10) Main","pro":False},
|
||||
{"target":"Refueling Base (MAP10) Yellow Blue","pro":False}]},
|
||||
{"name":"Refueling Base (MAP10) Yellow Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"Refueling Base (MAP10) Yellow","pro":False}]},
|
||||
|
||||
# Circle of Death (MAP11)
|
||||
{"name":"Circle of Death (MAP11) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":1,
|
||||
"connections":[
|
||||
{"target":"Circle of Death (MAP11) Blue","pro":False},
|
||||
{"target":"Circle of Death (MAP11) Red","pro":False}]},
|
||||
{"name":"Circle of Death (MAP11) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"Circle of Death (MAP11) Main","pro":False}]},
|
||||
{"name":"Circle of Death (MAP11) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":1,
|
||||
"connections":[{"target":"Circle of Death (MAP11) Main","pro":False}]},
|
||||
|
||||
# The Factory (MAP12)
|
||||
{"name":"The Factory (MAP12) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"The Factory (MAP12) Yellow","pro":False},
|
||||
{"target":"The Factory (MAP12) Blue","pro":False}]},
|
||||
{"name":"The Factory (MAP12) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"The Factory (MAP12) Main","pro":False}]},
|
||||
{"name":"The Factory (MAP12) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[]},
|
||||
|
||||
# Downtown (MAP13)
|
||||
{"name":"Downtown (MAP13) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"Downtown (MAP13) Yellow","pro":False},
|
||||
{"target":"Downtown (MAP13) Red","pro":False},
|
||||
{"target":"Downtown (MAP13) Blue","pro":False}]},
|
||||
{"name":"Downtown (MAP13) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Downtown (MAP13) Main","pro":False}]},
|
||||
{"name":"Downtown (MAP13) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Downtown (MAP13) Main","pro":False}]},
|
||||
{"name":"Downtown (MAP13) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Downtown (MAP13) Main","pro":False}]},
|
||||
|
||||
# The Inmost Dens (MAP14)
|
||||
{"name":"The Inmost Dens (MAP14) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[{"target":"The Inmost Dens (MAP14) Red","pro":False}]},
|
||||
{"name":"The Inmost Dens (MAP14) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"The Inmost Dens (MAP14) Main","pro":False},
|
||||
{"target":"The Inmost Dens (MAP14) Red East","pro":False}]},
|
||||
{"name":"The Inmost Dens (MAP14) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"The Inmost Dens (MAP14) Main","pro":False},
|
||||
{"target":"The Inmost Dens (MAP14) Red South","pro":False},
|
||||
{"target":"The Inmost Dens (MAP14) Red East","pro":False}]},
|
||||
{"name":"The Inmost Dens (MAP14) Red East",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"The Inmost Dens (MAP14) Blue","pro":False},
|
||||
{"target":"The Inmost Dens (MAP14) Main","pro":False}]},
|
||||
{"name":"The Inmost Dens (MAP14) Red South",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"The Inmost Dens (MAP14) Main","pro":False}]},
|
||||
|
||||
# Industrial Zone (MAP15)
|
||||
{"name":"Industrial Zone (MAP15) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"Industrial Zone (MAP15) Yellow East","pro":False},
|
||||
{"target":"Industrial Zone (MAP15) Yellow West","pro":False}]},
|
||||
{"name":"Industrial Zone (MAP15) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Industrial Zone (MAP15) Yellow East","pro":False}]},
|
||||
{"name":"Industrial Zone (MAP15) Yellow East",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"Industrial Zone (MAP15) Blue","pro":False},
|
||||
{"target":"Industrial Zone (MAP15) Main","pro":False}]},
|
||||
{"name":"Industrial Zone (MAP15) Yellow West",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Industrial Zone (MAP15) Main","pro":False}]},
|
||||
|
||||
# Suburbs (MAP16)
|
||||
{"name":"Suburbs (MAP16) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"Suburbs (MAP16) Red","pro":False},
|
||||
{"target":"Suburbs (MAP16) Blue","pro":False}]},
|
||||
{"name":"Suburbs (MAP16) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Suburbs (MAP16) Main","pro":False}]},
|
||||
{"name":"Suburbs (MAP16) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Suburbs (MAP16) Main","pro":False}]},
|
||||
|
||||
# Tenements (MAP17)
|
||||
{"name":"Tenements (MAP17) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Tenements (MAP17) Red","pro":False}]},
|
||||
{"name":"Tenements (MAP17) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"Tenements (MAP17) Red","pro":False}]},
|
||||
{"name":"Tenements (MAP17) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"Tenements (MAP17) Red","pro":False},
|
||||
{"target":"Tenements (MAP17) Blue","pro":False}]},
|
||||
{"name":"Tenements (MAP17) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"Tenements (MAP17) Yellow","pro":False},
|
||||
{"target":"Tenements (MAP17) Blue","pro":False},
|
||||
{"target":"Tenements (MAP17) Main","pro":False}]},
|
||||
|
||||
# The Courtyard (MAP18)
|
||||
{"name":"The Courtyard (MAP18) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[
|
||||
{"target":"The Courtyard (MAP18) Yellow","pro":False},
|
||||
{"target":"The Courtyard (MAP18) Blue","pro":False}]},
|
||||
{"name":"The Courtyard (MAP18) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"The Courtyard (MAP18) Main","pro":False}]},
|
||||
{"name":"The Courtyard (MAP18) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"The Courtyard (MAP18) Main","pro":False}]},
|
||||
|
||||
# The Citadel (MAP19)
|
||||
{"name":"The Citadel (MAP19) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[{"target":"The Citadel (MAP19) Red","pro":False}]},
|
||||
{"name":"The Citadel (MAP19) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":2,
|
||||
"connections":[{"target":"The Citadel (MAP19) Main","pro":False}]},
|
||||
|
||||
# Gotcha! (MAP20)
|
||||
{"name":"Gotcha! (MAP20) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":2,
|
||||
"connections":[]},
|
||||
|
||||
# Nirvana (MAP21)
|
||||
{"name":"Nirvana (MAP21) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Nirvana (MAP21) Yellow","pro":False}]},
|
||||
{"name":"Nirvana (MAP21) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[
|
||||
{"target":"Nirvana (MAP21) Main","pro":False},
|
||||
{"target":"Nirvana (MAP21) Magenta","pro":False}]},
|
||||
{"name":"Nirvana (MAP21) Magenta",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Nirvana (MAP21) Yellow","pro":False}]},
|
||||
|
||||
# The Catacombs (MAP22)
|
||||
{"name":"The Catacombs (MAP22) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[
|
||||
{"target":"The Catacombs (MAP22) Blue","pro":False},
|
||||
{"target":"The Catacombs (MAP22) Red","pro":False}]},
|
||||
{"name":"The Catacombs (MAP22) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Catacombs (MAP22) Main","pro":False}]},
|
||||
{"name":"The Catacombs (MAP22) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Catacombs (MAP22) Main","pro":False}]},
|
||||
|
||||
# Barrels o Fun (MAP23)
|
||||
{"name":"Barrels o Fun (MAP23) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Barrels o Fun (MAP23) Yellow","pro":False}]},
|
||||
{"name":"Barrels o Fun (MAP23) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Barrels o Fun (MAP23) Main","pro":False}]},
|
||||
|
||||
# The Chasm (MAP24)
|
||||
{"name":"The Chasm (MAP24) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Chasm (MAP24) Red","pro":False}]},
|
||||
{"name":"The Chasm (MAP24) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Chasm (MAP24) Main","pro":False}]},
|
||||
|
||||
# Bloodfalls (MAP25)
|
||||
{"name":"Bloodfalls (MAP25) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Bloodfalls (MAP25) Blue","pro":False}]},
|
||||
{"name":"Bloodfalls (MAP25) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Bloodfalls (MAP25) Main","pro":False}]},
|
||||
|
||||
# The Abandoned Mines (MAP26)
|
||||
{"name":"The Abandoned Mines (MAP26) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[
|
||||
{"target":"The Abandoned Mines (MAP26) Yellow","pro":False},
|
||||
{"target":"The Abandoned Mines (MAP26) Red","pro":False},
|
||||
{"target":"The Abandoned Mines (MAP26) Blue","pro":False}]},
|
||||
{"name":"The Abandoned Mines (MAP26) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Abandoned Mines (MAP26) Main","pro":False}]},
|
||||
{"name":"The Abandoned Mines (MAP26) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Abandoned Mines (MAP26) Main","pro":False}]},
|
||||
{"name":"The Abandoned Mines (MAP26) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Abandoned Mines (MAP26) Main","pro":False}]},
|
||||
|
||||
# Monster Condo (MAP27)
|
||||
{"name":"Monster Condo (MAP27) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[
|
||||
{"target":"Monster Condo (MAP27) Yellow","pro":False},
|
||||
{"target":"Monster Condo (MAP27) Red","pro":False},
|
||||
{"target":"Monster Condo (MAP27) Blue","pro":False}]},
|
||||
{"name":"Monster Condo (MAP27) Blue",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Monster Condo (MAP27) Main","pro":False}]},
|
||||
{"name":"Monster Condo (MAP27) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Monster Condo (MAP27) Main","pro":False}]},
|
||||
{"name":"Monster Condo (MAP27) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"Monster Condo (MAP27) Main","pro":False}]},
|
||||
|
||||
# The Spirit World (MAP28)
|
||||
{"name":"The Spirit World (MAP28) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[
|
||||
{"target":"The Spirit World (MAP28) Yellow","pro":False},
|
||||
{"target":"The Spirit World (MAP28) Red","pro":False}]},
|
||||
{"name":"The Spirit World (MAP28) Yellow",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Spirit World (MAP28) Main","pro":False}]},
|
||||
{"name":"The Spirit World (MAP28) Red",
|
||||
"connects_to_hub":False,
|
||||
"episode":3,
|
||||
"connections":[{"target":"The Spirit World (MAP28) Main","pro":False}]},
|
||||
|
||||
# The Living End (MAP29)
|
||||
{"name":"The Living End (MAP29) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[]},
|
||||
|
||||
# Icon of Sin (MAP30)
|
||||
{"name":"Icon of Sin (MAP30) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":3,
|
||||
"connections":[]},
|
||||
|
||||
# Wolfenstein2 (MAP31)
|
||||
{"name":"Wolfenstein2 (MAP31) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":4,
|
||||
"connections":[]},
|
||||
|
||||
# Grosse2 (MAP32)
|
||||
{"name":"Grosse2 (MAP32) Main",
|
||||
"connects_to_hub":True,
|
||||
"episode":4,
|
||||
"connections":[]},
|
||||
]
|
|
@ -0,0 +1,501 @@
|
|||
# This file is auto generated. More info: https://github.com/Daivuk/apdoom
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from worlds.generic.Rules import set_rule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import DOOM2World
|
||||
|
||||
|
||||
def set_episode1_rules(player, world, pro):
|
||||
# Entryway (MAP01)
|
||||
set_rule(world.get_entrance("Hub -> Entryway (MAP01) Main", player), lambda state:
|
||||
state.has("Entryway (MAP01)", player, 1))
|
||||
set_rule(world.get_entrance("Hub -> Entryway (MAP01) Main", player), lambda state:
|
||||
state.has("Entryway (MAP01)", player, 1))
|
||||
|
||||
# Underhalls (MAP02)
|
||||
set_rule(world.get_entrance("Hub -> Underhalls (MAP02) Main", player), lambda state:
|
||||
state.has("Underhalls (MAP02)", player, 1))
|
||||
set_rule(world.get_entrance("Hub -> Underhalls (MAP02) Main", player), lambda state:
|
||||
state.has("Underhalls (MAP02)", player, 1))
|
||||
set_rule(world.get_entrance("Hub -> Underhalls (MAP02) Main", player), lambda state:
|
||||
state.has("Underhalls (MAP02)", player, 1))
|
||||
set_rule(world.get_entrance("Underhalls (MAP02) Main -> Underhalls (MAP02) Red", player), lambda state:
|
||||
state.has("Underhalls (MAP02) - Red keycard", player, 1))
|
||||
set_rule(world.get_entrance("Underhalls (MAP02) Blue -> Underhalls (MAP02) Red", player), lambda state:
|
||||
state.has("Underhalls (MAP02) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("Underhalls (MAP02) Red -> Underhalls (MAP02) Blue", player), lambda state:
|
||||
state.has("Underhalls (MAP02) - Blue keycard", player, 1))
|
||||
|
||||
# The Gantlet (MAP03)
|
||||
set_rule(world.get_entrance("Hub -> The Gantlet (MAP03) Main", player), lambda state:
|
||||
(state.has("The Gantlet (MAP03)", player, 1)) and
|
||||
(state.has("Shotgun", player, 1) or
|
||||
state.has("Chaingun", player, 1) or
|
||||
state.has("Super Shotgun", player, 1)))
|
||||
set_rule(world.get_entrance("The Gantlet (MAP03) Main -> The Gantlet (MAP03) Blue", player), lambda state:
|
||||
state.has("The Gantlet (MAP03) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Gantlet (MAP03) Blue -> The Gantlet (MAP03) Red", player), lambda state:
|
||||
state.has("The Gantlet (MAP03) - Red keycard", player, 1))
|
||||
|
||||
# The Focus (MAP04)
|
||||
set_rule(world.get_entrance("Hub -> The Focus (MAP04) Main", player), lambda state:
|
||||
(state.has("The Focus (MAP04)", player, 1)) and
|
||||
(state.has("Shotgun", player, 1) or
|
||||
state.has("Chaingun", player, 1) or
|
||||
state.has("Super Shotgun", player, 1)))
|
||||
set_rule(world.get_entrance("The Focus (MAP04) Main -> The Focus (MAP04) Red", player), lambda state:
|
||||
state.has("The Focus (MAP04) - Red keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Focus (MAP04) Main -> The Focus (MAP04) Blue", player), lambda state:
|
||||
state.has("The Focus (MAP04) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Focus (MAP04) Yellow -> The Focus (MAP04) Red", player), lambda state:
|
||||
state.has("The Focus (MAP04) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Focus (MAP04) Red -> The Focus (MAP04) Yellow", player), lambda state:
|
||||
state.has("The Focus (MAP04) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Focus (MAP04) Red -> The Focus (MAP04) Main", player), lambda state:
|
||||
state.has("The Focus (MAP04) - Red keycard", player, 1))
|
||||
|
||||
# The Waste Tunnels (MAP05)
|
||||
set_rule(world.get_entrance("Hub -> The Waste Tunnels (MAP05) Main", player), lambda state:
|
||||
(state.has("The Waste Tunnels (MAP05)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("The Waste Tunnels (MAP05) Main -> The Waste Tunnels (MAP05) Red", player), lambda state:
|
||||
state.has("The Waste Tunnels (MAP05) - Red keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Waste Tunnels (MAP05) Main -> The Waste Tunnels (MAP05) Blue", player), lambda state:
|
||||
state.has("The Waste Tunnels (MAP05) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Waste Tunnels (MAP05) Blue -> The Waste Tunnels (MAP05) Yellow", player), lambda state:
|
||||
state.has("The Waste Tunnels (MAP05) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Waste Tunnels (MAP05) Blue -> The Waste Tunnels (MAP05) Main", player), lambda state:
|
||||
state.has("The Waste Tunnels (MAP05) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Waste Tunnels (MAP05) Yellow -> The Waste Tunnels (MAP05) Blue", player), lambda state:
|
||||
state.has("The Waste Tunnels (MAP05) - Yellow keycard", player, 1))
|
||||
|
||||
# The Crusher (MAP06)
|
||||
set_rule(world.get_entrance("Hub -> The Crusher (MAP06) Main", player), lambda state:
|
||||
(state.has("The Crusher (MAP06)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("The Crusher (MAP06) Main -> The Crusher (MAP06) Blue", player), lambda state:
|
||||
state.has("The Crusher (MAP06) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Crusher (MAP06) Blue -> The Crusher (MAP06) Red", player), lambda state:
|
||||
state.has("The Crusher (MAP06) - Red keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Crusher (MAP06) Blue -> The Crusher (MAP06) Main", player), lambda state:
|
||||
state.has("The Crusher (MAP06) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Crusher (MAP06) Yellow -> The Crusher (MAP06) Red", player), lambda state:
|
||||
state.has("The Crusher (MAP06) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Crusher (MAP06) Red -> The Crusher (MAP06) Yellow", player), lambda state:
|
||||
state.has("The Crusher (MAP06) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Crusher (MAP06) Red -> The Crusher (MAP06) Blue", player), lambda state:
|
||||
state.has("The Crusher (MAP06) - Red keycard", player, 1))
|
||||
|
||||
# Dead Simple (MAP07)
|
||||
set_rule(world.get_entrance("Hub -> Dead Simple (MAP07) Main", player), lambda state:
|
||||
(state.has("Dead Simple (MAP07)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
|
||||
# Tricks and Traps (MAP08)
|
||||
set_rule(world.get_entrance("Hub -> Tricks and Traps (MAP08) Main", player), lambda state:
|
||||
(state.has("Tricks and Traps (MAP08)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Tricks and Traps (MAP08) Main -> Tricks and Traps (MAP08) Red", player), lambda state:
|
||||
state.has("Tricks and Traps (MAP08) - Red skull key", player, 1))
|
||||
set_rule(world.get_entrance("Tricks and Traps (MAP08) Main -> Tricks and Traps (MAP08) Yellow", player), lambda state:
|
||||
state.has("Tricks and Traps (MAP08) - Yellow skull key", player, 1))
|
||||
|
||||
# The Pit (MAP09)
|
||||
set_rule(world.get_entrance("Hub -> The Pit (MAP09) Main", player), lambda state:
|
||||
(state.has("The Pit (MAP09)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("The Pit (MAP09) Main -> The Pit (MAP09) Yellow", player), lambda state:
|
||||
state.has("The Pit (MAP09) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Pit (MAP09) Main -> The Pit (MAP09) Blue", player), lambda state:
|
||||
state.has("The Pit (MAP09) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Pit (MAP09) Yellow -> The Pit (MAP09) Main", player), lambda state:
|
||||
state.has("The Pit (MAP09) - Yellow keycard", player, 1))
|
||||
|
||||
# Refueling Base (MAP10)
|
||||
set_rule(world.get_entrance("Hub -> Refueling Base (MAP10) Main", player), lambda state:
|
||||
(state.has("Refueling Base (MAP10)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Refueling Base (MAP10) Main -> Refueling Base (MAP10) Yellow", player), lambda state:
|
||||
state.has("Refueling Base (MAP10) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("Refueling Base (MAP10) Yellow -> Refueling Base (MAP10) Yellow Blue", player), lambda state:
|
||||
state.has("Refueling Base (MAP10) - Blue keycard", player, 1))
|
||||
|
||||
# Circle of Death (MAP11)
|
||||
set_rule(world.get_entrance("Hub -> Circle of Death (MAP11) Main", player), lambda state:
|
||||
(state.has("Circle of Death (MAP11)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Circle of Death (MAP11) Main -> Circle of Death (MAP11) Blue", player), lambda state:
|
||||
state.has("Circle of Death (MAP11) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("Circle of Death (MAP11) Main -> Circle of Death (MAP11) Red", player), lambda state:
|
||||
state.has("Circle of Death (MAP11) - Red keycard", player, 1))
|
||||
|
||||
|
||||
def set_episode2_rules(player, world, pro):
|
||||
# The Factory (MAP12)
|
||||
set_rule(world.get_entrance("Hub -> The Factory (MAP12) Main", player), lambda state:
|
||||
(state.has("The Factory (MAP12)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("The Factory (MAP12) Main -> The Factory (MAP12) Yellow", player), lambda state:
|
||||
state.has("The Factory (MAP12) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Factory (MAP12) Main -> The Factory (MAP12) Blue", player), lambda state:
|
||||
state.has("The Factory (MAP12) - Blue keycard", player, 1))
|
||||
|
||||
# Downtown (MAP13)
|
||||
set_rule(world.get_entrance("Hub -> Downtown (MAP13) Main", player), lambda state:
|
||||
(state.has("Downtown (MAP13)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Downtown (MAP13) Main -> Downtown (MAP13) Yellow", player), lambda state:
|
||||
state.has("Downtown (MAP13) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("Downtown (MAP13) Main -> Downtown (MAP13) Red", player), lambda state:
|
||||
state.has("Downtown (MAP13) - Red keycard", player, 1))
|
||||
set_rule(world.get_entrance("Downtown (MAP13) Main -> Downtown (MAP13) Blue", player), lambda state:
|
||||
state.has("Downtown (MAP13) - Blue keycard", player, 1))
|
||||
|
||||
# The Inmost Dens (MAP14)
|
||||
set_rule(world.get_entrance("Hub -> The Inmost Dens (MAP14) Main", player), lambda state:
|
||||
(state.has("The Inmost Dens (MAP14)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("The Inmost Dens (MAP14) Main -> The Inmost Dens (MAP14) Red", player), lambda state:
|
||||
state.has("The Inmost Dens (MAP14) - Red skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Inmost Dens (MAP14) Blue -> The Inmost Dens (MAP14) Red East", player), lambda state:
|
||||
state.has("The Inmost Dens (MAP14) - Blue skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Inmost Dens (MAP14) Red -> The Inmost Dens (MAP14) Main", player), lambda state:
|
||||
state.has("The Inmost Dens (MAP14) - Red skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Inmost Dens (MAP14) Red East -> The Inmost Dens (MAP14) Blue", player), lambda state:
|
||||
state.has("The Inmost Dens (MAP14) - Blue skull key", player, 1))
|
||||
|
||||
# Industrial Zone (MAP15)
|
||||
set_rule(world.get_entrance("Hub -> Industrial Zone (MAP15) Main", player), lambda state:
|
||||
(state.has("Industrial Zone (MAP15)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Industrial Zone (MAP15) Main -> Industrial Zone (MAP15) Yellow East", player), lambda state:
|
||||
state.has("Industrial Zone (MAP15) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("Industrial Zone (MAP15) Main -> Industrial Zone (MAP15) Yellow West", player), lambda state:
|
||||
state.has("Industrial Zone (MAP15) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("Industrial Zone (MAP15) Blue -> Industrial Zone (MAP15) Yellow East", player), lambda state:
|
||||
state.has("Industrial Zone (MAP15) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("Industrial Zone (MAP15) Yellow East -> Industrial Zone (MAP15) Blue", player), lambda state:
|
||||
state.has("Industrial Zone (MAP15) - Blue keycard", player, 1))
|
||||
|
||||
# Suburbs (MAP16)
|
||||
set_rule(world.get_entrance("Hub -> Suburbs (MAP16) Main", player), lambda state:
|
||||
(state.has("Suburbs (MAP16)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Suburbs (MAP16) Main -> Suburbs (MAP16) Red", player), lambda state:
|
||||
state.has("Suburbs (MAP16) - Red skull key", player, 1))
|
||||
set_rule(world.get_entrance("Suburbs (MAP16) Main -> Suburbs (MAP16) Blue", player), lambda state:
|
||||
state.has("Suburbs (MAP16) - Blue skull key", player, 1))
|
||||
|
||||
# Tenements (MAP17)
|
||||
set_rule(world.get_entrance("Hub -> Tenements (MAP17) Main", player), lambda state:
|
||||
(state.has("Tenements (MAP17)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Tenements (MAP17) Main -> Tenements (MAP17) Red", player), lambda state:
|
||||
state.has("Tenements (MAP17) - Red keycard", player, 1))
|
||||
set_rule(world.get_entrance("Tenements (MAP17) Red -> Tenements (MAP17) Yellow", player), lambda state:
|
||||
state.has("Tenements (MAP17) - Yellow skull key", player, 1))
|
||||
set_rule(world.get_entrance("Tenements (MAP17) Red -> Tenements (MAP17) Blue", player), lambda state:
|
||||
state.has("Tenements (MAP17) - Blue keycard", player, 1))
|
||||
|
||||
# The Courtyard (MAP18)
|
||||
set_rule(world.get_entrance("Hub -> The Courtyard (MAP18) Main", player), lambda state:
|
||||
(state.has("The Courtyard (MAP18)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("The Courtyard (MAP18) Main -> The Courtyard (MAP18) Yellow", player), lambda state:
|
||||
state.has("The Courtyard (MAP18) - Yellow skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Courtyard (MAP18) Main -> The Courtyard (MAP18) Blue", player), lambda state:
|
||||
state.has("The Courtyard (MAP18) - Blue skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Courtyard (MAP18) Blue -> The Courtyard (MAP18) Main", player), lambda state:
|
||||
state.has("The Courtyard (MAP18) - Blue skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Courtyard (MAP18) Yellow -> The Courtyard (MAP18) Main", player), lambda state:
|
||||
state.has("The Courtyard (MAP18) - Yellow skull key", player, 1))
|
||||
|
||||
# The Citadel (MAP19)
|
||||
set_rule(world.get_entrance("Hub -> The Citadel (MAP19) Main", player), lambda state:
|
||||
(state.has("The Citadel (MAP19)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("The Citadel (MAP19) Main -> The Citadel (MAP19) Red", player), lambda state:
|
||||
(state.has("The Citadel (MAP19) - Red skull key", player, 1)) and (state.has("The Citadel (MAP19) - Blue skull key", player, 1) or
|
||||
state.has("The Citadel (MAP19) - Yellow skull key", player, 1)))
|
||||
set_rule(world.get_entrance("The Citadel (MAP19) Red -> The Citadel (MAP19) Main", player), lambda state:
|
||||
(state.has("The Citadel (MAP19) - Red skull key", player, 1)) and (state.has("The Citadel (MAP19) - Yellow skull key", player, 1) or
|
||||
state.has("The Citadel (MAP19) - Blue skull key", player, 1)))
|
||||
|
||||
# Gotcha! (MAP20)
|
||||
set_rule(world.get_entrance("Hub -> Gotcha! (MAP20) Main", player), lambda state:
|
||||
(state.has("Gotcha! (MAP20)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
|
||||
|
||||
def set_episode3_rules(player, world, pro):
|
||||
# Nirvana (MAP21)
|
||||
set_rule(world.get_entrance("Hub -> Nirvana (MAP21) Main", player), lambda state:
|
||||
(state.has("Nirvana (MAP21)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Nirvana (MAP21) Main -> Nirvana (MAP21) Yellow", player), lambda state:
|
||||
state.has("Nirvana (MAP21) - Yellow skull key", player, 1))
|
||||
set_rule(world.get_entrance("Nirvana (MAP21) Yellow -> Nirvana (MAP21) Main", player), lambda state:
|
||||
state.has("Nirvana (MAP21) - Yellow skull key", player, 1))
|
||||
set_rule(world.get_entrance("Nirvana (MAP21) Yellow -> Nirvana (MAP21) Magenta", player), lambda state:
|
||||
state.has("Nirvana (MAP21) - Red skull key", player, 1) and
|
||||
state.has("Nirvana (MAP21) - Blue skull key", player, 1))
|
||||
set_rule(world.get_entrance("Nirvana (MAP21) Magenta -> Nirvana (MAP21) Yellow", player), lambda state:
|
||||
state.has("Nirvana (MAP21) - Red skull key", player, 1) and
|
||||
state.has("Nirvana (MAP21) - Blue skull key", player, 1))
|
||||
|
||||
# The Catacombs (MAP22)
|
||||
set_rule(world.get_entrance("Hub -> The Catacombs (MAP22) Main", player), lambda state:
|
||||
(state.has("The Catacombs (MAP22)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("BFG9000", player, 1) or
|
||||
state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1)))
|
||||
set_rule(world.get_entrance("The Catacombs (MAP22) Main -> The Catacombs (MAP22) Blue", player), lambda state:
|
||||
state.has("The Catacombs (MAP22) - Blue skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Catacombs (MAP22) Main -> The Catacombs (MAP22) Red", player), lambda state:
|
||||
state.has("The Catacombs (MAP22) - Red skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Catacombs (MAP22) Red -> The Catacombs (MAP22) Main", player), lambda state:
|
||||
state.has("The Catacombs (MAP22) - Red skull key", player, 1))
|
||||
|
||||
# Barrels o Fun (MAP23)
|
||||
set_rule(world.get_entrance("Hub -> Barrels o Fun (MAP23) Main", player), lambda state:
|
||||
(state.has("Barrels o Fun (MAP23)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
set_rule(world.get_entrance("Barrels o Fun (MAP23) Main -> Barrels o Fun (MAP23) Yellow", player), lambda state:
|
||||
state.has("Barrels o Fun (MAP23) - Yellow skull key", player, 1))
|
||||
set_rule(world.get_entrance("Barrels o Fun (MAP23) Yellow -> Barrels o Fun (MAP23) Main", player), lambda state:
|
||||
state.has("Barrels o Fun (MAP23) - Yellow skull key", player, 1))
|
||||
|
||||
# The Chasm (MAP24)
|
||||
set_rule(world.get_entrance("Hub -> The Chasm (MAP24) Main", player), lambda state:
|
||||
state.has("The Chasm (MAP24)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Rocket launcher", player, 1) and
|
||||
state.has("Plasma gun", player, 1) and
|
||||
state.has("BFG9000", player, 1) and
|
||||
state.has("Super Shotgun", player, 1))
|
||||
set_rule(world.get_entrance("The Chasm (MAP24) Main -> The Chasm (MAP24) Red", player), lambda state:
|
||||
state.has("The Chasm (MAP24) - Red keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Chasm (MAP24) Red -> The Chasm (MAP24) Main", player), lambda state:
|
||||
state.has("The Chasm (MAP24) - Red keycard", player, 1))
|
||||
|
||||
# Bloodfalls (MAP25)
|
||||
set_rule(world.get_entrance("Hub -> Bloodfalls (MAP25) Main", player), lambda state:
|
||||
state.has("Bloodfalls (MAP25)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Rocket launcher", player, 1) and
|
||||
state.has("Plasma gun", player, 1) and
|
||||
state.has("BFG9000", player, 1) and
|
||||
state.has("Super Shotgun", player, 1))
|
||||
set_rule(world.get_entrance("Bloodfalls (MAP25) Main -> Bloodfalls (MAP25) Blue", player), lambda state:
|
||||
state.has("Bloodfalls (MAP25) - Blue skull key", player, 1))
|
||||
set_rule(world.get_entrance("Bloodfalls (MAP25) Blue -> Bloodfalls (MAP25) Main", player), lambda state:
|
||||
state.has("Bloodfalls (MAP25) - Blue skull key", player, 1))
|
||||
|
||||
# The Abandoned Mines (MAP26)
|
||||
set_rule(world.get_entrance("Hub -> The Abandoned Mines (MAP26) Main", player), lambda state:
|
||||
state.has("The Abandoned Mines (MAP26)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Rocket launcher", player, 1) and
|
||||
state.has("BFG9000", player, 1) and
|
||||
state.has("Plasma gun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1))
|
||||
set_rule(world.get_entrance("The Abandoned Mines (MAP26) Main -> The Abandoned Mines (MAP26) Yellow", player), lambda state:
|
||||
state.has("The Abandoned Mines (MAP26) - Yellow keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Abandoned Mines (MAP26) Main -> The Abandoned Mines (MAP26) Red", player), lambda state:
|
||||
state.has("The Abandoned Mines (MAP26) - Red keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Abandoned Mines (MAP26) Main -> The Abandoned Mines (MAP26) Blue", player), lambda state:
|
||||
state.has("The Abandoned Mines (MAP26) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Abandoned Mines (MAP26) Blue -> The Abandoned Mines (MAP26) Main", player), lambda state:
|
||||
state.has("The Abandoned Mines (MAP26) - Blue keycard", player, 1))
|
||||
set_rule(world.get_entrance("The Abandoned Mines (MAP26) Yellow -> The Abandoned Mines (MAP26) Main", player), lambda state:
|
||||
state.has("The Abandoned Mines (MAP26) - Yellow keycard", player, 1))
|
||||
|
||||
# Monster Condo (MAP27)
|
||||
set_rule(world.get_entrance("Hub -> Monster Condo (MAP27) Main", player), lambda state:
|
||||
state.has("Monster Condo (MAP27)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Rocket launcher", player, 1) and
|
||||
state.has("Plasma gun", player, 1) and
|
||||
state.has("BFG9000", player, 1) and
|
||||
state.has("Super Shotgun", player, 1))
|
||||
set_rule(world.get_entrance("Monster Condo (MAP27) Main -> Monster Condo (MAP27) Yellow", player), lambda state:
|
||||
state.has("Monster Condo (MAP27) - Yellow skull key", player, 1))
|
||||
set_rule(world.get_entrance("Monster Condo (MAP27) Main -> Monster Condo (MAP27) Red", player), lambda state:
|
||||
state.has("Monster Condo (MAP27) - Red skull key", player, 1))
|
||||
set_rule(world.get_entrance("Monster Condo (MAP27) Main -> Monster Condo (MAP27) Blue", player), lambda state:
|
||||
state.has("Monster Condo (MAP27) - Blue skull key", player, 1))
|
||||
set_rule(world.get_entrance("Monster Condo (MAP27) Red -> Monster Condo (MAP27) Main", player), lambda state:
|
||||
state.has("Monster Condo (MAP27) - Red skull key", player, 1))
|
||||
|
||||
# The Spirit World (MAP28)
|
||||
set_rule(world.get_entrance("Hub -> The Spirit World (MAP28) Main", player), lambda state:
|
||||
state.has("The Spirit World (MAP28)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Rocket launcher", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Plasma gun", player, 1) and
|
||||
state.has("BFG9000", player, 1) and
|
||||
state.has("Super Shotgun", player, 1))
|
||||
set_rule(world.get_entrance("The Spirit World (MAP28) Main -> The Spirit World (MAP28) Yellow", player), lambda state:
|
||||
state.has("The Spirit World (MAP28) - Yellow skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Spirit World (MAP28) Main -> The Spirit World (MAP28) Red", player), lambda state:
|
||||
state.has("The Spirit World (MAP28) - Red skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Spirit World (MAP28) Yellow -> The Spirit World (MAP28) Main", player), lambda state:
|
||||
state.has("The Spirit World (MAP28) - Yellow skull key", player, 1))
|
||||
set_rule(world.get_entrance("The Spirit World (MAP28) Red -> The Spirit World (MAP28) Main", player), lambda state:
|
||||
state.has("The Spirit World (MAP28) - Red skull key", player, 1))
|
||||
|
||||
# The Living End (MAP29)
|
||||
set_rule(world.get_entrance("Hub -> The Living End (MAP29) Main", player), lambda state:
|
||||
state.has("The Living End (MAP29)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Rocket launcher", player, 1) and
|
||||
state.has("Plasma gun", player, 1) and
|
||||
state.has("BFG9000", player, 1) and
|
||||
state.has("Super Shotgun", player, 1))
|
||||
|
||||
# Icon of Sin (MAP30)
|
||||
set_rule(world.get_entrance("Hub -> Icon of Sin (MAP30) Main", player), lambda state:
|
||||
state.has("Icon of Sin (MAP30)", player, 1) and
|
||||
state.has("Rocket launcher", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Plasma gun", player, 1) and
|
||||
state.has("BFG9000", player, 1) and
|
||||
state.has("Super Shotgun", player, 1))
|
||||
|
||||
|
||||
def set_episode4_rules(player, world, pro):
|
||||
# Wolfenstein2 (MAP31)
|
||||
set_rule(world.get_entrance("Hub -> Wolfenstein2 (MAP31) Main", player), lambda state:
|
||||
(state.has("Wolfenstein2 (MAP31)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
|
||||
# Grosse2 (MAP32)
|
||||
set_rule(world.get_entrance("Hub -> Grosse2 (MAP32) Main", player), lambda state:
|
||||
(state.has("Grosse2 (MAP32)", player, 1) and
|
||||
state.has("Shotgun", player, 1) and
|
||||
state.has("Chaingun", player, 1) and
|
||||
state.has("Super Shotgun", player, 1)) and
|
||||
(state.has("Rocket launcher", player, 1) or
|
||||
state.has("Plasma gun", player, 1) or
|
||||
state.has("BFG9000", player, 1)))
|
||||
|
||||
|
||||
def set_rules(doom_ii_world: "DOOM2World", included_episodes, pro):
|
||||
player = doom_ii_world.player
|
||||
world = doom_ii_world.multiworld
|
||||
|
||||
if included_episodes[0]:
|
||||
set_episode1_rules(player, world, pro)
|
||||
if included_episodes[1]:
|
||||
set_episode2_rules(player, world, pro)
|
||||
if included_episodes[2]:
|
||||
set_episode3_rules(player, world, pro)
|
||||
if included_episodes[3]:
|
||||
set_episode4_rules(player, world, pro)
|
|
@ -0,0 +1,267 @@
|
|||
import functools
|
||||
import logging
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from BaseClasses import Entrance, CollectionState, Item, Location, MultiWorld, Region, Tutorial
|
||||
from worlds.AutoWorld import WebWorld, World
|
||||
from . import Items, Locations, Maps, Regions, Rules
|
||||
from .Options import DOOM2Options
|
||||
|
||||
logger = logging.getLogger("DOOM II")
|
||||
|
||||
DOOM_TYPE_LEVEL_COMPLETE = -2
|
||||
DOOM_TYPE_COMPUTER_AREA_MAP = 2026
|
||||
|
||||
|
||||
class DOOM2Location(Location):
|
||||
game: str = "DOOM II"
|
||||
|
||||
|
||||
class DOOM2Item(Item):
|
||||
game: str = "DOOM II"
|
||||
|
||||
|
||||
class DOOM2Web(WebWorld):
|
||||
tutorials = [Tutorial(
|
||||
"Multiworld Setup Guide",
|
||||
"A guide to setting up the DOOM II randomizer connected to an Archipelago Multiworld",
|
||||
"English",
|
||||
"setup_en.md",
|
||||
"setup/en",
|
||||
["Daivuk"]
|
||||
)]
|
||||
theme = "dirt"
|
||||
|
||||
|
||||
class DOOM2World(World):
|
||||
"""
|
||||
Doom II, also known as Doom II: Hell on Earth, is a first-person shooter game by id Software.
|
||||
It was released for MS-DOS in 1994.
|
||||
Compared to its predecessor, Doom II features larger levels, new enemies, a new "super shotgun" weapon
|
||||
"""
|
||||
options_dataclass = DOOM2Options
|
||||
options: DOOM2Options
|
||||
game = "DOOM II"
|
||||
web = DOOM2Web()
|
||||
data_version = 3
|
||||
required_client_version = (0, 3, 9)
|
||||
|
||||
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
|
||||
item_name_groups = Items.item_name_groups
|
||||
|
||||
location_name_to_id = {data["name"]: loc_id for loc_id, data in Locations.location_table.items()}
|
||||
location_name_groups = Locations.location_name_groups
|
||||
|
||||
starting_level_for_episode: List[str] = [
|
||||
"Entryway (MAP01)",
|
||||
"The Factory (MAP12)",
|
||||
"Nirvana (MAP21)"
|
||||
]
|
||||
|
||||
# Item ratio that scales depending on episode count. These are the ratio for 3 episode. In DOOM1.
|
||||
# The ratio have been tweaked seem, and feel good.
|
||||
items_ratio: Dict[str, float] = {
|
||||
"Armor": 41,
|
||||
"Mega Armor": 25,
|
||||
"Berserk": 12,
|
||||
"Invulnerability": 10,
|
||||
"Partial invisibility": 18,
|
||||
"Supercharge": 28,
|
||||
"Medikit": 15,
|
||||
"Box of bullets": 13,
|
||||
"Box of rockets": 13,
|
||||
"Box of shotgun shells": 13,
|
||||
"Energy cell pack": 10
|
||||
}
|
||||
|
||||
def __init__(self, world: MultiWorld, player: int):
|
||||
self.included_episodes = [1, 1, 1, 0]
|
||||
self.location_count = 0
|
||||
|
||||
super().__init__(world, player)
|
||||
|
||||
def get_episode_count(self):
|
||||
# Don't include 4th, those are secret levels they are additive
|
||||
return sum(self.included_episodes[:3])
|
||||
|
||||
def generate_early(self):
|
||||
# Cache which episodes are included
|
||||
self.included_episodes[0] = self.options.episode1.value
|
||||
self.included_episodes[1] = self.options.episode2.value
|
||||
self.included_episodes[2] = self.options.episode3.value
|
||||
self.included_episodes[3] = self.options.episode4.value # 4th episode are secret levels
|
||||
|
||||
# If no episodes selected, select Episode 1
|
||||
if self.get_episode_count() == 0:
|
||||
self.included_episodes[0] = 1
|
||||
|
||||
def create_regions(self):
|
||||
pro = self.options.pro.value
|
||||
|
||||
# Main regions
|
||||
menu_region = Region("Menu", self.player, self.multiworld)
|
||||
hub_region = Region("Hub", self.player, self.multiworld)
|
||||
self.multiworld.regions += [menu_region, hub_region]
|
||||
menu_region.add_exits(["Hub"])
|
||||
|
||||
# Create regions and locations
|
||||
main_regions = []
|
||||
connections = []
|
||||
for region_dict in Regions.regions:
|
||||
if not self.included_episodes[region_dict["episode"] - 1]:
|
||||
continue
|
||||
|
||||
region_name = region_dict["name"]
|
||||
if region_dict["connects_to_hub"]:
|
||||
main_regions.append(region_name)
|
||||
|
||||
region = Region(region_name, self.player, self.multiworld)
|
||||
region.add_locations({
|
||||
loc["name"]: loc_id
|
||||
for loc_id, loc in Locations.location_table.items()
|
||||
if loc["region"] == region_name and self.included_episodes[loc["episode"] - 1]
|
||||
}, DOOM2Location)
|
||||
|
||||
self.multiworld.regions.append(region)
|
||||
|
||||
for connection_dict in region_dict["connections"]:
|
||||
# Check if it's a pro-only connection
|
||||
if connection_dict["pro"] and not pro:
|
||||
continue
|
||||
connections.append((region, connection_dict["target"]))
|
||||
|
||||
# Connect main regions to Hub
|
||||
hub_region.add_exits(main_regions)
|
||||
|
||||
# Do the other connections between regions (They are not all both ways)
|
||||
for connection in connections:
|
||||
source = connection[0]
|
||||
target = self.multiworld.get_region(connection[1], self.player)
|
||||
|
||||
entrance = Entrance(self.player, f"{source.name} -> {target.name}", source)
|
||||
source.exits.append(entrance)
|
||||
entrance.connect(target)
|
||||
|
||||
# Sum locations for items creation
|
||||
self.location_count = len(self.multiworld.get_locations(self.player))
|
||||
|
||||
def completion_rule(self, state: CollectionState):
|
||||
for map_name in Maps.map_names:
|
||||
if map_name + " - Exit" not in self.location_name_to_id:
|
||||
continue
|
||||
|
||||
# Exit location names are in form: Entryway (MAP01) - Exit
|
||||
loc = Locations.location_table[self.location_name_to_id[map_name + " - Exit"]]
|
||||
if not self.included_episodes[loc["episode"] - 1]:
|
||||
continue
|
||||
|
||||
# Map complete item names are in form: Entryway (MAP01) - Complete
|
||||
if not state.has(map_name + " - Complete", self.player, 1):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def set_rules(self):
|
||||
pro = self.options.pro.value
|
||||
allow_death_logic = self.options.allow_death_logic.value
|
||||
|
||||
Rules.set_rules(self, self.included_episodes, pro)
|
||||
self.multiworld.completion_condition[self.player] = lambda state: self.completion_rule(state)
|
||||
|
||||
# Forbid progression items to locations that can be missed and can't be picked up. (e.g. One-time timed
|
||||
# platform) Unless the user allows for it.
|
||||
if not allow_death_logic:
|
||||
for death_logic_location in Locations.death_logic_locations:
|
||||
self.multiworld.exclude_locations[self.player].value.add(death_logic_location)
|
||||
|
||||
def create_item(self, name: str) -> DOOM2Item:
|
||||
item_id: int = self.item_name_to_id[name]
|
||||
return DOOM2Item(name, Items.item_table[item_id]["classification"], item_id, self.player)
|
||||
|
||||
def create_items(self):
|
||||
itempool: List[DOOM2Item] = []
|
||||
start_with_computer_area_maps: bool = self.options.start_with_computer_area_maps.value
|
||||
|
||||
# Items
|
||||
for item_id, item in Items.item_table.items():
|
||||
if item["doom_type"] == DOOM_TYPE_LEVEL_COMPLETE:
|
||||
continue # We'll fill it manually later
|
||||
|
||||
if item["doom_type"] == DOOM_TYPE_COMPUTER_AREA_MAP and start_with_computer_area_maps:
|
||||
continue # We'll fill it manually, and we will put fillers in place
|
||||
|
||||
if item["episode"] != -1 and not self.included_episodes[item["episode"] - 1]:
|
||||
continue
|
||||
|
||||
count = item["count"] if item["name"] not in self.starting_level_for_episode else item["count"] - 1
|
||||
itempool += [self.create_item(item["name"]) for _ in range(count)]
|
||||
|
||||
# Place end level items in locked locations
|
||||
for map_name in Maps.map_names:
|
||||
loc_name = map_name + " - Exit"
|
||||
item_name = map_name + " - Complete"
|
||||
|
||||
if loc_name not in self.location_name_to_id:
|
||||
continue
|
||||
|
||||
if item_name not in self.item_name_to_id:
|
||||
continue
|
||||
|
||||
loc = Locations.location_table[self.location_name_to_id[loc_name]]
|
||||
if not self.included_episodes[loc["episode"] - 1]:
|
||||
continue
|
||||
|
||||
self.multiworld.get_location(loc_name, self.player).place_locked_item(self.create_item(item_name))
|
||||
self.location_count -= 1
|
||||
|
||||
# Give starting levels right away
|
||||
for i in range(len(self.starting_level_for_episode)):
|
||||
if self.included_episodes[i]:
|
||||
self.multiworld.push_precollected(self.create_item(self.starting_level_for_episode[i]))
|
||||
|
||||
# Give Computer area maps if option selected
|
||||
if start_with_computer_area_maps:
|
||||
for item_id, item_dict in Items.item_table.items():
|
||||
item_episode = item_dict["episode"]
|
||||
if item_episode > 0:
|
||||
if item_dict["doom_type"] == DOOM_TYPE_COMPUTER_AREA_MAP and self.included_episodes[item_episode - 1]:
|
||||
self.multiworld.push_precollected(self.create_item(item_dict["name"]))
|
||||
|
||||
# Fill the rest starting with powerups, then fillers
|
||||
self.create_ratioed_items("Armor", itempool)
|
||||
self.create_ratioed_items("Mega Armor", itempool)
|
||||
self.create_ratioed_items("Berserk", itempool)
|
||||
self.create_ratioed_items("Invulnerability", itempool)
|
||||
self.create_ratioed_items("Partial invisibility", itempool)
|
||||
self.create_ratioed_items("Supercharge", itempool)
|
||||
|
||||
while len(itempool) < self.location_count:
|
||||
itempool.append(self.create_item(self.get_filler_item_name()))
|
||||
|
||||
# add itempool to multiworld
|
||||
self.multiworld.itempool += itempool
|
||||
|
||||
def get_filler_item_name(self):
|
||||
return self.multiworld.random.choice([
|
||||
"Medikit",
|
||||
"Box of bullets",
|
||||
"Box of rockets",
|
||||
"Box of shotgun shells",
|
||||
"Energy cell pack"
|
||||
])
|
||||
|
||||
def create_ratioed_items(self, item_name: str, itempool: List[DOOM2Item]):
|
||||
remaining_loc = self.location_count - len(itempool)
|
||||
ep_count = self.get_episode_count()
|
||||
|
||||
# Was balanced based on DOOM 1993's first 3 episodes
|
||||
count = min(remaining_loc, max(1, int(round(self.items_ratio[item_name] * ep_count / 3))))
|
||||
if count == 0:
|
||||
logger.warning("Warning, no ", item_name, " will be placed.")
|
||||
return
|
||||
|
||||
for i in range(count):
|
||||
itempool.append(self.create_item(item_name))
|
||||
|
||||
def fill_slot_data(self) -> Dict[str, Any]:
|
||||
return self.options.as_dict("difficulty", "random_monsters", "random_pickups", "random_music", "flip_levels", "allow_death_logic", "pro", "death_link", "reset_level_on_death", "episode1", "episode2", "episode3", "episode4")
|
|
@ -0,0 +1,23 @@
|
|||
# DOOM II
|
||||
|
||||
## Where is the settings page?
|
||||
|
||||
The [player settings page](../player-settings) contains the options needed to configure your game session.
|
||||
|
||||
## What does randomization do to this game?
|
||||
|
||||
Guns, keycards, and level unlocks have been randomized. Typically, you will end up playing different levels out of order to find your keycards and level unlocks and eventually complete your game.
|
||||
|
||||
Maps can be selected on a level select screen. You can exit a level at any time by visiting the hub station at the beginning of each level. The state of each level is saved and restored upon re-entering the level.
|
||||
|
||||
## What is the goal?
|
||||
|
||||
The goal is to complete every level.
|
||||
|
||||
## What is a "check" in DOOM II?
|
||||
|
||||
Guns, keycards, and powerups have been replaced with Archipelago checks. The switch at the end of each level is also a check.
|
||||
|
||||
## What "items" can you unlock in DOOM II?
|
||||
|
||||
Keycards and level unlocks are your main progression items. Gun unlocks and some upgrades are your useful items. Temporary powerups, ammo, healing, and armor are filler items.
|
|
@ -0,0 +1,51 @@
|
|||
# DOOM II Randomizer Setup
|
||||
|
||||
## Required Software
|
||||
|
||||
- [DOOM II (e.g. Steam version)](https://store.steampowered.com/app/2300/DOOM_II/)
|
||||
- [Archipelago Crispy DOOM](https://github.com/Daivuk/apdoom/releases)
|
||||
|
||||
## Optional Software
|
||||
|
||||
- [ArchipelagoTextClient](https://github.com/ArchipelagoMW/Archipelago/releases)
|
||||
|
||||
## Installing AP Doom
|
||||
1. Download [APDOOM.zip](https://github.com/Daivuk/apdoom/releases) and extract it.
|
||||
2. Copy DOOM2.WAD from your steam install into the extracted folder.
|
||||
You can find the folder in steam by finding the game in your library,
|
||||
right clicking it and choosing *Manage→Browse Local Files*.
|
||||
|
||||
## Joining a MultiWorld Game
|
||||
|
||||
1. Launch apdoom-launcher.exe
|
||||
2. Select `DOOM II` from the drop-down
|
||||
3. Enter the Archipelago server address, slot name, and password (if you have one)
|
||||
4. Press "Launch DOOM"
|
||||
5. Enjoy!
|
||||
|
||||
To continue a game, follow the same connection steps.
|
||||
Connecting with a different seed won't erase your progress in other seeds.
|
||||
|
||||
## Archipelago Text Client
|
||||
|
||||
We recommend having Archipelago's Text Client open on the side to keep track of what items you receive and send.
|
||||
APDOOM has in-game messages,
|
||||
but they disappear quickly and there's no reasonable way to check your message history in-game.
|
||||
|
||||
### Hinting
|
||||
|
||||
To hint from in-game, use the chat (Default key: 'T'). Hinting from DOOM II can be difficult because names are rather long and contain special characters. For example:
|
||||
```
|
||||
!hint Underhalls (MAP02) - Red keycard
|
||||
```
|
||||
The game has a hint helper implemented, where you can simply type this:
|
||||
```
|
||||
!hint map02 red
|
||||
```
|
||||
For this to work, include the map short name (`MAP01`), followed by one of the keywords: `map`, `blue`, `yellow`, `red`.
|
||||
|
||||
## Auto-Tracking
|
||||
|
||||
APDOOM has a functional map tracker integrated into the level select screen.
|
||||
It tells you which levels you have unlocked, which keys you have for each level, which levels have been completed,
|
||||
and how many of the checks you have completed in each level.
|
Loading…
Reference in New Issue