예제 #1
0
    nipl = {}
    for (label, pool) in pools:
        dipl[pool] = []
        pt_cipl[pool] = []
        level_ipl[pool] = []
        dl_ia[pool] = []
        nipl[pool] = []

    # Now loop through and find out what we need to find out
    for (label, pool) in pools:
        full_cat = '{}_{}'.format(pool, weight)
        if full_cat in categories:
            (orig_pools, to_change) = categories[full_cat]
            for object_name in to_change:

                node = data.get_node_by_full_object(object_name)
                parsed = node.get_structure()

                found = False

                if 'DefaultItemPoolList' in parsed:
                    for (dipl_idx, pool_list) in enumerate(parsed['DefaultItemPoolList']):
                        if 'ItemPool' in pool_list:
                            for check_pool in orig_pools:
                                if check_pool in pool_list['ItemPool']:
                                    dipl[pool].append((dipl_idx, object_name))
                                    dipl_count += 1
                                    found = True
                                    break

                if 'NewItemPoolList' in parsed:
예제 #2
0
from ftexplorer.data import Data
from modprocessor import ModProcessor

data = Data('BL2')

lines = []
lines.append('BL2')
lines.append('#<omg>')
lines.append('')

# Loop through levels
for (label, level) in data.get_levels():
    lines.append('#<{}>'.format(label))
    lines.append('')
    for package in data.get_level_package_names(level):
        main_node = data.get_node_by_full_object(package)
        for soundvol in main_node.get_children_with_name('wwisesoundvolume'):
            soundvolstruct = soundvol.get_structure()
            if 'EnvironmentalEffects' in soundvolstruct and soundvolstruct[
                    'EnvironmentalEffects'] != '':
                for (idx, effect) in enumerate(
                        soundvolstruct['EnvironmentalEffects']):
                    lines.append(
                        'level {} set {}.{} EnvironmentalEffects[{}].Effect None'
                        .format(level, package, soundvol.name, idx))
                    lines.append('')
    lines.append('#</{}>'.format(label))
    lines.append('')

lines.append('')
lines.append('#</omg>')
예제 #3
0
 if processing:
     if start_stop_str in line or extra_stop_str in line:
         processing = False
     else:
         line = line.strip()
         if line == '':
             continue
         match = re.search('<value>",(.*?),BalancedItems\[(\d+)\]\.(.*),,(.*?)"', line)
         if match:
             main_pool = match.group(1)
             bal_idx = int(match.group(2))
             var_changed = match.group(3)
             changed_to = match.group(4)
             if var_changed == 'ItmPoolDefinition' and changed_to == 'None':
                 if main_pool not in pool_cache:
                     pool_cache[main_pool] = data.get_node_by_full_object(main_pool).get_structure()
                 (junk, destination, junk2) = pool_cache[main_pool]['BalancedItems'][bal_idx]['ItmPoolDefinition'].split("'", 2)
                 freed_pools.add(destination)
                 if destination not in pool_cache:
                     pool_cache[destination] = data.get_node_by_full_object(destination).get_structure()
                 if len(pool_cache[destination]['BalancedItems']) > 1:
                     raise Exception('Pool {} has {} items'.format(destination, len(pool_cache[destination]['BalancedItems'])))
                 (junk, ultimate, junk2) = pool_cache[destination]['BalancedItems'][0]['InvBalanceDefinition'].split("'", 2)
                 from_values['{}_{}'.format(main_pool, bal_idx)] = ultimate
             elif var_changed == 'InvBalanceDefinition' and 'InventoryBalanceDefinition' in changed_to:
                 (junk, new_inv, junk2) = changed_to.split("'", 2)
                 to_values['{}_{}'.format(main_pool, bal_idx)] = new_inv
             else:
                 raise Exception('Unknown line found: {}'.format(line))
 else:
     if start_stop_str in line:
