Tasheni Posted October 15, 2018 Share Posted October 15, 2018 I'm currently working on the ability to let my followers walk beside the player, I used Ishara's nice mod Followers as Companions to get this done via dialogue. It works very well so far. But there's a line in the code I can't understand. Code is this, attached to dialogue: function Fragment_3(ObjectReference akSpeakerRef) actor akSpeaker = akSpeakerRef as actor akSpeaker.addtofaction(StayCloseLeft) utility.wait(0.500000) TravelBesidesAliasQuestLeft.stop() utility.wait(0.500000) TravelBesidesAliasQuestLeft.start() game.SetGameSettingFloat("fAIMinGreetingDistance", (XNumber.getvalueint() - 1) as Float) akSpeaker.SetHeadtracking(false) akSpeaker.evaluatepackage() endFunction And this is the line I can't understand: game.SetGameSettingFloat("fAIMinGreetingDistance", (XNumber.getvalueint() - 1) as Float) I know that the value of fAIMinGreetingDistance is normally at 150. And I know that the global value is changed, but I don't understand why this must be set, or what happens exactly with this value. And - when player wants to stop the follower walking besides, does it not need to be set back to the regular value? (XNumber.GetValueInt() +1) Thanks for helping me. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted October 15, 2018 Share Posted October 15, 2018 Why does that need to be set? When the follower goes into walk beside mode, they are within greeting distance range and will start talking non-stop at the player. Thus the greeting distance gets adjusted so that the player does not get annoyed by constant chatter. This value does not need to be set back, but it can be if one desires. It only governs the distance away an NPC must be before they will say their random lines at the player. Force greets still happen no matter this setting. On the single follower version of Followers as Companions that setting gets set when the MCM menu is closed. It is either restored to the value it was initially before the feature was activated in the MCM or it uses one less the distance of the X coordinate position from the player. And because the change does not persist across save games there is a maintenance block on an alias script to set the value to either the original before the feature was activated or to one less than the distance of the X coordinate from the player. tonycubed2 modified the mod to work with multiple followers via dialogue and to not edit the stock quest that manages followers. Where they ended up needing to set the greet distance or restore the greet distance, I have no idea. Here are my uses from the single follower version if that helps: MCM script snippet Float Property TalkDist = 0.0 Auto Hidden Event OnConfigInit() If TalkDist == 0.0 TalkDist = Game.GetGameSettingFloat("fAIMinGreetingDistance") ; Debug.Trace("FAC: NPC Greeting Distance = "+TalkDist) EndIf EndEvent Event OnConfigClose() PlayerRef = Game.GetPlayer() If UseUninstall == false UnregisterForAllKeys() RegisterForKey(HKST) RegisterForKey(HKEP) RegisterForKey(HKSB) PFPScript.BackAngle = UseYAngle PFPScript.BackDist = UseYDist PFPScript.RightAngle = UseXAngle PFPScript.RightDist = UseXDist PFPScript.UpAngle = UseZAngle PFPScript.UpDist = UseZDist If USENoPush == true RegisterForMenu("Dialogue Menu") EndIf If abimFWalkAtSide.GetValueInt() > 0 Game.SetGameSettingFloat("fAIMinGreetingDistance", (UseXDist - 1)) ; Debug.Trace("FAC: NPC Greeting Distance = "+(UseXDist - 1)) EndIf If Follower.GetActorReference() Follower.GetActorReference().EvaluatePackage() EndIf If Animal.GetActorReference() Animal.GetActorReference().EvaluatePackage() EndIf If USENotes == true Debug.Notification("$Follower re-evaluating AI package stack.") EndIf Else UnregisterForAllKeys() UnregisterForMenu("Dialogue Menu") UnregisterForActorAction(7) UnregisterForActorAction(9) UnregisterForAnimationEvent(PlayerRef, "tailSneakIdle") UnregisterForAnimationEvent(PlayerRef, "tailSneakLocomotion") UnregisterForAnimationEvent(PlayerRef, "tailMTIdle") UnregisterForAnimationEvent(PlayerRef, "tailMTLocomotion") Game.SetGameSettingFloat("fAIMinGreetingDistance", TalkDist) ; Debug.Trace("FAC: NPC Greeting Distance = "+TalkDist) USENotes = false ; default value SetToggleOptionValue(OIDNotes, USENotes) USENoPush = false ; default value SetToggleOptionValue(OIDNoPush, USENoPush) UseUninstall = false ;default value SetToggleOptionValue(OIDUninstall, UseUninstall) HKST = -1 SetKeyMapOptionValue(OIDST,HKST) HKEP = -1 SetKeyMapOptionValue(OIDEP,HKEP) HKSB = -1 SetKeyMapOptionValue(OIDEP,HKSB) UseXDist = 70.0 SetSliderOptionValue(OIDXDist, UseXDist) UseYDist = 25.0 SetSliderOptionValue(OIDYDist, UseYDist) UseZDist = 0.0 SetSliderOptionValue(OIDZDist, UseZDist) UseXAngle = 0.0 SetSliderOptionValue(OIDXAngle, UseXAngle) UseYAngle = 0.0 SetSliderOptionValue(OIDYAngle, UseYAngle) UseZAngle = 0.0 SetSliderOptionValue(OIDZAngle, UseZAngle) ShowMessage("$Mod safe to uninstall") EndIf EndEvent player alias snippet Event OnPlayerLoadGame() If MCMScript.TalkDist == 0.0 MCMScript.TalkDist = Game.GetGameSettingFloat("fAIMinGreetingDistance") ; Debug.Trace("FAC: NPC Greeting Distance = "+MCMScript.TalkDist) EndIf If abimFWalkAtSide.GetValueInt() == 1 Game.SetGameSettingFloat("fAIMinGreetingDistance", (MCMScript.UseXDist - 1)) ; Debug.Trace("FAC: NPC Greeting Distance = "+(MCMScript.UseXDist - 1)) Else Game.SetGameSettingFloat("fAIMinGreetingDistance", MCMScript.TalkDist) ; Debug.Trace("FAC: NPC Greeting Distance = "+MCMScript.TalkDist) EndIf EndEvent Link to comment Share on other sites More sharing options...
Tasheni Posted October 15, 2018 Author Share Posted October 15, 2018 Ah, of course! With a follower right and left firing all dialogue that was written under the category hello - ha ha!I tried your mod before integrating, the single and the multiple version and I looked through every script in both versions. I decided to keep it simple without mcm and using dialogue instead. The version from tonycubed2 was confusing and in my opinion not the best solution to mix it with the single version. In the multiple version the mcm has no function but to show messages if configured. No other setting works, so it's not useful. I adapted it for my custom followers. I cleaned out all the unnecessary stuff and made a single quest that has the alias script, the packages with scripts and the dialogue with scripts alltogether. Your code is very clear and logical and I figured out all (you know I'm a scripting noob) but this one line of code. I will look at this mcm script to learn, thanks for posting it.I have now two followers that walk besides player, with sometimes funny behaviour. Sometimes they walk backwards or sidewards, but if player moves in a certain way they start to behave correctly. Sometimes both of them walk on the same side of the player what looks very cool but shows, that the game is not able to process the distance correctly. I will implement that for all six followers and play around with the values - let's see where it goes :)A weird thing is the package. It's a follow package and not FollowPlayer. I assigned more conditions on it, so it should not run if player is in interiors or has unequipped weapons and spells. But the package stops working. I deleted the conditions and had only the faction and GetIsId assigned and it runs. I know I did nothing wrong because I have several packages with these conditions that run without problems. I will test the FollowPlayer package instead. That should work.Thank you very much, dear Ishara, that you did this great mod and let others (me) use your work. And thanks for your explanations. Good night. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted October 15, 2018 Share Posted October 15, 2018 If your followers are custom, you may want to take a look at Vilja. That author added in the walk beside ability and Vilja does not have many of the issues that plague adding it to stock followers (i.e. walking in the wrong direction etc...) Link to comment Share on other sites More sharing options...
Tasheni Posted October 16, 2018 Author Share Posted October 16, 2018 Yes, I know, I've read through all the comments under your mod. I want to do that, but Vilja's scripts are well advanced class and I understand certain lines but there's far more I don't understand. I will do that and maybe I will get wiser. Link to comment Share on other sites More sharing options...
Tasheni Posted October 16, 2018 Author Share Posted October 16, 2018 Update: I was able to implement this in exact the same way like Vilja has, but follower has the same issues as before. I tested on a new game. And I experience that follower stops following after going through a load door. Maybe that Vilja has other mechanism to control that, but I can't figure that out. Link to comment Share on other sites More sharing options...
ReDragon2013 Posted October 16, 2018 Share Posted October 16, 2018 No idea.. next is what you are looking for or not? TestFollowerAliasScript Scriptname TestFollowerAliasScript extends ReferenceAlias ; We assume this script is attached to Follower alias, which is part of a quest. ; https://forums.nexusmods.com/index.php?/topic/7071626-can-someone-explain-me-a-certain-line-in-a-script/ ; Tasheni wrote: "I experience that follower stops following after going through a load door." ; -- EVENTs -- 2 EVENT OnCellLoad() cell cc = self.GetReference().GetParentCell() cell pc = Game.GetPlayer().GetParentCell() Debug.Trace("OnCellLoad() - NPC = " +cc+ ", player = " +pc) ; just for information ENDEVENT EVENT OnLocationChange(Location akOldLoc, Location akNewLoc) gotoState("Busy") ; ### STATE ### myF_Distance(akOldLoc, akNewLoc) gotoState("") ; ### STATE ### back to normal state ENDEVENT ;=========================== state Busy ; I am busy! ;========= EVENT OnLocationChange(Location akOldLoc, Location akNewLoc) ENDEVENT ;======= endState ; -- FUNCTIONs -- 2 ;----------------------------------------------------------- FUNCTION myF_Distance(Location akOldLoc, Location akNewLoc) ;----------------------------------------------------------- IF ( akNewLoc ) ELSE RETURN ; - STOP - location is <None>, almost in the wilderness ENDIF ;--------------------- Utility.Wait(0.5) ; give other scripts runtime actor aRef = self.GetActorReference() cell cc = aRef.GetParentCell() cell pc = Game.GetPlayer().GetParentCell() IF (cc == pc) RETURN ; - STOP - same cell do nothing ENDIF ;--------------------- myF_TryMoving(aRef) ENDFUNCTION ;---------------------------------- FUNCTION myF_TryMoving(Actor aRef) ;---------------------------------- actor player = Game.GetPlayer() IF player.IsSprinting() RETURN ; - STOP - is sprinting, do not move any actor ENDIF ;--------------------- IF player.HasLOS(aRef) RETURN ; - STOP - is in the Line Of Sight ENDIF ;--------------------- IF (player.GetDistance(aRef) < 3000) ; 3000 units, maybe adjustable RETURN ; - STOP - follower is near the player ENDIF ;--------------------- aRef.DisableNoWait() ; invisible aRef.MoveTo(player) aRef.Enable(TRUE) ; enable again after moving Utility.Wait(0.25) aRef.EvaluatePackage() ; update package stack, this could make noises like weapon draw ENDFUNCTION Greetings Link to comment Share on other sites More sharing options...
Tasheni Posted October 17, 2018 Author Share Posted October 17, 2018 (edited) Hello Redragon, thank you very much for your script, I tried that, but it doesn't solve the problem in this special case. I switched back to Ishara's code that works solid, the code that Vilja uses is simple, but the behaviour of the actors seems to be more weird.In both implementations is the issue, that the followers don't turn round with the player, if player changes direction. They will then start walking backwards or sidewards. Is there a way to let them always turn in the direction the player looks, through a script? Edited October 17, 2018 by Tasheni Link to comment Share on other sites More sharing options...
ReDragon2013 Posted October 22, 2018 Share Posted October 22, 2018 (edited) You asked: "the followers don't turn round with the player, if player changes direction. They will then start walking backwards or sidewards.Is there a way to let them always turn in the direction the player looks, through a script?" Maybe like this, but I have no experience akActor.SetHeadTracking(TRUE)about the Vilja Mod, you wrote: "Maybe that Vilja has other mechanism to control that, but I can't figure that out."the author is using factions and packages to manage distance (and walk by side) of follower 1) AAEM_FlwDistanceCloser.psc ;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment ;NEXT FRAGMENT INDEX 1 Scriptname AAEM_FlwDistanceCloser extends TopicInfo Hidden Faction PROPERTY AAEMSideBySideFaction auto Faction PROPERTY AAEMDistancefaction auto ;BEGIN FRAGMENT Fragment_0 Function Fragment_0(ObjectReference akSpeakerRef) Actor akSpeaker = akSpeakerRef as Actor ;BEGIN CODE akSpeaker.SetFactionRank(AAEMDistancefaction, 0) ; @line 9 akSpeaker.RemoveFromFaction(AAEMSideBySideFaction) ; @line 10 akSpeaker.EvaluatePackage() ; @line 11 ;END CODE EndFunction ;END FRAGMENT ;END FRAGMENT CODE - Do not edit anything between this and the begin comment AAEM_FollowerDistanted.psc ;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment ;NEXT FRAGMENT INDEX 1 Scriptname AAEM_FollowerDistanted extends TopicInfo Hidden Faction PROPERTY AAEMSideBySideFaction auto Faction PROPERTY AAEMDistancefaction auto ;BEGIN FRAGMENT Fragment_0 Function Fragment_0(ObjectReference akSpeakerRef) Actor akSpeaker = akSpeakerRef as Actor ;BEGIN CODE akSpeaker.SetFactionRank(AAEMDistancefaction, 1) ; @line 9 akSpeaker.RemoveFromFaction(AAEMSideBySideFaction) ; @line 10 akSpeaker.EvaluatePackage() ; @line 11 ;END CODE EndFunction ;END FRAGMENT ;END FRAGMENT CODE - Do not edit anything between this and the begin comment2) PF_AAEMFollowTarget2_011FB205.psc ;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment ;NEXT FRAGMENT INDEX 1 Scriptname PF_AAEMFollowTarget2_011FB205 extends Package Hidden Actor PROPERTY Viljaref auto Faction PROPERTY AAEMXFactor auto ;BEGIN FRAGMENT Fragment_0 Function Fragment_0(Actor akActor) ;BEGIN CODE Viljaref.AddToFaction(AAEMXFactor) ; @line 8 ;END CODE EndFunction ;END FRAGMENT ;BEGIN FRAGMENT Fragment_1 Function Fragment_1(Actor akActor) ;BEGIN CODE Viljaref.RemoveFromFaction(AAEMXFactor) ; @line 16 ;END CODE EndFunction ;END FRAGMENT ;END FRAGMENT CODE - Do not edit anything between this and the begin comment 3) PF_AAEMFollowSidebyside_01263094.psc ;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment ;NEXT FRAGMENT INDEX 1 Scriptname PF_AAEMFollowSidebyside_01263094 extends Package Hidden Actor PROPERTY Viljaref auto Faction PROPERTY AAEMBesidePlayer auto Float PROPERTY sidedistance auto ; [default=0] ;BEGIN FRAGMENT Fragment_2 Function Fragment_2(Actor akActor) ;BEGIN CODE Viljaref.ClearKeepOffsetFromActor() ; @line 8 Viljaref.ModActorValue("CarryWeight", 0.001) ; @line 9 Viljaref.ModActorValue("CarryWeight", -0.001) ; @line 10 Viljaref.EvaluatePackage() ; @line 11 Viljaref.RemoveFromFaction(AAEMBesidePlayer) ; @line 12 ;END CODE EndFunction ;END FRAGMENT ;BEGIN FRAGMENT Fragment_0 Function Fragment_0(Actor akActor) ;BEGIN CODE Viljaref.AddToFaction(AAEMBesidePlayer) ; @line 20 Viljaref.SetFactionRank(AAEMBesidePlayer, 1) ; @line 21 Viljaref.ClearKeepOffsetFromActor() ; @line 22 Viljaref.ModActorValue("CarryWeight", 0.001) ; @line 23 Viljaref.ModActorValue("CarryWeight", -0.001) ; @line 24 int RandomSide = Utility.RandomInt(1, 2) ; @line 25 float SideDistanceValue = 64.0 ; @line 26 IF (RandomSide == 1) ; @line 28 sidedistance = SideDistanceValue * -1.0 ; @line 29 left side: negativ ELSEIF (RandomSide == 2) ; @line 30 sidedistance = SideDistanceValue ; @line 31 right side: positiv ENDIF ; https://www.creationkit.com/index.php?title=KeepOffsetFromActor_-_Actor ; "The default values will cause the follower to continually run into the target, use larger values instead." ; 64.0 = afCatchUpRadius Viljaref.KeepOffsetFromActor(Game.GetPlayer(), sidedistance, 24.0, 0.0, 0.0, 0.0, 0.0, 64.0, 0.0) ; @line 34 Viljaref.ModActorValue("CarryWeight", 0.001) ; @line 35 Viljaref.ModActorValue("CarryWeight", -0.001) ; @line 36 ;END CODE EndFunction ;END FRAGMENT ;BEGIN FRAGMENT Fragment_1 Function Fragment_1(Actor akActor) ;BEGIN CODE Viljaref.ClearKeepOffsetFromActor() ; @line 45 Viljaref.ModActorValue("CarryWeight", 0.001) ; @line 46 Viljaref.ModActorValue("CarryWeight", -0.001) ; @line 47 Viljaref.EvaluatePackage() ; @line 48 Viljaref.RemoveFromFaction(AAEMBesidePlayer) ; @line 50 ;END CODE EndFunction ;END FRAGMENT ;END FRAGMENT CODE - Do not edit anything between this and the begin comment Edited October 22, 2018 by ReDragon2013 Link to comment Share on other sites More sharing options...
Tasheni Posted October 23, 2018 Author Share Posted October 23, 2018 (edited) I looked at the side by side walking implementation in Vilja already and did it the same way. The same things happened: When player turns some degrees left or right, followers stay in the position they were when started walking and thus turn side or backwards. Headtracking must be disabled like Ishara did, because things get worse if followers permanently look at the player. Sometimes it helps to stop and wait a moment, the followers always turn to player and if player walks again, they sometimes manage to turn in the right direction. Sometimes they turn side or backwards if the navmesh lets them stumble.The game knows exactly in which direction the player is looking, so I guess this could perhaps be used to turn the followers in that direction. But I don't know how the script would look like, I haven't yet read through the necessary wiki articles.Thank you very much for your answer, that's much appreciated. Edited October 23, 2018 by Tasheni Link to comment Share on other sites More sharing options...
Recommended Posts