Jump to content

[FO4 CK] General Help Thread


Recommended Posts

Posted
4 hours ago, bihb said:

only aaf is installed. I definitely did not install something or installed it incorrectly. please help

 

You're asking in the Creation Kit help topic, but you seem to have questions about AAF. You should ask in the AAF support thread, or better still on the AAF Discord linked from the first post there.

 

At first glance, it looks like you've probably got some mixed up and conflicting AAF data from different animation packs and patches, but digging into that will take some time (and is off-topic for the CK thread here anyway).

Posted
On 8/9/2022 at 2:40 AM, EgoBallistic said:

That’s how I am doing it.  Kind of a pain but it’s the best way I’ve found to detect item slot conflicts between arbitrary items.

 

Can you point to an example of where you did this? I'm trying to follow the samples in the Actor.GetWornItem() documentation, but the compiler complains with  "actor#wornitem is not a known user-defined script type" and I'm starting to wonder if it's related to being an F4SE extension. This is what my function looks like (it's a bit of a rough and hacky draft still):

 

Spoiler
Function UpdateNudity() global
    Int Nude = 0
    Int Unarmored = 0
    Int Unclothed = 0
    If Game.GetPlayer().IsInPowerArmor() == false
        Int[] UnclothedMasks = new Int[0]
        UnclothedMasks.Add(0x40) ; slot index 6
        UnclothedMasks.Add(0x80) ; slot index 7
        UnclothedMasks.Add(0x100) ; slot index 8
        UnclothedMasks.Add(0x200) ; slot index 9
        UnclothedMasks.Add(0x400) ; slot index 10
        Int[] UnarmoredMasks = new Int[0]
        UnarmoredMasks.Add(0x800) ; slot index 11
        UnarmoredMasks.Add(0x1000) ; slot index 12
        UnarmoredMasks.Add(0x2000) ; slot index 13
        UnarmoredMasks.Add(0x4000) ; slot index 14
        UnarmoredMasks.Add(0x8000) ; slot index 15
        Int Index = 0
        Int MaskCount = 0
        While Index < 43
            Actor:WornItem Worn = Game.GetPlayer().GetWornItem(Index)
            While MaskCount < UnclothedMasks.Length
                If Math.LogicalAnd(Worn.GetSlotMask(), UnclothedMasks[MaskCount]) == UnclothedMasks[MaskCount]
                    Nude += 10
                    Unclothed += 20
                EndIf
                MaskCount += 1
            EndWhile
            MaskCount = 0
            While MaskCount < UnarmoredMasks.Length
                If Math.LogicalAnd(Worn.GetSlotMask(), UnarmoredMasks[MaskCount]) == UnarmoredMasks[MaskCount]
                    Nude += 10
                    Unarmored += 20
                EndIf
                MaskCount += 1
            EndWhile
            Index += 1
        EndWhile
    EndIf
    GlobalVariable PercentNude = Game.GetFormFromFile(0x0000DEAD, "Example.esp") as GlobalVariable
    GlobalVariable PercentUnarmored = Game.GetFormFromFile(0x0000DEAE, "Example.esp") as GlobalVariable
    GlobalVariable PercentUnclothed = Game.GetFormFromFile(0x0000DEAF, "Example.esp") as GlobalVariable
    PercentNude.SetValue(Nude)
    PercentUnarmored.SetValue(Unarmored)
    PercentUnclothed.SetValue(Unclothed)
EndFunction

 

 

Posted
45 minutes ago, vaultbait said:

Can you point to an example of where you did this? I'm trying to follow the samples in the Actor.GetWornItem() documentation, but the compiler complains with  "actor#wornitem is not a known user-defined script type" and I'm starting to wonder if it's related to being an F4SE extension. This is what my function looks like (it's a bit of a rough and hacky draft still):

 