예제 #4
0
    ('Axton', 'GD_Soldier_Streaming.Pawn_Soldier',
     'GD_Soldier.Character.CharClass_Soldier'),
    ('Gaige', 'GD_Tulip_Mechro_Streaming.Pawn_Mechromancer',
     'GD_Tulip_Mechromancer.Character.CharClass_Mechromancer'),
    ('Krieg', 'GD_Lilac_Psycho_Streaming.Pawn_LilacPlayerClass',
     'GD_Lilac_PlayerClass.Character.CharClass_LilacPlayerClass'),
    ('Maya', 'GD_Siren_Streaming.Pawn_Siren',
     'GD_Siren.Character.CharClass_Siren'),
    ('Salvador', 'GD_Mercenary_Streaming.Pawn_Mercenary',
     'GD_Mercenary.Character.CharClass_Mercenary'),
    ('Zero', 'GD_Assassin_Streaming.Pawn_Assassin',
     'GD_Assassin.Character.CharClass_Assassin'),
]:

    print('{}:'.format(name))
    struct_streaming = data.get_node_by_full_object(
        streaming_obj).get_structure()
    struct_player = data.get_node_by_full_object(player_obj).get_structure()
    print(' * Player GroundSpeed: {}'.format(struct_player['GroundSpeed']))
    print(' * Streaming GroundSpeed: {}'.format(
        struct_streaming['GroundSpeed']))
    print(' * Streaming GroundSpeedBaseValue: {}'.format(
        struct_streaming['GroundSpeedBaseValue']))
    print(' * Player AirSpeed: {}'.format(struct_player['AirSpeed']))
    print(' * Streaming AirSpeed: {}'.format(struct_streaming['AirSpeed']))
    print(' * Streaming AirSpeedBaseValue: {}'.format(
        struct_streaming['AirSpeedBaseValue']))
    print(' * Player JumpZ: {}'.format(struct_player['JumpZ']))
    print(' * Streaming JumpZ: {}'.format(struct_streaming['JumpZ']))
    print(' * Streaming JumpZBaseValue: {}'.format(
        struct_streaming['JumpZBaseValue']))
    print(' * Player CrouchedPct: {}'.format(struct_player['CrouchedPct']))
예제 #5
0
    'GD_Petunia_Weapons.AssaultRifles.AR_Bandit_3_CryBaby',
    'GD_Cork_Weap_SniperRifles.A_Weapons_Legendary.Sniper_Vladof_5_Longnail',
])

print('Loading TPS index')
data = Data('TPS')

print('Checking data')
hotfix_idx = 0
create_luneshine_attachments = []
for weapon_obj in weapons:

    if weapon_obj in weap_exclude:
        continue

    node = data.get_node_by_full_object(weapon_obj)
    struct = node.get_structure()
    if 'RuntimePartListCollection' in struct:
        (junk1, runtime_parts,
         junk2) = struct['RuntimePartListCollection'].split("'", 2)
    else:
        raise Exception('No runtime part list found for {}'.format(weapon_obj))

    if runtime_parts:
        partnode = data.get_node_by_full_object(runtime_parts)
        struct = partnode.get_structure()

        parts = struct['GripPartData']['WeightedParts']
        if len(parts) == 1:
            print('{}: {}'.format(weapon_obj, len(parts)))
예제 #6
0
mod_version = '1.1.0'
output_filename = '{}.blcm'.format(mod_name)
output_source_filename = '{}-source.txt'.format(mod_name)

###
### Processing the mod
###

data = Data('TPS')
free_count = 0
prefix = ' ' * (2 * 4)
hotfix_output = []
saved_pools = []

