Jump to content

[FO4 CK] General Help Thread


Recommended Posts

8 hours ago, JB. said:

OK, I have a timer that kills you in x hours until you get something. Is there a way I can tell the player how many hours they have left? 

 

In addition to the other suggestions, I think you can interpolate into topicinfos as well, so if it makes sense in your scenario there could be a follower or similar NPC to ask for updates or who blurts them in idle topics.

 

Edit: Scratch that. Topicinfos can't have dynamic lines because that would make their corresponding voice files impossible. Dunno what I was thinking of there... ?

Edited by vaultbait
Link to comment
1 hour ago, JB. said:

Yeah, I was thinking about notifications or a button on the MCM. In fact, right now, when I activate the collar, you get a message box telling you how much time you have for the chore to be done.  My problem is how to get the remaining time.

 

Let's say you have 48 hours. And the next day you'll want to know how much time you have left before the collar kills you.  There is no "GetTimerTimeRemaining" type function or whatever it can be called. Or is there? 

 

I can see the remaining time in the papyrus log if I type "dpt". 

 

Maybe there's a simpler way, but I'd just store either the start time or the expected end time in a variable and then do the math to calculate the time remaining.

 

I agree, at least the Papyrus docs don't seem to mention any way to inspect the timer, only (re)set or cancel, or catch the end event for it.

Link to comment
4 hours ago, vaultbait said:

Maybe there's a simpler way, but I'd just store either the start time or the expected end time in a variable and then do the math to calculate the time remaining.

 

Yeah. You can use Utility.GetCurrentGameTime to get the time (in days) since game start, store that, and then subtract it from the current time at each notification. Use a combo of modulus and integer division to break the time down into HH:MM:SS

 

Or, alternatively, if you want 48 hours, set a property to 48, and then set ScriptObject.OnTimerGameTime to trigger in one hour, game time. Each time the timer expires, decrement the count and use that as "hours remaining". Although that doesn't always take proper account of sleeping and fast travel so you might still want to do the maths.

Link to comment

Oh Havok, bane of my existence... so I have an activator which uses a customized mesh based on the "plastic pumpkin" moveable static (because there's no equivalent plain static for that). Since I'm customizing the mesh anyway, I'd like to make it properly static so I don't need to force disable Havok physics on it via an OnLoad script (which gets fiddly and doesn't always seem to stick properly anyway).

 

I'd read that I could delete the bhkPhysicsSystem blob from the mesh with Nifskope, but when I tried that the mesh just CTDs the game instantly when I enter the cell. What am I missing? Is there another better/easier solution?

 

Edit: I seem to have figured it out. For the benefit of anyone else trying to do this who finds my post (including future me, when the brain cells where this memory resides succumb to my rampant alcohol abuse), the quick solution is to load a motion keyframed mesh (the ones used by any of the "static" world objects) in Nifskope, right-click its bhkPhysicsSystem block and choose copy. Then load the offending physics ("moveable static") mesh in Nifskope, right-click its bhkPhysicsSystem block and choose to paste over it. Save the altered mesh, and it loads in game for me successfully now but doesn't move around any more.

Edited by vaultbait
Link to comment
  • 2 weeks later...
On 8/26/2022 at 11:08 AM, vaultbait said:

So I need to track future objective completion externally to the objectives themselves, and orchestrate "completing" them as soon as they're displayed if I want their completion indicated and tracked in the Pip-Boy's quest log/journal. The CK doesn't have the capability of doing that built in.

 

After rather a lot of coding and debugging, I got this implemented...

 

Like a lot of mods, this one has a "Main" (control) quest which I use for things like pulse loops to handle effect refreshes and decaying scores, etc. I defined a struct in it which is just a pair of ints for QuestID and Objective, and then gave the Main quest a property which is an auto array of that struct, and initialized it to an empty array on quest start. I have a wrapper function which I use whenever I want to complete an objective for a running quest, and if that objective is not displayed yet then I serialize the lower 3 bytes of the quest's FormID (LogicalAnd it against a mask so I can GetFormFromFile later in case the mod's index changes at some point in that playthrough), and store that along with the objective into a new element of the deferrals array on the Main quest. Now, any time I complete an objective or change a quest stage, the wrapper functions I use for those things check the deferrals array to see if any deferred objectives can be completed and then completes them if so.

 

The remaining piece of this puzzle was that placed items which are used as refaliases for story quests might get taken before their quests start, and since I complete their objectives with scripts attached to those aliases, there's no event to trigger recording deferred completion of their objectives because the aliases to them don't exist yet at that point. The workaround I settled on was to make the aliases for items which can be taken optional, and then at quest start iterate through them in a fragment on the first stage checking to see whether their corresponding references don't exist or are contained somewhere (as they might be in the player's inventory, deposited in something, or perhaps sold). Basically, if the script is unable to fill their alias or if their alias isn't still sitting out where the player can find and take it, then record those objectives completed (possibly deferred as well in case they're for later quest stages).

 

