Jump to content

Can there be multiple instances of a Quest?


Recommended Posts

Originally, it was keeping actors in furniture that I was having trouble with. I used keywords and removed vanilla keywords and for some reason NPCs would still try to walk out of the furniture at random times. Using wait package in a scene was the only thing I found that completely locked them down.

 

I'm sure that there is a way to do it in all contexts. But, the vanilla game has so many layers of influence going on it ends up being a matter of which strategy allows you to avoid having to dissect what keywords are being used in x,y,z case.

Link to comment
Share on other sites

Originally, it was keeping actors in furniture that I was having trouble with. I used keywords and removed vanilla keywords and for some reason NPCs would still try to walk out of the furniture at random times. Using wait package in a scene was the only thing I found that completely locked them down.

 

I'm sure that there is a way to do it in all contexts. But, the vanilla game has so many layers of influence going on it ends up being a matter of which strategy allows you to avoid having to dissect what keywords are being used in x,y,z case.

It's not so complex really. All npc can use only one package at the same time. The main thing is what package is on the top. The top one is defined by quest priority. The game checks thepackage stack from the top to the bottom and uses the first one with matching conditions.

Scenes work not the same. When you give a package to a ref alias, the NPC will use the package until you clear the alias, or until another alias from some quest with a higher priority is allpied to the NPC, or until the package conditions are no longer met.

In a scene an NPC will use a scene package during the scene or phase that tells to use the package. You can add a timer action to the phase to make it last longer. And you can stretch the package action to work during all other phases (i.e. to make an npc sit and talk in the same time).

But as soon as your phase/scene is over, the NPC checks their package stack and picks another one to use.

 

You don't need to know or manage other keywords the game uses to use the linked ref option.

You just create a new keyword to link NPCs to your furniture objects and only need to manage this keyword.

 

Let's say you want 10 differents NPCs to use different furnitures and you want them to ignore all other packages. Then you make a quest with a really high priority ( something like 97-98 , higher than follower quest) . Though if you only want to use it for settlers, 50 priority should be enough. Create a ref collection alias and add your package to the alias. The package must have HasLinkedRef yourkeword ==1 condition to avoid possible ctd if the linked ref no longer exists. The package must be set to use linked ref and your keyword. If you want NPC to ingnore combat, you can also check the "Ignore combat" flag.

Then you need a few functions to manage NPCs and furniture objects. This function can be defined in the RefCollectionAlias Script. Something like this:

Keyword Property LinkKeyword Auto Const ; a custom keyword to linke NpC to  their  markers
Formlist Property FurnitureList Auto Const  ; a list of furniture markers to create
GlobalVariable Property  mySelection Auto Const ; a varible that  will tell what furniture  to select from the list

Function  AddNewNPC(Actor NewActor)  ; a function to  call from other scripts
If NewActor
     AddRef(NewActor)
     AssignFurniture(NewActor)
EndIf
EndFunction
    
Function  AssignFurniture(Actor MyActor)
If MyActor
       int MyIndex = mySelection.GetValueInt()
       If MyIndex >-1 && MyIndex < FurnitureList.GetSize()
            Form MyFurniture =  FurnitureList.GetAt(MyIndex)
                 If MyFirniture
                       ObjectReference  MyFurnRef = myActor.PlaceAtMe(MyFurniture, 1)
                       MyFurnRef.SetAnge(0, 0, 0)
                       MyFurnRef.MoveToTheNearestNavmesh()
                       MyActor.SetLinkedRef(MyFurnRef,  LinkKeyword) ; now  the actor  has  linked ref  with the required  keyword and will use the  sit package
                       MyActor.EvaluatePackage()
                  EndIf
       EndIf
Endif
EndFunction

Function RemoveActor(Actor myActor) ;
if myActor
    ObjectReference  FurnRef = myActor.GetLinkedRef(LinkKeword) 
           If FurnRef  
                  FurnRef.Delete()
            EndIf
      MyActor.SetLinkedRef(none, LinkKeword)
      RemoveRef(myActor)
Endif
EndFunction
     
 Event OnUnload(ObjectReference akSender) ; optional remove  actor  and delete his furniture when the actor  unloads
     Actor akActor = akSender as Actor
     RemoveActor(akActor)