You need to call GetSlotMask() on an Armor.  GetWornItem() returns a WornItem struct; WornItem.Item is the base item (which will be an Armor or Weapon).  So your code should look like this:

 

        While Index < 43
            Actor:WornItem Worn = Game.GetPlayer().GetWornItem(Index)
            Armor WornArmor = Worn.Item as Armor
            If WornArmor != None
                While MaskCount < UnclothedMasks.Length
                    If Math.LogicalAnd(WornArmor.GetSlotMask(), UnclothedMasks[MaskCount]) == UnclothedMasks[MaskCount]
                        Nude += 10
                        Unclothed += 20
                    EndIf
                    MaskCount += 1
                EndWhile
                MaskCount = 0
                While MaskCount < UnarmoredMasks.Length
                    If Math.LogicalAnd(WornArmor.GetSlotMask(), UnarmoredMasks[MaskCount]) == UnarmoredMasks[MaskCount]
                        Nude += 10
                        Unarmored += 20
                    EndIf
                    MaskCount += 1
                EndWhile
                Index += 1
            EndIf
        EndWhile

 

Posted
5 hours ago, EgoBallistic said:

You need to call GetSlotMask() on an Armor.  GetWornItem() returns a WornItem struct; WornItem.Item is the base item (which will be an Armor or Weapon).

 

Aha, perfect. That was precisely my problem, thanks! I misunderstood the compiler error, and mistakenly thought it wasn't finding the struct definition. Should have looked more closely at the example in the Papyrus docs.

Posted

Unless I am skipping something, I cannot compile the GetCameraState() function of F4SE in its latest version, but I can if I download and install the 0.6.21 version. ?‍♂️

Posted (edited)
14 minutes ago, JB. said:

Unless I am skipping something, I cannot compile the GetCameraState() function of F4SE in its latest version, but I can if I download and install the 0.6.21 version. ?‍♂️

 

I still see the native function declaration in Game.psc, what error is the compiler returning?

 

Edit: Okay, comparing both archives side-by-side, one glaring difference is that 0.6.21 shipped the source files under Data\Scripts\Source\User while 0.6.23 just has them in Data\Scripts\Source instead. Maybe the compiler's looking in the wrong place?

Edited by vaultbait
Posted
9 minutes ago, vaultbait said:

 

I still see the native function declaration in Game.psc, what error is the compiler returning?

 

Edit: Okay, comparing both archives side-by-side, one glaring difference is that 0.6.21 shipped the source files under Data\Scripts\Source\User while 0.6.23 just has them in Data\Scripts\Source instead. Maybe the compiler's looking in the wrong place?


Yep that is the problem.  The 0.6.23 archive is messed up.

Posted
1 minute ago, EgoBallistic said:

Yep that is the problem.  The 0.6.23 archive is messed up.

 

@JB.: Given that, you could probably just move the F4SE script source files into User and try again.

Posted

Here's a fun new challenge... has anyone worked with displays (magazine racks specifically in this case)?

 

In a cell I've placed a vanilla magazine rack. It's the spinning stand model currently if that matters, though I may change that up anyway. I have applied a script to its reference to inject some magazines into it on load via AddItem() calls so that I can take advantage of a soft dependency on another plugin which provides those magazines. It also, of course, inherits the vanilla MagazineRackContainerScript, which I hoped would take care of displaying the injected items automagically.

 

In game, the magazines show up listed as retrievable container contents in the rack, but the mesh updates to display them don't happen unless I take the magazines out and put them back in. Is there some function I can call to force update the display after scripting content injection, or should I just replace MagazineRackContainerScript on it with a modified version to handle that?

Posted
40 minutes ago, vaultbait said:

Here's a fun new challenge... has anyone worked with displays (magazine racks specifically in this case)?

 

In a cell I've placed a vanilla magazine rack. It's the spinning stand model currently if that matters, though I may change that up anyway. I have applied a script to its reference to inject some magazines into it on load via AddItem() calls so that I can take advantage of a soft dependency on another plugin which provides those magazines. It also, of course, inherits the vanilla MagazineRackContainerScript, which I hoped would take care of displaying the injected items automagically.

 

