Jump to content

Grape_You_In_The_Mouth

Members
  • Posts

    225
  • Joined

  • Last visited

Posts posted by Grape_You_In_The_Mouth

  1. You should make it happen, it would only require changing one thing.  This is the status effect that links crits to the second effect, gaining focus:

    "$type": "Game.GameData.StatusEffectGameData, Assembly-CSharp",
    "DebugName": "The_Complete_Self_SE_ApplyOnEvent",
    "ID": "962ed740-cbec-4da4-8055-241acaf726e0",

    It's in the statuseffects.gamedatabundle file.  In that specific section of code where this status effect is, it limits it to Cipher attacks via:

    "ClassTypeID": "ccdc9675-e2a7-46fa-83e9-7a5368b56265"

    So just change it to the wizard's class ID, acfd1303-4699-4939-91eb-6ac46d4af0bd.

    This would do exactly what you want, but now you'd want to copy these effects and their linked ability code, and create a sub-class out of it.  Rename the DebugName, create new IDs for them, create new text strings to describe them, etc.

     

    • Like 2
  2. Carnage works via ApplyStatusEffectToEnemyOnEvent --> AttackTargetOnEvent [Primary], for attacking with the primary weapon, and then again for a "Secondary" in the AttackOverrideValue.  All of this is in the StatusEffects gamedatabundle. 

     

    Not sure how the stag carnage applies all the effects to everyone but they might have changed the stag's melee attack data to be an AoE that deals less damage (if it wasn't before) and that would spread all the effects in that way.  This would be instead of the way Carnage works, because Carnage has to deal with whatever weapons the player chooses to equip in either slot.  The stag doesn't equip items, so they probably didn't even make it like Carnage.

  3. 46c6c0898120d98c112d6ead5921a4d34cf5f90af2621112de046b1f4cb84d31.jpg.1caa4dac31d6f5f7671101869c02afca.jpg

     

    Not sure if anyone has seen any charging abilities in the game, but I couldn't find any and finally figured out how to make one.  By charging abilities, I mean abilities that make you "charge up" by dedicating time to the ability, and allow you to release the effect at any time, and the effect is bigger the more you charged up.  Megaman's or Samus's blaster are good examples.

     

    The abilities are going to be on an item I'm making called Evelyn's Jaunt.  I made two modal abilities and grouped them together via a modal group:

            {
                "$type": "Game.GameData.ModalGroupGameData, Assembly-CSharp",
                "DebugName": "MG_evelyns_jaunt",
                "ID": "113f042e-5a0e-4b62-95e3-a20bdf957622",
                "Components": [
                    {
                        "$type": "Game.GameData.ModalGroupComponent, Assembly-CSharp",
                        "DisplayName": 305151077,
                        "MustBeActive": "true"
                    }
                ]
            }

     

    Then I made one ability charge up ("Charge Up") and the other bursts you into the air ("Liftoff").  Charge Up will stack effects at a rapid pace, which will be applied OnClear via ApplyStatusEffectOnEvent.  But we need a fast tick rate, so I made one to be 10x per second:

            {
                "$type": "Game.GameData.IntervalRateGameData, Assembly-CSharp",
                "DebugName": "Interval_10_Per_Second_evelynsjaunt",
                "ID": "222ecc89-771e-4a80-b749-d1e552205d3b",
                "Components": [
                    {
                        "$type": "Game.GameData.IntervalRateComponent, Assembly-CSharp",
                        "Interval": 0.1,
                        "OnlyWhileMoving": "false"
                    }
                ]
            },

     

    The Charge Up modal ability is: Ability -> Attack (simple melee attack only to apply status effects) -> ApplyStatusEffectonEvent [OnInterval] -> ApplyStatusEffectOnEvent [OnClear] -> Accuracy stacking bonus, launching stacking effect, and another ApplyStatusEffectonEvent using OnClear after 1s to create visual effects and restrictions to the player at the perfect time

    Unfortunately, the VerticalLaunch effect is inconsistent after multiple uses, so I had to make it for a set amount of time and make some graphics changes to hide the limitation.  However, the Accuracy and other effects stack just fine.  I used AddDurationIfAlreadyApplied on the visual effects to last as long as the stacking bonuses, and then made them with "Event": "OnStop" to occur at the end of the status effects.

    Then we have the Liftoff modal ability, which is just an attack with a keyword.  This keyword will be used to clear the effects built up during Charge Up, by creating this in the Charge Up trigger settings for the 1st & 2nd ApplyStatusEffectOnEvent :

                        "TriggerAdjustment": {
                            "TriggerOnEvent": "OnLaunchesAttack",
                            "TriggerOffEvent": "None",
                            "ValidateWithAttackFilter": "true",
                            "ParamValue": 0,
                            "ValueAdjustment": 0,
                            "DurationAdjustment": 0,
                            "ResetTriggerOnEffectTimeout": "false",
                            "MaxTriggerCount": 1,
                            "IgnoreMaxTriggerCount": "false",
                            "RemoveEffectAtMax": "true",
                            "ChanceToTrigger": 1
                        },

     

    Then on the AttackFilter we put in the keyword that we created and assigned to the Liftoff modal ability's attack.  Keywords can be made via this code:

            {
                "$type": "Game.GameData.KeywordGameData, Assembly-CSharp",
                "DebugName": "evelyns_jaunt_Keyword",
                "ID": "d9f0545a-6897-4b2e-ae36-b9b3e4082fbd",
                "Components": [
                    {
                        "$type": "Game.GameData.KeywordComponent, Assembly-CSharp",
                        "GuiDisplayString": 305151076,
                        "AbilitiesDisplayString": -1,
                        "Description": -1,
                        "OverridePluralEffect": -1,
                        "Icon": "",
                        "TintableIcon": ""
                    }
                ]
            },

    Then you put that keyword ID at the beginning of the Liftoff modal's attack and make sure it's in the attack filter of the Charge Up modal's 2nd ApplyStatusEffectOnEvent.  Now when we use Charge Up, we gain stacks every 0.1 seconds, and when we use Liftoff, our Charge Up effects recognize it and are removed, which triggers them to apply all at once because they're set to OnClear.  To be precise, "OnClear" is at the "EventValue" not the ApplicationType, which can be confusing.  ApplicationType is almost always ApplyOnStart because it has limited options.

     

    But wait: What could go wrong?  Well, you'll always have problems with visual effects and deciding when to use HideFromUI or HideFromCombatTooltip.  But what's really wrong with this?  We probably don't want to have the player able to use the Charge Up modal again while the current effects are still applied.  Maybe you do, but for my ability, that would be too good, so we have to disable the other modal ability somehow.

     

    How do you disable a modal ability?  It's actually really hard.  DisableKeywordAbilities didn't work for me.  DisableModalAbilities removed all the effects of the Charge Up, even though I don't need to use that modal anymore!  Instead, I had to apply a Conditional to the Charge Up ability so that whenever I had a status effect with a Charge Up keyword used, the Charge Up ability deactivated, then reactivated afterwards:

    First I created the new keyword (using the same method as before) for Charge Up (this is a new keyword) and put it on a status effect that would last as long as the others. 

                        "KeywordsIDs": [
                            "4d7d49fc-2305-4c8b-9fe1-5c9c0c244c06"
                        ],

    Then I created the Conditional on the Charge Up ability:

                        "ActivationPrerequisites": {
                            "Conditional": {
                                "Operator": 0,
                                "Components": [
                                    {
                                        "$type": "OEIFormats.FlowCharts.ConditionalCall, OEIFormats",
                                        "Data": {
                                            "FullName": "Boolean HasStatusEffectWithKeyword(Guid, Guid)",
                                            "Parameters": [
                                                "7d150000-0000-0000-0000-000000000000",
                                                "4d7d49fc-2305-4c8b-9fe1-5c9c0c244c06"
                                            ],
                                            "Flags": "",
                                            "UnrealCall": "",
                                            "FunctionHash": 0,
                                            "ParameterHash": 0
                                        },
                                        "Not": true,
                                        "Operator": 0
                                    }
                                ]
                            }
                        },
                        "ApplicationPrerequisites": {
                            "Conditional": {
                                "Operator": 0,
                                "Components": []
                            }
                        },
                        "DeactivationPrerequisites": {
                            "Conditional": {
                                "Operator": 0,
                                "Components": [
                                    {
                                        "$type": "OEIFormats.FlowCharts.ConditionalCall, OEIFormats",
                                        "Data": {
                                            "FullName": "Boolean HasStatusEffectWithKeyword(Guid, Guid)",
                                            "Parameters": [
                                                "7d150000-0000-0000-0000-000000000000",
                                                "4d7d49fc-2305-4c8b-9fe1-5c9c0c244c06"
                                            ],
                                            "Flags": "",
                                            "UnrealCall": "",
                                            "FunctionHash": 0,
                                            "ParameterHash": 0
                                        },
                                        "Not": false,
                                        "Operator": 0
                                    }
                                ]
                            }
                        },

    Now this says the Charge Up ability will Deactivate when I have a Charge Up status effect with my new Charge Up keyword, and activate again when that effect is gone.  Now you can charge up and blast off into the air, and a whole new type of abilities are available to Deadfire.

     

    What are the downsides to charging abilities?  They take up valuable space on the screen, but only one space per modal group.  I'm not sure what else, but I think it's really cool.

    • Like 1
    • Thanks 1
  4. Unfortunately you do need the conditionals to prevent being able to upgrade everything.  To answer your earlier question, that's what the conditionals there are for--limiting availability.  Something cool I just learned is that you can add your own item sketches in the top of the item data and just put the 300x240 png in that location: 

    "PencilSketchTexture": "gui/itemsketches/sketch_solo_hero_back.png"
  5. Triggers in Deadfire refer to something different.  In the Trigger section of the status effects you can set actions that would trigger changes to the status effect.  You can change duration, status effect value, etc.

     

    What you're talking about is "how to trigger an effect after an action", which could also be called triggers but there is a specific use for the term trigger in Deadfire.  You ApplyStatusEffectOnEvent to have a status effect create when the EventValue occurs.

     

    For instance, let's say you make that ApplyStatusEfectOnEvent status to create a Damage status effect OnHit.  So Whenever you're hit, you create damage to yourself.  But if you wanted to increase the damage OnCriticallyHit, then you'd put that in the TriggerOnEvent for the Damage status effect, and ValueAdjustment 5, to increase the damage by 5.  TriggerOffEvent would be OnDamaged to clear the bonus damage before the next round of hits.

    • Thanks 2
  6. OnHitOrCriticallyHit just excludes grazes, that's the difference.  OnDamaged is better, you were right there.  Another problem with OnDamaged would be it applying a lot during rapid damage ticking effects or wall spells, etc. You may want to put "hostile" instead of "default" in the attack filter so it doesn't trigger if you damage or hit yourself.  I don't know if it filters for attack hostility normally, but I don't often filter for hostile attacks so I guess it does check automatically. 

     

    Changing the duration of dazzling lights to infinite was a dumb suggestion from me (as I mentioned before), but the ApplyOnEvent should be infinite.  You are correct that if you wanted different durations you'd have to make new copies of the spells and ideally change their guids to prevent overwrite, and change the names to avoid confusion, but you could always point to different affliction statuses if you want to save the time and work.

  7. I'm glad that you said it worked but doesn't that combat log say that Dazzling Lights started because you hit someone else?  I thought you wanted it to start when you were hit. OnHitOrCriticallyHit is the correct event trigger for that.

     

    Btw, the Trigger section of statuseffects is for altering the status on events.  So if you wanted to adjust the duration OnHit, you could do that.

    And I was wrong to say that the Dazzling Lights should have infinite duration, that was just dumb

  8. 1. Install visual studio code

    2. Configure the settings to recognize .gamedatabundle files as json format as shown on the tutorial

    3. Copy an existing mod - atlas folder is for icons, design folder is for code, localized folder is for names and descriptions for your code

    4. Make the ability in Visual Studio.  The game data sequence is Ability or Item --> Attacks --> StatusEffects.  Those link from one to the other

    5. Before you start, you'll want to open up a browser with one tab for the random guid generator website, one tab for the Obsidian enumeration documentation (Concepts documentation), and one tab on the Fextralife abilities list.  GUIDs are the unique identifiers for a code section, used for linking together and referencing them.

    6. Create a text file for the text strings you're going to make to name and describe the ability, item, statuseffect.  All of these will have names so you'll need to keep a running list of the text string number you give it.  Make it a big number so other people don't choose the same one, then each new number is 1+ the previous number

    7. It's extremely helpful to have a textfile of helpful guids, such as keywords, animation times, class IDs, tick rates, etc.

    8. Copy the exported folder in your game file and look at the copies for reference.  Look at similar abilities and statuses and use those as a base for your new ability.

    9. Create a ring that gives you the ability so you can just use the console command giveitem ring_name and then put the ring on you, and test it faster that way to see if it works.  Visual effects are a pain.  If the game won't load because of spinning gears on the main menu, you screwed up your localization text strings.

    10. Icons are created using the Sprite Sheet Packer in the tutorial.  Just make one big sprite sheet and don't worry about other folders with the same name as your sprite sheet.  It's all loaded.  The icon location is ...../abilities/icon_name.png

    11. Use the Append method in the tutorial to add the ability to the ability tree.  Subclasses use special Conditional code that you have to copy and use.  All of the base code is in the pt_progressiontables file

    12. Your first ability might take 40 hours.  If you keep doing it and make nice text files to help you reference easier, you can make an ability as fast as 30 minutes without testing it.

  9. Pro-Tip:

    +OnMovementEnd sometimes "doesn't work" because it triggers automatically an extra time, immediately when you don't want it to!
        - So if you have it cancel on the 2nd time, via MaxTriggerCount: 2, RemoveEffectAtMax: True, then it works as intended
        - I can't tell when exactly it triggers, but apparently at the end of casting, and at rest. Maybe the beginning of the current action.

     

    E9uZiYD.jpg

  10. the characters.gamedatabundle links to the PT_Serafen table 

    4d20749f-17b8-4ddf-9517-e5396172c99a

    But he has more tables in the progressiontables.gamedatabundle, so you'd have to see how each of these might interact.  Does all of his PT_Serafen abilities exist with other abilities if you choose a multiclass? I don't know.  Are his tables special or do they only have the same abilities as everyone else?  PT_Serafen certainly has different abilities but I'm not sure about the rest of them.  It looks like you'd just have to replace the 

    PT_Serafen_Barbarian

    table but that's from my cursory view.  It would be an easy copy+paste job, I think.  Usually all of the PT tables are independent of each other, so there is a new one for each variant.  Alternatively you could use the append method to add the subclass abilities to his tables but that would be more difficult because subclasses have different versions of abilities already on those tables.

     

×
×
  • Create New...