EndEvent  
Link to comment
Share on other sites

Thank you for breaking that process down. I had not tried a set-up like that and I think that will be helpful to understand in the future.

 

I actually had to eventually move away from the furniture method that I was using because, after getting it all working, I later discovered that it doesn't allow changing the idle a second time on NPC actors. So, it would animate the actor with a looping idle once. But, when I later went to add a switch animation functionality, only the PC would change. Using a different way to lock actors in place fixed it.

Edited by dagobaking
Link to comment
Share on other sites

 

Let's say you want 10 differents NPCs to use different furnitures and you want them to ignore all other packages. Then you make a quest with a really high priority ( something like 97-98 , higher than follower quest) . Though if you only want to use it for settlers, 50 priority should be enough. Create a ref collection alias and add your package to the alias. The package must have HasLinkedRef yourkeword ==1 condition to avoid possible ctd if the linked ref no longer exists. The package must be set to use linked ref and your keyword. If you want NPC to ingnore combat, you can also check the "Ignore combat" flag.

Then you need a few functions to manage NPCs and furniture objects. This function can be defined in the RefCollectionAlias Script. Something like this:

Keyword Property LinkKeyword Auto Const ; a custom keyword to linke NpC to  their  markers
Formlist Property FurnitureList Auto Const  ; a list of furniture markers to create
GlobalVariable Property  mySelection Auto Const ; a varible that  will tell what furniture  to select from the list

Function  AddNewNPC(Actor NewActor)  ; a function to  call from other scripts
If NewActor
     AddRef(NewActor)
     AssignFurniture(NewActor)
EndIf
EndFunction
    
Function  AssignFurniture(Actor MyActor)
If MyActor
       int MyIndex = mySelection.GetValueInt()
       If MyIndex >-1 && MyIndex < FurnitureList.GetSize()
            Form MyFurniture =  FurnitureList.GetAt(MyIndex)
                 If MyFirniture
                       ObjectReference  MyFurnRef = myActor.PlaceAtMe(MyFurniture, 1)
                       MyFurnRef.SetAnge(0, 0, 0)
                       MyFurnRef.MoveToTheNearestNavmesh()
                       MyActor.SetLinkedRef(MyFurnRef,  LinkKeyword) ; now  the actor  has  linked ref  with the required  keyword and will use the  sit package
                       MyActor.EvaluatePackage()
                  EndIf
       EndIf
Endif
EndFunction

Function RemoveActor(Actor myActor) ;
if myActor
    ObjectReference  FurnRef = myActor.GetLinkedRef(LinkKeword) 
           If FurnRef  
                  FurnRef.Delete()
            EndIf
      MyActor.SetLinkedRef(none, LinkKeword)
      RemoveRef(myActor)
Endif
EndFunction
     
 Event OnUnload(ObjectReference akSender) ; optional remove  actor  and delete his furniture when the actor  unloads
     Actor akActor = akSender as Actor
     RemoveActor(akActor)
EndEvent  

 

I now suspect that he problem I am seeing is caused by calling ForceRefTo too many times in a short time. There is this note on the CK:

 

Use of this function causes actors in any current running scene in the quest to re-eval their packages. Calling this multiple times in a row can result in actors in running scenes to lose their scene package permanently and result in brokenness. Do not call this multiple times in a row while a scene is running in the quest whose alias you are forcing to.

 

 

https://www.creationkit.com/fallout4/index.php?title=ForceRefTo_-_ReferenceAlias

 

While I don't think that I am calling it in the way this note describes exactly. The fact that doing so can break packages sounds eerily familiar. I am calling ForceRefTo many times on different Quests all timed almost at the exact same moment (from Flash).

 

SO, I would like to try an alternative way of populating aliases or running packages to avoid ForceRefTo to see if that helps.

 

Your above example uses furnitures. I am no longer using furnitures in any way for this. So, need something a bit different. Is there a way to use the method you describe here but cause it to populate a refalias on a quest through a keyword?

Link to comment
Share on other sites

I see in the Reference Alias panel that there is an option for "Find Matching Reference".

 

