Jump to content

IDontEvenKnow

Premium Member
  • Posts

    24
  • Joined

  • Last visited

Posts posted by IDontEvenKnow

  1. Oh. Oh. Here's how to fix this:

    • Open the console
    • Select the PA frame
    • run this command: cf setlinkedref none workshopitemkeyword
    Crafting should start working as expected.

     

    Turns out that if you move a PA frame using the workshop system, it'll link the PA frame to that workshop, rather than the nothing it's supposed to be linked to. This can be caused by something like Movable Power Armor, but there are probably other mods out there that'll do it.

     

    Anyway, if the PA frame is linked to a workshop, the crafting system will look for resources from that workshop, rather than from the PA station/local workshop that it's supposed to. Most of the time you won't notice, but if you end up accidentally linking it to a workshop outside of your supply line network, crafting will appear to be broken. Manually clearing the link with the console command I wrote above will fix the frame, until you move it again anyway.

  2. If you're referring to the vanilla/Nuka World ammo types, .308 Winchester and 7.62x39mm aren't at all related, realistically.

     

    The easiest way to accomplish this would probably be to write a script that converts the ammo in your inventory instead, i.e.

    int diff = (PlayerRef.GetItemCount(Ammo308Caliber) - PlayerRef.GetItemCount(Ammo762)) / 2
    if (diff > 0)
    	PlayerRef.RemoveItem(Ammo308Caliber, diff)
    	PlayerRef.AddItem(Ammo762, diff)
    else
    	diff = -diff
    	PlayerRef.RemoveItem(Ammo762, diff)
    	PlayerRef.AddItem(Ammo308Caliber, diff)
    endif
    to just average the amount of both you're carrying out, which would work fine until you get very low on the ammo anyway.

     

    If you really want to go down the complicated route, take a look at https://forums.nexusmods.com/index.php?/topic/8844713-attatch-omod-to-equipped-weapon/&do=findComment&comment=83497518

    and maybe https://www.nexusmods.com/fallout4/mods/24225/?

    The first of which is relatively straightforward to reverse engineer and/or tweak, and shows a basic method of attaching arbitrary mods to the currently equipped weapon.

    The second is a more fully-fledged (and many times more complex) implementation that changes the mods of equipped weapons based on their keywords/base ammo type, usually automatically, triggered by animation events. Most of the relevant code is in idek:gac:WeaponControlScript, and you can find examples of most of the sort of things you'd need somewhere in there if you want to dig.

  3. You'll probably want Subject GetPlayerTeammate, otherwise you're checking if the player is their own teammate and the RefCollectionAlias probably won't fill with anything.

     

    Do note that the Story Manager only auto-fills aliases when the quest first starts up, so you'll probably have to periodically stop and restart the quest to update the actors in the RefCollectionAlias. Note that this will reset any script data attached to the quest and any aliases, so if there's any state-sensitive data anywhere in you're script, you'll need separate "controller" and "finder" quests, and AddRefCollection the data in the finder quest over to the controller quest or whatever.

    Or, if you already have an external reference, you can always manually AddRef() to your RefCollectionAlias as necessary.

  4. Not possible, the Syringer and Junk Jet both use hard-coded, non-extensible special handling at the engine level. See the AmmoSyringer_DO, KeywordSyringer_DO and ObjectTypeSyringerAmmo_DO Default Objects, as well as AmmoJunkJet_DO, KeywordJunkJet_DO and NotJunkJetAmmo_DO.

     

    You could certainly make something share the Syringer ammo types, and add additional Syringer ammo if you wanted to, just look at the forms hooked up to the DFOBs and make sure you have the appropriate keywords on the new weapon/ammo.

     

    If you wanted a totally separate set of ammo from the default Syringer, it may very well be possible to set up a different set of keywords, and use F4SE to fiddle with the DFOBs, like via OnEquipped on a script attached to the weapon or something:

    https://www.creationkit.com/fallout4/index.php?title=DefaultObject_Script

    Just make sure to set the Default Objects back to their original forms when you're done, otherwise you'll break the Syringer.

  5. I made a pseudo-copy of the function a few years ago for this mod: https://www.nexusmods.com/fallout4/mods/28945
    It was a pain. Here's the Papyrus bit:

     

    Function StoreJunk()
    	ObjectReference storage = StorageContainer.GetReference()
    	if (storage != None)
    		ObjectReference tempContainer = storage.PlaceAtMe(ILS_TempContainer, 1, false, false, true)
    		int iterations = Math.Ceiling(PlayerRef.GetItemCount(ILS_ComponentList) / 65535)
    		int i = 0 
    		while (i < iterations)
    			PlayerRef.RemoveItem(ILS_ComponentList, 65535, true, tempContainer)
    			i += 1
    		endwhile
    		tempContainer.RemoveItem(ILS_QuestItemBlacklist, -1, true, PlayerRef)
    		i = 0
    		while (i < iterations)
    			tempContainer.RemoveItem(ILS_ComponentList, 65535, true, storage)
    			i += 1
    		endwhile
    		tempContainer.Delete()
    	endif
    EndFunction

     

    Annoyingly, there are a number of quest items registered with components, and there isn't any way to differentiate quest items (i.e. things that couldn't normally be removed from your inventory) from any other scrap, so the best I could come up with was to manually maintain a FormList of those and just transfer them back to the player if they get taken.

    I never managed to get the "real" button to work. I believe the way it works is that activating a container directly from the "special" TRANSFER UI button—provided by containers with WorkshopKeyword (defined by the Workshop Default Object in the CK), or a workbech/crafting station linked to one such container via WorkshopItemKeyword (defined by the WorkshopItem DFOB etc)—sets some state that watches for the extra button press event or whatever, and somehow links the UI button up to that; and also passes some extra data into the ContainerMenu Scaleform object that sets uiMode to 6 (CM_WORKBENCH), which enables the "native" button in the UI: https://i.imgur.com/7jlly14.png
    And you can change this so it will show up in other containers, but that only changes the UI. it doesn't actually make the button work. https://i.imgur.com/f6tR5qS.jpg

    I think the only way you could get this to work is by being really good at reverse engineering, and then use that to create an F4SE plugin that allows you to open containers in "workbench" mode. I don't think it's possible to "trick" it to work with other containers without completely breaking the workshop system (changing the Default Object).

  6. With that sort of structure, the easiest thing is probably just to let a very short timer expiration handle it:

    ScriptName MyFirstScript extends Quest
    
    Actor Property PlayerRef Auto
    FormList Property ArmorList Auto
    
    Form[] ArmorForms
    
    Event OnInit()
    	ArmorForms = New Form[0]
    	RegisterForRemoteEvent(PlayerRef, "OnItemUnequipped")
    	PlayerRef.UnequipAll()
    	UnregisterForRemoteEvent(PlayerRef, "OnItemUnequipped")
    EndEvent
    
    Event Actor.OnItemUnequipped(Actor akSender, Form akBaseObject, ObjectReference akReference)
    	if (akBaseObject is Armor)
    		ArmorForms[ArmorCount] = akBaseObject
    		StartTimer(0.1)
    	else
    		RETURN
    	endif
    EndEvent
    
    Event OnTimer(int aiTimerID)
    	; nothing has restarted the timer in the last 0.1 seconds, so unequips are probably finished
    	
    	int i = ArmorForms.Length
    	while (i >= 0)
    		; do something with ArmorForms[i]
    		i -= 1
    	endwhile
    	
    	ArmorForms.Clear()
    EndEvent
    I do this sort of thing in a few places when I'm waiting for repeated events to stop, e.g. in the event handler for RegisterForAnimationEvent(PlayerRef, "WeaponFire"), so I can wait until a burst from something like a Gatling Laser is finished before I try running some longer code.
  7. As far as I know, it just isn't possible. Two masters is max, which allows for, at most, Fallout4 + the developer's .esp to merge into Fallout4.esm; or FO4 + 1 DLC + the developer's .esp to merge into the DLC. Bethesda never bothered to expand the version control system to support more than that because they just never had a need for it, I guess.

    IIRC the error only shows up when you go to "commit" the changes, so you might never have seen it.

    I did write an xEdit script that sort of works as a replacement:
    https://gist.github.com/EyeDeck/9cc4a65c5156870dba2a3f60efd64547

    The intended usage is to have a master (master count for that master is irrelevant), and a "dev" plugin for that master. Do whatever work you want with the dev plugin "actively" loaded in the CK, then run that xEdit script on your dev plugin when you want to commit those changes (because it's xEdit you can also review and/or tweak them first, which is handy), choose which master you want to merge into, and hit Ok. It'll copy all the changes you've made into the master (including renumbering and merging new records), and delete them from the plugin.

    Note that it does not work with NavMeshes (I don't even know what happens if you do try to run it on a plugin with navmesh data). For that you'd have to have someone load the master up in the CK and do the navmesh edits on it directly. It also doesn't work with ESL-flagged dev plugins so don't try, and there may still be unknown bugs, but it's worked well enough for me when I've used it.

  8. Disabled objects still fire OnLoad script events, worth testing yourself tho. With the frame rate drop around greentech which is map 0,0,0 that has a tonne of junk underground I infer it does have an impact so move disabled crap to specific holding cells I create.

    One time I accidentally made a save just as the 0,0,0 cell loaded, and happened to look at it in FallrimTools later. Over 400 active OnLoad scripts...

  9. Oh, I made a mod that does exactly that a few weeks ago. Mostly as a basic demo, but it does work.

    https://drive.google.com/file/d/1Ol9pAUNKYhEWkWig_bsyIxKY8yhZ9jIm/view?usp=sharing

    Source is in the .ba2.

    In that version, compatibility for new weapons is achieved by adding additional entries to the WeaponOverrides array, which should be fairly self-explanatory. It has "pseudo-compatibility" for the vanilla Assault Rifle, and 10mm pistols as examples, but the intention is to replace those entries entirely with the "semi-auto"/"full auto" OMODs that lots of weapon mods tend to provide.

     

    If you uncomment lines 81-87 in idek:mst:FireModeController and recompile, it will also swap between two "generic" auto/semi-auto mods for any weapon type that's not in the WeaponOverrides array, and that does work on absolutely any weapon. It isn't guaranteed to work properly, though, since it doesn't affect base fire rates and so on. (edit: oh, you'll have to tweak the MST_FireModeSemi/MST_FireModeAuto OMODs too, at one point I removed the property that sets bIsAutomatic from them)

     

    There's also some commented-out code that mostly works that's based off of ObjectReference.AttachMod(), instead of ObjectReference.AttachModToInventoryItem() that the "active" code is based off of. Some of it might be of interest to you if you want to experiment.

     

    If you wanted to add "soft" compatibility to nearly any number of mods, you'd unflag WeaponOverrides as Const, and write some additional code to do a bunch of Game.IsPluginloaded() checks, followed by grabbing the appropriate forms via Game.GetFormFromFile(), inserting them into new WeaponOverride struct instances, and adding the new structs to WeaponOverrides, all at runtime.

     

    Feel free to do whatever you want with it by the way, I never intended to release it anyway. It's a good base to start from if you want to polish it up into a fully-featured mod.

  10. Using all DLCs as masters would indeed cause trouble here, iirc the version control system simply does not work if a file has more than...two masters I think is the limit. It should give you a warning telling you you're doing it wrong and multiple masters aren't implemented "yet" because we're not making DLC yet, or something to that effect.

     

    Other than that, the version control system does work if you set it up precisely as described in the CK wiki tutorial. It can certainly slow your workflow down quite a bit though, since you have to deal with checking records in/out all the time.

  11. Totally didn't mean to find this thread, but for anyone who still cares:
    • If I recall correctly, that's Sclerocephalus, from the UFO4P team.
    • No, he isn't why your game crashed, he was just the last person to compile some script that threw an error (most likely in original Bethesda code), that coincidentally happened prior to your crash.
    • The Papyrus log does not contain information relevant to game stability—unless you're seeing loads of stack dumps, in which case general script overload might have caused your crash, maybe.
    • You should thank him, because he's put a ton of work into patching up this broken game.
  12. Oh, that'll be because you've got "Hide no conflict and empty rows" checked. You can find the option in the context menu if you right click anywhere in the right pane. That option is really handy for conflict resolution, but not as much for mod development.

     

    The CK is definitely a necessity for serious development, though, so no harm in picking it up. Learning to use its clunky and painfully slow interfaces takes time though, it's an absolute behemoth of a tool.

  13. You just have to right click on the empty section next to the APPR subrecord and click Add, then you can edit it as you like. The subrecord doesn't exist in the record until you do that, so you can't edit it.

     

    xEdit also has a really handy feature where you can ctrl+click multiple similar records and click+drag subrecords between them, like so

    wfwcxh3.png

    It makes doing stuff like what you're trying a lot easier, especially if you need to update or edit similar data in many records at a time.

  14. Eureka!

     

    So, the PA furniture exit animations are ExitToStand.hkx, ExitToStandCombat.hkx, and QuickExitToStand.hkx. I had the idea to look closely at the existing idle animations, and it occurred to me that only the first two of those animations are ever actually played, because the condition functions on the idle animation record for QuickExitToStand.hkx are set to be impossible to fulfill for Power Armor. Since it's never used anyway, I can co-opt it for my own purposes by reconfiguring the condition functions like so, and then replacing the vanilla animation with your custom, 2-frame variant.

     

    By doing this, it provides me a way to force the player to reenter their power armor in just a few frames, which is an acceptable workaround for the ugly visual bug that had been plaguing me. It took me three weeks to find this.

     

    The visual bug in question makes an appearance around 2:20, so it's not 100% fixed, but without this workaround you always get the bug, and to me it just looks absolutely awful.

     

    Unfortunately this does mean that only one mod in a given load order can exploit this particular quirk without a manual patch, but I'd be surprised if there are any other mods that make use of it anyway.

    Actually I realized that this is a perfect use case for record injection, see the spoiler.

     

    Also, here's a more detailed description, which I wrote as a PM, but I'm putting up publicly for anyone else who stumbles across this thread:

     

    Here's the whole script I'm using to do it: https://idek.chir.uno/fo4/AdjustableHeadlampScript.psc

    Look in UpdateHeadlamp().

    (That GetFormFromFile() is there just as a temporary alternative to a property, it's faster to do that and just reloadscript "idek:ipa:AdjustableHeadlampScript" than to have to tweak the plugin file when I'm trying different things--that and the HotLoadPlugin (hlp) commands are a massive time-saver if you don't know about them already)

     

    Here are the important parts trimmed out and annotated:

    float t
    ObjectReference c
     
    ; add keyword and force player out of armor
    wearer.AddKeyword(FastPowerArmorExitAnimation)
     
    ; seems like the animation condition functions take a moment to update,
    ; I find it fails sometimes without a delay at least this long
    Utility.Wait(0.1)
     
    ; kick the player out of their armor
    wearer.SwitchToPowerArmor(None)
     
    t = Utility.GetCurrentRealTime()
     
    ; get the player\'s armor furniture object
    int i = 0
    while (i < 10)
        c = self.GetContainer()
        Util.Trace(self + " in container " + c)
        if (c == wearer)
            Utility.Wait(0.05)
            i += 1
        else
            i = 100
        endif
    endwhile
    ; The wiki mentions that you could do this instead:
    ; c = wearer.GetLinkedRef(LinkPowerArmorKeyword)
    ; SwitchToPowerArmor(None) will silently fail if there isn\'t some clear space directly behind the player,
    ; though, so you\'d need some different method of error checking
     
    ; wait at least 0.2s since we last recorded the time
    Utility.Wait(Math.Min(0.2, Math.Max(0, t + 0.2 - Utility.GetCurrentRealTime())))
     
    ; remove the quick eject keyword and return to the PA
    wearer.ResetKeyword(FastPowerArmorExitAnimation)
    wearer.SwitchToPowerArmor(c)
     
    ; If the quick-eject thing didn\'t work right, we\'ll be sitting through the full 3.5s animation right now:
    ; the furniture object appears as soon as SwitchToPowerArmor(None) does anything, so we can\'t be
    ; 100% sure that we\'re fully out of the armor and finished with the animation right now.
    ; this bit checks for that and keeps trying to shove us back into the PA for up to 5s
    Utility.Wait(0.1)
    int i = 0
    while (i < 10)
        c = self.GetContainer()
        if (c != wearer)
            ; Util.Trace(self + " ...reequip failed--wrong animation? Waiting a moment and retrying...")
            Utility.Wait(0.5)
            
            wearer.SwitchToPowerArmor(c)
            i += 1
        else
            i = 100
        endif
    endwhile
    The way I'm doing it for the headlamp thing requires that I attach this script to each helmet base object, which I would avoid if I could but it's the best way to do it in this case. Forcing the reequip with an "external" script like a RefAlias or Quest is certainly possible, but requires the script to be written a little differently to work.

     

    To allow for an arbitrary number of mods to exploit this system without conflicting, I strongly recommend utilizing record injection, so we can share a common keyword, and edit to the idle animation record.

     

    The easiest way to do this is to grab this pseudo-mod: https://idek.chir.uno/fo4/CommonFastExitInjection.esp (also attached to this post)

    Then Copy as Override... both of the records from that plugin into your own plugin. This will give you the FastPowerArmorExitAnimation keyword to use in your script, and set up the edit to FurnitureNoMirrorExitToStandCombat properly.

     

    To do the same thing from scratch, in xEdit, you'll want to make a new keyword, and give it the FormID of 006D6DD5 (chosen arbitrarily by RNG). I recommend naming it FastPowerArmorExitAnimation.

    Then, make an override for the FurnitureNoMirrorExitToStandCombat idle animation record, and set it up like this.

     

    Next you override the unused vanilla animation at Meshes\Actors\Character\Animations\Furniture\PowerArmor\Neutral\QuickExitToStand.hkx

    with langnao's cut-down 2-frame animation.

    Then, as long as the player has our injected keyword, they'll use the near-instant exit animation, and that code snippet above will work to cycle the player out of and back into the PA frame in about 0.3s or so.

     

    Note that I do not recommend leaving this keyword on the player longer than you have to, because it could potentially interfere with unrelated animations without a much more complicated set of condition functions on the idle animation record. If you want a more general, longer-term animation replacer, the cleanest way to implement it is with animation subgraphs, which I explored earlier in the thread.

     

     

    Edit: The mod this was for been released here: https://www.nexusmods.com/fallout4/mods/45572

  15. It seems that the PA frame is very resistant to reloading subgraphs, at least with regards to the exit animation. I tried getting into the PA frame, adding a keyword that should switch subgraphs, calling AttemptAnimationSetSwitch(), then opening/closing the pip-boy menu (well, sort of, since the PA interface is different), drawing and holstering a weapon, then fast travelling, but even then the subgraph that was active when I entered the PA frame is still used. At the moment I have two different subgraphs, where one has my conditional keyword on the actor, and another where it's on the target, and I tried the same process by tweaking either the furniture's keywords, or the actor's keywords, but that turns out to make no difference. Saving and then reloading works, but is obviously not a viable solution.

     

    Bah, there has to be some solution that will work, right? The struggle continues.

     

    Perhaps there's some unused animation the FurnitureNoMirrorBehavior graph points to that I can "inject" into the Meshes\Actors\Character\Animations\Furniture\PowerArmor\Neutral path, then set up a condition to use that animation in the Idle Animations menu, rather than fuss around with subgraphs. The game is much snappier about selecting from animations within a subgraph than it is switching subgraphs. I doubt this idea is viable, though.

  16. Sure, I might as well, thanks. My intended use case always involves immediately shoving the player back into the PA frame, but I was still concerned that my 0 duration hack might screw up the animation graph state (or something) somehow, and it can't hurt to nip a future problem in the bud. All of my released mods are open sourced, so maybe someone else might want to rip the asset for some other purpose in the future.

     

    Now I face a new problem, which is that the game doesn't like to reevaluate which animation set it ought to be using very often. In practice, the animation set used on exiting PA tends to be equal to whatever set of keywords the player had when entering the PA, which I suppose means that getting into PA probably immediately forces the game to reevaluate which subgraph to use. AttemptAnimationSetSwitch() doesn't help, as far as I can tell. If only I could see into the future...

     

    Well, at least it's progress, and I get to fight something slightly different for a while. Hmm...

  17. Yep, your implementation works as intended. Thanks for that, really.

     

    I've noticed that:

    • The CK will look into archives during the GenerateAnimInfo process, so if there is already existing AnimTextData in a .ba2, the CK will not attempt to regenerate it, even if it needs to
    • Related to the above, it the CK also tends not to regenerate AnimTextData if loose files already exist. If you keep your mods cleanly separated with MO2 like I do, just nuking the entire folder works. If you've got any mods installed directly to your Data folder that aren't packed into archives, this would become much more difficult.

     

    Also, I figured out what I was doing wrong, turns out I am a f*#@ing idiot. There was a subtle typo in a file path that took me a solid three days to discover.

    Actors\Character\Behavoirs\FurnitureNoMirrorBehavior.hkx

     

    9equaNV.jpg

     

    I'm sure I looked at that typo a hundred times and never noticed it. Here's an implementation of the earlier test mod that works properly after fixing the typo and regenerating AnimTextData.

     

    At least someone might find something else in my post useful some day.

  18. I swear I have never met another more frustrating issue while modding a Bethesda game.

    So, I had the idea to add in dimmable headlamps for Power Armor helmets. Not too hard of a problem: add a new craftable OMOD for each helmet, then write a bunch of Papyrus that will swap that headlamp with other OMODs of varying brightness levels when an aid item/hotkey is used.

    Straightforward enough, until I found that there's an engine bug where the game only properly loads the first headlamp spotlight you equip after entering a suit of Power Armor. All headlamps lights after the first one don't load the gobo (the texture the light filters through to project an image), and the color of the light is not loaded properly either (it'll be tinted purple for some reason).

    Simple reproduction steps to see this bug in a vanilla game:

     

    • Get two PA helmets
    • Mod one helmet with the Vault Boy headlamp, and the other helmet with Bright or something
    • Put the Bright headlamp helmet on the PA frame, then get in it
    • Turn on the headlamp
    • Open your inventory and equip the Vault Boy headlamp helmet
    • Close your inventory and turn on the headlamp
      You'll notice that the really annoying vault boy overlay (bogo) is missing, and the light is sort of blue-greenish.
      And in reverse:
    • Exit and then re-enter the PA frame
    • Turn on the headlamp: notice that the Vault Boy gobo will have loaded this time, and the color is correct
    • Equip the other helmet and then turn it on
      This time the Bright headlamp will be missing its gobo (some concentric rings, to simulate an imperfect spotlight reflector/lens assembly), and the color will be distinctly purple instead of yellow.

    There's a thread here where the author eventually diagnoses this issue as the gobo loading improperly, and notes that it doesn't happen if the light is not set to use a gobo, but it seems that this is not true for headlamps.



    Anyway, not totally insurmountable: forcing an exit/reentry of the PA frame will reload the light and make it display properly. Here is where the real problem starts.

    Turns out that getting the player out and back into their PA quickly is almost possible, but every avenue I've tried has been a dead end:

    • The first thing I tried was to simply wearer.SwitchToPowerArmor(None), wearer.SwitchToPowerArmor(PAFrame).
      (Skimming over the boring bits, like finding the PA frame furniture object--also, wearer is my local variable for the actor currently wearing the helmet with an adjustable headlamp)
      So, just kick the player out of their frame, then immediately force them back into it. Was a decent idea, but the second SwitchToPowerArmor() call won't work while the player is playing the exit animation, which is like 3.5 seconds. Adding a wait works, but feels absolutely horrible, because switching from the lowest to highest lamp setting takes up to 15 seconds of watching that damn animation.
    • Next I thought to do wearer.SwitchToPowerArmor(None), wearer.MoveTo(wearer), wearer.SwitchToPowerArmor(PAFrame).
      The first time I tried this it worked fine, the wearer.MoveTo(wearer) call would cancel the exit animation, allowing us to complete the whole cycle in just a few frames. A little clunky, but it works...or, it did, until I relaunched the game. After that, moving the player to themselves now always triggers a loading screen. I have no idea why this started, but I cannot get this method to work anymore, even in an unmodded game. I also tried placing something at the player's feet and then MoveTo()ing them to that, or MoveTo()ing to the PA frame, but these also trigger loading screens. I also tried fiddling with the fMinPlayerMoveToDistForLoadScreen ini setting, but it seems to do nothing.

      I have no explanation for why this worked in the first place. Moving on...
    • Next I attempted to find some way to cancel an ongoing animation, like playing a different idle with a script, and trying every Papyrus function I could think of that might also interrupt animations. No dice here, nothing seems to be able to do this except for MoveTo().
    • Right, so, maybe there's some way to artificially unequip a PA frame without SwitchToPowerArmor(None)? Maybe...wearer.UnequipAll()? Uh, no, oh god no, now my player character requires an SCP designation. Moving on...
    • Okay, so what if I make the animation shorter? Easy enough, I just have to find the animation files (in Meshes\Actors\Character\Animations\Furniture\PowerArmor\Neutral: ExitToStand.hkx, ExitToStandCombat.hkx, and QuickExitToStand.hkx), unpack them, hack the duration value to 0, repack and replace. Hacky, but works great as a proof of concept: moving the player out of and then back into their PA is back to only taking a few frames, which is kludgy, but workable.

      But, obviously, this creates a new problem: since this is an animation replacer, the PA exit animation is always instant. Not a good side-effect.

      Moving on...
    • After a little research, it's pretty simple to conditionally use different sets of animations, based on actor keywords, by setting up an animation subgraph. Perfect! Right?
      The process doesn't seem too difficult: in this case, all I (apparently) need to do is:
      • Make a new keyword
      • Duplicate HumanRaceSubGraphData
      • Set it to be Additive to HumanRaceSubGraphData
      • Make a (near) duplicate of the already-existing subgraph entry for Meshes\Actors\Character\Behavoirs\FurnitureNoMirrorBehavior.hkx with a target keyword of FurnitureTypePowerArmor, with some slight modifications: add my new keyword into the Actor Keywords filter, and add a new path pointing to where I've put my custom ExitToStand.hkx/etc animations--like so [image]
      • Confirm that the entry does, in fact, add (the UI is dodgy)
      • Save
      • Run the CK with these arguments to build anim text data:
        CreationKit.exe -GenerateAnimInfo:IDEK_ExitAnimTest.esp .\Data .\Data
      According to the information I've found about this process, this should be all I have to do. Now, if I just add my keyword to an actor with a script, they'll use my instant exit animations, and I can turn the animation set back to vanilla by removing the keyword again.

      Unfortunately, though, this doesn't seem to work, at all. Instead of using a different animation set, this prevents the actor from playing any PA furniture-related animations. If the player character is already in a suit of PA, attempting to exit shows the message You can't exit your armor here. Attempting to get into a PA frame shows You cannot use this at this time. Removing the keyword for the new subgraph returns things to normal.

      Thinking that this might be because of my crappy hacked animations, I tried setting the animation paths up as an exact duplicate of the vanilla one, except with my actor keyword, and rebuilt anim text data again. Theoretically, then, actors with my keyword should use my new subgraph, but they'll use the exact same animation set as the vanilla subgraph. Same issue. Removing my additive subgraph Race record and moving the (still near-duplicate) subgraph entry as a direct edit into HumanRaceSubGraphData also does not work. #!@%!#?!

    So, here's where I'm at. I cannot find an adequate solution to any of these problems:

    • Lights and their gobos not loading properly
    • Reloading an incorrectly loaded spotlight without restarting the game, or exiting and reentering the PA frame
    • Removing an actor from their Power Armor without having to watch the exit animation
    • Cancelling or interrupting a PA exit animation
    • Conditionally replacing the PA exit animations

    Since the last one is the most complicated, but also the most promising, I made a little test mod here in case anyone would be willing to experiment with it. It adds an additive subgraph that's active when an actor has a particular keyword, which can be toggled by the Aid item that the mod also adds to your inventory on install. Theoretically, using the item should allow you to instantly exit a PA frame. Using the item again should restore the normal animation. In practice, using the item prevents PA animations from working at all.

    Hopefully someone with more knowledge on how subgraphs work can educate me on what I'm doing wrong.
    Or, if anyone can think of a solution to any of the other problems I just listed, any one of those would work too, and I would be greatly appreciative.

    If nothing else, maybe future generations will find this post and save themselves the bother of attempting such an undertaking.

    Thanks for reading my dissertation about an exercise in frustration.

  19. Given that there are zero non-vestigial uses of that event in any official script, and that all of the game holotapes have an associated default object (form IDs 249e80--249e84), it looks like Bethesda gave up on getting that event to work--or, at least, gave up on trying to use it--and hard-coded everything into the executable instead.

     

    Have you tried experimenting with the abandoned turret hack holotape (TurretHack_Holotape "turret_override.exe" [NOTE:00106E96]) yet? The flash file that that uses probably still sends that event.

     

    I've been around Bethesda games long enough to have a pretty good guess what likely happened, and why that event was abandoned:

    1. The event was initially set up to be received by the terminal ref that the tape was being played on. This presents an issue, however, because they would have needed to put a script to listen for this event on every terminal in the game that has a holotape drive, which would get annoying fast.
    2. Bethesda further tried to work around this by allowing the OnHolotapeChatter event to be received by reference aliases as well. It would probably be workable to set up a quest, with some minor abuse of the story manager, to find any terminals nearby the player and just force them into a reference alias, and listen on that instead.
    3. This probably didn't work terribly reliably in case e.g. there were multiple terminals near the player, or perhaps it was too annoying to try to manage a number of separate reference aliases, so OnHolotapeChatter was made to work with reference collection aliases as well. It would trivial to find any terminals nearby the player and force them into a RefCollectionAlias, and at that point you only need to worry about one "array" of object references and one script instance handling all of them. So far so good.
    4. ...until Bethesda realized that this system had to work when the holotape was played on the pip-boy as well. This presents an issue because there is no terminal reference for the pip-boy, so the chatter from the flash file would just be would be getting sent into the void. Bethesda tried to fix this by also allowing ActiveMagicEffect objects to receive OnHolotapeChatter, and then probably made a hidden perk or whatever that applied a magic effect to the player with a script that would listen for the event, but this didn't work at all, so they gave up and had some C++ dev do it instead.

    Of course this mostly speculation, but it's also exactly the sort of thing I'd expect to happen around Bethesda devs.

×
×
  • Create New...