Skip to content

Commit

Permalink
Code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Ziktofel committed Sep 25, 2023
1 parent 0bfa790 commit 78eb003
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 51 deletions.
6 changes: 1 addition & 5 deletions worlds/sc2wol/MissionTables.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ def get_campaign_difficulty(campaign: SC2Campaign, excluded_missions: list[str]
return max([mission.pool for mission in included_missions])


def get_campaign_goal_priority(campaign: SC2Campaign, excluded_missions: list[str] = None) -> SC2CampaignGoalPriority:
def get_campaign_goal_priority(campaign: SC2Campaign, excluded_missions: List[str] | frozenset[str] = None) -> SC2CampaignGoalPriority:
"""
Gets a modified campaign goal priority.
If all the campaign's goal missions are excluded, it's ineligible to have the goal
Expand Down Expand Up @@ -461,7 +461,3 @@ def get_campaign_potential_goal_missions(campaign: SC2Campaign) -> List[SC2Missi

def get_no_build_missions() -> List[SC2Mission]:
return [mission for mission in SC2Mission if not mission.build]


def get_missions_by_pool(pool: MissionPools) -> List[SC2Mission]:
return [mission for mission in SC2Mission if pool == mission.pool]
67 changes: 36 additions & 31 deletions worlds/sc2wol/PoolFilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .Items import get_full_item_list, spider_mine_sources, second_pass_placeable_items
from .MissionTables import mission_orders, MissionInfo, MissionPools, get_campaign_missions, \
get_campaign_goal_priority, campaign_final_mission_locations, campaign_alt_final_mission_locations, \
get_missions_by_pool, get_no_build_missions, SC2Campaign, SC2Race, SC2CampaignGoalPriority
get_no_build_missions, SC2Campaign, SC2Race, SC2CampaignGoalPriority, SC2Mission
from .Options import get_option_value, MissionOrder, \
get_enabled_campaigns, get_disabled_campaigns
from .LogicMixin import SC2WoLLogic
Expand All @@ -21,7 +21,7 @@
STARPORT_UNITS = {"Medivac", "Wraith", "Viking", "Banshee", "Battlecruiser", "Hercules", "Science Vessel", "Raven", "Liberator", "Valkyrie"}


def filter_missions(multiworld: MultiWorld, player: int) -> Dict[MissionPools, List[str]]:
def filter_missions(multiworld: MultiWorld, player: int) -> Dict[MissionPools, List[SC2Mission]]:
"""
Returns a semi-randomly pruned tuple of no-build, easy, medium, and hard mission sets
"""
Expand All @@ -31,21 +31,23 @@ def filter_missions(multiworld: MultiWorld, player: int) -> Dict[MissionPools, L
enabled_campaigns = get_enabled_campaigns(multiworld, player)
disabled_campaigns = get_disabled_campaigns(multiworld, player)
excluded_missions = get_option_value(multiworld, player, "excluded_missions")
mission_pools = {
MissionPools.STARTER: [mission.mission_name for mission in get_missions_by_pool(MissionPools.STARTER)],
MissionPools.EASY: [mission.mission_name for mission in get_missions_by_pool(MissionPools.EASY)],
MissionPools.MEDIUM: [mission.mission_name for mission in get_missions_by_pool(MissionPools.MEDIUM)],
MissionPools.HARD: [mission.mission_name for mission in get_missions_by_pool(MissionPools.HARD)],
MissionPools.VERY_HARD: [mission.mission_name for mission in get_missions_by_pool(MissionPools.VERY_HARD)],
MissionPools.FINAL: []
}
mission_pools: Dict[MissionPools, List[SC2Mission]] = {}
for mission in SC2Mission:
if not mission_pools.get(mission.pool):
mission_pools[mission.pool] = list()
mission_pools[mission.pool].append(mission)
# A bit of safeguard:
for mission_pool in MissionPools:
if not mission_pools.get(mission_pool):
mission_pools[mission_pool] = []

if mission_order_type == MissionOrder.option_vanilla:
# Vanilla uses the entire mission pool
goal_priorities: Dict[SC2Campaign, SC2CampaignGoalPriority] = {campaign: get_campaign_goal_priority(campaign) for campaign in enabled_campaigns}
goal_level = max(goal_priorities.values())
candidate_campaigns = [campaign for campaign, goal_priority in goal_priorities.items() if goal_priority == goal_level]
goal_campaign = multiworld.random.choice(candidate_campaigns)
mission_pools[MissionPools.FINAL] = [campaign_final_mission_locations[goal_campaign].mission.mission_name]
mission_pools[MissionPools.FINAL] = [campaign_final_mission_locations[goal_campaign].mission]
remove_final_mission_from_other_pools(mission_pools)
return mission_pools
# Omitting No-Build missions if not shuffling no-build
Expand All @@ -64,44 +66,47 @@ def filter_missions(multiworld: MultiWorld, player: int) -> Dict[MissionPools, L
if primary_goal is None or primary_goal.mission.mission_name in excluded_missions:
# No primary goal or its mission is excluded
candidate_missions = list(campaign_alt_final_mission_locations[goal_campaign].keys())
candidate_missions = [mission for mission in candidate_missions if mission.mission_name not in excluded_missions]
if len(candidate_missions) == 0:
raise Exception("There are no valid gaol missions. Please exclude fewer missions.")
goal_mission = multiworld.random.choice(candidate_missions).mission_name
else:
goal_mission = campaign_final_mission_locations[goal_campaign].mission
goal_mission = primary_goal.mission

# Excluding missions
for difficulty, mission_pool in mission_pools.items():
mission_pools[difficulty] = [mission for mission in mission_pool if mission not in excluded_missions]
mission_pools[MissionPools.FINAL].append(goal_mission.mission_name)
mission_pools[difficulty] = [mission for mission in mission_pool if mission.name not in excluded_missions]
mission_pools[MissionPools.FINAL] = [goal_mission]

# Mission pool changes on Build-Only
if not get_option_value(multiworld, player, 'shuffle_no_build'):
def move_mission(mission_name, current_pool, new_pool):
if mission_name in mission_pools[current_pool]:
mission_pools[current_pool].remove(mission_name)
mission_pools[new_pool].append(mission_name)
def move_mission(mission: SC2Mission, current_pool, new_pool):
if mission in mission_pools[current_pool]:
mission_pools[current_pool].remove(mission)
mission_pools[new_pool].append(mission)
# Replacing No Build missions with Easy missions
move_mission("Zero Hour", MissionPools.EASY, MissionPools.STARTER)
move_mission("Evacuation", MissionPools.EASY, MissionPools.STARTER)
move_mission("Devil's Playground", MissionPools.EASY, MissionPools.STARTER)
move_mission(SC2Mission.ZERO_HOUR, MissionPools.EASY, MissionPools.STARTER)
move_mission(SC2Mission.EVACUATION, MissionPools.EASY, MissionPools.STARTER)
move_mission(SC2Mission.DEVILS_PLAYGROUND, MissionPools.EASY, MissionPools.STARTER)
# Pushing Outbreak to Normal, as it cannot be placed as the second mission on Build-Only
move_mission("Outbreak", MissionPools.EASY, MissionPools.MEDIUM)
move_mission(SC2Mission.OUTBREAK, MissionPools.EASY, MissionPools.MEDIUM)
# Pushing extra Normal missions to Easy
move_mission("The Great Train Robbery", MissionPools.MEDIUM, MissionPools.EASY)
move_mission("Echoes of the Future", MissionPools.MEDIUM, MissionPools.EASY)
move_mission("Cutthroat", MissionPools.MEDIUM, MissionPools.EASY)
move_mission(SC2Mission.THE_GREAT_TRAIN_ROBBERY, MissionPools.MEDIUM, MissionPools.EASY)
move_mission(SC2Mission.ECHOES_OF_THE_FUTURE, MissionPools.MEDIUM, MissionPools.EASY)
move_mission(SC2Mission.CUTTHROAT, MissionPools.MEDIUM, MissionPools.EASY)
# Additional changes on Advanced Tactics
if get_option_value(multiworld, player, "required_tactics") > 0:
move_mission("The Great Train Robbery", MissionPools.EASY, MissionPools.STARTER)
move_mission("Smash and Grab", MissionPools.EASY, MissionPools.STARTER)
move_mission("Moebius Factor", MissionPools.MEDIUM, MissionPools.EASY)
move_mission("Welcome to the Jungle", MissionPools.MEDIUM, MissionPools.EASY)
move_mission("Engine of Destruction", MissionPools.HARD, MissionPools.MEDIUM)
move_mission(SC2Mission.THE_GREAT_TRAIN_ROBBERY, MissionPools.EASY, MissionPools.STARTER)
move_mission(SC2Mission.SMASH_AND_GRAB, MissionPools.EASY, MissionPools.STARTER)
move_mission(SC2Mission.THE_MOEBIUS_FACTOR, MissionPools.MEDIUM, MissionPools.EASY)
move_mission(SC2Mission.WELCOME_TO_THE_JUNGLE, MissionPools.MEDIUM, MissionPools.EASY)
move_mission(SC2Mission.ENGINE_OF_DESTRUCTION, MissionPools.HARD, MissionPools.MEDIUM)

remove_final_mission_from_other_pools(mission_pools)
return mission_pools


def remove_final_mission_from_other_pools(mission_pools: Dict[MissionPools, List[str]]):
def remove_final_mission_from_other_pools(mission_pools: Dict[MissionPools, List[SC2Mission]]):
final_missions = mission_pools[MissionPools.FINAL]
for pool, missions in mission_pools.items():
if pool == MissionPools.FINAL:
Expand Down
31 changes: 16 additions & 15 deletions worlds/sc2wol/Regions.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from typing import List, Dict, Tuple, Optional, Callable, NamedTuple, SupportsIndex
from typing import List, Dict, Tuple, Optional, Callable, NamedTuple
from BaseClasses import MultiWorld, Region, Entrance, Location
from .Locations import LocationData
from .Options import get_option_value, MissionOrder, get_enabled_campaigns, campaign_depending_orders
from .MissionTables import MissionInfo, mission_orders, vanilla_mission_req_table, \
MissionPools, SC2Campaign, lookup_name_to_mission, get_goal_location, SC2Mission, MissionConnection
MissionPools, SC2Campaign, get_goal_location, SC2Mission, MissionConnection
from .PoolFilter import filter_missions


class SC2MissionSlot(NamedTuple):
campaign: SC2Campaign
slot: MissionPools | SC2Mission | None


def create_regions(multiworld: MultiWorld, player: int, locations: Tuple[LocationData, ...], location_cache: List[Location])\
-> Tuple[Dict[SC2Campaign, Dict[str, MissionInfo]], int, str]:
locations_per_region = get_locations_per_region(locations)
Expand All @@ -20,8 +21,8 @@ def create_regions(multiworld: MultiWorld, player: int, locations: Tuple[Locatio
enabled_campaigns = get_enabled_campaigns(multiworld, player)
shuffle_campaigns = get_option_value(multiworld, player, "shuffle_campaigns")

mission_pools = filter_missions(multiworld, player)
final_mission = lookup_name_to_mission[mission_pools[MissionPools.FINAL][0]]
mission_pools: Dict[MissionPools, List[SC2Mission]] = filter_missions(multiworld, player)
final_mission = mission_pools[MissionPools.FINAL][0]

regions = [create_region(multiworld, player, locations_per_region, location_cache, "Menu")]

Expand Down Expand Up @@ -119,7 +120,7 @@ def create_regions(multiworld: MultiWorld, player: int, locations: Tuple[Locatio
if mission_order_type in campaign_depending_orders:
# Do slot removal per campaign
for campaign in enabled_campaigns:
campaign_mission_pool = [mission for mission in mission_pool if lookup_name_to_mission[mission].campaign == campaign]
campaign_mission_pool = [mission for mission in mission_pool if mission.campaign == campaign]
campaign_mission_pool_size = len(campaign_mission_pool)

removals = len(mission_order[campaign]) - campaign_mission_pool_size
Expand All @@ -134,7 +135,7 @@ def create_regions(multiworld: MultiWorld, player: int, locations: Tuple[Locatio
mission_slots.append(SC2MissionSlot(campaign, final_mission))
else:
# Not the goal, find the most difficult mission in the pool and set the difficulty
campaign_difficulty = max(lookup_name_to_mission[mission].pool for mission in campaign_mission_pool)
campaign_difficulty = max(mission.pool for mission in campaign_mission_pool)
mission_slots.append(SC2MissionSlot(campaign, campaign_difficulty))
else:
mission_slots.append(SC2MissionSlot(campaign, mission.type))
Expand Down Expand Up @@ -183,20 +184,20 @@ def pick_mission(slot):
if shuffle_campaigns or mission_order not in campaign_depending_orders:
# Pick a mission from any campaign
filler = multiworld.random.randint(0, len(missions_to_add) - 1)
mission = lookup_name_to_mission[missions_to_add.pop(filler)]
mission = missions_to_add.pop(filler)
slot_campaign = mission_slots[slot].campaign
mission_slots[slot] = SC2MissionSlot(slot_campaign, mission)
else:
# Pick a mission from required campaign
slot_campaign = mission_slots[slot].campaign
candidate_missions = [lookup_name_to_mission[mission_name] for mission_name in missions_to_add]
candidate_missions = [mission_name for mission_name in missions_to_add]
campaign_mission_candidates = [mission for mission in candidate_missions if mission.campaign == slot_campaign]
filler = multiworld.random.randint(0, len(campaign_mission_candidates) - 1)
mission = lookup_name_to_mission[missions_to_add.pop(filler)]
mission = missions_to_add.pop(filler)
mission_slots[slot] = SC2MissionSlot(slot_campaign, mission)

# Add no_build missions to the pool and fill in no_build slots
missions_to_add = mission_pools[MissionPools.STARTER]
missions_to_add: List[SC2Mission] = mission_pools[MissionPools.STARTER]
if len(no_build_slots) > len(missions_to_add):
raise Exception("There are no valid No-Build missions. Please exclude fewer missions.")
for slot in no_build_slots:
Expand Down Expand Up @@ -351,8 +352,8 @@ def create_region(multiworld: MultiWorld, player: int, locations_per_region: Dic

def connect(world: MultiWorld, player: int, used_names: Dict[str, int], source: str, target: str,
rule: Optional[Callable] = None):
sourceRegion = world.get_region(source, player)
targetRegion = world.get_region(target, player)
source_region = world.get_region(source, player)
target_region = world.get_region(target, player)

if target not in used_names:
used_names[target] = 1
Expand All @@ -361,13 +362,13 @@ def connect(world: MultiWorld, player: int, used_names: Dict[str, int], source:
used_names[target] += 1
name = target + (' ' * used_names[target])

connection = Entrance(player, name, sourceRegion)
connection = Entrance(player, name, source_region)

if rule:
connection.access_rule = rule

sourceRegion.exits.append(connection)
connection.connect(targetRegion)
source_region.exits.append(connection)
connection.connect(target_region)


def get_locations_per_region(locations: Tuple[LocationData, ...]) -> Dict[str, List[LocationData]]:
Expand Down

0 comments on commit 78eb003

Please sign in to comment.