Archipelago/worlds/sc2/Options.py

908 lines
33 KiB
Python
Raw Normal View History

from dataclasses import dataclass, fields, Field
from typing import FrozenSet, Union, Set
from Options import Choice, Toggle, DefaultOnToggle, ItemSet, OptionSet, Range, PerGameCommonOptions
from .MissionTables import SC2Campaign, SC2Mission, lookup_name_to_mission, MissionPools, get_no_build_missions, \
campaign_mission_table
from worlds.AutoWorld import World
class GameDifficulty(Choice):
"""
The difficulty of the campaign, affects enemy AI, starting units, and game speed.
For those unfamiliar with the Archipelago randomizer, the recommended settings are one difficulty level
lower than the vanilla game
"""
display_name = "Game Difficulty"
option_casual = 0
option_normal = 1
option_hard = 2
option_brutal = 3
default = 1
class GameSpeed(Choice):
"""Optional setting to override difficulty-based game speed."""
display_name = "Game Speed"
option_default = 0
option_slower = 1
option_slow = 2
option_normal = 3
option_fast = 4
option_faster = 5
default = option_default
class DisableForcedCamera(Toggle):
"""
Prevents the game from moving or locking the camera without the player's consent.
"""
display_name = "Disable Forced Camera Movement"
class SkipCutscenes(Toggle):
"""
Skips all cutscenes and prevents dialog from blocking progress.
"""
display_name = "Skip Cutscenes"
class AllInMap(Choice):
"""Determines what version of All-In (WoL final map) that will be generated for the campaign."""
display_name = "All In Map"
option_ground = 0
option_air = 1
class MissionOrder(Choice):
"""
Determines the order the missions are played in. The last three mission orders end in a random mission.
Vanilla (83 total if all campaigns enabled): Keeps the standard mission order and branching from the vanilla Campaigns.
Vanilla Shuffled (83 total if all campaigns enabled): Keeps same branching paths from the vanilla Campaigns but randomizes the order of missions within.
Mini Campaign (47 total if all campaigns enabled): Shorter version of the campaign with randomized missions and optional branches.
Medium Grid (16): A 4x4 grid of random missions. Start at the top-left and forge a path towards bottom-right mission to win.
Mini Grid (9): A 3x3 version of Grid. Complete the bottom-right mission to win.
Blitz (12): 12 random missions that open up very quickly. Complete the bottom-right mission to win.
Gauntlet (7): Linear series of 7 random missions to complete the campaign.
Mini Gauntlet (4): Linear series of 4 random missions to complete the campaign.
Tiny Grid (4): A 2x2 version of Grid. Complete the bottom-right mission to win.
Grid (variable): A grid that will resize to use all non-excluded missions. Corners may be omitted to make the grid more square. Complete the bottom-right mission to win.
"""
display_name = "Mission Order"
option_vanilla = 0
option_vanilla_shuffled = 1
option_mini_campaign = 2
option_medium_grid = 3
option_mini_grid = 4
option_blitz = 5
option_gauntlet = 6
option_mini_gauntlet = 7
option_tiny_grid = 8
option_grid = 9
class MaximumCampaignSize(Range):
"""
Sets an upper bound on how many missions to include when a variable-size mission order is selected.
If a set-size mission order is selected, does nothing.
"""
display_name = "Maximum Campaign Size"
range_start = 1
range_end = 83
default = 83
class GridTwoStartPositions(Toggle):
"""
If turned on and 'grid' mission order is selected, removes a mission from the starting
corner sets the adjacent two missions as the starter missions.
"""
display_name = "Start with two unlocked missions on grid"
default = Toggle.option_false
class ColorChoice(Choice):
option_white = 0
option_red = 1
option_blue = 2
option_teal = 3
option_purple = 4
option_yellow = 5
option_orange = 6
option_green = 7
option_light_pink = 8
option_violet = 9
option_light_grey = 10
option_dark_green = 11
option_brown = 12
option_light_green = 13
option_dark_grey = 14
option_pink = 15
option_rainbow = 16
option_default = 17
default = option_default
class PlayerColorTerranRaynor(ColorChoice):
"""Determines in-game team color for playable Raynor's Raiders (Terran) factions."""
display_name = "Terran Player Color (Raynor)"
class PlayerColorProtoss(ColorChoice):
"""Determines in-game team color for playable Protoss factions."""
display_name = "Protoss Player Color"
class PlayerColorZerg(ColorChoice):
"""Determines in-game team color for playable Zerg factions before Kerrigan becomes Primal Kerrigan."""
display_name = "Zerg Player Color"
class PlayerColorZergPrimal(ColorChoice):
"""Determines in-game team color for playable Zerg factions after Kerrigan becomes Primal Kerrigan."""
display_name = "Zerg Player Color (Primal)"
class EnableWolMissions(DefaultOnToggle):
"""
Enables missions from main Wings of Liberty campaign.
"""
display_name = "Enable Wings of Liberty missions"
class EnableProphecyMissions(DefaultOnToggle):
"""
Enables missions from Prophecy mini-campaign.
"""
display_name = "Enable Prophecy missions"
class EnableHotsMissions(DefaultOnToggle):
"""
Enables missions from Heart of the Swarm campaign.
"""
display_name = "Enable Heart of the Swarm missions"
class EnableLotVPrologueMissions(DefaultOnToggle):
"""
Enables missions from Prologue campaign.
"""
display_name = "Enable Prologue (Legacy of the Void) missions"
class EnableLotVMissions(DefaultOnToggle):
"""
Enables missions from Legacy of the Void campaign.
"""
display_name = "Enable Legacy of the Void (main campaign) missions"
class EnableEpilogueMissions(DefaultOnToggle):
"""
Enables missions from Epilogue campaign.
These missions are considered very hard.
Enabling Wings of Liberty, Heart of the Swarm and Legacy of the Void is strongly recommended in order to play Epilogue.
Not recommended for short mission orders.
See also: Exclude Very Hard Missions
"""
display_name = "Enable Epilogue missions"
class EnableNCOMissions(DefaultOnToggle):
"""
Enables missions from Nova Covert Ops campaign.
Note: For best gameplay experience it's recommended to also enable Wings of Liberty campaign.
"""
display_name = "Enable Nova Covert Ops missions"
class ShuffleCampaigns(DefaultOnToggle):
"""
Shuffles the missions between campaigns if enabled.
Only available for Vanilla Shuffled and Mini Campaign mission order
"""
display_name = "Shuffle Campaigns"
class ShuffleNoBuild(DefaultOnToggle):
"""
Determines if the no-build missions are included in the shuffle.
If turned off, the no-build missions will not appear. Has no effect for Vanilla mission order.
"""
display_name = "Shuffle No-Build Missions"
class StarterUnit(Choice):
"""
Unlocks a random unit at the start of the game.
Off: No units are provided, the first unit must be obtained from the randomizer
Balanced: A unit that doesn't give the player too much power early on is given
Any Starter Unit: Any starter unit can be given
"""
display_name = "Starter Unit"
option_off = 0
option_balanced = 1
option_any_starter_unit = 2
class RequiredTactics(Choice):
"""
Determines the maximum tactical difficulty of the world (separate from mission difficulty). Higher settings
increase randomness.
Standard: All missions can be completed with good micro and macro.
Advanced: Completing missions may require relying on starting units and micro-heavy units.
No Logic: Units and upgrades may be placed anywhere. LIKELY TO RENDER THE RUN IMPOSSIBLE ON HARDER DIFFICULTIES!
Locks Grant Story Tech option to true.
"""
display_name = "Required Tactics"
option_standard = 0
option_advanced = 1
option_no_logic = 2
class GenericUpgradeMissions(Range):
"""Determines the percentage of missions in the mission order that must be completed before
level 1 of all weapon and armor upgrades is unlocked. Level 2 upgrades require double the amount of missions,
and level 3 requires triple the amount. The required amounts are always rounded down.
If set to 0, upgrades are instead added to the item pool and must be found to be used."""
display_name = "Generic Upgrade Missions"
range_start = 0
range_end = 100
default = 0
class GenericUpgradeResearch(Choice):
"""Determines how weapon and armor upgrades affect missions once unlocked.
Vanilla: Upgrades must be researched as normal.
Auto In No-Build: In No-Build missions, upgrades are automatically researched.
In all other missions, upgrades must be researched as normal.
Auto In Build: In No-Build missions, upgrades are unavailable as normal.
In all other missions, upgrades are automatically researched.
Always Auto: Upgrades are automatically researched in all missions."""
display_name = "Generic Upgrade Research"
option_vanilla = 0
option_auto_in_no_build = 1
option_auto_in_build = 2
option_always_auto = 3
class GenericUpgradeItems(Choice):
"""Determines how weapon and armor upgrades are split into items. All options produce 3 levels of each item.
Does nothing if upgrades are unlocked by completed mission counts.
Individual Items: All weapon and armor upgrades are each an item,
resulting in 18 total upgrade items for Terran and 15 total items for Zerg and Protoss each.
Bundle Weapon And Armor: All types of weapon upgrades are one item per race,
and all types of armor upgrades are one item per race,
resulting in 18 total items.
Bundle Unit Class: Weapon and armor upgrades are merged,
but upgrades are bundled separately for each race:
Infantry, Vehicle, and Starship upgrades for Terran (9 items),
Ground and Flyer upgrades for Zerg (6 items),
Ground and Air upgrades for Protoss (6 items),
resulting in 21 total items.
Bundle All: All weapon and armor upgrades are one item per race,
resulting in 9 total items."""
display_name = "Generic Upgrade Items"
option_individual_items = 0
option_bundle_weapon_and_armor = 1
option_bundle_unit_class = 2
option_bundle_all = 3
class NovaCovertOpsItems(Toggle):
"""
If turned on, the equipment upgrades from Nova Covert Ops may be present in the world.
If Nova Covert Ops campaign is enabled, this option is locked to be turned on.
"""
display_name = "Nova Covert Ops Items"
default = Toggle.option_true
class BroodWarItems(Toggle):
"""If turned on, returning items from StarCraft: Brood War may appear in the world."""
display_name = "Brood War Items"
default = Toggle.option_true
class ExtendedItems(Toggle):
"""If turned on, original items that did not appear in Campaign mode may appear in the world."""
display_name = "Extended Items"
default = Toggle.option_true
# Current maximum number of upgrades for a unit
MAX_UPGRADES_OPTION = 12
class EnsureGenericItems(Range):
"""
Specifies a minimum percentage of the generic item pool that will be present for the slot.
The generic item pool is the pool of all generically useful items after all exclusions.
Generically-useful items include: Worker upgrades, Building upgrades, economy upgrades,
Mercenaries, Kerrigan levels and abilities, and Spear of Adun abilities
Increasing this percentage will make units less common.
"""
display_name = "Ensure Generic Items"
range_start = 0
range_end = 100
default = 25
class MinNumberOfUpgrades(Range):
"""
Set a minimum to the number of upgrades a unit/structure can have.
Note that most units have 4 or 6 upgrades.
If a unit has fewer upgrades than the minimum, it will have all of its upgrades.
Doesn't affect shared unit upgrades.
"""
display_name = "Minimum number of upgrades per unit/structure"
range_start = 0
range_end = MAX_UPGRADES_OPTION
default = 2
class MaxNumberOfUpgrades(Range):
"""
Set a maximum to the number of upgrades a unit/structure can have. -1 is used to define unlimited.
Note that most unit have 4 to 6 upgrades.
Doesn't affect shared unit upgrades.
"""
display_name = "Maximum number of upgrades per unit/structure"
range_start = -1
range_end = MAX_UPGRADES_OPTION
default = -1
class KerriganPresence(Choice):
"""
Determines whether Kerrigan is playable outside of missions that require her.
Vanilla: Kerrigan is playable as normal, appears in the same missions as in vanilla game.
Not Present: Kerrigan is not playable, unless the mission requires her to be present. Other hero units stay playable,
and locations normally requiring Kerrigan can be checked by any unit.
Kerrigan level items, active abilities and passive abilities affecting her will not appear.
In missions where the Kerrigan unit is required, story abilities are given in same way as Grant Story Tech is set to true
Not Present And No Passives: In addition to the above, Kerrigan's passive abilities affecting other units (such as Twin Drones) will not appear.
Note: Always set to "Not Present" if Heart of the Swarm campaign is disabled.
"""
display_name = "Kerrigan Presence"
option_vanilla = 0
option_not_present = 1
option_not_present_and_no_passives = 2
class KerriganLevelsPerMissionCompleted(Range):
"""
Determines how many levels Kerrigan gains when a mission is beaten.
NOTE: Setting this too low can result in generation failures if The Infinite Cycle or Supreme are in the mission pool.
"""
display_name = "Levels Per Mission Beaten"
range_start = 0
range_end = 20
default = 0
class KerriganLevelsPerMissionCompletedCap(Range):
"""
Limits how many total levels Kerrigan can gain from beating missions. This does not affect levels gained from items.
Set to -1 to disable this limit.
NOTE: The following missions have these level requirements:
Supreme: 35
The Infinite Cycle: 70
See Grant Story Levels for more details.
"""
display_name = "Levels Per Mission Beaten Cap"
range_start = -1
range_end = 140
default = -1
class KerriganLevelItemSum(Range):
"""
Determines the sum of the level items in the world. This does not affect levels gained from beating missions.
NOTE: The following missions have these level requirements:
Supreme: 35
The Infinite Cycle: 70
See Grant Story Levels for more details.
"""
display_name = "Kerrigan Level Item Sum"
range_start = 0
range_end = 140
default = 70
class KerriganLevelItemDistribution(Choice):
"""Determines the amount and size of Kerrigan level items.
Vanilla: Uses the distribution in the vanilla campaign.
This entails 32 individual levels and 6 packs of varying sizes.
This distribution always adds up to 70, ignoring the Level Item Sum setting.
Smooth: Uses a custom, condensed distribution of 10 items between sizes 4 and 10,
intended to fit more levels into settings with little room for filler while keeping some variance in level gains.
This distribution always adds up to 70, ignoring the Level Item Sum setting.
Size 70: Uses items worth 70 levels each.
Size 35: Uses items worth 35 levels each.
Size 14: Uses items worth 14 levels each.
Size 10: Uses items worth 10 levels each.
Size 7: Uses items worth 7 levels each.
Size 5: Uses items worth 5 levels each.
Size 2: Uses items worth 2 level eachs.
Size 1: Uses individual levels. As there are not enough locations in the game for this distribution,
this will result in a greatly reduced total level, and is likely to remove many other items."""
display_name = "Kerrigan Level Item Distribution"
option_vanilla = 0
option_smooth = 1
option_size_70 = 2
option_size_35 = 3
option_size_14 = 4
option_size_10 = 5
option_size_7 = 6
option_size_5 = 7
option_size_2 = 8
option_size_1 = 9
default = option_smooth
class KerriganTotalLevelCap(Range):
"""
Limits how many total levels Kerrigan can gain from any source. Depending on your other settings,
there may be more levels available in the world, but they will not affect Kerrigan.
Set to -1 to disable this limit.
NOTE: The following missions have these level requirements:
Supreme: 35
The Infinite Cycle: 70
See Grant Story Levels for more details.
"""
display_name = "Total Level Cap"
range_start = -1
range_end = 140
default = -1
class StartPrimaryAbilities(Range):
"""Number of Primary Abilities (Kerrigan Tier 1, 2, and 4) to start the game with.
If set to 4, a Tier 7 ability is also included."""
display_name = "Starting Primary Abilities"
range_start = 0
range_end = 4
default = 0
class KerriganPrimalStatus(Choice):
"""Determines when Kerrigan appears in her Primal Zerg form.
This greatly increases her energy regeneration.
Vanilla: Kerrigan is human in missions that canonically appear before The Crucible,
and zerg thereafter.
Always Zerg: Kerrigan is always zerg.
Always Human: Kerrigan is always human.
Level 35: Kerrigan is human until reaching level 35, and zerg thereafter.
Half Completion: Kerrigan is human until half of the missions in the world are completed,
and zerg thereafter.
Item: Kerrigan's Primal Form is an item. She is human until it is found, and zerg thereafter."""
display_name = "Kerrigan Primal Status"
option_vanilla = 0
option_always_zerg = 1
option_always_human = 2
option_level_35 = 3
option_half_completion = 4
option_item = 5
class SpearOfAdunPresence(Choice):
"""
Determines in which missions Spear of Adun calldowns will be available.
Affects only abilities used from Spear of Adun top menu.
Not Present: Spear of Adun calldowns are unavailable.
LotV Protoss: Spear of Adun calldowns are only available in LotV main campaign
Protoss: Spear od Adun calldowns are available in any Protoss mission
Everywhere: Spear od Adun calldowns are available in any mission of any race
"""
display_name = "Spear of Adun Presence"
option_not_present = 0
option_lotv_protoss = 1
option_protoss = 2
option_everywhere = 3
default = option_lotv_protoss
# Fix case
@classmethod
def get_option_name(cls, value: int) -> str:
if value == SpearOfAdunPresence.option_lotv_protoss:
return "LotV Protoss"
else:
return super().get_option_name(value)
class SpearOfAdunPresentInNoBuild(Toggle):
"""
Determines if Spear of Adun calldowns are available in no-build missions.
If turned on, Spear of Adun calldown powers are available in missions specified under "Spear of Adun Presence".
If turned off, Spear of Adun calldown powers are unavailable in all no-build missions
"""
display_name = "Spear of Adun Present in No-Build"
class SpearOfAdunAutonomouslyCastAbilityPresence(Choice):
"""
Determines availability of Spear of Adun powers, that are autonomously cast.
Affects abilities like Reconstruction Beam or Overwatch
Not Presents: Autocasts are not available.
LotV Protoss: Spear of Adun autocasts are only available in LotV main campaign
Protoss: Spear od Adun autocasts are available in any Protoss mission
Everywhere: Spear od Adun autocasts are available in any mission of any race
"""
display_name = "Spear of Adun Autonomously Cast Powers Presence"
option_not_present = 0
option_lotv_protoss = 1
option_protoss = 2
option_everywhere = 3
default = option_lotv_protoss
# Fix case
@classmethod
def get_option_name(cls, value: int) -> str:
if value == SpearOfAdunPresence.option_lotv_protoss:
return "LotV Protoss"
else:
return super().get_option_name(value)
class SpearOfAdunAutonomouslyCastPresentInNoBuild(Toggle):
"""
Determines if Spear of Adun autocasts are available in no-build missions.
If turned on, Spear of Adun autocasts are available in missions specified under "Spear of Adun Autonomously Cast Powers Presence".
If turned off, Spear of Adun autocasts are unavailable in all no-build missions
"""
display_name = "Spear of Adun Autonomously Cast Powers Present in No-Build"
class GrantStoryTech(Toggle):
"""
If set true, grants special tech required for story mission completion for duration of the mission.
Otherwise, you need to find these tech by a normal means as items.
Affects story missions like Back in the Saddle and Supreme
Locked to true if Required Tactics is set to no logic.
"""
display_name = "Grant Story Tech"
class GrantStoryLevels(Choice):
"""
If enabled, grants Kerrigan the required minimum levels for the following missions:
Supreme: 35
The Infinite Cycle: 70
The bonus levels only apply during the listed missions, and can exceed the Total Level Cap.
If disabled, either of these missions is included, and there are not enough levels in the world, generation may fail.
To prevent this, either increase the amount of levels in the world, or enable this option.
If disabled and Required Tactics is set to no logic, this option is forced to Minimum.
Disabled: Kerrigan does not get bonus levels for these missions,
instead the levels must be gained from items or beating missions.
Additive: Kerrigan gains bonus levels equal to the mission's required level.
Minimum: Kerrigan is either at her real level, or at the mission's required level,
depending on which is higher.
"""
display_name = "Grant Story Levels"
option_disabled = 0
option_additive = 1
option_minimum = 2
default = option_minimum
class TakeOverAIAllies(Toggle):
"""
On maps supporting this feature allows you to take control over an AI Ally.
"""
display_name = "Take Over AI Allies"
class LockedItems(ItemSet):
"""Guarantees that these items will be unlockable"""
display_name = "Locked Items"
class ExcludedItems(ItemSet):
"""Guarantees that these items will not be unlockable"""
display_name = "Excluded Items"
class ExcludedMissions(OptionSet):
"""Guarantees that these missions will not appear in the campaign
Doesn't apply to vanilla mission order.
It may be impossible to build a valid campaign if too many missions are excluded."""
display_name = "Excluded Missions"
valid_keys = {mission.mission_name for mission in SC2Mission}
class ExcludeVeryHardMissions(Choice):
"""
Excludes Very Hard missions outside of Epilogue campaign (All-In, Salvation, and all Epilogue missions are considered Very Hard).
Doesn't apply to "Vanilla" mission order.
Default: Not excluded for mission orders "Vanilla Shuffled" or "Grid" with Maximum Campaign Size >= 20,
excluded for any other order
Yes: Non-Epilogue Very Hard missions are excluded and won't be generated
No: Non-Epilogue Very Hard missions can appear normally. Not recommended for too short mission orders.
See also: Excluded Missions, Enable Epilogue Missions, Maximum Campaign Size
"""
display_name = "Exclude Very Hard Missions"
option_default = 0
option_true = 1
option_false = 2
@classmethod
def get_option_name(cls, value):
return ["Default", "Yes", "No"][int(value)]
class LocationInclusion(Choice):
option_enabled = 0
option_resources = 1
option_disabled = 2
class VanillaLocations(LocationInclusion):
"""
Enables or disables item rewards for completing vanilla objectives.
Vanilla objectives are bonus objectives from the vanilla game,
along with some additional objectives to balance the missions.
Enable these locations for a balanced experience.
Enabled: All locations fitting into this do their normal rewards
Resources: Forces these locations to contain Starting Resources
Disabled: Removes item rewards from these locations.
Note: Individual locations subject to plando are always enabled, so the plando can be placed properly.
See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando)
"""
display_name = "Vanilla Locations"
class ExtraLocations(LocationInclusion):
"""
Enables or disables item rewards for mission progress and minor objectives.
This includes mandatory mission objectives,
collecting reinforcements and resource pickups,
destroying structures, and overcoming minor challenges.
Enables these locations to add more checks and items to your world.
Enabled: All locations fitting into this do their normal rewards
Resources: Forces these locations to contain Starting Resources
Disabled: Removes item rewards from these locations.
Note: Individual locations subject to plando are always enabled, so the plando can be placed properly.
See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando)
"""
display_name = "Extra Locations"
class ChallengeLocations(LocationInclusion):
"""
Enables or disables item rewards for completing challenge tasks.
Challenges are tasks that are more difficult than completing the mission, and are often based on achievements.
You might be required to visit the same mission later after getting stronger in order to finish these tasks.
Enable these locations to increase the difficulty of completing the multiworld.
Enabled: All locations fitting into this do their normal rewards
Resources: Forces these locations to contain Starting Resources
Disabled: Removes item rewards from these locations.
Note: Individual locations subject to plando are always enabled, so the plando can be placed properly.
See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando)
"""
display_name = "Challenge Locations"
class MasteryLocations(LocationInclusion):
"""
Enables or disables item rewards for overcoming especially difficult challenges.
These challenges are often based on Mastery achievements and Feats of Strength.
Enable these locations to add the most difficult checks to the world.
Enabled: All locations fitting into this do their normal rewards
Resources: Forces these locations to contain Starting Resources
Disabled: Removes item rewards from these locations.
Note: Individual locations subject to plando are always enabled, so the plando can be placed properly.
See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando)
"""
display_name = "Mastery Locations"
class MineralsPerItem(Range):
"""
Configures how many minerals are given per resource item.
"""
display_name = "Minerals Per Item"
range_start = 0
range_end = 500
default = 25
class VespenePerItem(Range):
"""
Configures how much vespene gas is given per resource item.
"""
display_name = "Vespene Per Item"
range_start = 0
range_end = 500
default = 25
class StartingSupplyPerItem(Range):
"""
Configures how much starting supply per is given per item.
"""
display_name = "Starting Supply Per Item"
range_start = 0
range_end = 200
default = 5
@dataclass
class Starcraft2Options(PerGameCommonOptions):
game_difficulty: GameDifficulty
game_speed: GameSpeed
disable_forced_camera: DisableForcedCamera
skip_cutscenes: SkipCutscenes
all_in_map: AllInMap
mission_order: MissionOrder
maximum_campaign_size: MaximumCampaignSize
grid_two_start_positions: GridTwoStartPositions
player_color_terran_raynor: PlayerColorTerranRaynor
player_color_protoss: PlayerColorProtoss
player_color_zerg: PlayerColorZerg
player_color_zerg_primal: PlayerColorZergPrimal
enable_wol_missions: EnableWolMissions
enable_prophecy_missions: EnableProphecyMissions
enable_hots_missions: EnableHotsMissions
enable_lotv_prologue_missions: EnableLotVPrologueMissions
enable_lotv_missions: EnableLotVMissions
enable_epilogue_missions: EnableEpilogueMissions
enable_nco_missions: EnableNCOMissions
shuffle_campaigns: ShuffleCampaigns
shuffle_no_build: ShuffleNoBuild
starter_unit: StarterUnit
required_tactics: RequiredTactics
ensure_generic_items: EnsureGenericItems
min_number_of_upgrades: MinNumberOfUpgrades
max_number_of_upgrades: MaxNumberOfUpgrades
generic_upgrade_missions: GenericUpgradeMissions
generic_upgrade_research: GenericUpgradeResearch
generic_upgrade_items: GenericUpgradeItems
kerrigan_presence: KerriganPresence
kerrigan_levels_per_mission_completed: KerriganLevelsPerMissionCompleted
kerrigan_levels_per_mission_completed_cap: KerriganLevelsPerMissionCompletedCap
kerrigan_level_item_sum: KerriganLevelItemSum
kerrigan_level_item_distribution: KerriganLevelItemDistribution
kerrigan_total_level_cap: KerriganTotalLevelCap
start_primary_abilities: StartPrimaryAbilities
kerrigan_primal_status: KerriganPrimalStatus
spear_of_adun_presence: SpearOfAdunPresence
spear_of_adun_present_in_no_build: SpearOfAdunPresentInNoBuild
spear_of_adun_autonomously_cast_ability_presence: SpearOfAdunAutonomouslyCastAbilityPresence
spear_of_adun_autonomously_cast_present_in_no_build: SpearOfAdunAutonomouslyCastPresentInNoBuild
grant_story_tech: GrantStoryTech
grant_story_levels: GrantStoryLevels
take_over_ai_allies: TakeOverAIAllies
locked_items: LockedItems
excluded_items: ExcludedItems
excluded_missions: ExcludedMissions
exclude_very_hard_missions: ExcludeVeryHardMissions
nco_items: NovaCovertOpsItems
bw_items: BroodWarItems
ext_items: ExtendedItems
vanilla_locations: VanillaLocations
extra_locations: ExtraLocations
challenge_locations: ChallengeLocations
mastery_locations: MasteryLocations
minerals_per_item: MineralsPerItem
vespene_per_item: VespenePerItem
starting_supply_per_item: StartingSupplyPerItem
def get_option_value(world: World, name: str) -> Union[int, FrozenSet]:
if world is None:
field: Field = [class_field for class_field in fields(Starcraft2Options) if class_field.name == name][0]
return field.type.default
player_option = getattr(world.options, name)
return player_option.value
def get_enabled_campaigns(world: World) -> Set[SC2Campaign]:
enabled_campaigns = set()
if get_option_value(world, "enable_wol_missions"):
enabled_campaigns.add(SC2Campaign.WOL)
if get_option_value(world, "enable_prophecy_missions"):
enabled_campaigns.add(SC2Campaign.PROPHECY)
if get_option_value(world, "enable_hots_missions"):
enabled_campaigns.add(SC2Campaign.HOTS)
if get_option_value(world, "enable_lotv_prologue_missions"):
enabled_campaigns.add(SC2Campaign.PROLOGUE)
if get_option_value(world, "enable_lotv_missions"):
enabled_campaigns.add(SC2Campaign.LOTV)
if get_option_value(world, "enable_epilogue_missions"):
enabled_campaigns.add(SC2Campaign.EPILOGUE)
if get_option_value(world, "enable_nco_missions"):
enabled_campaigns.add(SC2Campaign.NCO)
return enabled_campaigns
def get_disabled_campaigns(world: World) -> Set[SC2Campaign]:
all_campaigns = set(SC2Campaign)
enabled_campaigns = get_enabled_campaigns(world)
disabled_campaigns = all_campaigns.difference(enabled_campaigns)
disabled_campaigns.remove(SC2Campaign.GLOBAL)
return disabled_campaigns
def get_excluded_missions(world: World) -> Set[SC2Mission]:
mission_order_type = get_option_value(world, "mission_order")
excluded_mission_names = get_option_value(world, "excluded_missions")
shuffle_no_build = get_option_value(world, "shuffle_no_build")
disabled_campaigns = get_disabled_campaigns(world)
excluded_missions: Set[SC2Mission] = set([lookup_name_to_mission[name] for name in excluded_mission_names])
# Excluding Very Hard missions depending on options
if (get_option_value(world, "exclude_very_hard_missions") == ExcludeVeryHardMissions.option_true
) or (
get_option_value(world, "exclude_very_hard_missions") == ExcludeVeryHardMissions.option_default
and (
mission_order_type not in [MissionOrder.option_vanilla_shuffled, MissionOrder.option_grid]
or (
mission_order_type == MissionOrder.option_grid
and get_option_value(world, "maximum_campaign_size") < 20
)
)
):
excluded_missions = excluded_missions.union(
[mission for mission in SC2Mission if
mission.pool == MissionPools.VERY_HARD and mission.campaign != SC2Campaign.EPILOGUE]
)
# Omitting No-Build missions if not shuffling no-build
if not shuffle_no_build:
excluded_missions = excluded_missions.union(get_no_build_missions())
# Omitting missions not in enabled campaigns
for campaign in disabled_campaigns:
excluded_missions = excluded_missions.union(campaign_mission_table[campaign])
return excluded_missions
campaign_depending_orders = [
MissionOrder.option_vanilla,
MissionOrder.option_vanilla_shuffled,
MissionOrder.option_mini_campaign
]
kerrigan_unit_available = [
KerriganPresence.option_vanilla,
]