Jump to content

[LE] Function OnInit problem


Tasheni

Recommended Posts

Hello ReDragon2013, thank you for your script. Yes, that's really cool to use only one script, I wanted to do that, too, but for some reason didn't get that to work. Now it will :) Dosh, overlooked that GetEquippedObject is SKSE function. Thanks for pointing me on it.

 

No, the ReferenceAlias script is not running on playerAlias anymore. I changed that because it was too slow to mount the followers.

I attached my script to each follower ReferenceAlias inside one quest, so six scripts are running at the same time to mount the followers at once:

 

Soupdragon 1234 wrote: Part of the problem of them not mounting fast enough is that its a single threaded script it has to run through and check each and every single follower one by one, daisy chain fashion until it reaches the end.

 

I got around the problem on my mod by making it multi-threaded each follower alias has copy of the same script that will fire upon player mount/dismount. The script itself is short and the event fires for each follower simulaneously making it much more efficient.

 

So OnPlayerLoadGame will not work. Of course I can use the same script on a playerAlias, too. Makes that sense or is it overkill?

 

I had to change my script started dialogue quests back to start game enabled. I discovered that dialogue will be repeated despite flagged as say once, if the quests are not start game enabled. I didn't know, but this may not happen.

 

; playerAlias script only:
; self.GetReference() == Game.GetPlayer() as ObjectReference
; self.GetActorReference() == Game.GetPlayer()

 

Is it not possible here to use a property playerRef?

 

 

Debug.SendAnimationEvent(theNPC as ObjectReference, "Jumpland") ; "is more reliable than IdleForceDefaultState" (*)

 

Good to know, thank you.

 

I think I understand that script. The functions allow to use properties for the horses and followers and you just call the functions inside the event. So the same script can be attached to all followers. I will implement that immediately and delete the other scripts.

But the OnInit problem still exists.

 

Thank you for your patience with me. ;)

Link to comment
Share on other sites

You wrote: "I think I understand that script."

A had to think about your implementation.

It would be a good idea to add a playeralias into your "frame quest" as replacement for the 6 followerAlias scripts. That means the assigned playerAlias script is running all the time regardeless of a running followerquests.

 

_MountPlayerAliasScript v2

 

Scriptname _MountPlayerAliasScript extends ReferenceAlias
; https://forums.nexusmods.com/index.php?/topic/10690973-function-oninit-problem/

;scriptName _ChiomaraPlayerMountMonitorScript extends ReferenceAlias
;scriptName _RubyPlayerMountMonitorScript extends ReferenceAlias


  Faction PROPERTY CurrentFollowerFaction auto
 
  VisualEffect PROPERTY Effect auto
  Float fEffectTime = 0.3


  Actor PROPERTY theNPC auto Hidden
      ; 1 Chiomara,
      ; 2 Ruby
 
  Actor PROPERTY theHorse auto Hidden
      ; 1 Dubha,
      ; 2 Assan


;-- EVENTs -- 4

EVENT OnInit()
    RegisterForSingleUpdate(2.0)
ENDEVENT

EVENT OnPlayerLoadGame()
    RegisterForSingleUpdate(2.1)
ENDEVENT

EVENT OnUpdate()
    Utility.Wait(1.0)

    objectReference player = self.GetReference()                    ; self.GetReference() == Game.GetPlayer() as ObjectReference  // playerAlias script only
    IF ( player )
        Debug.Trace("tailHorse animations will be register for " +self)        ; see "papyrus.0.log"

        RegisterForAnimationEvent(player, "tailHorseMount")         ; register for mount animation (start horse riding)
        RegisterForAnimationEvent(player, "tailHorseDismount")      ; register for dismount        (stop horse riding)
    ENDIF
ENDEVENT


EVENT OnAnimationEvent(Objectreference akSource, String asEventName)
    myF_Anim(asEventName == "tailHorseMount")
ENDEVENT


;-- FUNCTIONs -- 5

;------------------------------------------------------------
FUNCTION SetActors(ReferenceAlias FollowerAlias, Actor Horse)  ; external called by quest fragments
;------------------------------------------------------------
;;;    (PlayerAlias as _MountPlayerAliasScript).SetActors(FollowerAlias, Horse)

    theNPC = FollowerAlias.GetActorReference()
    theHorse = Horse
ENDFUNCTION


;------------------------
FUNCTION myF_Anim(Bool b)
;------------------------
IF ( theNPC )
ELSE
    RETURN    ; - STOP - /1    there is no follower assigned