Examples:

 

1. The player wakes up as a captive in a cave, and a story quest begins. They're hungry and thirsty so they need to find sustenance as initial objectives, but in stumbling about they bumble into a radioactive part of the cave and through a trigger box which would normally complete a later objective (looking around for a way out). Clearly the player can see an exit beyond the deadly radiation, they just can't get to it. After they've gotten some food and a drink, the quest advances to the stage where it tells them to look for a way out, but clearly they already know where that is. Instead of the usual tactic of making the trigger box start disabled and then enabling it in a quest stage fragment, such that the player would be directed to revisit the radiation they already know they can't get past, the objective is just automatically completed and the quest advances to the next stage where they're tasked with finding a way to survive the radiation.

 

2. Player reads a note left by a now deceased NPC. Later a quest starts and one of its eventual objectives is to read that note. Since the note is not where it was placed in the cell, the quest concludes the player has already found it and records that its future objective should get automatically completed. Once the player completes some objectives (talking to other captives who mention the dead character and the note next to them), the quest advances to the stage where the player needs the information in that note, but as they've already found it the objective gets completed for them straight away. This avoids the "hey where did that note suddenly come from" effect of having the quest enable a previously disabled object or place a new ref on a marker in a space where the player had just been moments before.

Link to comment

I'm new to the CK and need help with getting items from mods be useable as crafting components. Example, I can change noodle cup recipe by adding the vanilla laser gun as component and it will show up under the crafting menu in the cooking station as razor grain + dirty water + laser gun but a weapon from a mod won't show up only can get razor grain + dirty water. What do I need to add to the mod item to make it appear as crafting components? Thanks.

Link to comment
7 minutes ago, Bing9889 said:

I'm new to the CK and need help with getting items from mods be useable as crafting components. Example, I can change noodle cup recipe by adding the vanilla laser gun as component and it will show up under the crafting menu in the cooking station as razor grain + dirty water + laser gun but a weapon from a mod won't show up only can get razor grain + dirty water. What do I need to add to the mod item to make it appear as crafting components? Thanks.

 

Doing it that way, you'd need the mod plugin which provides that component to be a "master" of your plugin. Unfortunately, the CK as released by Bethesda doesn't allow you to have any non-ESM masters in the plugin you edit (and if you add them through other means it will strip them on save), so if the other mod is an ESP you probably need a community patch for the CK. Alternatively, make your mod with FO4Edit instead of the CK.

Link to comment
3 hours ago, vaultbait said:

 

Doing it that way, you'd need the mod plugin which provides that component to be a "master" of your plugin. Unfortunately, the CK as released by Bethesda doesn't allow you to have any non-ESM masters in the plugin you edit (and if you add them through other means it will strip them on save), so if the other mod is an ESP you probably need a community patch for the CK. Alternatively, make your mod with FO4Edit instead of the CK.

