Пример #1
0
    def write_mod(self):

        mod = Mod(
            f'money_grenade_changes_{self.mod_filename}.bl3hotfix',
            f'Money Grenade Changes: {self.mod_label}',
            'Apocalyptech',
            [
                f"Changes the 'Money' grenade part to drop {self.desc_text} instead of money.",
            ],
            contact='https://apocalyptech.com/contact.php',
            lic=Mod.CC_BY_SA_40,
            v='1.0.0',
            cats='joke, gear-grenade, cheat',
            ss=
            f'https://raw.githubusercontent.com/BLCM/bl3mods/master/Apocalyptech/gear_changes/money_grenade_changes/screenshot_{self.mod_filename}.png',
        )

        mod.header('Update item prefixes')
        mod.reg_hotfix(
            Mod.PATCH, '',
            '/Game/Gear/GrenadeMods/_Design/Naming/GrenadeModNamingStrategy',
            'SingleNames.SingleNames[20].NamePart.Object..PartName',
            self.single_name)
        mod.reg_hotfix(
            Mod.PATCH, '',
            '/Game/Gear/GrenadeMods/_Design/Naming/GrenadeModNamingStrategy',
            'TripleNames.TripleNames[11].NamePart.Object..PartName',
            self.triple_name)
        self._combo_name(mod, 19, self.combo_name_mirv)
        self._combo_name(mod, 36, self.combo_name_rain)
        self._combo_name(mod, 52, self.combo_name_nuke)
        self._combo_name(mod, 67, self.combo_name_large)
        self._combo_name(mod, 81, self.combo_name_bouncy)
        self._combo_name(mod, 94, self.combo_name_spring)
        self._combo_name(mod, 106, self.combo_name_sticky)
        self._combo_name(mod, 117, self.combo_name_artillery)
        self._combo_name(mod, 127, self.combo_name_lingering)
        self._combo_name(mod, 136, self.combo_name_divide)
        self._combo_name(mod, 144, self.combo_name_singularity)
        self._combo_name(mod, 151, self.combo_name_roider)
        self._combo_name(mod, 157, self.combo_name_link)
        self._combo_name(mod, 162, self.combo_name_transfusion)
        self._combo_name(mod, 166, self.combo_name_generator)
        self._combo_name(mod, 169, self.combo_name_elemental)
        self._combo_name(mod, 171, self.combo_name_force)
        self._combo_name(mod, 172, self.combo_name_money)
        mod.newline()

        mod.header('Update part name')
        mod.reg_hotfix(
            Mod.PATCH, '',
            '/Game/Gear/GrenadeMods/_Design/PartSets/Part_Behavior/Money/UIStat_Grenade_Money_Icon',
            'Text', self.part_text.upper())
        mod.newline()

        mod.header('Update drop pools and card descriptions')
        for pool_label, rewards, (uistat_name, uistat_text) in [
            ('Single-part grenade', self.rewards1, self.uistat1),
            ('Double-part grenade', self.rewards2, self.uistat2),
            ('Triple-part grenade', self.rewards3, self.uistat3),
        ]:
            mod.comment(pool_label)
            mod.reg_hotfix(Mod.PATCH, '', rewards.pool_name, 'BalancedItems',
                           str(rewards))
            mod.reg_hotfix(Mod.PATCH, '', uistat_name, 'FormatText',
                           uistat_text.format(self.card_text))
            mod.newline()

        # Special-case hardcodes for some mod types
        if self.mod_label == 'Diamond Keys':

            # Fix up the diamond key item so that it looks better when dropped
            # (by default it just looks like eridium, and also doesn't auto-pickup)

            mod.header_lines([
                "Fixing up droppable Diamond Key object",
                "",
                "We're making a few changes here which affect the item card specifically,",
                "though the item card will basically never be seen since we're enabling",
                "auto-pickup as well.  If you *do* get a glimpse of the card (using Photo",
                "Mode or the like) you'll see a bit of weirdness still -- the card might",
                "inherit the visual price of whatever card was last looked at, and the",
                "loot beam icon might inherit the last-looked-at item as well.  In the",
                "end I'm not bothering to track that down, though, since you've gotta",
                "work hard to see the card anyway.",
            ])

            mod.comment('Use an actual key mesh')
            mod.reg_hotfix(
                Mod.PATCH,
                '',
                '/Game/PatchDLC/VaultCard/Data/Currency/BP_DiamondKey_Single.Default__BP_DiamondKey_Single_C',
                'ItemMeshComponent.Object..StaticMesh',

                # Tried lots of various meshes here; I'm tempted to go with one of the keyring ones,
                # but in the end I just went with one of the smaller single-key ones.  Would be nice
                # if I could get that Geranium Key-to-City ones to interact with physics, though
                # that might cause weird problems with the key during the plot (or on Decoration),
                # so eh.  We'll just stick with the tiny key for now.

                # A bit much, though it's a nice big size.  Is definitely a keyring, though.
                #Mod.get_full_cond('/Dandelion/Missions/Plot/Ep04_Trashtown/Janitor_Keyring/Model/Meshes/SM_Janitor_Keyring', 'StaticMesh'),

                # Definitely a keyring; probably better than SM_Janitor_Keyring if I feel okay with that...
                #Mod.get_full_cond('/Ixora2/Missions/02_Eden6/Keyring/Model/Meshes/SM_Key_Ring', 'StaticMesh'),

                # Hah, just a rusty sphere basically
                #Mod.get_full_cond('/Geranium/LevelArt/Lodge/Props/Model/Meshes/SM_Apple_Key', 'StaticMesh'),

                # Very nice (and rightly-sized!) key, but it weirdly doesn't seem to actually interact with physics
                # at all?  Just hangs there in midair.
                #Mod.get_full_cond('/Geranium/InteractiveObjects/MissionAssets/Plot_5/Model/Meshes/SM_Key_to_City', 'StaticMesh'),
                # Same story here; and seemingly identical to the other one.  Almost certainly a copied object.
                #Mod.get_full_cond('/Game/PatchDLC/Geranium/InteractiveObjects/PlayerQuarters/RoomDecoMeshes/Meshes/SM_Key_to_City_RoomDeco', 'StaticMesh'),

                # Perfectly serviceable key, but quite small
                #Mod.get_full_cond('/Hibiscus/InteractiveObjects/MissionSpecific/Plot/EP03/Pickups/SM_Key_GateKey', 'StaticMesh'),
                # Perfectly serviceable key, but quite small
                Mod.get_full_cond(
                    '/Game/LevelArt/Environments/_Global/Props/Keys/Key_Scooters/Model/Meshes/SM_Key_Scooters',
                    'StaticMesh'),
            )
            mod.newline()

            mod.comment('Set a different item card type')
            mod.reg_hotfix(
                Mod.PATCH,
                '',
                '/Game/PatchDLC/VaultCard/Data/Currency/InvData_DiamondKey',
                'ItemCardTypeFrameName',
                #'currencyEridium',
                # Mission is nice; has a diamondy icon, even!
                'Mission',
                # Cash works well
                #'Cash',
            )
            mod.newline()

            mod.comment(
                'Set monetary value to 1; might prevent currency from inheriting from previously-viewed items'
            )
            mod.reg_hotfix(
                Mod.PATCH, '',
                '/Game/PatchDLC/VaultCard/Data/Currency/InvData_DiamondKey',
                'MonetaryValue', BVCF(bvc=1))
            mod.newline()

            mod.comment(
                'Assign Legendary rarity (instead of Eridium), for loot bar + frame color'
            )
            mod.reg_hotfix(
                Mod.PATCH, '',
                '/Game/PatchDLC/VaultCard/Data/Currency/InventoryBalance_DiamondKey',
                'RarityData',
                Mod.get_full_cond(
                    '/Game/GameData/Loot/RarityData/RarityData_05_Legendary',
                    'RarityData'))
            mod.newline()

            mod.comment('Auto-pickup Diamond Keys')
            mod.reg_hotfix(
                Mod.PATCH,
                '',
                '/Game/Gear/_Shared/_Design/InventoryCategories/InventoryCategory_DiamondKey',
                'PickupActionType',
                #'OnUseOnly',
                'OnUseOrTouch',
            )
            mod.newline()

        mod.close()