for keyed in sorted(data.get_all_by_type('KeyedItemPoolDefinition')):
    structure = data.get_node_by_full_object(keyed).get_structure()
    for (bi_idx, item) in enumerate(structure['BalancedItems']):
        (junk, pool, junk2) = item['ItmPoolDefinition'].split("'")
        saved_pools.append(pool)
        innerpool = data.get_node_by_full_object(pool).get_structure()
        if len(innerpool['BalancedItems']) != 1:
            raise Exception('Inner pool {} has {} items'.format(
                pool, len(innerpool['BalancedItems'])))
        (junk, actualcustom, junk2
         ) = innerpool['BalancedItems'][0]['InvBalanceDefinition'].split("'")

        # Hotfix to unlink the intermediate pool
        hotfix_output.append(
            '{}level None set {} BalancedItems[{}].ItmPoolDefinition None'.
            format(
                prefix,
예제 #7
0
    rv = child_distance <= distance
    return (rv, '({:0.1f}, {:0.1f}, {:0.1f}) @ {:0.1f}'.format(
        child_x, child_y, child_z, child_distance))


types = [
    ('WillowPopulationOpportunityPoint_', 'Location', 'PopulationDef'),
    ('PopulationOpportunityPoint_', 'Location', 'PopulationDef'),
    ('InterpActor_', 'Location', 'ReplicatedMesh'),
    ('WillowInteractiveObject_', 'Location', 'InteractiveObjectDefinition'),
    # Eh, nothing useful to report on this one.
    #('StaticMeshActor_', 'Location', 'foo'),
]

for (package_name, data_type) in data.get_level_package_nodes(level_package):
    node = data.get_node_by_full_object(package_name)
    for child in node.children.values():
        for (type_prefix, loc_attr, report_attr) in types:
            if child.name.startswith(type_prefix):
                struct = child.get_structure()
                if loc_attr in struct:
                    (match, suffix) = is_close(struct[loc_attr]['X'],
                                               struct[loc_attr]['Y'],
                                               struct[loc_attr]['Z'])
                    if match:
                        print('{prefix}.{name} - {report} {suffix}'.format(
                            prefix=package_name,
                            name=child.name,
                            report=struct[report_attr],
                            suffix=suffix,
                        ))
예제 #8
0
            ('Rotgut Distillery', 'Distillery_P'),
            ('Wam Bam Island', 'Easter_P'),
            ],
    }

for game, levelnames in control.items():
    popdefs = {}
    print('Processing {}'.format(game))
    print('==============')
    print('')
    data = Data(game)
    for (english, levelname) in levelnames:
        
        # Get the info on what objects we need to load.
        level_packages = ['{}.TheWorld:PersistentLevel'.format(levelname)]
        node = data.get_node_by_full_object('{}.TheWorld'.format(levelname))
        for childname, child in node.children.items():
            if childname[:14].lower() == 'levelstreaming':
                childstruct = child.get_structure()
                if childstruct['LoadedLevel'] != 'None':
                    level_packages.append(childstruct['LoadedLevel'].split("'", 2)[1])

        # Report
        #print(levelname)
        #for package in level_packages:
        #    print(' * {}'.format(package))
        #print('')

        # Now loop through 'em to get all the population definitions
        traps = set()
        for package in level_packages:
예제 #9
0
        ('Rotgut Distillery', 'Distillery_P'),
        ('Wam Bam Island', 'Easter_P'),
    ],
}

for game, levelnames in control.items():
    popdefs = {}
    print('Processing {}'.format(game))
    print('==============')
    print('')
    data = Data(game)
    for (english, levelname) in levelnames:

        # Get the info on what objects we need to load.
        level_packages = ['{}.TheWorld:PersistentLevel'.format(levelname)]
        node = data.get_node_by_full_object('{}.TheWorld'.format(levelname))
        for childname, child in node.children.items():
            if childname[:14].lower() == 'levelstreaming':
                childstruct = child.get_structure()
                if childstruct['LoadedLevel'] != 'None':
                    level_packages.append(childstruct['LoadedLevel'].split(
                        "'", 2)[1])

        # Report
        #print(levelname)
        #for package in level_packages:
        #    print(' * {}'.format(package))
        #print('')

        # Now loop through 'em to get all the population definitions
        traps = set()
예제 #10
0
#!/usr/bin/env python
# vim: set expandtab tabstop=4 shiftwidth=4:

from ftexplorer.data import Data

