import json import sys import logging logging.basicConfig(encoding='utf-8', level=logging.INFO) # drive_c/Program Files/Tempo Launcher - Beta/The Bazaar game_64/bazaarwinprodlatest/TheBazaar_Data/StreamingAssets/StaticData/.derived/v2_Cards.json input_file = sys.argv[1] input_item_name = None if len(sys.argv) > 2: input_item_name = sys.argv[2] with open(input_file, 'r', encoding='utf-8') as f: loaded = json.load(f) item_infobox_props = { 'title': '{{PAGENAME}}', 'image': '{{PAGENAME}}.png', 'cost': '?', 'type': '?', 'size': '?', 'starting_tier': '?', 'effects': '?', 'cooldown': '?', 'ammo': '?', 'collection': '?', } def build_infobox(template_name, props): s = '{{' + template_name + '\n' for p in props: s += '|' + p + '=' + props[p] + '\n' s += '}}' return s def collect_tier_values(thing, prop_name): tiers = thing.get('Tiers', {}) values = [] for tier_name in tiers: tier = tiers.get(tier_name, {}) value = tier.get('Attributes', {}).get(prop_name) if value is not None: values.append(str(value)) return values def tooltips_to_effects(thing, tooltips): # { # "Content": { # "Key": "ac8610f98cff92e2b0afcd73ec532c4f", # "Text": "Deal {ability.0} damage." # }, # "TooltipType": "Active" # }, effects = [] abilities = thing.get('Abilities') lookups = {} if abilities: for idx in abilities: ability = abilities[idx] # TActionPlayerDamage # TActionCardSlow action_type = ability.get('Action', {}).get('$type') # ex. {ability.0} default_ability_key = '{ability.' + str(idx) + '}' if action_type == 'TActionPlayerDamage': lookups[default_ability_key] = '/'.join(collect_tier_values(thing, 'DamageAmount')) if action_type == 'TActionPlayerPoisonApply': # Examples: # - Catfish lookups[default_ability_key] = '/'.join( collect_tier_values(thing, 'PoisonApplyAmount') ) if action_type == 'TActionPlayerBurnApply': # Examples: # - Trebuchet lookups[default_ability_key] = '/'.join( collect_tier_values(thing, 'BurnApplyAmount') ) if action_type == 'TActionPlayerHeal': # Examples: # - Seaweed lookups[default_ability_key] = '/'.join(collect_tier_values(thing, 'HealAmount')) if action_type == 'TActionPlayerShieldApply': # Examples: # - Force Field lookups[default_ability_key] = '/'.join( collect_tier_values(thing, 'ShieldApplyAmount') ) if action_type == 'TActionCardReload': # Examples: # - Panic lookups[default_ability_key] = '/'.join(collect_tier_values(thing, 'ReloadAmount')) lookups['{ability.' + str(idx) + '.targets}'] = '/'.join( collect_tier_values(thing, 'ReloadTargets') ) if action_type == 'TActionCardFreeze': # Examples: # - Quick Freeze values = collect_tier_values(thing, 'FreezeAmount') lookups[default_ability_key] = '/'.join( '{:.1f}'.format(int(v) / 1000) for v in values ) lookups['{ability.' + str(idx) + '.targets}'] = '/'.join( collect_tier_values(thing, 'FreezeTargets') ) if action_type == 'TActionCardHaste': values = collect_tier_values(thing, 'HasteAmount') lookups[default_ability_key] = '/'.join( '{:.1f}'.format(int(v) / 1000) for v in values ) lookups['{ability.' + str(idx) + '.targets}'] = '/'.join( collect_tier_values(thing, 'HasteTargets') ) if action_type == 'TActionCardHaste': values = collect_tier_values(thing, 'HasteAmount') lookups[default_ability_key] = '/'.join( '{:.1f}'.format(int(v) / 1000) for v in values ) lookups['{ability.' + str(idx) + '.targets}'] = '/'.join( collect_tier_values(thing, 'HasteTargets') ) if action_type == 'TActionCardCharge': # Examples: # - Blunderbuss values = collect_tier_values(thing, 'ChargeAmount') lookups[default_ability_key] = '/'.join( '{:.1f}'.format(int(v) / 1000) for v in values ) if action_type == 'TActionCardSlow': # Examples: # - Bolas values = collect_tier_values(thing, 'SlowAmount') lookups[default_ability_key] = '/'.join( '{:.1f}'.format(int(v) / 1000) for v in values ) lookups['{ability.' + str(idx) + '.targets}'] = '/'.join( collect_tier_values(thing, 'SlowTargets') ) if action_type == 'TActionGameSpawnCards': # "Action": { # "$type": "TActionGameSpawnCards", # "TargetPlayer": { # "$type": "TTargetPlayerAbsolute", # "TargetMode": "Player", # "Conditions": null # }, # "SpawnContext": { # "$type": "TSpawnContextQuery", # "Groups": [ # { # "$type": "TSpawnGroup", # "Filters": [ # { # "$type": "TSpawnFilterIdList", # "Ids": [ # "1a3d4cde-333c-4936-b147-263d73f6d200" # ] # } # ], # "SelectionMethod": "Random", # "Limit": null, # "Prerequisites": null, # "RandomWeight": 0, # "Behaviors": null # } # ], # "SelectionMethod": "Sequential", # "Limit": { # "$type": "TFixedValue", # --> "Value": 3.0 # }, # "Behaviors": [ # { # "$type": "TSpawnBehaviorAllowDuplicates", # "AllowDuplicates": true # } # ] # Examples: # - Pinata action_spawn_ctx = ability.get('Action', {}).get('SpawnContext', {}) spawn_limit_type = action_spawn_ctx.get('Limit', {}).get('$type') if spawn_limit_type == 'TFixedValue': value = action_spawn_ctx.get('Limit', {}).get('Value') lookups[default_ability_key] = str(int(value)) if action_type in ['TActionCardModifyAttribute', 'TActionPlayerModifyAttribute']: # This is a more dynamic thing where the ability value comes from a dynamic # field name # # "Text": "When you sell this, give your leftmost weapon +{ability.1} damage." # # "Action": { # "$type": "TActionCardModifyAttribute", # "Value": { # "$type": "TReferenceValueCardAttribute", # "Target": { # "$type": "TTargetCardSelf", # "Conditions": null # }, # --> "AttributeType": "Custom_0", # "DefaultValue": 0.0, # "Modifier": null # }, # "Tiers": { # "Bronze": { # "AbilityIds": [ # "0", # "1" # ], # "Attributes": { # "CooldownMax": 5000, # "BuyPrice": 2, # "SellPrice": 1, # "Multicast": 1, # "DamageAmount": 5, # --> "Custom_0": 5 # Examples: # - Magnifying Glass # - Catfish # - Bluenanas attr_type_name = ability.get('Action', {}).get('Value', {}).get('AttributeType') lookups[default_ability_key] = '/'.join(collect_tier_values(thing, attr_type_name)) # TODO should take the tooltip ids from Tiers for tip in tooltips: # TODO active/passive ordering? content = tip.get('Content', {}).get('Text') if not content: continue hydrated = content for lookup, replacement in lookups.items(): hydrated = hydrated.replace(lookup, replacement) effects.append(hydrated) return effects for uid in loaded: thing = loaded[uid] internal_name = thing['InternalName'] # only one item if input_item_name and internal_name != input_item_name: continue box = dict(item_infobox_props) box['title'] = internal_name # collection if 'Heroes' in thing: collection = ','.join(thing['Heroes']) box['collection'] = collection # cost if 'Tiers' in thing: cost = '?' prices = [] tiers = thing['Tiers'] for tier_name in tiers: attrs = tiers[tier_name].get('Attributes') if not attrs: continue price = attrs.get('BuyPrice') if price is not None: prices.append(str(price)) box['cost'] = '/'.join(prices) # type if 'Tags' in thing: tags = thing['Tags'] box['type'] = ', '.join(tags) # size if 'Size' in thing: box['size'] = thing['Size'] # cooldown if 'Tiers' in thing: cds = [] for tier_name in tiers: attrs = tiers[tier_name].get('Attributes') cd_max = attrs.get('CooldownMax') if cd_max is not None: cds.append('{:.1f}'.format(cd_max / 1000)) box['cooldown'] = '/'.join(cds) # starting_tier box['starting_tier'] = thing.get('StartingTier', '?') # ammo if 'Tiers' in thing: for tier_name in tiers: attrs = tiers[tier_name].get('Attributes') ammo_max = attrs.get('AmmoMax') if ammo_max is not None: box['ammo'] = str(ammo_max) break # effects if 'Localization' in thing: local = thing['Localization'] tooltips = local.get('Tooltips') if tooltips: box['effects'] = '
'.join(tooltips_to_effects(thing, tooltips)) # effects if 'Localization' in thing: local = thing['Localization'] tooltips = local.get('Tooltips') if tooltips: box['effects'] = '
'.join(tooltips_to_effects(thing, tooltips)) # logging.info(json.dumps(thing, indent=4)) logging.info(json.dumps(thing.get('Tiers'), indent=4)) logging.info(json.dumps(thing.get('Abilities'), indent=4)) print(build_infobox('Item', box))