Пример #2
0
        'Mayhem 2.0',
        '/Game/PatchDLC/Mayhem2/Gear/Weapon/DataTable_WeaponBalance_Mayhem2',
        [
            ('The Monarch', 'AR_TheMonarch', 1.6, 0.7),
            ('Plaguebearer', 'HW_Plague', 1.1, 0.9),
            ('Backburner', 'HW_Backburner', 2, 1.7),
            # TODO: GBX nerfed Kaoson from 2.25 to 1.6, but also buffed most other legendary SMGs.
            # Should re-test all the SMGs in here to see how they fare now.
            ('Kaoson', 'Kaoson', 1.6, 1),
            ('Sand Hawk', 'SR_SandHawk', 1.5, 0.5),
            ('Reflux', 'SG_Reflux', 1.75, 1.5),
        ]),
]:
    mod.header(cat_name)
    for weap_label, row, default_scale, new_scale in sorted(weapons):
        mod.comment('{} (default: {})'.format(weap_label, default_scale))
        mod.table_hotfix(Mod.PATCH, '', balance_obj, row,
                         'DamageScale_2_4F6EF14648BA8F2AE9217DAFEA60EE53',
                         new_scale)
        mod.newline()
        readme_reports.append('{}: `{}` -> `{}`'.format(
            weap_label, default_scale, new_scale))