data = Data('BL2')
for aidef in data.get_all_by_type('AIClassDefinition'):
    structure = data.get_node_by_full_object(aidef).get_structure()
    chance_modifier = None
    duration_modifier = None
    damage_impact_modifier = None
    damage_status_modifier = None
    report = False
    if 'BaseShockChanceResistanceModifier' in structure:
        value = round(
            float(structure['BaseShockChanceResistanceModifier']
                  ['BaseValueConstant']), 6)
        if value != 1:
            chance_modifier = value
            report = True
    if 'BaseShockDurationResistanceModifier' in structure:
        value = round(
            float(structure['BaseShockDurationResistanceModifier']
                  ['BaseValueConstant']), 6)
        if value != 1:
            duration_modifier = value
            report = True
    if 'BaseShockDamageModifiers' in structure:
        value = round(
            float(structure['BaseShockDamageModifiers']['ResistanceToImpact']
                  ['BaseValueConstant']), 6)
    # Loop through popdefs to get a list of all pawnbalances which can spawn
    pawnbalances = set()
    for popdef in popdefs:
        for pawnbalance in get_spawns_from_popdef(popdef, data):
            pawnbalances.add(pawnbalance)

    print('{} ({})'.format(level_label, level_name))
    print('')
    same = []
    for pawnbalance in sorted(pawnbalances):
        if pawnbalance in pawnbalance_cache:
            same.append(pawnbalance)
        else:
            print(' * {}'.format(pawnbalance))
            pb_struct = data.get_node_by_full_object(pawnbalance).get_structure()
            pawnbalance_cache[pawnbalance] = pb_struct
            print_blank_line = False
            have_cipl_on_first = False
            if ('PlayThroughs' in pb_struct and
                    pb_struct['PlayThroughs'] != '' and
                    len(pb_struct['PlayThroughs']) > 0):
                for (pt_idx, pt) in enumerate(pb_struct['PlayThroughs']):
                    print_blank_line = True
                    if 'CustomItemPoolList' in pt and pt['CustomItemPoolList'] != '':
                        found_shield = False
                        if pt_idx == 0 and int(pt['PlayThrough']) == 1:
                            have_cipl_on_first = True
                        for (cipl_idx, cipl) in enumerate(pt['CustomItemPoolList']):
                            if shield_pool in cipl['ItemPool']:
                                found_shield = True
예제 #12
0
data = Data('TPS')

filenames = [
        'resources/TPS/dumps/WeaponPartListCollectionDefinition.dump.xz',
        'resources/TPS/dumps/ItemPartListCollectionDefinition.dump.xz',
    ]

part_hotfix_idx = 0
for filename in filenames:
    with lzma.open(filename, 'rt', encoding='latin1') as df:
        for line in df.readlines():
            match = re.match(r"^\*\*\* Property dump for object '\S+ (\S+)' \*\*\*", line)
            if match:
                obj_name = match.group(1)
                struct = data.get_node_by_full_object(obj_name).get_structure()

                if 'ConsolidatedAttributeInitData' not in struct:
                    # Should maybe keep track of which of these doesn't have it...
                    continue

                # Figure out our caid values
                caid = struct['ConsolidatedAttributeInitData']
                caid_values = []
                for caid_val in caid:
                    caid_values.append(float(caid_val['BaseValueConstant']))

                # Now loop through all our items.
                caid_updates = set()
                for key, val in struct.items():
                    if key[-8:] == 'PartData':
예제 #13
0
import sys
from ftexplorer.data import Data

def striptype(obj_name):
    (junk1, name, junk2) = obj_name.split("'", 2)
    return name

def dotnode(obj_name):
    name_parts = obj_name.split('.')
    return name_parts[-1].lower().replace('-', '_')

data = Data('BL2')
with open('b2missions.dot', 'w') as df:
    print('digraph b2 {', file=df)
    for mission_obj in data.get_all_by_type('MissionDefinition'):
        node = data.get_node_by_full_object(mission_obj)
        mission = node.get_structure()

        dot_name = dotnode(mission_obj)
        print('    {} [label=<{}>];'.format(dot_name, mission['MissionName']), file=df)

        print('{} ({})'.format(mission['MissionName'], mission_obj))
        if 'Dependencies' in mission:
            main_deps = set()
            for dep in mission['Dependencies']:
                print(' * {}'.format(dep))
                if dep[:17] != 'MissionDefinition':
                    raise Exception('Unknown mission dep type: {}'.format(dep))
                depname = striptype(dep)
                main_deps.add(depname)
                depname_dot = dotnode(depname)
