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))