From 8c8b29ae92fae551fd48a2e414e6ca203522d6ec Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Thu, 2 May 2024 12:20:57 +0200 Subject: [PATCH] SC2: For non-campaign order pick one of the hardest missions as goal (#3180) This allows End Game as the goal even if long campaigns are present --- worlds/sc2/MissionTables.py | 7 +++--- worlds/sc2/PoolFilter.py | 48 +++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/worlds/sc2/MissionTables.py b/worlds/sc2/MissionTables.py index 99b6448a..4dece464 100644 --- a/worlds/sc2/MissionTables.py +++ b/worlds/sc2/MissionTables.py @@ -650,7 +650,7 @@ campaign_final_mission_locations: Dict[SC2Campaign, SC2CampaignGoal] = { SC2Campaign.PROLOGUE: SC2CampaignGoal(SC2Mission.EVIL_AWOKEN, "Evil Awoken: Victory"), SC2Campaign.LOTV: SC2CampaignGoal(SC2Mission.SALVATION, "Salvation: Victory"), SC2Campaign.EPILOGUE: None, - SC2Campaign.NCO: None, + SC2Campaign.NCO: SC2CampaignGoal(SC2Mission.END_GAME, "End Game: Victory"), } campaign_alt_final_mission_locations: Dict[SC2Campaign, Dict[SC2Mission, str]] = { @@ -683,7 +683,6 @@ campaign_alt_final_mission_locations: Dict[SC2Campaign, Dict[SC2Mission, str]] = SC2Mission.THE_ESSENCE_OF_ETERNITY: "The Essence of Eternity: Victory", }, SC2Campaign.NCO: { - SC2Mission.END_GAME: "End Game: Victory", SC2Mission.FLASHPOINT: "Flashpoint: Victory", SC2Mission.DARK_SKIES: "Dark Skies: Victory", SC2Mission.NIGHT_TERRORS: "Night Terrors: Victory", @@ -709,10 +708,10 @@ def get_goal_location(mission: SC2Mission) -> Union[str, None]: return primary_campaign_goal.location campaign_alt_goals = campaign_alt_final_mission_locations[campaign] - if campaign_alt_goals is not None: + if campaign_alt_goals is not None and mission in campaign_alt_goals: return campaign_alt_goals.get(mission) - return None + return mission.mission_name + ": Victory" def get_campaign_potential_goal_missions(campaign: SC2Campaign) -> List[SC2Mission]: diff --git a/worlds/sc2/PoolFilter.py b/worlds/sc2/PoolFilter.py index e94dc4e2..f5f6faa9 100644 --- a/worlds/sc2/PoolFilter.py +++ b/worlds/sc2/PoolFilter.py @@ -1,4 +1,4 @@ -from typing import Callable, Dict, List, Set, Union, Tuple +from typing import Callable, Dict, List, Set, Union, Tuple, Optional from BaseClasses import Item, Location from .Items import get_full_item_list, spider_mine_sources, second_pass_placeable_items, progressive_if_nco, \ progressive_if_ext, spear_of_adun_calldowns, spear_of_adun_castable_passives, nova_equipment @@ -69,21 +69,39 @@ def filter_missions(world: World) -> Dict[MissionPools, List[SC2Mission]]: return mission_pools # Finding the goal map - goal_priorities = {campaign: get_campaign_goal_priority(campaign, excluded_missions) for campaign in enabled_campaigns} - goal_level = max(goal_priorities.values()) - candidate_campaigns: List[SC2Campaign] = [campaign for campaign, goal_priority in goal_priorities.items() if goal_priority == goal_level] - candidate_campaigns.sort(key=lambda it: it.id) - goal_campaign = world.random.choice(candidate_campaigns) - primary_goal = campaign_final_mission_locations[goal_campaign] - if primary_goal is None or primary_goal.mission 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 not in excluded_missions] - if len(candidate_missions) == 0: - raise Exception("There are no valid goal missions. Please exclude fewer missions.") - goal_mission = world.random.choice(candidate_missions) + goal_mission: Optional[SC2Mission] = None + if mission_order_type in campaign_depending_orders: + # Prefer long campaigns over shorter ones and harder missions over easier ones + goal_priorities = {campaign: get_campaign_goal_priority(campaign, excluded_missions) for campaign in enabled_campaigns} + goal_level = max(goal_priorities.values()) + candidate_campaigns: List[SC2Campaign] = [campaign for campaign, goal_priority in goal_priorities.items() if goal_priority == goal_level] + candidate_campaigns.sort(key=lambda it: it.id) + + goal_campaign = world.random.choice(candidate_campaigns) + primary_goal = campaign_final_mission_locations[goal_campaign] + if primary_goal is None or primary_goal.mission 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 not in excluded_missions] + if len(candidate_missions) == 0: + raise Exception("There are no valid goal missions. Please exclude fewer missions.") + goal_mission = world.random.choice(candidate_missions) + else: + goal_mission = primary_goal.mission else: - goal_mission = primary_goal.mission + # Find one of the missions with the hardest difficulty + available_missions: List[SC2Mission] = \ + [mission for mission in SC2Mission + if (mission not in excluded_missions and mission.campaign in enabled_campaigns)] + available_missions.sort(key=lambda it: it.id) + # Loop over pools, from hardest to easiest + for mission_pool in range(MissionPools.VERY_HARD, MissionPools.STARTER - 1, -1): + pool_missions: List[SC2Mission] = [mission for mission in available_missions if mission.pool == mission_pool] + if pool_missions: + goal_mission = world.random.choice(pool_missions) + break + if goal_mission is None: + raise Exception("There are no valid goal missions. Please exclude fewer missions.") # Excluding missions for difficulty, mission_pool in mission_pools.items():