Hey thanks for the advice. I managed to make the new recipe in FO4Edit. So under the "soup" tab I now have two noodle bowl recipes, the original and the modded one. I tried to rename the recipe via override but than I get the same problem just with the new name, Laser noodle, Laser noodle. Is there anyway to keep the original name and keep the new name so that I have two recipes noodle bowl and laser noodle? Also, I think you answered it, but is there no other way to make components from mods/non dlc workable with edit outside of a patch? I tried flagging esp mods as esm in FOEdit but the components still won't show up.

Edited by Bing9889
Link to comment
18 hours ago, Bing9889 said:

Hey thanks for the advice. I managed to make the new recipe in FO4Edit. So under the "soup" tab I now have two noodle bowl recipes, the original and the modded one. I tried to rename the recipe via override but than I get the same problem just with the new name, Laser noodle, Laser noodle. Is there anyway to keep the original name and keep the new name so that I have two recipes noodle bowl and laser noodle?

 

If I understand the question, you want to "copy as new record into" rather than "copy as override into" your new plugin.

 

18 hours ago, Bing9889 said:

Also, I think you answered it, but is there no other way to make components from mods/non dlc workable with edit outside of a patch? I tried flagging esp mods as esm in FOEdit but the components still won't show up.

 

Unfortunately just flagging an ESP as ESM isn't sufficient. The CK requires the plugin's file name to end in .esm instead. Also make sure you've configured the CK to allow "multiple masters" (I don't recall the option name in its INI file, but a quick web search should turn it up for you).

 

As for the FO4CK Fixes patch, it addresses a bunch of other usability bugs as well, so if you're going to be using the CK much then you likely want to consider it anyway.

Link to comment

Has anybody had luck coming up with an event-driven means of detecting the player leaving sneak? In classic Bethesda fashion there's Actor.OnEnterSneaking which I can catch just fine, but no corresponding exit event.

 

I've found a few (obscure) examples around which seem to use OnAnimationEvent to catch sneakStateExit or sneakStop, but when I register for those (successfully according to the return from the RegisterForAnimationEvent() call) I never seem to catch anything for those.

 

I know I can just use timers to start a polling loop to check IsSneaking() but that seems... unclean.

Link to comment
7 hours ago, vaultbait said:

Has anybody had luck coming up with an event-driven means of detecting the player leaving sneak? In classic Bethesda fashion there's Actor.OnEnterSneaking which I can catch just fine, but no corresponding exit event.

 

I've found a few (obscure) examples around which seem to use OnAnimationEvent to catch sneakStateExit or sneakStop, but when I register for those (successfully according to the return from the RegisterForAnimationEvent() call) I never seem to catch anything for those.

 

I know I can just use timers to start a polling loop to check IsSneaking() but that seems... unclean.

 

If this is strictly for player only then you could try a combination of