예제 #14
0
#!/usr/bin/env python
# vim: set expandtab tabstop=4 shiftwidth=4:

from ftexplorer.data import Data

#data = Data('BL2')
data = Data('TPS')

affected = {}
for challenge_def in data.get_all_by_type('ChallengeDefinition'):
    challenge_struct = data.get_node_by_full_object(
        challenge_def).get_structure()
    if 'Levels' in challenge_struct:
        for (idx, level) in enumerate(challenge_struct['Levels']):
            reward = Data.get_struct_attr_obj(level, 'RewardItemPool')
            if reward:
                affected[reward] = (
                    challenge_struct['ChallengeName'],
                    challenge_struct['Description'],
                    idx + 1,
                )

print('Pool | Name | Level | Description')
print('--- | --- | --- | ---')
for reward in sorted(affected.keys()):
    (name, desc, num) = affected[reward]
    print('`{}` | {} | {} | {}'.format(reward, name, num, desc))
예제 #15
0
        weight = round(bvc * bvsc, 6)
        self.total += weight
        self.items.append((title, weight))

    def get_report(self):
        if self.total == 0:
            return ""
        ret_list = []
        for (title, weight) in self.items:
            prob = weight / self.total * 100
            if prob >= 1:
                prob = round(prob)
            else:
                prob = round(prob, 2)
            ret_list.append("\t{}%: {}".format(prob, title))
        return "\n".join(ret_list)


data = Data('TPS')
with open('/home/pez/Programs/games/borderlands_tps/ucp/enemy_use.txt') as df:
    for line in df.readlines():
        if line[:3] == 'GD_':
            pool = line.strip()
            structure = data.get_node_by_full_object(pool).get_structure()
            bal = Balanced()
            for item in structure['BalancedItems']:
                bal.add_item(item)
            print(pool)
            print(bal.get_report())
            print('')
예제 #16
0
#!/usr/bin/env python
# vim: set expandtab tabstop=4 shiftwidth=4:

from ftexplorer.data import Data

# So, I've seen this coming for awhile.  We've never actually handled quotes
# properly, and I've gotten away with it because nothing I've wanted to
# programmatically deal with has ever had a quoted comma in it.  Well,
# the BPD grapher finally came across one of those, specifically:
#
#   GD_Shields.Skills.Spike_Shield_Skill_CorrosiveLegendary:BehaviorProviderDefinition_0
#
# So, just a little util to trigger that parsing, so that I can finally
# address that.
#
# ... and actually, the "fix" for this probably only really handles one
# specific case.  I wouldn't be surprised if something else comes to bite
# me related to quotes again.

data = Data('TPS')
node = data.get_node_by_full_object(
    'GD_Shields.Skills.Spike_Shield_Skill_CorrosiveLegendary:BehaviorProviderDefinition_0'
)
node_struct = node.get_structure()
print(node_struct)
예제 #17
0
#!/usr/bin/env python
# vim: set expandtab tabstop=4 shiftwidth=4:

import sys
import argparse
from ftexplorer.data import Data

data = Data('TPS')

for obj_name in data.get_all_by_type('WeaponNamePartDefinition'):
    obj = data.get_node_by_full_object(obj_name).get_structure()
    if 'PartName' not in obj or obj['PartName'] == '' or obj[
            'PartName'] == 'None':
        print(obj_name)