mod.close()

print('Info for pasting into README:')
print('')
for line in sorted(readme_reports):
    print('  - {}'.format(line))
print('')
def save_mod(save_filename):
    """
    Save out a mod file.  This actually relies on an awful lot of global variables.
    Apologies.
    """
    mod = Mod(save_filename,
            'Arbitrary Partlocks: {}'.format(bal_last),
            'Apocalyptech',
            [
                'Auto-generated partlocks, chosen with an interactive CLI app.',
            ],
            lic=Mod.CC_BY_SA_40,
            )

    for cat_idx, cat_actions in enumerate(actions):
        cur_cat = categories[cat_idx]
        always_vals = set()
        never_vals = set()
        for action in cat_actions.values():
            if action.action == Action.ALWAYS:
                always_vals.add(action.list_idx)
            else:
                never_vals.add(action.list_idx)

        # Now, loop through each category and assign new weights
        if len(always_vals) > 0 or len(never_vals) > 0:
            if cat_idx == 0:

                # We could try to generalize, but whatever.  Just process anoints separately
                cur_idx = 0
                if cur_cat.cat.partlist:
                    cur_source = cur_cat.cat.partlist[0].anoint_source
                for num, part in enumerate(cur_cat.cat.partlist):

                    # Reset our array index if needed
                    if part.anoint_source != cur_source:
                        cur_idx = 0
                        cur_source = part.anoint_source

                    # If we have any "always" entries, we effectively assume everything else
                    # is a "never", so we process a bit differently
                    if len(always_vals) > 0:
                        if num not in always_vals:
                            never_vals.add(num)

                    # Now write out
                    if part.anoint_source != balance_name:
                        extra_txt = ' (affects anything using this anoint)'
                        attr_ref = 'GenericParts.Parts'
                    else:
                        extra_txt = ''
                        attr_ref = 'RuntimeGenericPartList.PartList'
                    if num in always_vals:
                        mod.comment('Anointments: Always choose {}{}'.format(part.short_name, extra_txt))
                        mod.reg_hotfix(Mod.PATCH, '',
                                part.anoint_source,
                                '{}[{}].Weight'.format(attr_ref, cur_idx),
                                BVCF(bvc=1))
                        mod.newline()
                    elif num in never_vals:
                        mod.comment('Anointments: Never choose {}{}'.format(part.short_name, extra_txt))
                        mod.reg_hotfix(Mod.PATCH, '',
                                part.anoint_source,
                                '{}[{}].Weight'.format(attr_ref, cur_idx),
                                BVCF(bvc=0))
                        mod.newline()

                    # Increment our index
                    cur_idx += 1

            else:

                # Make sure this is set to use weights
                if not cur_cat.cat.use_weight_with_mult:
                    mod.comment('Category {}: Enable weight-based part picking'.format(cat_idx))
                    mod.reg_hotfix(Mod.PATCH, '',
                            balance.partset_name,
                            'ActorPartLists.ActorPartLists[{}].bUseWeightWithMultiplePartSelection'.format(cat_idx-1),
                            'True')
                    mod.newline()

                # Regular parts
                # TODO: If we ever get GPartExpansion objects which do more than add expansions,
                # well have to support it here, too.
                cur_idx = cur_cat.start_part_idx
                for num, part in enumerate(cur_cat.cat.partlist):

                    # If we have any "always" entries, we effectively assume everything else
                    # is a "never", so we process a bit differently
                    if len(always_vals) > 0:
                        if num not in always_vals:
                            never_vals.add(num)

                    # Now write out
                    if num in always_vals:
                        mod.comment('Category {}: Always choose {}'.format(cat_idx, part.short_name))
                        mod.reg_hotfix(Mod.PATCH, '',
                                balance_name,
                                'RuntimePartList.AllParts[{}].Weight'.format(cur_idx),
                                BVCF(bvc=1))
                        mod.newline()
                    elif num in never_vals:
                        mod.comment('Category {}: Never choose {}'.format(cat_idx, part.short_name))
                        mod.reg_hotfix(Mod.PATCH, '',
                                balance_name,
                                'RuntimePartList.AllParts[{}].Weight'.format(cur_idx),
                                BVCF(bvc=0))
                        mod.newline()

                    # Increment index
                    cur_idx += 1

    print('')
    print(color_success + '='*80)
    mod.close()
    print(color_success + '='*80)
    print(color_reset)
    input('Hit Enter to Continue...')
    print('')