RegisterForControl("Sneak")   [ https://www.creationkit.com/fallout4/index.php?title=RegisterForControl_-_ScriptObject ] and

Event OnControlDown(string control)

    If (control == "Sneak")

        ; handle updating sneak state on player with PlayerRef.IsSneaking()

    EndIf

EndEvent

 

Looked into this and "sneakStateEnter" and "sneakStateExit" do work BUT only when in first person view (WTF).

If you are in first person and sneaking, and switch to third person view, "sneakStateExit" is raised while actor is in fact still sneaking (WTF).

If you are sneaking in third person view and switch to first person, "sneakStateEnter" is raised (WTF).

Registering for events "sneakStart" and "sneakStop" does fuck all.

 

Luckily there's additional animation event "sneakState" which seems to be raised in both perspectives if state changes,

so I was thinking using that signal a handler to update sneak state with actor.IsSneaking call. I did noticed some timing issues with this,

but I'm no sure if it is caused by lag in notification system or something else. But it is the best I got.

 

Maybe you could get some interest from dll framework authors to add OnExitSneaking?

Edited by requiredname65
Link to comment
4 hours ago, requiredname65 said:

Looked into this and "sneakStateEnter" and "sneakStateExit" do work BUT only when in first person view (WTF).

If you are in first person and sneaking, and switch to third person view, "sneakStateExit" is raised while actor is in fact still sneaking (WTF).

If you are sneaking in third person view and switch to first person, "sneakStateEnter" is raised (WTF).

 

Yikes. That explains why I wasn't getting squat, at least. I hardly ever use first person, so was testing entirely in third. Thanks for the deep dive!

 

4 hours ago, requiredname65 said:

Registering for events "sneakStart" and "sneakStop" does fuck all.

 

Yeah, I'm getting the impression that those were used in Skyrim (or maybe earlier) and superseded, so in FO4 they seem to just be unused vestiges.

 

4 hours ago, requiredname65 said:

Luckily there's additional animation event "sneakState" which seems to be raised in both perspectives if state changes,

so I was thinking using that signal a handler to update sneak state with actor.IsSneaking call. I did noticed some timing issues with this,

but I'm no sure if it is caused by lag in notification system or something else. But it is the best I got.

 

Oh, I can make that work. It's still better than starting a timer when sneaking starts and polling repeatedly until the player is no longer sneaking. I can basically hybridize the two approaches and start a (faster) timer loop once that animation event fires in order to deal with any lag. It might still be racy if the player spams the sneak button, but this is really a cosmetic feature anyway to keep activation text overrides on a few NPCs from persisting when the player could pickpocket them in sneak, so if an override does or doesn't switch in rare cases it's probably not the end of the world.

 

4 hours ago, requiredname65 said:

Maybe you could get some interest from dll framework authors to add OnExitSneaking?

 

Good point, I should also ask them for a Papyrus equivalent of the WornCoversBipedSlot condition function while I'm at it.

Link to comment
6 hours ago, vaultbait said:

Oh, I can make that work. It's still better than starting a timer when sneaking starts and polling repeatedly until the player is no longer sneaking. I can basically hybridize the two approaches and start a (faster) timer loop once that animation event fires in order to deal with any lag. It might still be racy if the player spams the sneak button, but this is really a cosmetic feature anyway to keep activation text overrides on a few NPCs from persisting when the player could pickpocket them in sneak, so if an override does or doesn't switch in rare cases it's probably not the end of the world.

 

Thanks to suggestions from @requiredname65, I was able to get a fairly robust implementation which doesn't offend my sense of script efficiency too much (in repeated tests, the polling only seems to kick in under heavy lag from other scripts):

Spoiler
Scriptname Example extends Actor Const
Message Property ActivateText Auto Const

Event OnLoad()
    Actor Player = Game.GetPlayer()
    RegisterForRemoteEvent(Player, "OnEnterSneaking")
    If Player.IsSneaking()
        Debug.Trace("MHK: Player sneaking on load, not overriding activation text on " + Self)
        StartTimer(2.0)
    Else
        Debug.Trace("MHK: Player not sneaking on load, overriding activation text on " + Self)
        SetActivateTextOverride(ActivateText)
    EndIf
EndEvent

Event Actor.OnEnterSneaking(Actor akActor)
    If akActor == Game.GetPlayer()
        Debug.Trace("MHK: Player started sneaking, unsetting activation text on " + Self)
        SetActivateTextOverride(None)
        ; Don't start looking for the state change event right away
        ; since one corresponding to the start may arrive soon after
        ; this point
        StartTimer(2.0, 0)
    EndIf
EndEvent

Event OnTimer(int aiTimerID)
    Actor Player = Game.GetPlayer()
    If Player.IsSneaking()
        If aiTimerID == 0
            ; Now it should have been long enough that any new state
            ; that a new state change is likely sneak stopping
            RegisterForAnimationEvent(Player, "sneakState")
        Else
            StartTimer(0.5, 1)
        EndIf
    Else
        Debug.Trace("MHK: Player stopped sneaking, overriding activation text on " + Self)
        SetActivateTextOverride(ActivateText)
    EndIf
EndEvent

Event OnAnimationEvent(ObjectReference akSource, string asEventName)
    Actor Player = Game.GetPlayer()
    If akSource == Player as ObjectReference && asEventName == "sneakState"
        UnRegisterForAnimationEvent(Player, "sneakState")
        If Player.IsSneaking()
            ; Poll in a tight loop since the state change event may race
            ; actually stopping
            StartTimer(0.5, 1)
            Debug.Trace("MHK: Got sneakState event for sneaking player, starting to poll")
        Else
            Debug.Trace("MHK: Player stopped sneaking, overriding activation text on " + Self)
            SetActivateTextOverride(ActivateText)
        EndIf
    EndIf
EndEvent

Event OnUnload()
    CancelTimer(0)
    CancelTimer(1)
    Actor Player = Game.GetPlayer()
    UnRegisterForAnimationEvent(Player, "sneakState")
    UnRegisterForRemoteEvent(Player, "OnEnterSneaking")
EndEvent

 

 

Edited by vaultbait
Link to comment
21 hours ago, vaultbait said:

Thanks to suggestions from @requiredname65, I was able to get a fairly robust implementation which doesn't offend my sense of script efficiency too much (in repeated tests, the polling only seems to kick in under heavy lag from other scripts):

 

I haven't read all the way back to the beginning so I might be way off base here, but couldn't you accomplish this with a perk on the player?  In the bondage mod I'm working on I have a perk that replaces activation on actors to prevent the player from pickpocketing them:

 

image.png

 

You could make a similar perk and add another condition so it would only block the player from pickpocketing them specifically.

Edited by EgoBallistic
Link to comment
53 minutes ago, EgoBallistic said:

I haven't read all the way back to the beginning so I might be way off base here, but couldn't you accomplish this with a perk on the player?  In the bondage mod I'm working on I have a perk that replaces activation on actors to prevent the player from pickpocketing them:

 

You could make a similar perk and add another condition so it would only block the player from pickpocketing them specifically.

 

Interesting idea! But no, in this case I don't mind the player pickpocketing the NPCs (in fact, they need to in order to complete one of the quest objectives). I simply want the activation text of those NPCs overridden only when the player isn't sneaking, so that the see the normal pickpocket activation text when they sneak.

 

In other words, the game normally makes NPCs (assuming a conversant race) have a default activation text of "Talk" when the player is not sneaking and "Pickpocket" when the player is sneaking. Ideally I would override the "Talk" activation text on those NPCs to something else and not the "Pickpocket" activation text, but the SetActivateTextOverride() function overrides all activation text normally, so I need a way to automatically toggle it in and out depending on sneak state.

 

And yes, I'm that OCD.

Edited by vaultbait
Link to comment

@vaultbait

I may be very wrong because my sources come from skyrim/fallout forums, but I always worked my scripts with the premise that it is better to define references in properties:

 

PlayerREF rather than Game.GetPlayer() (and similar)

 

as a matter of efficiency / speed. 

 

 

Edited by JB.
Link to comment
8 minutes ago, JB. said:

@vaultbait

I may be very wrong because my sources come from skyrim/fallout forums, but I always worked my scripts with the premise that it is better to define references in properties:

 

PlayerREF rather than Game.GetPlayer() (and similar)

 

as a matter of efficiency / speed.

 

Generally speaking, yes. From what I understand, each external function call like Game.GetPlayer() occupies a timeslice (based on the framerate), so calling those as few times as possible leaves more available bandwidth for other function calls. Calling Game.GetPlayer() multiple times in a function is where I've drawn the line, so you'll see in those function definitions if I need to reference the player more than once I generally dereference it at the beginning of the function or at least immediately prior to first use. In many cases I do use lots of properties and fill them in the CK, though manually filling a Player property in every single script assignment seems like a bit much. Is there an easier way?

Link to comment
On 9/17/2022 at 8:35 PM, vaultbait said:

 

Generally speaking, yes. From what I understand, each external function call like Game.GetPlayer() occupies a timeslice (based on the framerate), so calling those as few times as possible leaves more available bandwidth for other function calls. Calling Game.GetPlayer() multiple times in a function is where I've drawn the line, so you'll see in those function definitions if I need to reference the player more than once I generally dereference it at the beginning of the function or at least immediately prior to first use. In many cases I do use lots of properties and fill them in the CK, though manually filling a Player property in every single script assignment seems like a bit much. Is there an easier way?

 

Every modder who masters the simple scripting should take a look here

 

https://www.creationkit.com/fallout4/index.php?title=Performance_(Papyrus)

 

to optimize his/her scripts.

 

 

Link to comment

This one seems so easy ?

 

How can I run a function on an array? I have like 5 references in my array, but I can't compile. Example. 


ObjectReference[] Property Workbenches Auto Const

 

Function Myfunction()

Workbenches.AddKeyword()

EndFunction

Link to comment
2 hours ago, JB. said:

This one seems so easy ?

 

How can I run a function on an array? I have like 5 references in my array, but I can't compile. Example. 


ObjectReference[] Property Workbenches Auto Const

 

Function Myfunction()

Workbenches.AddKeyword()

EndFunction

 

It isn't clear from your example what you're trying to do with the AddKeyword() method. Are you trying to call it on each ObjectReference in the Workbenches array? If so, you'd need to loop over the elements, for example:

 

Function MyFunction()
    Int Counter = 0
    While Counter < Workbenches.Length
        Workbenches[Counter].AddKeyword(MyKeyword)
        Counter += 1
    EndWhile
EndFunction

 

Link to comment
1 hour ago, vaultbait said:

 

It isn't clear from your example what you're trying to do with the AddKeyword() method. Are you trying to call it on each ObjectReference in the Workbenches array? If so, you'd need to loop over the elements, for example:

 

Function MyFunction()
    Int Counter = 0
    While Counter < Workbenches.Length
        Workbenches[Counter].AddKeyword(MyKeyword)
        Counter += 1
    EndWhile
EndFunction

 

Thank you! That's what I'm looking for.

Link to comment
  • 2 weeks later...

So... here's my latest head-scratcher (pun intended!):

 

I have a custom piece of headwear. It's open like a crown/tiara sort of deal, so I want the wearer's hair to clip through it. If I leave it in the hair top+long slots then hair is hidden, not what I'm looking for obviously. If I switch it to another slot though, like the headband or beard slot, hair's no longer hidden but the mesh doesn't render on the actor's head at all.

 

Does anybody have an idea as to what I'm missing? I've tried comparing the Armor and ArmorAddon records to other headwear like eyeglasses, and can't see any obvious culprit. Is there something embedded in the mesh itself which governs this? I started browsing around inside it with Nifskope but honestly don't know what I'm looking for at this point.

 

Edit: Figured it out, chalk this one up to me still not knowing WTF I'm doing in Outfit Studio. The base game mesh I was modifying had a subsegment covering the whole thing, mapped to the long hair slot. When I set that subsegment's type to default and the slot to none and applied that, the item using that mesh in-game started behaving precisely as I wanted.

Edited by vaultbait
Link to comment
1 hour ago, Momauryus said:

Hello i need help because my game crash everywhere after some time. i play 3 hour without CTD and know i cant play more 5 minutes and i CTD.

I have buffout. this is the crash log.

Thx

 

This is the Creation Kit help thread, not a general help thread.

 

Nevertheless, it seems this crash is related to weapons and weapon animations.  Possible culprits would be Classic Holstered Weapons, Tactical Reload, and any weapon mod you are using.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use