예제 #18
0
def investigate_pool(pool, report):
    """
    Looks into a pool to see if we should report it.
    """
    if (pool['ItemPool'] != 'None' and
            'AmmoAndResourcePools' not in pool['ItemPool'] and
            'EnemyUse' not in pool['ItemPool'] and
            'Pool_GunsAndGear_Weighted' not in pool['ItemPool'] and
            'ItemPool_MoxxiPicture' not in pool['ItemPool'] and
            'Pool_GrenadeMods_All' not in pool['ItemPool'] and
            'GD_CustomItemPools' not in pool['ItemPool'] and
            'Pool_SpellGrenade' not in pool['ItemPool'] and
            'Pool_Shields_All_01_Common' not in pool['ItemPool']
            ):
        prob = pool['PoolProbability']
        if is_fixed(prob):
            print(report)

for classname in data.get_all_by_type('AIPawnBalanceDefinition'):
    pawn = data.get_node_by_full_object(classname).get_structure()
    if 'DefaultItemPoolList' in pawn:
        for (dipl, pool) in enumerate(pawn['DefaultItemPoolList']):
            investigate_pool(pool, '{} DefaultItemPoolList[{}]'.format(classname, dipl))
    if 'PlayThroughs' in pawn:
        for (pt_idx, pt) in enumerate(pawn['PlayThroughs']):
            if ('CustomItemPoolList' in pt and
                    pt['CustomItemPoolList'] is not None and
                    pt['CustomItemPoolList'] != ''):
                for (cipl, pool) in enumerate(pt['CustomItemPoolList']):
                    investigate_pool(pool, '{} PlayThroughs[{}].CustomItemPoolList[{}]'.format(classname, pt_idx, cipl))
예제 #19
0
    (link_index, link_length) = compliment(link)
    print('{}Links at {}, length {}'.format(prefix, link_index, link_length))
    for cold_index in range(link_index, link_index + link_length):
        cold = cold_data[cold_index]
        (link_id, bindex) = compliment(cold['LinkIdAndLinkedBehavior'])
        behavior = behavior_data[bindex]
        print('{}* (delay {}) Behavior {}: {}'.format(
            prefix, round(float(cold['ActivateDelay'])), bindex,
            behavior['Behavior']))
        follow(behavior['OutputLinks']['ArrayIndexAndLength'],
               cold_data,
               behavior_data,
               prefix='{}  '.format(prefix))


bpd = data.get_node_by_full_object(bpd_name).get_structure()
seq0 = bpd['BehaviorSequences'][0]

event_data = seq0['EventData2']
behavior_data = seq0['BehaviorData2']
variable_data = seq0['VariableData']
cold_data = seq0['ConsolidatedOutputLinkData']
var_data = seq0['ConsolidatedVariableLinkData']
link_data = seq0['ConsolidatedLinkedVariables']

for event in event_data:
    if event['UserData']['bEnabled'] == 'True':
        print('Event {}:'.format(event['UserData']['EventName']))
        follow(event['OutputLinks']['ArrayIndexAndLength'],
               cold_data,
               behavior_data,
예제 #20
0
mod_version = '1.0.0'
output_filename = '{}.txt'.format(mod_name)

###
### Processing the mod
###

data = Data('TPS')
hfs = Hotfixes()
free_count = 0
prefix = ' '*(2*4)
hotfix_output = []
saved_pools = []

for keyed in sorted(data.get_all_by_type('KeyedItemPoolDefinition')):
    structure = data.get_node_by_full_object(keyed).get_structure()
    for (bi_idx, item) in enumerate(structure['BalancedItems']):
        (junk, pool, junk2) = item['ItmPoolDefinition'].split("'")
        saved_pools.append(pool)
        innerpool = data.get_node_by_full_object(pool).get_structure()
        if len(innerpool['BalancedItems']) != 1:
            raise Exception('Inner pool {} has {} items'.format(pool, len(innerpool['BalancedItems'])))
        (junk, actualcustom, junk2) = innerpool['BalancedItems'][0]['InvBalanceDefinition'].split("'")

        # Hotfix to unlink the intermediate pool
        hf_id = 'unlink_{}'.format(free_count)
        hfs.add_level_hotfix(hf_id, 'TPSSkinpool',
            ',{},BalancedItems[{}].ItmPoolDefinition,,None'.format(
                keyed,
                bi_idx,
                ))