From b2aa251c4755870006de20ddba655c0a140b0838 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 12 Sep 2022 01:51:25 +0200 Subject: [PATCH] SC2: fix bitflag overflow when multiple instances of an Item are acquired (#1008) --- Starcraft2Client.py | 59 ++++++++++++++---------------------------- worlds/sc2wol/Items.py | 14 ++++++++++ 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/Starcraft2Client.py b/Starcraft2Client.py index f81d4ec3..a9ed9c04 100644 --- a/Starcraft2Client.py +++ b/Starcraft2Client.py @@ -19,10 +19,11 @@ from sc2.data import Race from sc2.main import run_game from sc2.player import Bot +import NetUtils from MultiServer import mark_raw from Utils import init_logging, is_windows from worlds.sc2wol import SC2WoLWorld -from worlds.sc2wol.Items import lookup_id_to_name, item_table +from worlds.sc2wol.Items import lookup_id_to_name, item_table, ItemData, type_flaggroups from worlds.sc2wol.Locations import SC2WOL_LOC_ID_OFFSET from worlds.sc2wol.MissionTables import lookup_id_to_mission from worlds.sc2wol.Regions import MissionInfo @@ -429,47 +430,27 @@ wol_default_categories = [ ] -def calculate_items(items): - unit_unlocks = 0 - armory1_unlocks = 0 - armory2_unlocks = 0 - upgrade_unlocks = 0 - building_unlocks = 0 - merc_unlocks = 0 - lab_unlocks = 0 - protoss_unlock = 0 - minerals = 0 - vespene = 0 - supply = 0 +def calculate_items(items: typing.List[NetUtils.NetworkItem]) -> typing.List[int]: + network_item: NetUtils.NetworkItem + accumulators: typing.List[int] = [0 for _ in type_flaggroups] - for item in items: - data = lookup_id_to_name[item.item] + for network_item in items: + name: str = lookup_id_to_name[network_item.item] + item_data: ItemData = item_table[name] - if item_table[data].type == "Unit": - unit_unlocks += (1 << item_table[data].number) - elif item_table[data].type == "Upgrade": - upgrade_unlocks += (1 << item_table[data].number) - elif item_table[data].type == "Armory 1": - armory1_unlocks += (1 << item_table[data].number) - elif item_table[data].type == "Armory 2": - armory2_unlocks += (1 << item_table[data].number) - elif item_table[data].type == "Building": - building_unlocks += (1 << item_table[data].number) - elif item_table[data].type == "Mercenary": - merc_unlocks += (1 << item_table[data].number) - elif item_table[data].type == "Laboratory": - lab_unlocks += (1 << item_table[data].number) - elif item_table[data].type == "Protoss": - protoss_unlock += (1 << item_table[data].number) - elif item_table[data].type == "Minerals": - minerals += item_table[data].number - elif item_table[data].type == "Vespene": - vespene += item_table[data].number - elif item_table[data].type == "Supply": - supply += item_table[data].number + # exists exactly once + if item_data.quantity == 1: + accumulators[type_flaggroups[item_data.type]] |= 1 << item_data.number - return [unit_unlocks, upgrade_unlocks, armory1_unlocks, armory2_unlocks, building_unlocks, merc_unlocks, - lab_unlocks, protoss_unlock, minerals, vespene, supply] + # exists multiple times + elif item_data.type == "Upgrade": + accumulators[type_flaggroups[item_data.type]] += 1 << item_data.number + + # sum + else: + accumulators[type_flaggroups[item_data.type]] += item_data.number + + return accumulators def calc_difficulty(difficulty): diff --git a/worlds/sc2wol/Items.py b/worlds/sc2wol/Items.py index 8da40de5..6bb74076 100644 --- a/worlds/sc2wol/Items.py +++ b/worlds/sc2wol/Items.py @@ -163,3 +163,17 @@ filler_items: typing.Tuple[str, ...] = ( lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in get_full_item_list().items() if data.code} +# Map type to expected int +type_flaggroups: typing.Dict[str, int] = { + "Unit": 0, + "Upgrade": 1, + "Armory 1": 2, + "Armory 2": 3, + "Building": 4, + "Mercenary": 5, + "Laboratory": 6, + "Protoss": 7, + "Minerals": 8, + "Vespene": 9, + "Supply": 10, +}