In game, the magazines show up listed as retrievable container contents in the rack, but the mesh updates to display them don't happen unless I take the magazines out and put them back in. Is there some function I can call to force update the display after scripting content injection, or should I just replace MagazineRackContainerScript on it with a modified version to handle that?

Do those custom books have 'PerkMagKeyword' keyword? Does it work if you add 'PerkMagKeyword' to custom injected books?

Posted
1 hour ago, requiredname65 said:

Do those custom books have 'PerkMagKeyword' keyword? Does it work if you add 'PerkMagKeyword' to custom injected books?

 

Yes, they have the keyword, which is why I'm able to manually place them into the rack in-game (the vanilla script already rejects anything lacking that keyword if the player tries to put it in the container). Good suggestion though, just not the problem in this case.

Posted (edited)
1 hour ago, vaultbait said:

 

Yes, they have the keyword, which is why I'm able to manually place them into the rack in-game (the vanilla script already rejects anything lacking that keyword if the player tries to put it in the container). Good suggestion though, just not the problem in this case.

 

Perhaps something like this? DeletePerkMags and DisplayPerkMags handle visual updates based on what is in PerkMagsInContainer array. That array gets updated by OnItem* events but those events are received only after InventoryFilter is set to something,

which in vanilla scripts is set in OnActivated handler (in addition maybe item events aren't emited when script adds them, not sure about that one).

 

Scriptname DoesThisWork extends MagazineRackContainerScript

Bool Pristine = True

Event OnLoad()
    Parent.OnLoad()
    If Pristine && PerkMagsInContainer
        ; handle injecting here
        InjectMag(...)
        DeletePerkMags()
        Utility.Wait(0.1)
        DisplayPerkMags()
        Pristine = False
    EndIf
EndEvent

; need to handle state of PerkMagsInContainer when we inject for DisplayPerkMags function to work on them
Function InjectMag(Book mag)
    if mag.HasKeyword(PerkMagkeyword) \
    && PerkMagsInContainer.Length < DisplayPerkMagStructArray.Length
        Self.AddItem(mag)
        PerkMagsInContainer.Add(mag)
    else
EndFunction

 

Edited by requiredname65
refinements to script
Posted
33 minutes ago, requiredname65 said:

Perhaps something like this? DeletePerkMags and DisplayPerkMags handle visual updates based on what is in PerkMagsInContainer array. That array gets updated by OnItem* events but those events are received only after InventoryFilter is set to something,

which in vanilla scripts is set in OnActivated handler (in addition maybe item events aren't emited when script adds them, not sure about that one).

 

Oh, thanks! Doing the script as "extends MagazineRackContainerScript" so I can call its functions directly is the bit I was missing. Still very new to Papyrus and haven't extended scripts from anything other than basic types, so this option hadn't dawned on me at all (though the types are scripts themselves, so I certainly should have thought of it).

Posted
On 8/9/2022 at 3:23 PM, EgoBallistic said:

At that point it might be better not to put conditions on the perks / abilities and instead use Actor.OnItemEquipped / OnItemUnequipped (for weapons and normal armor) and OnSit / OnGetUp (for power armor) on an alias.  You can then have a single function that checks the actor with nested Ifs, starting with IsInPowerArmor() and going from there.  This way the checks only run on an event-driven basis, which is relatively rare in the scheme of things.

 

Just to follow up, this worked out really well. I went with the global variables approach to use for conditions in CK.

 

One thing I noticed fairly quickly is that these checks can really pile up in parallel due to rapid-fire events all retriggering calls to the update function, since it can take up to several seconds to complete depending on how bogged down the game is. I addressed it by cobbling together my own mutex and serial queue which skips new calls if there's one in progress and another one already pending. This ensures that a dogpile of events only results in two total calls to the function, making sure it executes as early as possible but also executes at least once after the event activity settles down. And as an added safety I stuck a (lengthy) timeout in what amounts to the pending state, so it won't leave the routine running indefinitely waiting on an earlier call to complete. I'm not sure if there are other techniques mod authors use for these sorts of situations, but it seems to have dealt with the problem for me at least.

 

Oh, one other note. It seems from the Papyrus docs and some testing so far that OnSit() is sufficient for Power Armor, since it gets triggered on entering and on exiting (as well as on inserting a fusion core, apparently). It does not appear an OnGetUp() handler is warranted after all, oddly.

Posted

It's me again. I'm back this time looking for general advice about quest design, since I've reached that point in the mod I've been developing for months now. I've watched a bunch of tutorials, most of which seem to center around dialogue-driven quests, but a lot of the things I want to do are triggered by story elements like reading a note or acquiring an item.

 

The examples I've seen so far "cheat" by basically making the triggering items load disabled by default, and then make script calls to magically enable them at the relevant quest stage. While that certainly works, it's a bit ugly and unimmersive. "Oh I saw some note over there, you should check it out." [Player trudges to other end of the room where they just came from, but now somehow there's an obvious note there they'd not spotted before.] From a storytelling perspective, that sort of thing just drives me batty. And yes, I already know I'm OCD, no need to point it out. ?

 

The model I have in my head (I get that this is not the actual data model for a FO4 quest) is that objectives are associated with particular stages. A number of my stages have multiple objectives to complete before advancing to the next stage, but which can be completed in any order, and that part works well enough. What I'd like, though, is for the player to be able to complete objectives for future stages, perhaps accidentally, and then have that objective automatically clear when the corresponding stage of the quest is reached.

 

I had hoped that SetObjectiveCompleted() on an objective which wasn't displayed yet would cause it to get immediately marked completed once SetObjectiveDisplayed() was called on it, but in testing it seems that completing it before it's displayed is a no-op (it doesn't generate any Papyrus error that I can find, but displaying the objective at the later stage doesn't show it as completed). Is there some additional magic I'm missing to make that work, or is this just the wrong way to approach it?

Posted (edited)
5 hours ago, vaultbait said:

It's me again. I'm back this time looking for general advice about quest design, since I've reached that point in the mod I've been developing for months now. I've watched a bunch of tutorials, most of which seem to center around dialogue-driven quests, but a lot of the things I want to do are triggered by story elements like reading a note or acquiring an item.

 

The examples I've seen so far "cheat" by basically making the triggering items load disabled by default, and then make script calls to magically enable them at the relevant quest stage. While that certainly works, it's a bit ugly and unimmersive. "Oh I saw some note over there, you should check it out." [Player trudges to other end of the room where they just came from, but now somehow there's an obvious note there they'd not spotted before.] From a storytelling perspective, that sort of thing just drives me batty. And yes, I already know I'm OCD, no need to point it out. ?

 

The model I have in my head (I get that this is not the actual data model for a FO4 quest) is that objectives are associated with particular stages. A number of my stages have multiple objectives to complete before advancing to the next stage, but which can be completed in any order, and that part works well enough. What I'd like, though, is for the player to be able to complete objectives for future stages, perhaps accidentally, and then have that objective automatically clear when the corresponding stage of the quest is reached.

 

I had hoped that SetObjectiveCompleted() on an objective which wasn't displayed yet would cause it to get immediately marked completed once SetObjectiveDisplayed() was called on it, but in testing it seems that completing it before it's displayed is a no-op (it doesn't generate any Papyrus error that I can find, but displaying the objective at the later stage doesn't show it as completed). Is there some additional magic I'm missing to make that work, or is this just the wrong way to approach it?

You can make a second quest where you host all these hidden objectives, and ask the first quest to display or complete them as you see fit. 

 

If this second quest is miscellaneous, the objectives shown and completed will not be shown in the main quest, so this may not be what you are looking for. 

 

Anyway you can also make a stage in your main quest and put: 

 

SetObjectiveDisplayed(25)
Utility.Wait(2)
SetObjectiveCompleted(25)


 

Edited by JB.
Posted
6 hours ago, vaultbait said:

The examples I've seen so far "cheat" by basically making the triggering items load disabled by default, and then make script calls to magically enable them at the relevant quest stage. While that certainly works, it's a bit ugly and unimmersive. "Oh I saw some note over there, you should check it out." [Player trudges to other end of the room where they just came from, but now somehow there's an obvious note there they'd not spotted before

 

You can add the note to a container at the start of the quest. That means the player could perhaps read ti ahead of time, but that sounds like something you might want in some situations.

 

You can also add the note to an NPC's inventory. ("I don't know if it's any use to you, but I found this while you were busy murdering Evil Bob over there...")

 

I'd also normally suggest the courier, but that doesn't work so well for Fallout 4 :) You could have a radio transmission if you can get the VA. Or have a radio station transmitting data (modem noise) that decodes to a message in the pipboy (add a holotape).

 

Ot you could just have a generic NPC wander up the next time the player is in Diamond city and say "Oi! I heard you were the one that killed Evil Bob! I know someone that would like a word with you..."

 

For future objectives, just make reading the note (or whatever) set a bool property on the quest, and then make the quest objective true if that property is true.

Posted
5 hours ago, JB. said:

Anyway you can also make a stage in your main quest and put: 

 

SetObjectiveDisplayed(25)
Utility.Wait(2)
SetObjectiveCompleted(25)

 

4 hours ago, DocClox said:

For future objectives, just make reading the note (or whatever) set a bool property on the quest, and then make the quest objective true if that property is true.

 

Thanks, that was basically what I was trying to find out. 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.

Posted

I already made a thread but seems like this was the wright place, so sorry for the double posting.

 

Been getting into the creation kit a bit and just fooling around with the basics. 

 

I was looking for a setting or directory in the cc to disable the always character movement tied to where you aim once you pull your weapon out. I get the funcionality, but ill rather have the 360 movement always and just have the camera tied once im actually holding the aim button.

 

Does someone know how to do this? im asking since i looked a lot and seems no one has gone their way to try this.

 

Thank you!

Posted
35 minutes ago, falcont2t said:

I was looking for a setting or directory in the cc to disable the always character movement tied to where you aim once you pull your weapon out. I get the funcionality, but ill rather have the 360 movement always and just have the camera tied once im actually holding the aim button.

 

Does someone know how to do this? im asking since i looked a lot and seems no one has gone their way to try this.

 

I doubt you'll be able to override this with the CK. Camera override mods I've seen generally end up getting implemented as F4SE plugins (so need a bit of familiarity with C++ and relevant compiler/toolchain).

 

Even just from a logistical standpoint though, how do you envision 3rd person combat to work if camera movement is no longer used to aim down sights?

Posted
1 minute ago, vaultbait said:

 

I doubt you'll be able to override this with the CK. Camera override mods I've seen generally end up getting implemented as F4SE plugins (so need a bit of familiarity with C++ and relevant compiler/toolchain).

 

Even just from a logistical standpoint though, how do you envision 3rd person combat to work if camera movement is no longer used to aim down sights?

 

I had games like the last of us in my mind. The aim only occurs when you hold the aim button, and wherever you have your weapon out or not is irrelevant to the camera, so its useful to, lets say, run away from enemies and being able to see them without taking your weapon away.

 

Fallout already lets you do this if you hold the camera button while moving in third person. but freezes the combat options.

 

But im aware of the technical block i have to get over first to even talk details.

 

Even if disabling it is a tick or marker thats easy to uncheck, the mod probably would need work making a system that enables the camera-mouse tied movement whenever you shoot, so the character shoots to where you are pointing irrelevant to where its looking at.

Posted

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? 

Posted
1 hour 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? 

 

Notifications every 30 seconds, real time?

 

A hotkey that pops up a message box with the numbers interpolated into the text?

 

You can maybe interpolate into with the quest description text as well, but I'm not sure about that. You could certainiy have a "smart holotape" that updated with the remaining time.

Posted
20 minutes ago, DocClox said:

 

Notifications every 30 seconds, real time?

 

A hotkey that pops up a message box with the numbers interpolated into the text?

 

You can maybe interpolate into with the quest description text as well, but I'm not sure about that. You could certainiy have a "smart holotape" that updated with the remaining time.

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". 

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...