908 lines
33 KiB
Python
908 lines
33 KiB
Python
|
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,
|
||
|
]
|