| 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'] = '<br>'.join(tooltips_to_effects(thing, tooltips))
|
|
|
| # effects
|
| if 'Localization' in thing:
|
| local = thing['Localization']
|
| tooltips = local.get('Tooltips')
|
| if tooltips:
|
| box['effects'] = '<br>'.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))
|