Jump to content

[LE] Ride and talk horse - script needs improvement


Tasheni

Recommended Posts

Ah, thank you for this explanation, it's very helpful. I know this ck website, using it very often but overlooked the extends part. Think this is because I'm using mostly script fragments where the extended script is automatically used - I have to pay more attention to it.

Alright, I will dive deeper into that matter.

 

Do not use different scripts to hold the same References, that is very bad.

 

I have different dialogs and these trigger scripts and in them I use of course the same refs, because I manipulate the same things, don't know how to do it other way. Also PlayerRef is many times used in different scripts of other mods, is that bad?

 

 

So the way to do it right would be to create a mainscript with all necessary functions and events and attach it to the scripts tab inside a quest and than only using fragments of it? So the refs would be only inside the mainscript?

Link to comment
Share on other sites

Having the same object used in multiple scripts is just fine (well, except when those scripts try to do different things and cause a fight). The persistence problem is outlined here: https://www.creationkit.com/index.php?title=Persistence_(Papyrus)

 

Explicitly assigning PlayerRef as a property has no problems, because the player is already persistent, but doing so with other objects can lead to save bloat and slowdown.

Link to comment
Share on other sites

Thank you for your code, Ishara, but I have a question: If I remove the ring via script into a container, what happens then with the script attached to the ring? Because it runs when player unequip the ring and then change the horse. Is it not the same when I remove the ring - player must unequip it first - or doesn't it affect this event?

 