Would it work to populate that alias to check that option and then add a condition for "HasKeyword" and specify a unique keyword to give them at the moment I want to run the scene?

 

I can try these strategies to test. But, they each take a lot of set-up. So, it would help to get some insight if you know what will/won't work?

Link to comment
Share on other sites

Sure, you can add "haskeyword" condition or any other codition. If you use the "find matching reference" option, it will chose actors based on your conditions. You can also use another alias option to set linked ref to another alias without scripting. But note, that is this case the link only exists while the actor is in this alias. The good thing is that you don't need to think about cleaning the linked ref manually.

 

Just thought about it ..If you meant , you want to chage the condition dinamically and clear filled alieases based on this condition, then no, it won't work this way. While you can change conditions dinamically by using global variables in conditions, quests only check alias conditions when they are started. Just not sure what exactly you want to achieve.

Edited by kitcat81
Link to comment
Share on other sites

I'd like to have it set up so that if I add a keyword to an actor dynamically in script, that will cause this quest alias to populate with that actor. I want to do this so that I can then run a scene on the quest that controls the actor. Possible?

 

I'm still a bit lost about what linked references are exactly. It sounds like you link a keyword to a furniture or other object. Then you can give that keyword to an actor and connect them to the furniture so that they use it in a specific way (with a specific package). Right?

 

That sounds like roughly the same functionality that I need. But, I'd like to apply it via a Quest to run a scene because the scene has two phases (travel to and wait). Whereas a package would just be one part of it and I would need more set-up to transition to a second package.

Link to comment
Share on other sites

Yes it's possible, but you need to add the keyword before starting the quest. All "matching reference" and pre-defined reference aliases are filled on quest start.

 

Linked reference is a way to link an actor to some object mostly for further usage with packages.

Packages only have a few different options to set package target. Using existing refID option does not allow you to use dinamically created items. The options that allow to set spawned ref as a target are :1) Reference Alias 2) Linked Ref.

Reference Alias option is limited, you need to create an alias for each reference and to manage them all. Linked reference is not limited, you can link any number of actors to the same object with the same keyword.

Note, the actor that gets a linked ref, can only have one linked reference per keyword. This makes sence, because if you could add 2 linked references to the same actor using the same keyword, the actor would not know which one to use with the package. If you want to add 2 linked references to the same actor, you need to use different keywords for them. Also, setting linked ref makes the object temporary persistent. So it's always better to remove linked references when you don't need them anymore.

Linked references have nothing to do with furniture keywords, furniture does not need to have these keywords at all. Imagine that a keyword for linked ref is like a coloured rope. You need this rope to attach the actor to some object. If all ropes were the same, the actor would not know what rope to use because the package tells him to use the rope, but does not tell which one. But when they are all different , you can make the package tell the actor which one to use. So you can attach 30 different actors to a sofa with a red rope and to a bench with a blue rope and tell them to use the blue rope in the morning and red rope in the evening. And all this with just 2 keywords and 2 packages.

Edited by kitcat81
Link to comment
Share on other sites

Keyword before starting the quest is ok. I will try that.

 

So, I just made an adjustment to what I was doing. And it looks like it fixed the problem I was having. But, now, that old bug with all the NPCs AI not working is back!

 

So frustrating.

 

I guess it means that the two issues are somehow related...

 

[since I noticed the old bug right away, I was able to backtrack better. So, I think I understand a LITTLE better what is causing it. In my wait package, I had set the flags to basically ignore everything, combat, no aggro radius, etc. That IS what I want during the wait scene. But, apparently, something about those flags on that package somehow remain in effect not only the reference alias but every NPC... Once I turned those flags off, the AI bug doesn't happen... It really doesn't make sense though because if the Wait package was still running, the character released from the ref alias when the Quest stop would stay still right? They don't. They walk around... Anyway, it looks like both bugs are fixed. Knock on wood.

 

PS: Thank you for the clarifying linked references. I get it now. If I discover that this latest build has a flaw I haven't noticed yet, I may try using those.]

Edited by dagobaking
Link to comment
Share on other sites

  • Recently Browsing   0 members

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