Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Item processing stability #333

Merged
merged 13 commits into from
Oct 27, 2024
166 changes: 71 additions & 95 deletions worlds/sc2/__init__.py

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions worlds/sc2/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
# CommonClient import first to trigger ModuleUpdater
from CommonClient import CommonContext, server_loop, ClientCommandProcessor, gui_enabled, get_base_parser
from Utils import init_logging, is_windows, async_start
from . import item_names
from .item_groups import item_name_groups, unlisted_item_name_groups
from worlds.sc2.item import item_names
from worlds.sc2.item.item_groups import item_name_groups, unlisted_item_name_groups
from . import options
from .options import (
MissionOrder, KerriganPrimalStatus, kerrigan_unit_available, KerriganPresence, EnableMorphling,
Expand Down Expand Up @@ -52,7 +52,7 @@
from worlds._sc2common.bot.data import Race
from worlds._sc2common.bot.main import run_game
from worlds._sc2common.bot.player import Bot
from .items import (
from worlds.sc2.item.item_tables import (
lookup_id_to_name, get_full_item_list, ItemData,
race_to_item_type, ZergItemType, ProtossItemType, upgrade_bundles,
WEAPON_ARMOR_UPGRADE_MAX_LEVEL,
Expand Down Expand Up @@ -931,8 +931,8 @@ async def main():
CompatItemHolder(item_name)
for item_name, item_data in get_full_item_list().items()
if item_data.type in (ProtossItemType.War_Council, ProtossItemType.War_Council_2)
and item_name != item_names.DESTROYER_REFORGED_BLOODSHARD_CORE
and item_name != item_names.OBSERVER_INDUCE_SCOPOPHOBIA
and item_name != item_names.DESTROYER_REFORGED_BLOODSHARD_CORE
and item_name != item_names.OBSERVER_INDUCE_SCOPOPHOBIA
}


Expand Down
5 changes: 2 additions & 3 deletions worlds/sc2/client_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from kvui import GameManager, HoverBehavior, ServerToolTip, KivyJSONtoTextParser
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.tabbedpanel import TabbedPanelItem
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
from kivy.uix.label import Label
Expand All @@ -16,8 +15,8 @@
from kivy.uix.scrollview import ScrollView
from kivy.properties import StringProperty, BooleanProperty

from worlds.sc2.client import SC2Context, calc_unfinished_nodes, force_settings_save_on_close
from worlds.sc2.item_descriptions import item_descriptions
from worlds.sc2.client import SC2Context, calc_unfinished_nodes
from worlds.sc2.item.item_descriptions import item_descriptions
from worlds.sc2.mission_tables import lookup_id_to_mission, campaign_race_exceptions, \
SC2Mission, SC2Race
from worlds.sc2.locations import LocationType, lookup_location_id_to_type, lookup_location_id_to_flags
Expand Down
42 changes: 42 additions & 0 deletions worlds/sc2/item/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import enum
from dataclasses import dataclass
from typing import Optional

from BaseClasses import Item, ItemClassification
from worlds.sc2.item.item_tables import ItemData


class ItemFilterFlags(enum.IntFlag):
Available = 0
Locked = enum.auto()
StartInventory = enum.auto()
NonLocal = enum.auto()
Removed = enum.auto()
Plando = enum.auto()
Excluded = enum.auto()
AllowedOrphan = enum.auto()
"""Used to flag items that shouldn't be filtered out with their parents"""
ForceProgression = enum.auto()
"""Used to flag items that aren't classified as progression by default"""
Necessary = enum.auto()
"""Used to flag items that are never allowed to be culled.
This differs from `Locked` in that locked items may still be culled if there's space issues or in some circumstances when a parent item is culled."""

Unremovable = Locked|StartInventory|Plando|Necessary


@dataclass
class FilterItem:
name: str
data: ItemData
index: int = 0
flags: ItemFilterFlags = ItemFilterFlags.Available


class StarcraftItem(Item):
game: str = "Starcraft 2"
filter_flags: ItemFilterFlags = ItemFilterFlags.Available

def __init__(self, name: str, classification: ItemClassification, code: Optional[int], player: int, filter_flags: ItemFilterFlags = ItemFilterFlags.Available):
Item.__init__(self, name, classification, code, player)
Ziktofel marked this conversation as resolved.
Show resolved Hide resolved
self.filter_flags = filter_flags
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
import inspect

from . import item_names, items
from worlds.sc2.item import item_tables, item_names

WEAPON_ARMOR_UPGRADE_NOTE = inspect.cleandoc("""
Must be researched during the mission if the mission type isn't set to auto-unlock generic upgrades.
Expand Down Expand Up @@ -751,7 +751,8 @@ def _ability_desc(unit_name_plural: str, ability_name: str, ability_description:
item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL: "Infested Liberators instantly transform into a cloud of microscopic organisms while attacking, reducing the damage they take by 85%.",
item_names.INFESTED_LIBERATOR_VIRAL_CONTAMINATION: "Increases the damage Infested Liberators deal to their primary target by 100%.",
item_names.FRIGHTFUL_FLESHWELDER_INFESTED_SIEGE_TANK: _get_resource_efficiency_desc(item_names.INFESTED_SIEGE_TANK),
item_names.FRIGHTFUL_FLESHWELDER_INFESTED_DIAMONDBACK: _get_resource_efficiency_desc(item_names.INFESTED_DIAMONDBACK),
item_names.FRIGHTFUL_FLESHWELDER_INFESTED_DIAMONDBACK: _get_resource_efficiency_desc(
item_names.INFESTED_DIAMONDBACK),
item_names.FRIGHTFUL_FLESHWELDER_INFESTED_BANSHEE: _get_resource_efficiency_desc(item_names.INFESTED_BANSHEE),
item_names.FRIGHTFUL_FLESHWELDER_INFESTED_LIBERATOR: _get_resource_efficiency_desc(item_names.INFESTED_LIBERATOR),
item_names.ZERG_EXCAVATING_CLAWS: "Increases movement speed of uprooted Zerg structures, especially off creep. Also increases root speed.",
Expand Down Expand Up @@ -969,8 +970,10 @@ def _ability_desc(unit_name_plural: str, ability_name: str, ability_description:
item_names.ZEALOT_SENTINEL_CENTURION_LEG_ENHANCEMENTS: "Zealots, Sentinels, and Centurions gain increased movement speed.",
item_names.ZEALOT_SENTINEL_CENTURION_SHIELD_CAPACITY: "Zealots, Sentinels, and Centurions gain +30 maximum shields.",
item_names.ZEALOT_WHIRLWIND: "Zealot War Council upgrade. Gives Zealots the whirlwind ability, dealing damage in an area over 3 seconds.",
item_names.CENTURION_RESOURCE_EFFICIENCY: "Centurion War Council upgrade. " + _get_resource_efficiency_desc(item_names.CENTURION),
item_names.SENTINEL_RESOURCE_EFFICIENCY: "Sentinel War Council upgrade. " + _get_resource_efficiency_desc(item_names.SENTINEL),
item_names.CENTURION_RESOURCE_EFFICIENCY: "Centurion War Council upgrade. " + _get_resource_efficiency_desc(
item_names.CENTURION),
item_names.SENTINEL_RESOURCE_EFFICIENCY: "Sentinel War Council upgrade. " + _get_resource_efficiency_desc(
item_names.SENTINEL),
item_names.STALKER_PHASE_REACTOR: "Stalker War Council upgrade. Stalkers restore 80 shields over 5 seconds after they Blink.",
item_names.DRAGOON_PHALANX_SUIT: "Dragoon War Council upgrade. Dragoons gain +1 range, move slightly faster, and can form tighter formations.",
item_names.INSTIGATOR_RESOURCE_EFFICIENCY: f"Instigator War Council upgrade. {_get_resource_efficiency_desc(item_names.INSTIGATOR)}",
Expand Down Expand Up @@ -1051,6 +1054,6 @@ def _ability_desc(unit_name_plural: str, ability_name: str, ability_description:
# Key descriptions
key_descriptions = {
key: GENERIC_KEY_DESC
for key in items.key_item_table.keys()
for key in item_tables.key_item_table.keys()
}
item_descriptions.update(key_descriptions)
88 changes: 45 additions & 43 deletions worlds/sc2/item_groups.py → worlds/sc2/item/item_groups.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import typing
from . import item_names, items
from .mission_tables import campaign_mission_table, SC2Campaign, SC2Mission, SC2Race
from worlds.sc2.item import item_tables, item_names
from worlds.sc2.mission_tables import campaign_mission_table, SC2Campaign, SC2Mission, SC2Race

"""
Item name groups, given to Archipelago and used in YAMLs and /received filtering.
Expand Down Expand Up @@ -29,20 +29,20 @@
# These item name groups should not show up in documentation
unlisted_item_name_groups = {
"Missions", "WoL Missions",
items.TerranItemType.Progressive.display_name,
items.TerranItemType.Nova_Gear.display_name,
items.TerranItemType.Mercenary.display_name,
items.ZergItemType.Ability.display_name,
items.ZergItemType.Morph.display_name,
items.ZergItemType.Strain.display_name,
item_tables.TerranItemType.Progressive.display_name,
item_tables.TerranItemType.Nova_Gear.display_name,
item_tables.TerranItemType.Mercenary.display_name,
item_tables.ZergItemType.Ability.display_name,
item_tables.ZergItemType.Morph.display_name,
item_tables.ZergItemType.Strain.display_name,
}

# Some item names only differ in bracketed parts
# These items are ambiguous for short-hand name groups
bracketless_duplicates: typing.Set[str]
# This is a list of names in ItemNames with bracketed parts removed, for internal use
_shortened_names = [(name[:name.find(' (')] if '(' in name else name)
for name in [item_names.__dict__[name] for name in item_names.__dir__() if not name.startswith('_')]]
for name in [item_names.__dict__[name] for name in item_names.__dir__() if not name.startswith('_')]]
# Remove the first instance of every short-name from the full item list
bracketless_duplicates = set(_shortened_names)
for name in bracketless_duplicates:
Expand All @@ -52,7 +52,7 @@
del _shortened_names

# All items get sorted into their data type
for item, data in items.get_full_item_list().items():
for item, data in item_tables.get_full_item_list().items():
# Items get assigned to their flaggroup's display type
item_name_groups.setdefault(data.type.display_name, []).append(item)
# Items with a bracket get a short-hand name group for ease of use in YAMLs
Expand Down Expand Up @@ -178,16 +178,17 @@ def get_all_group_names(cls) -> typing.Set[str]:

# Terran
item_name_groups[ItemGroupNames.TERRAN_ITEMS] = terran_items = [
item_name for item_name, item_data in items.item_table.items()
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.race == SC2Race.TERRAN
]
item_name_groups[ItemGroupNames.TERRAN_UNITS] = terran_units = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type in (items.TerranItemType.Unit, items.TerranItemType.Unit_2, items.TerranItemType.Mercenary)
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type in (
item_tables.TerranItemType.Unit, item_tables.TerranItemType.Unit_2, item_tables.TerranItemType.Mercenary)
]
item_name_groups[ItemGroupNames.TERRAN_GENERIC_UPGRADES] = terran_generic_upgrades = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type == items.TerranItemType.Upgrade
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type == item_tables.TerranItemType.Upgrade
]
barracks_wa_group = [
item_names.MARINE, item_names.FIREBAT, item_names.MARAUDER,
Expand Down Expand Up @@ -220,12 +221,12 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_names.EMPERORS_GUARDIAN, item_names.NIGHT_HAWK, item_names.NIGHT_WOLF,
]
item_name_groups[ItemGroupNames.TERRAN_BUILDINGS] = terran_buildings = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type == items.TerranItemType.Building
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type == item_tables.TerranItemType.Building
]
item_name_groups[ItemGroupNames.TERRAN_MERCENARIES] = terran_mercenaries = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type == items.TerranItemType.Mercenary
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type == item_tables.TerranItemType.Mercenary
]
item_name_groups[ItemGroupNames.NCO_UNITS] = nco_units = [
item_names.MARINE, item_names.MARAUDER, item_names.REAPER,
Expand All @@ -237,8 +238,8 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_names.BUNKER, item_names.MISSILE_TURRET, item_names.PLANETARY_FORTRESS,
]
item_name_groups[ItemGroupNames.NOVA_EQUIPMENT] = nova_equipment = [
*[item_name for item_name, item_data in items.item_table.items()
if item_data.type == items.TerranItemType.Nova_Gear],
*[item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type == item_tables.TerranItemType.Nova_Gear],
item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE,
]
item_name_groups[ItemGroupNames.WOL_UNITS] = wol_units = [
Expand Down Expand Up @@ -401,8 +402,8 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_name_groups[ItemGroupNames.NCO_MAX_PROGRESSIVE_ITEMS] = nco_unit_technology + nova_equipment + terran_generic_upgrades
item_name_groups[ItemGroupNames.NCO_MIN_PROGRESSIVE_ITEMS] = nco_units + nco_baseline_upgrades
item_name_groups[ItemGroupNames.TERRAN_PROGRESSIVE_UPGRADES] = terran_progressive_items = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type in (items.TerranItemType.Progressive, items.TerranItemType.Progressive_2)
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type in (item_tables.TerranItemType.Progressive, item_tables.TerranItemType.Progressive_2)
]
item_name_groups[ItemGroupNames.WOL_ITEMS] = vanilla_wol_items = (
wol_units
Expand All @@ -414,7 +415,7 @@ def get_all_group_names(cls) -> typing.Set[str]:

# Zerg
item_name_groups[ItemGroupNames.ZERG_ITEMS] = zerg_items = [
item_name for item_name, item_data in items.item_table.items()
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.race == SC2Race.ZERG
]
item_name_groups[ItemGroupNames.ZERG_BUILDINGS] = zerg_buildings = [
Expand All @@ -424,8 +425,9 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_names.NYDUS_WORM,
item_names.OMEGA_WORM]
item_name_groups[ItemGroupNames.ZERG_UNITS] = zerg_units = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type in (items.ZergItemType.Unit, items.ZergItemType.Mercenary, items.ZergItemType.Morph)
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type in (
item_tables.ZergItemType.Unit, item_tables.ZergItemType.Mercenary, item_tables.ZergItemType.Morph)
Ziktofel marked this conversation as resolved.
Show resolved Hide resolved
and item_name not in zerg_buildings
]
# For W/A upgrades
Expand Down Expand Up @@ -453,8 +455,8 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT, item_names.INFESTED_BANSHEE, item_names.INFESTED_LIBERATOR,
]
item_name_groups[ItemGroupNames.ZERG_GENERIC_UPGRADES] = zerg_generic_upgrades = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type == items.ZergItemType.Upgrade
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type == item_tables.ZergItemType.Upgrade
]
item_name_groups[ItemGroupNames.HOTS_UNITS] = hots_units = [
item_names.ZERGLING, item_names.SWARM_QUEEN, item_names.ROACH, item_names.HYDRALISK,
Expand All @@ -478,13 +480,13 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT,
]
item_name_groups[ItemGroupNames.ZERG_MORPHS] = zerg_morphs = [
item_name for item_name, item_data in items.item_table.items() if item_data.type == items.ZergItemType.Morph
item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ZergItemType.Morph
]
item_name_groups[ItemGroupNames.ZERG_MERCS] = zerg_mercs = [
item_name for item_name, item_data in items.item_table.items() if item_data.type == items.ZergItemType.Mercenary
item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ZergItemType.Mercenary
]
item_name_groups[ItemGroupNames.KERRIGAN_ABILITIES] = kerrigan_abilities = [
item_name for item_name, item_data in items.item_table.items() if item_data.type == items.ZergItemType.Ability
item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ZergItemType.Ability
]
item_name_groups[ItemGroupNames.KERRIGAN_PASSIVES] = kerrigan_passives = [
item_names.KERRIGAN_HEROIC_FORTITUDE, item_names.KERRIGAN_CHAIN_REACTION,
Expand Down Expand Up @@ -528,7 +530,7 @@ def get_all_group_names(cls) -> typing.Set[str]:

# Zerg Upgrades
item_name_groups[ItemGroupNames.HOTS_STRAINS] = hots_strains = [
item_name for item_name, item_data in items.item_table.items() if item_data.type == items.ZergItemType.Strain
item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ZergItemType.Strain
]
item_name_groups[ItemGroupNames.HOTS_MUTATIONS] = hots_mutations = [
item_names.ZERGLING_HARDENED_CARAPACE, item_names.ZERGLING_ADRENAL_OVERLOAD, item_names.ZERGLING_METABOLIC_BOOST,
Expand Down Expand Up @@ -576,12 +578,12 @@ def get_all_group_names(cls) -> typing.Set[str]:

# Protoss
item_name_groups[ItemGroupNames.PROTOSS_ITEMS] = protoss_items = [
item_name for item_name, item_data in items.item_table.items()
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.race == SC2Race.PROTOSS
]
item_name_groups[ItemGroupNames.PROTOSS_UNITS] = protoss_units = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type in (items.ProtossItemType.Unit, items.ProtossItemType.Unit_2)
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type in (item_tables.ProtossItemType.Unit, item_tables.ProtossItemType.Unit_2)
]
protoss_ground_wa = [
item_names.ZEALOT, item_names.CENTURION, item_names.SENTINEL, item_names.SUPPLICANT,
Expand All @@ -603,8 +605,8 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_names.ARBITER, item_names.ORACLE,
]
item_name_groups[ItemGroupNames.PROTOSS_GENERIC_UPGRADES] = protoss_generic_upgrades = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type == items.ProtossItemType.Upgrade
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type == item_tables.ProtossItemType.Upgrade
]
item_name_groups[ItemGroupNames.LOTV_UNITS] = lotv_units = [
item_names.ZEALOT, item_names.CENTURION, item_names.SENTINEL,
Expand Down Expand Up @@ -648,8 +650,8 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_names.ARBITER, item_names.ORACLE,
]
item_name_groups[ItemGroupNames.PROTOSS_BUILDINGS] = protoss_buildings = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type == items.ProtossItemType.Building
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type == item_tables.ProtossItemType.Building
]
item_name_groups[ItemGroupNames.AIUR_UNITS] = [
item_names.ZEALOT, item_names.DRAGOON, item_names.SENTRY, item_names.AVENGER, item_names.HIGH_TEMPLAR,
Expand All @@ -672,12 +674,12 @@ def get_all_group_names(cls) -> typing.Set[str]:
item_names.MIRAGE, item_names.DAWNBRINGER, item_names.TRIREME, item_names.TEMPEST,
]
item_name_groups[ItemGroupNames.SOA_ITEMS] = soa_items = [
*[item_name for item_name, item_data in items.item_table.items() if item_data.type == items.ProtossItemType.Spear_Of_Adun],
*[item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ProtossItemType.Spear_Of_Adun],
item_names.SOA_PROGRESSIVE_PROXY_PYLON,
]
lotv_soa_items = [item_name for item_name in soa_items if item_name != item_names.SOA_PYLON_OVERCHARGE]
item_name_groups[ItemGroupNames.PROTOSS_GLOBAL_UPGRADES] = [
item_name for item_name, item_data in items.item_table.items() if item_data.type == items.ProtossItemType.Solarite_Core
item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ProtossItemType.Solarite_Core
]
item_name_groups[ItemGroupNames.LOTV_GLOBAL_UPGRADES] = lotv_global_upgrades = [
item_names.NEXUS_OVERCHARGE,
Expand All @@ -700,8 +702,8 @@ def get_all_group_names(cls) -> typing.Set[str]:
)

item_name_groups[ItemGroupNames.WAR_COUNCIL] = [
item_name for item_name, item_data in items.item_table.items()
if item_data.type in (items.ProtossItemType.War_Council, items.ProtossItemType.War_Council_2)
item_name for item_name, item_data in item_tables.item_table.items()
if item_data.type in (item_tables.ProtossItemType.War_Council, item_tables.ProtossItemType.War_Council_2)
]

item_name_groups[ItemGroupNames.OVERPOWERED_ITEMS] = [
Expand Down
File renamed without changes.
Loading
Loading