ENDIF
;---------------------
IF theNPC.IsInFaction(CurrentFollowerFaction)
ELSE
    RETURN    ; - STOP - /2    npc is not a real follower at time
ENDIF
;---------------------
IF (theNPC.GetActorValue("WaitingForPlayer") == 0)
ELSE
    RETURN    ; - STOP - /3    npc is waiting for the player
ENDIF
;---------------------
IF myF_IsHandToHand()
    RETURN    ; - STOP - /4    npc does not have anything equipped by hand
ENDIF
;---------------------
    IF ( b )                    ; == TRUE, player mounted a horse
;;;        Debug.SendAnimationEvent(theNPC as ObjectReference, "IdleForceDefaultState")    ; play special idle here
        Debug.SendAnimationEvent(theNPC as ObjectReference, "Jumpland")                    ; (*)

        Effect.Play(theNPC as ObjectReference, fEffectTime)        ; https://www.creationkit.com/index.php?title=Play_-_VisualEffect

        MoveHorseToNPC()
        Utility.Wait(0.1)
        myF_FixAI(TRUE)
    ELSE                        ; == False, player dismount a horse
        Utility.Wait(0.1)
        IF theNPC.Dismount()    ; "No need to declare this as a bool it just waits till they dismount to continue below" (*Sphered)  ???
            myF_FixAI(False)
        ENDIF
    ENDIF
ENDFUNCTION


;-------------------------------
Bool FUNCTION myF_IsHandToHand()  ; helper
;-------------------------------
IF theNPC.GetEquippedItemType(0)            ; leftHand
    Return False
ENDIF
;---------
IF theNPC.GetEquippedItemType(1)            ; rightHand
    Return False
ENDIF
;---------
    Return TRUE            ; 0: Nothing (Hand to hand)
ENDFUNCTION


;-------------------------
FUNCTION myF_FixAI(Bool b)  ; helper
;-------------------------
; "I have to assume your AIPack is telling your follower to mount at this point otherwise you need to activate the horse" (*Sphered)

    theNPC.SetAnimationVariableBool("bIsRiding", b)     ; "Is this necessary though?" (*)
    theNPC.EvaluatePackage()                            ; "Their package stack should be using IsMounted etc checks" (*)
ENDFUNCTION


;------------------------
FUNCTION MoveHorseToNPC()  ; helper, code outsourced for better overview and maintenance
;------------------------
    float aZ = theNPC.GetAngleZ() + 90.0        ; get the angleZ and add 90 degree
    float fx = Math.SIN(aZ) * 52.5
    float fy = Math.COS(aZ) * 52.5

IF ( theHorse )
    theHorse.MoveTo(theNPC as ObjectReference, fx, fy, 0.0, TRUE)
ENDIF
ENDFUNCTION


; Chiomora
;    myHorse.MoveTo(myFollower as objectreference, 50.0000 * math.sin(myFollower.GetAngleZ() + 90.0000), 50.0000 * math.cos(myFollower.GetAngleZ() + 90.0000), 0.000000, true)
;    utility.Wait(0.100000)

; Ruby
;    myHorse.MoveTo(myFollower as objectreference, 55.0000 * math.sin(myFollower.GetAngleZ() + 90.0000), 55.0000 * math.cos(myFollower.GetAngleZ() + 90.0000), 0.000000, true)
;    ;utility.Wait(0.100000)

 

 

 

Change the quest fragment script to make a handshake with PlayerAlias script, to write down the current follower and related horse.

  ReferenceAlias PROPERTY PlayerAlias auto

; next two properties depends on your fragment quest script
  ReferenceAlias PROPERTY ChimoraAlias auto   ; FollowerAlias 1
  Actor PROPERTY Dubha auto                   ; Horse 1
(PlayerAlias as _MountPlayerAliasScript).SetActors(FollowerAlias, Horse)
Edited by ReDragon2013
Link to comment
Share on other sites

 

It would be a good idea to add a playeralias into your "frame quest" as replacement for the 6 followerAlias scripts.

No, not as a replacer. I had that first and mounting was faster than before, but still too slow. Soupdragon1234 mentioned that performance is better with copies of the mounting script on each follower alias and he was right. That's why I asked if it's of advantage to add the script to the player alias, together with the copies on the follower aliases. I would like to find a solution for the OnInit problem not firing anymore, if player changes race. If I remember right, I tried this with OnPlayerLoadGame, too, but this didn't work either.

 

