def load_base(self, classdef, base_dot_chance, base_dot_duration, base_damage): if self.report_dot: chance_val = Weight(classdef[base_dot_chance], self.pt).value if chance_val < 1: self.base.dot_chance = chance_val duration_val = Weight(classdef[base_dot_duration], self.pt).value if duration_val != 1: self.base.dot_duration = duration_val impact_val = Weight(classdef[base_damage]['ResistanceToImpact'], self.pt).value if impact_val != 1: self.base.impact = impact_val damage_val = Weight(classdef[base_damage]['ResistanceToStatusEffect'], self.pt).value if damage_val != 1: self.base.dot_damage = damage_val
def find_has_shields(poollist): if poollist is None or poollist == '': return (False, None) for pool in poollist: if 'Pool_Shields_Standard_EnemyUse' in pool['ItemPool']: shieldweight = Weight(pool['PoolProbability']) if shieldweight.value > 0: return (True, shieldweight.value) return (False, None)
def process_caid(obj_struct): """ Given an `obj_struct` which contains a `ConsolidatedAttributeInitData` structure, process it into a dict which is more useful to us. """ caids = {} for (idx, caid) in enumerate(obj_struct['ConsolidatedAttributeInitData']): #caids[idx] = Weight(caid).value try: caids[idx] = Weight(caid).value except Exception: # If something tries to reference this later on, we'll die then. pass return caids
# Don't process anything in the blacklist if baldef_name in blacklist[game]: continue baldef_struct = data.get_struct_by_full_object(baldef_name) partlist_name = Data.get_struct_attr_obj(baldef_struct, 'RuntimePartListCollection') if partlist_name: partlist = data.get_struct_by_full_object(partlist_name) # First get our CAID data caids = {} for (idx, caid) in enumerate(partlist['ConsolidatedAttributeInitData']): caids[idx] = Weight(caid).value # Now loop through gun_types = 1 gun_types_no_luneshine = 1 for attr in [ 'BodyPartData', 'GripPartData', 'BarrelPartData', 'SightPartData', 'StockPartData', 'ElementalPartData', 'Accessory1PartData', 'Accessory2PartData' ]: if attr in partlist: part_count = 0 part_count_no_luneshine = 0 zero_weights = 0 if partlist[attr]['bEnabled'] == 'False': continue
def add_to_asv_dict(cur_dict, asv_list, pt): for asv in asv_list: name = Data.get_attr_obj(asv['Attribute']) cur_dict[name] = Weight(asv['BaseValue'], pt).value return cur_dict
def __init__(self, label, pawn_name, pt, pawnbalance, classdef): self.label = label self.pawn_name = pawn_name self.pt = pt self.pt_label = 'PT{}'.format(pt) # Create a combined AttributeStartingValues dict. # Technically the ASVs in AIPawnBalanceDefinition.PlayThroughs will override # values found in AIClassDefinitions. In practice, this doesn't actually # happen anywhere in the BL2 data, or at least not for the vars we care about. # Still, we're technically supporting it here. asv_dict = {} if 'AttributeStartingValues' in classdef and classdef['AttributeStartingValues'] != '': AttributeSet.add_to_asv_dict(asv_dict, classdef['AttributeStartingValues'], idx+1) ptstruct = pawnbalance['PlayThroughs'][pt-1] if 'AttributeStartingValues' in ptstruct and ptstruct['AttributeStartingValues'] != '': AttributeSet.add_to_asv_dict(asv_dict, ptstruct['AttributeStartingValues'], idx+1) # Now define all our bits which provide resistance to things self.explosive = AttributePair('Explosive', pt, pawnbalance, classdef, asv_dict, base_damage='BaseExplosiveDamageModifiers', mod_impact='D_Attributes.DamageTypeModifers.ExplosiveImpactDamageModifier', report_dot=False, ) self.grenade = AttributePair('Grenade', pt, pawnbalance, classdef, asv_dict, mod_impact='D_Attributes.DamageSourceModifiers.ReceivedGrenadeDamageModifier', report_dot=False, report_base=False, ) self.melee = AttributePair('Melee', pt, pawnbalance, classdef, asv_dict, mod_impact='D_Attributes.DamageSourceModifiers.ReceivedMeleeDamageModifier', report_dot=False, report_base=False, ) self.normal = AttributePair('Normal', pt, pawnbalance, classdef, asv_dict, base_damage='BaseNormalDamageModifiers', report_dot=False, ) self.slag = AttributePair('Slag', pt, pawnbalance, classdef, asv_dict, base_dot_chance='BaseAmpChanceResistanceModifier', base_dot_duration='BaseAmpDurationResistanceModifier', base_damage='BaseAmpDamageModifiers', mod_is_useless=True, mod_dot_chance='D_Attributes.StatusEffectModifiers.AmpChanceResistanceModifier', mod_dot_duration='D_Attributes.StatusEffectModifiers.AmpDurationResistanceModifier', mod_impact='D_Attributes.DamageTypeModifers.AmpImpactDamageModifier', mod_dot_damage='D_Attributes.DamageTypeModifers.AmpStatusEffectDamageModifier', ) self.corrosive = AttributePair('Corrosive', pt, pawnbalance, classdef, asv_dict, base_dot_chance='BaseCorrosiveChanceResistanceModifier', base_dot_duration='BaseCorrosiveDurationResistanceModifier', base_damage='BaseCorrosiveDamageModifiers', mod_is_useless=True, mod_dot_chance='D_Attributes.StatusEffectModifiers.CorrosiveChanceResistanceModifier', mod_dot_duration='D_Attributes.StatusEffectModifiers.CorrosiveDurationResistanceModifier', mod_impact='D_Attributes.DamageTypeModifers.CorrosiveImpactDamageModifier', mod_dot_damage='D_Attributes.DamageTypeModifers.CorrosiveStatusEffectDamageModifier', ) self.fire = AttributePair('Fire', pt, pawnbalance, classdef, asv_dict, base_dot_chance='BaseIgniteChanceResistanceModifier', base_dot_duration='BaseIgniteDurationResistanceModifier', base_damage='BaseIncendiaryDamageModifiers', mod_is_useless=True, mod_dot_chance='D_Attributes.StatusEffectModifiers.IgniteChanceResistanceModifier', mod_dot_duration='D_Attributes.StatusEffectModifiers.IgniteDurationResistanceModifier', mod_impact='D_Attributes.DamageTypeModifers.IncendiaryImpactDamageModifier', mod_dot_damage='D_Attributes.DamageTypeModifers.IncendiaryStatusEffectDamageModifier', ) self.shock = AttributePair('Shock', pt, pawnbalance, classdef, asv_dict, base_dot_chance='BaseShockChanceResistanceModifier', base_dot_duration='BaseShockDurationResistanceModifier', base_damage='BaseShockDamageModifiers', mod_is_useless=True, mod_dot_chance='D_Attributes.StatusEffectModifiers.ShockChanceResistanceModifier', mod_dot_duration='D_Attributes.StatusEffectModifiers.ShockDurationResistanceModifier', mod_impact='D_Attributes.DamageTypeModifers.ShockImpactDamageModifier', mod_dot_damage='D_Attributes.DamageTypeModifers.ShockStatusEffectDamageModifier', ) # Get phaselockability self.disable_phaselock = None if 'DesignerFlagStartingValues' in classdef and classdef['DesignerFlagStartingValues'] != '': for dfsv in classdef['DesignerFlagStartingValues']: if 'GD_AI_Flags.Skills.Flag_Skills_DisablePhaseLock' in dfsv['FlagToSet']: chance_val = Weight(dfsv['ChanceTrue'], pt=pt).value if chance_val > 0: if chance_val > 1: self.disable_phaselock = 1 else: self.disable_phaselock = chance_val # Get phaselock time scale pt_time = 'GD_Siren_Skills.Attributes.PhaselockTimeScale' if self.disable_phaselock is None and pt_time in asv_dict and asv_dict[pt_time] != 1: self.phaselock_time = asv_dict[pt_time] else: self.phaselock_time = None
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 prob = Weight(cipl['PoolProbability']) print(' Shield Chance at [{}]PlayThrough {}, CIPL {}: {:d}%'.format( pt_idx, pt['PlayThrough'], cipl_idx, round(prob.value*100), )) break if not found_shield: print(' No Shield on [{}]PlayThrough {}'.format( pt_idx, pt['PlayThrough'], )) else: print(' No CIPL to override on [{}]PlayThrough {}'.format( pt_idx,
'GD_Population_Psycho.Population.PopDef_PsychoSuicide', ] pawns = set([ 'GD_Population_Marauder.Balance.PawnBalance_MarauderElite', 'GD_Population_Marauder.Balance.PawnBalance_MarauderRegular', 'GD_Population_Marauder.Balance.PawnBalance_Scavenger', 'GD_Population_Midget.Balance.PawnBalance_MidgetShotgun' ]) commands = [] for popdef_name in popdefs: reported = False popdef = data.get_struct_by_full_object(popdef_name) for (archetype_idx, archetype) in enumerate(popdef['ActorArchetypeList']): prob = Weight(archetype['Probability']) if prob.value > 0: factory_name = Data.get_struct_attr_obj(archetype, 'SpawnFactory') factory = data.get_struct_by_full_object(factory_name) pawn_name = Data.get_struct_attr_obj(factory, 'PawnBalanceDefinition') if pawn_name in pawns: if not reported: print(popdef_name) reported = True print(' * [{}] {} @ {}'.format(archetype_idx, pawn_name, prob.value)) commands.append("""set {} ActorArchetypeList[{}].Probability ( BaseValueConstant=200000, BaseValueAttribute=None, InitializationDefinition=None, BaseValueScaleConstant=1
# Now dig down to see if we can find health modifiers archetype_name = Data.get_struct_attr_obj(baldef, 'AIPawnArchetype') if not archetype_name: print('WARNING: No archetype name for {} ({})'.format( pawn_name, classname)) continue archetype = data.get_struct_by_full_object(archetype_name) aiclass_name = Data.get_struct_attr_obj(archetype, 'AIClass') if not aiclass_name: print('WARNING: No AIClass name for {}'.format(archetype_name)) continue aiclass = data.get_struct_by_full_object(aiclass_name) health_modifier = None if ('AttributeStartingValues' in aiclass and aiclass['AttributeStartingValues'] != None and aiclass['AttributeStartingValues'] != ''): for value in aiclass['AttributeStartingValues']: if 'GD_Balance_HealthAndDamage.AIParameters.Attribute_HealthMultiplier' in value[ 'Attribute']: if health_modifier is None: health_modifier = Weight(value['BaseValue']) else: print('WARNING: Overridden health value in {}'.format( aiclass_name)) if health_modifier is not None: if health_modifier.value < 1: print( '{} ({}): Health Modifier: {} (shield in {}, prob {})'.format( pawn_name, classname, health_modifier.value, shield_loc, shield_prob))