Jump to content

[LE] Can someone explain me a certain line in a script?


Tasheni

Recommended Posts

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

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

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

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

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

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

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 by Tasheni
Link to comment
Share on other sites

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 comment

2) 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 by ReDragon2013
Link to comment
Share on other sites

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 by Tasheni
Link to comment
Share on other sites

  • Recently Browsing   0 members

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