I will try it out. I already have a dummycell and a chest is easy to implement there. It will take some days because of real life ;(

 

Thank you so much for now, I report back.

If you are having the player equip the ring in order to swap the actor one direction and then unequip the ring to swap them back, yes it would be a problem as the unequip event would be triggered when removed. To work around this issue, use a single equip event for both. Something like:

 

 

Bool bRidingHorse = false

Event OnEquipped(Actor akActor)
  If bRidingHorse == false
    ;swap from talking horse to riding horse
    ValaNPC.Disable()
    ValaHorse.Enable()
    bRidingHorse = true
    PlayerRef.UnequipItem(Self)
    ;anything else needed
  Else
    ;swap from riding horse to talking horse
    ValaHorse.Disable()
    ValaNPC.Enable()
    bRidingHorse = false
    ;anything else needed
  EndIf
EndEvent 

With the above you can safely move the ring to a container when the player is riding a horse and move it back when they stop riding the horse.

 

 

Link to comment
Share on other sites

I know is not easy to learn things which are not really evidently. So I will try my best to make it not to complicated.

 

Tasheni_ValaQuestScript

 

Scriptname Tasheni_ValaQuestScript extends Quest
{written by ReDragon 2017}    ; attached to the quest used as property "myQuest" in script below

 ; questscript that has the following properties

 ObjectReference PROPERTY ValaNPC   auto    ; Vala in race NPC
 ObjectReference PROPERTY ValaHorse auto    ; Vala in race horse

 

 

 

I assume the following objectRef script is attached to the ring itself. So it does not make sense to use an extra property for the ring.

Additionally I split some event code into functions to get a better overview. Keep in mind I changed the script name.

 

Tasheni_PlayerOnHorseRingEquip

 

Scriptname Tasheni_PlayerOnHorseRingEquip extends ObjectReference
{rewritten by ReDragon 2017}    ; attached to the special ring

; https://forums.nexusmods.com/index.php?/topic/5553117-ride-and-talk-horse-script-needs-improvement/page-2

  Quest PROPERTY myQuest auto                ; put in the controller quest,
 
 ; which has attached a questscript that has the following properties

 ;ObjectReference PROPERTY ValaNPC   auto    ; Vala in race NPC
 ;ObjectReference PROPERTY ValaHorse auto    ; Vala in race horse

 ;Actor Property Vala         auto
 ;Actor Property ValaNPCActor auto

 ;Armor Property Ring auto
  Armor Property Saddle auto
  Armor Property NPCSaddle auto

  MiscObject Property MiscItemSaddle auto


; -- EVENTs -- 2 + "Done"

EVENT OnUnequipped(Actor akActor)    ; turn Vala into NPC
;=================
IF (akActor == Game.GetPlayer())
ELSE
    RETURN    ; - STOP -    we are only interested on player equipping
ENDIF
;--------------------- from here akActor is equal to fomer used "playerRef"
IF akActor.IsOnMount()
    myF_Revert(akActor, 1)
    RETURN    ; - STOP - prevents player from unequipping ring while mounted
ENDIF
;---------------------
    objectReference oRef = myF_GetHorseRef(1)    ; oRef = (myQuest as Tasheni_ValaQuestScript).ValaHorse
IF ( oRef )
    oRef.Disable()
;;; ValaHorse.Disable()
ELSE
    RETURN    ; - STOP -    missing property or quest script
ENDIF
;---------------------
    oRef = myF_GetHorseRef(0)                    ; oRef = (myQuest as Tasheni_ValaQuestScript).ValaNPC
    oRef.Enable(TRUE)
;;; ValaNPC.Enable()

    ; saddle should not be removed by the ring, only via player dialog
    myF_Action(akActor, oRef, NPCSaddle, False)
ENDEVENT


EVENT OnEquipped(Actor akActor)        ; if ring is equipped by player, turn Vala into a horse and saddle up.
;===============
IF (akActor == Game.GetPlayer())
ELSE
    RETURN    ; - STOP -    we are only interested on player equipping
ENDIF
;--------------------- from here akActor is equal to fomer used "playerRef"
IF akActor.IsOnMount()
    myF_Revert(akActor, 0)
    RETURN    ; - STOP - prevents player from equipping ring while mounted because game will crash.
ENDIF
;---------------------
    objectReference oRef = myF_GetHorseRef(0)    ; oRef = (myQuest as Tasheni_ValaQuestScript).ValaNPC
IF ( oRef )
    oRef.Disable()
;;; ValaNPC.Disable()
ELSE
    RETURN    ; - STOP -    missing property or quest script
ENDIF
;---------------------
    oRef = myF_GetHorseRef(1)                    ; oRef = (myQuest as Tasheni_ValaQuestScript).ValaHorse
    oRef.Enable(TRUE)
;;; ValaHorse.Enable()

    myF_Action(akActor, oRef, Saddle, TRUE)
ENDEVENT


;===============================
state Done        ; to cover the opposite event
;=========
EVENT OnUnequipped(Actor akActor)
    ; akActor.UnequipItem(Ring, TRUE, TRUE)
ENDEVENT

EVENT OnEquipped(Actor akActor)
    ; akActor.EquipItem(Ring, False, TRUE)
ENDEVENT
;=======
endState


; -- FUNCTIONs -- 3

;------------------------------------------
FUNCTION myF_Revert(Actor playerRef, Int i)
;------------------------------------------
    gotoState("Done")                ; ### STATE ###
IF (i == 1)
    Debug.Notification("You must dismount before removing the ring")
    playerRef.EquipItem(self as Form, False, TRUE)
ELSE
    ; avoid using the ring while mounted because game will crash
    Debug.Notification("You must dismount before using the ring")
    playerRef.UnequipItem(self as Form, TRUE, TRUE)
ENDIF
    Utility.Wait(0.1)
    gotoState("")                    ; ### STATE ### back to no state
ENDFUNCTION

;----------------------------------------------
ObjectReference FUNCTION myF_GetHorseRef(Int i)
;----------------------------------------------
    Tasheni_ValaQuestScript ps = myQuest as Tasheni_ValaQuestScript
IF ( !ps )
    Debug.Notification("Quest property or script is missing!")
    RETURN None                ; objectRef is <None>
ENDIF
;=========
IF (i == 0)
    RETURN ps.ValaNPC        ; i=0 -> NPC
ENDIF
;---------
;IF (i == 1)
    RETURN ps.ValaHorse      ; i=1 -> Horse
;ENDIF
ENDFUNCTION

;---------------------------------------------------------------------------------
FUNCTION myF_Action(Actor playerRef, ObjectReference oRef, Armor AR, Bool bRemove)
;---------------------------------------------------------------------------------
; playerRef = akActor
; oRef = ValaNPC or ValaHorse
; AR   = NPCSaddle or Saddle

    IF ( bRemove )
        int i = playerRef.GetItemCount(MiscItemSaddle)    ; How many vanilla saddle has the player?
        IF (i > 0)
            ; player has the saddle in his inventory
            playerRef.RemoveItem(MiscItemSaddle, 1)        ; remove one saddle from player and let horse equip it
        ENDIF
    ENDIF

    (oRef as Actor).EquipItem(AR as Form)

    float az = playerRef.GetAngleZ()     ; teleport horse near player - thank you cdcooley
    float fx = Math.SIN(az) * 80.0
    float fy = Math.COS(az) * 80.0
    oRef.MoveTo(playerRef as ObjectReference, fx, fy, 10.0, 0)

    (oRef as Actor).EvaluatePackage()
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

 

I know is not easy to learn things which are not really evidently. So I will try my best to make it not to complicated.

I'm so thankful that you invest your time in my undertakings. I think I fully understand this script and even understand better the logic behind Papyrus concepts. I will implement it soon and with yours and Isharas help this should work now like a charm. I report back. I'm very happy.

 

At the moment my head is full with Skyrim's magic and the lore of it, because I've created two magician companions and they should be worth for the player to take with him. So my thoughts go with a trainer that explains the different schools of magic and train with the player visually - similar to the bow training at Angi's Camp that I enjoyed pretty much when first were not too skilled with it. New idea, perhaps I should stay with the elder ones I got before it raises over my head :)

 

Until next time and have a nice day.

Link to comment
Share on other sites

I'm ready with it, scripts are implemented and it works pretty nice. My horse is now much more fun to me. And I've learned a lot with all your help. Thank you so much and here is a little gift for you, a song for the night written and performed by me. This is the first I made for Skyrim and the voice is purely recorded without manipulation. Enjoy:

 

Edited by Tasheni
Link to comment
Share on other sites

  • Recently Browsing   0 members

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