Had no time today to implement your version of the script, but will do. It's better than mine. Then I will test and report back. Thank you for helping me. It's much appreciated.

Link to comment
Share on other sites

Your first script gives me an compile error:

IF (asEventName == "tailHorseDismount")
    int i = 10
    WHILE (i)
        Utility.Wait(0.1)
        IF theNPC.Dismount()           
            myF_FixAI(False)
            RETURN    ; - STOP - /4a    theNPC is dismounted as well
        ENDIF
;        ----------------------
        i = i - 1        ; decrease counter to have an escape option for this loop
    ENDWHILE
    RETURN    ; - STOP - /4b    player is dismounted
ENDIF

Error: ... no viable alternative at character "-"

no viable alternative at input "i"

I can't see what's wrong with it,should compile fine.

 

 

I have a separate quest for the monitoring of player mounting. It's not my frame quest for the storyline.

All followers have a referenceAlias here with the mounting script attached I posted at the start of this topic.

 

I added now the playerAlias and attached your script version 2 to it. Compiles fine.

To make it short: I have no idea where to put this:

Change the quest fragment script to make a handshake with PlayerAlias script, to write down the current follower and related horse.

  ReferenceAlias PROPERTY PlayerAlias auto

; next two properties depends on your fragment quest script
  ReferenceAlias PROPERTY ChimoraAlias auto   ; FollowerAlias 1
  Actor PROPERTY Dubha auto                   ; Horse 1

(PlayerAlias as _MountPlayerAliasScript).SetActors(FollowerAlias, Horse)

In the script fragment of quest stage 0 of my frame quest?

The PlayerMountingQuest is started by script fragment 1 and fragment 3 in my frame quest (either player goes through Helgen intro or plays Alternate Start). And all npcs my mod adds have aliases here. Don't know if it's a good idea, but quest design for a story is new to me.

 

Or would it be better to set it in the first stage script fragment of my playerMounting quest? :unsure:

 

Link to comment
Share on other sites

Sorry I am late.

 

about this

 

Your first script gives me an compile error:

IF (asEventName == "tailHorseDismount")
int i = 10
WHILE (i)
Utility.Wait(0.1)
IF theNPC.Dismount()
myF_FixAI(False)
RETURN ; - STOP - /4a theNPC is dismounted as well
ENDIF
; ----------------------
i = i - 1 ; decrease counter to have an escape option for this loop
ENDWHILE
RETURN ; - STOP - /4b player is dismounted
ENDIF

Error: ... no viable alternative at character "-"

no viable alternative at input "i"

I can't see what's wrong with it,should compile fine.

 

 

 

I copy and paste both script versions of _MountPlayerAliasScript.psc I posted here, and both versions compiled without error message.

 

You wrote: "I have no idea where to put this:"

and also "In the script fragment of quest stage 0 of my frame quest?" or "Or would it be better to set it in the first stage script fragment of my playerMounting quest?"

 

Please post the script(s) which is starting each of your builded NPC as as player follower.

You mentioned to use quest stages for each follower, that means there should exist a quest fragment script like this "qf_<formID>.psc"

 

And it would be a good idea to explain how many quests exists, and which have scripts and the script names. Or send me the the current mod.esp via PM. I will look into the file with TesVEdit.

Edited by ReDragon2013
Link to comment
Share on other sites

You seem to be having a time with this so I adapted the approach I use into a demo to show a different way you can have follower mounting with ease

 

I since infer you arent using SKSE? Why lol? The AI package is the main part anyhow so ignore the rest and feel free to use it as a template to incorporate into whatever you use to have them reliably mount when you do. The important part is to ensure the summoned entity sets either your followers actorbase or a faction the follower is in, to be its owner so the follower can mount it. The faction, if you go that route, has to be flagged as able to be owner. But yeah, works smoothly

 

https://www.dropbox.com/s/q40cowjlni8s11h/EZMountDemo.zip?dl=0

Link to comment
Share on other sites

@sphered

Thank you so much for your help. It's not that my script is generally not working. It just stops working if player changes race. But I will look inside your esp and the script you posted. For learning purposes ;)

 

@ReDragon2013

I'm thankful that you want to invest your time into this. I will send you the mod via PM the next days. You will find a lot of things that could have done better, I'm sure. But I hope it's not that worse anymore like some years ago, do you remember? ;)

Link to comment
Share on other sites

  • Recently Browsing   0 members

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