Reginald001 Posted April 7, 2018 Share Posted April 7, 2018 (edited) I want my player character to be able to initiate the NPCCoupleHolding animation when (s)he's talking to my custom companion called Ivy. I've been researching several ways to trigger this animation but the more I search, the more questions come up. I hope one of the more experienced modders can help me out! I am following these ideas/strategies hoping to decide on the best one: 1) Create a scene, where at the beginning of the phase I spawn the furniture NPCCoupleHolding, then trigger my actors to use it. (I just know the principle I don't know yet how to trigger it all or even bind it together). 2) Simply call a 'playanimation' or 'playgamebryo' animation on the actors, but I don't think it works like that either. 3) Create a scene and add a package that the players follow. So an open question: What would be the best strategy to have my player character and NPC initiate this animation for say 20 seconds? (edit) I've created a scene in my companion quest called 'hug scene'. I got it to work for the GoodNeighbor Hancock hug/kill scene. Consequently, my custom companion killed me, like Hancock killed that guy in Goodneighbor. That means I think I'm on the right track. I've checked into the idle Anims available and I'm missing the hugging animation there. I'm sure I need to define it somewhere, but I can't seem to find WHERE the idle Anims are defined, so I can add the .htk files there (so that subsequently I can select them in the dialogue Idle anim). Edited April 7, 2018 by Reginald001 Link to comment Share on other sites More sharing options...
kitcat81 Posted April 7, 2018 Share Posted April 7, 2018 (edited) It's a furniture animation so It's defined in HumanRaceSubgraphData record. It doesn't work the same way as idles. Though you can try to force actors to use the furniture by giving them a package to use linked refs or objects with some certain keyword.Also, you can use SnapIntoInteraction script function that will snap the NPC or player into interaction with the furniture marker. In this case actors teleport to the marker , so it's not an immersive way. To avoid it looking unimmersive you can make screen go black/white for a few seconds to hide this manipulation. But I'm just not sure that the dialogue will work while being loaded in the furniture. For the package example tou can look at WorkshopParentScript , check WorkshopActorApplyAlias. It has different packages. Some of them tell NPC to use owned refs , these packages are to make them work and sleep. Relaxation package makes them use furniture with the FurnitureClassRelaxation Keyword. Edited April 7, 2018 by kitcat81 Link to comment Share on other sites More sharing options...
Reginald001 Posted April 7, 2018 Author Share Posted April 7, 2018 (edited) It's a furniture animation so It's defined in HumanRaceSubgraphData record. It doesn't work the same way as idles. Though you can try to force actors to use the furniture by giving them a package to use linked refs or objects with some certain keyword.Also, you can use SnapIntoInteraction script function that will snap the NPC or player into interaction with the furniture marker. In this case actors teleport to the marker , so it's not an immersive way. To avoid it looking unimmersive you can make screen go black/white for a few seconds to hide this manipulation. But I'm just not sure that the dialogue will work while being loaded in the furniture. For the package example tou can look at WorkshopParentScript , check WorkshopActorApplyAlias. It has different packages. Some of them tell NPC to use owned refs , these packages are to make them work and sleep. Relaxation package makes them use furniture with the FurnitureClassRelaxation Keyword. I was looking into that. I don't know where the HumanRaceSubgraphData is defined though. In the actor? In the nif? In some definition I'm missing? I was looking into the NPCCoupleHold anim, it's an anim marker used in Vault 111, when two people are holding each other. I can use a walktoobject action, then trigger the anims, but I'm not sure how to set up the package. I know I must create a package and add that to the scene. The package must have a Sit template, and it should point to the furniture. I can spawn the furniture, but I don't know how to point my 'holdinghands' furniture package to the dynamically spawned piece of furniture.When I edit the package I can only select keywords and direct references, but a direct reference won't work as it needs to be dynamic.Perhaps I need to set up a quest alias first, then spawn that. But what kind of reference would that be for the furniture, so I can spawn it dynamically in the players location?I'm just lost a bit.. Edited April 7, 2018 by Reginald001 Link to comment Share on other sites More sharing options...
kitcat81 Posted April 7, 2018 Share Posted April 7, 2018 (edited) Just type the name it in the CK search field , it's not hidden inside other files , it's a file named HumanRaceSubGraphData. But I doubt that it will help you. This animation can't be played with script functions.The sit package should be enough, usually it makes NPC go to the furniture.You can point either by alias or linked ref. Linked Ref is more flexible.How to add a linked ref :Duplicate a keyword and rename it to something. In the package select "linked ref " option and your keyword. Set a new condition for this package : HasLinkedRef - YourKeyword. This is for safety and to prevent CTD in case the marker reference does not exist. Then you can use script function SetLinkedRef: MyActor.SetLinkedRef(MarkerRef, YourKeyword) To remove linked ref use the same function: MyActor.SetLinkedRef(none, YourKeyword) Edited April 7, 2018 by kitcat81 Link to comment Share on other sites More sharing options...
Reginald001 Posted April 7, 2018 Author Share Posted April 7, 2018 (edited) Just type the name it in the CK search field , it's not hidden inside other files , it's a file named HumanRaceSubGraphData. But I doubt that it will help you. This animation can't be played with script functions.The sit package should be enough, usually it makes NPC go to the furniture.You can point either by alias or linked ref. Linked Ref is more flexible.How to add a linked ref :Duplicate a keyword and rename it to something. In the package select "linked ref " option and your keyword. Set a new condition for this package : HasLinkedRef - YourKeyword. This is for safety and to prevent CTD in case the marker reference does not exist. Then you can use script function SetLinkedRef: MyActor.SetLinkedRef(MarkerRef, YourKeyword) To remove linked ref use the same function: MyActor.SetLinkedRef(none, YourKeyword)Thanks, this sounds like what I need. I'm going to try it out!!Also, the explenation on Linked Refs really helps. :smile: Ran into a snag. It says I can't use a furniture object as a linked ref. My current code: Game.GetPlayer().PlaceAtme(p_ivy_Hugging_Furn)Actor IvCompIvComp = qIvyComp.GetActorRef()IvComp.SetLinkedRef(p_ivy_Hugging_Furn, p_ivyHugAnimKW)Game.GetPlayer().SetLinkedRef(p_ivy_Hugging_Furn, p_ivyHugAnimKW)Utility.Wait(10) Error: Papyrus Compiler Version 2.8.0.4 for Fallout 4Copyright © ZeniMax Media. All rights reserved.Starting 1 compile threads for 1 files...Compiling "Fragments:TopicInfos:TIF__IvyCompQuest_01015569"...C:\Users\AppData\Local\Temp\PapyrusTemp\Fragments\TopicInfos\TIF__IvyCompQuest_01015569.psc(11,20): type mismatch on parameter 1 - cannot pass a furniture to a objectreferenceC:\Users\AppData\Local\Temp\PapyrusTemp\Fragments\TopicInfos\TIF__IvyCompQuest_01015569.psc(12,30): type mismatch on parameter 1 - cannot pass a furniture to a objectreferenceNo output generated for Fragments:TopicInfos:TIF__IvyCompQuest_01015569, compilation failed. Batch compile of 1 files finished. 0 succeeded, 1 failed.Failed on Fragments:TopicInfos:TIF__IvyCompQuest_01015569 Edited April 7, 2018 by Reginald001 Link to comment Share on other sites More sharing options...
kitcat81 Posted April 7, 2018 Share Posted April 7, 2018 (edited) Not at all :smile: . That's because you are trying to link the actor to the furniture base object. You need to link to the spawned reference . These are 2 functions you can add to the script and call them from some events. ObjectReference MyMarkerRef ; this must be outside of functions and events so it can be accessed from different functions and events Function CreateMyMarker() MyMarkerRef = Game.GetPlayer().PlaceAtme(p_ivy_Hugging_Furn) Actor IvComp = qIvyComp.GetActorRef() IvComp.SetLinkedRef(MyMarkerRef, p_ivyHugAnimKW) Game.GetPlayer().SetLinkedRef(MyMarkerRef, p_ivyHugAnimKW) EndFunction Function RemoveMyMarker() Actor IvComp = qIvyComp.GetActorRef() IvComp.SetLinkRef(None, p_ivyHugAnimKW) Game.GetPlayer().SetLinkedRef(None, p_ivyHugAnimKW) MyMarkerRef.Delete() MyMarkerRef = none EndFunctionI've just noticed that you added it to the topic info. I don't recommend you to do that, you won't be able to track the marker in this case. It's better to add functions to the Quest Script and then call this function from some fragment. Even better to make your topic info set some stage. And in the stage fragment call the quest script function Quest Property MyQuest Auto Const (MyQuest as YourQuestScriptNameHere).CreateMyMarkers() Edited April 7, 2018 by kitcat81 Link to comment Share on other sites More sharing options...
Reginald001 Posted April 8, 2018 Author Share Posted April 8, 2018 (edited) So I integrated this script as a quest script to the comquest for my companion but nothing happens.I'll debug it by placing another (visible) object and some traces and will try to figure out what goes wrong.Thanks so far, but I didn't get it yet. I'm calling the start/end from the phase in my dialogue, with a wait action in between, it should work... but it doesn't.I'll rewrite the entire quest to use stages, though strictly that really shouldn't be necessary at all. Edited April 8, 2018 by Reginald001 Link to comment Share on other sites More sharing options...
kitcat81 Posted April 8, 2018 Share Posted April 8, 2018 In theory it should not be necessary. But I once tried to add a script to assign NPCs to settlements to the topic fragment. The part of the script I copied from vanilla fragment workled fine and I got the location menu open. But any function added after openining the menu never fiired. Tried to add unitility.wait(0.5) to see if can make the fragment wait until you exist the location menu. But it did not help and any call after this did not work. The same thing added to the quest script and called from stage fragment works fine. I still don't know why it happened, might be that opening any menu makes the rest of the topic fragment script never fire or maybe there is a problem with updating fragment scripts in game. Even thoughI loaded a clean save...So I came to a conclusion that it's not always relible to use them. I also suggest you looking at the Slot Machine quest ( vault DLC). it's called "WorkshopSlotMachineHandler". It does the same thing you want to achive. It chooses some random settler in your settlement, makes the settler go sit the machine and say topics related to gambling. Link to comment Share on other sites More sharing options...
Reginald001 Posted April 8, 2018 Author Share Posted April 8, 2018 (edited) In theory it should not be necessary. But I once tried to add a script to assign NPCs to settlements to the topic fragment. The part of the script I copied from vanilla fragment workled fine and I got the location menu open. But any function added after openining the menu never fiired. Tried to add unitility.wait(0.5) to see if can make the fragment wait until you exist the location menu. But it did not help and any call after this did not work. The same thing added to the quest script and called from stage fragment works fine. I still don't know why it happened, might be that opening any menu makes the rest of the topic fragment script never fire or maybe there is a problem with updating fragment scripts in game. Even thoughI loaded a clean save...So I came to a conclusion that it's not always relible to use them. I also suggest you looking at the Slot Machine quest ( vault DLC). it's called "WorkshopSlotMachineHandler". It does the same thing you want to achive. It chooses some random settler in your settlement, makes the settler go sit the machine and say topics related to gambling. Thanks! Those topic inconsistencies make it harder to learn the engine. :smile: I switched it up and made one script event that just handles everything. I first had a separate script, but moved the function to the already existing companion script for my companion. I tried it out and I think it actually works, but my player just got 'stuck'... This leads me to think the script part might be fine at this point, it could be that the Furniture itself (coupleholdhands) which was meant for NPC's is not set up correctly for my needs. I just looked and the 'ismarker' checkbox was off, so I checked it and am about to fire up another test. I set the global variable up as this is a conditional for the topics in her 'chatter' shared response topic. (edit) Nope, again, nothing.. I'm going to change it to a chair and will see what happens there, then I'll look into the slot machine.(edit2) Maybe I'm missing the actual 'activate' command: ; Have the player 'activate' the door, bypassing any blocked activation and NOT sending an event to any script NeatDoor.Activate(Game.GetPlayer(), true) Furniture Property p_ivy_Hugging_Furn Auto Const Keyword Property p_ivyHugAnimKW Auto Const ObjectReference MyMarkerRef ; this must be outside of functions and events so it can be accessed from different functions and events Function DoHugging() Actor IvComp = pIVYCOMP.GetActorRef() p_ivy_IsHugging.SetValueInt(1) MyMarkerRef = Game.GetPlayer().PlaceAtme(p_ivy_Hugging_Furn) IvComp.SetLinkedRef(MyMarkerRef, p_ivyHugAnimKW) MyMarkerRef.Activate(IvComp, true) Game.GetPlayer().SetLinkedRef(MyMarkerRef, p_ivyHugAnimKW) MyMarkerRef.Activate(Game.GetPlayer(), true) Utility.Wait(1) IvComp.Say(p_IvySpontChatter, IvComp, False, Game.GetPlayer()) Utility.Wait(5) MyMarkerRef.Activate(IvComp, true) IvComp.SetLinkedRef(None, p_ivyHugAnimKW) MyMarkerRef.Activate(Game.GetPlayer(), true) Game.GetPlayer().SetLinkedRef(None, p_ivyHugAnimKW) MyMarkerRef.Delete() MyMarkerRef = none p_ivy_IsHugging.SetValueInt(0) EndFunction Edited April 8, 2018 by Reginald001 Link to comment Share on other sites More sharing options...
kitcat81 Posted April 8, 2018 Share Posted April 8, 2018 You can also add EvaluatePackage functions to make actors notice the marker faster. And I believe that to make player use the package you need to set player AI driven ( SetPlayerAIDriven( true)). Actor Property PlayerRef Auto Const ; optimisation to avoid unnecessary function calls MyMarkerRef = Game.GetPlayer().PlaceAtme(p_ivy_Hugging_Furn) IvComp.SetLinkedRef(MyMarkerRef, p_ivyHugAnimKW) PlayerRef.SetLinkedRef(MyMarkerRef, p_ivyHugAnimKW) PlayerRef.SetPlayerAIDriven(true) ; don't forget to set it false afterwards IvComp.EvaluatePackage() PlayerRef.EvaluatePackage()And the furniture must have 2 interaction points so it can be used by 2 actors in the same time. It can be adjusted in the marker record. Link to comment Share on other sites More sharing options...
Recommended Posts