Jump to content

I need some help with a script for a follower I'm building.


Recommended Posts

Posted (edited)

Bear with me. I'm new to scripting. I am trying to create a Mimic follower, building off Mihail's mimic creature mod, with an extra feature, where I ask it to "hide me". The screen fades out and a devouring noise is played. When it fades back in, the player character and the mimic are replaced by a chest. I can hide like that for 30 seconds. Any longer and my player character is digested by the mimic and dies. I am running into consistent issues towards the end of the script and I'm kind of drawing a blank. The displayed errors are starting from the last function in the script. If anyone can help me out, I'd massively appreciate it.

 

Scriptname MimicDevouredQuestScript extends Quest

; Constants
DEFINE_INT   MAX_DIGEST_TIME = 30 ; In seconds
DEFINE_FLOAT FADEOUT_DURATION = 2.0 ; In seconds

; Functions

 

FUNCTION OnSwallow()
    ; Start digestion quest and set started time
    QuestStart("MimicDevouredQuest")
    SetQuestStartedTime("MimicDigest", GetGameTime())

 

    ; Play devouring sound
    INT soundHandle = sndPlayBackground("mihailmimicsound/Mimic.wav")

 

    ; Wait for fadeout duration
    Wait(FADEOUT_DURATION)

 

    ; Reduce sound volume after fadeout
    sndSetVolume(soundHandle, 0.5) 

 

    ; Transport player and mimic to new cell
    SetLocation(GetPlayerRef(), GetMimicRef().GetActorLocation())
    SetCell(GetPlayerRef())

 

    ; Create chest object in mimic's place
    ObjectReference ChestRef = PlaceAtMe("ChestModel", GetMimicRef().GetPosition())
    GetMimicRef().SetCollisionEnabled(false) ; Disable mimic collision

 

    ; Lock camera on chest or invisible character
    CameraLockOnObject(ChestRef, true)

 

    ; Start message loop
    MESSAGE_LOOP = TRUE
ENDFUNCTION

 

FUNCTION DigestPlayer()
    ; Increment digest time
    INT CurrentTime = GetGameTime() - GetQuestStartedTime("MimicDigest")

 

    IF (CurrentTime >= MAX_DIGEST_TIME * 1000)
        ; Player was not released, kill them
        
        ; Stop devouring sound when death occurs
        sndStopBackground("mihailmimicsound/Mimic.wav")

 

        Kill(GetPlayerRef())
    ELSEIF (InputGetState(INPUT_R) == INPUT_PRESSED)
        ; Player pressed R, release from mimic
        QuestReset("MimicDigest") ; Reset digestion quest
        SetLocation(GetPlayerRef(), ChestRef.GetPosition() + Vector(0, 0, 10))
        CameraLockOnObject(GetPlayerRef(), false)

 

    ENDIF

 

    IF (CurrentTime < MAX_DIGEST_TIME * 1000 - 20000) ; 20 seconds before death
        DisplayMessage("I need to get out soon or the mimic will digest me!")
    ELSEIF (CurrentTime < MAX_DIGEST_TIME * 1000)
        DisplayMessage("The mimic has started to digest you")
    ENDIF
ENDFUNCTION

 

FUNCTION OnMimicInit()
    MESSAGE_LOOP = FALSE

ENDFUNCTION

 

; Events
FUNCTION PlayerDialogueEvent()
    IF (GetDialogTopic() == "MimicDialogue" AND GetDialogResponse() == "Quick, hide me!")
        OnSwallow()
    ENDIF
ENDFUNCTION

 

; Quests
MimicDevouredQuest = Quest()

 

 

 

Edited by SerpentineStorm
Posted

So again, this is my first time scripting in Papyrus. I've done some minor modding for personal use before and I wanted to try something a bit more elaborate. Though this mod is for personal use, should there be interest from others, I'd be more than happy to upload it when it's finished and tested. Checking the Vortex website, Mihail appears to not have a problem with this kind of mod. But before I publicize it, it needs to be in working condition. Which should be within a few days if I manage to get that script fixed.

Posted (edited)

You really need to learn how to format and code in papyrus before doing this.  Nothing you made is even close to functional.  This is an outline of what you want in a kinda-code-ish format.

 

Learn the format and how it works.  Define your properties.  Start small.  Debug code to know what works and what doesn't.  There are many tutorials on papyrus and it appears you already have some knowledge of coding so you've got a leg-up on most.

 

Some basics:

 

"DEFINE_INT   MAX_DIGEST_TIME = 30 ; In seconds"

should be

 

"float property Max_Digest_time = 30.0 ; in seconds"

Time in papyrus is a float.  You can convert it, but why take the extra step?  This is likely best used as an Event OnUpdate() timer, so RegisterForSingleUpdate(Max_Digest_time) when you need it.  If not used as an OnUpdate() timer, you will need to be polling and then checking the time within the script which just adds lag to a bottleneck-sensitive scripting language.

 

"QuestStart("MimicDevouredQuest")"
"SetQuestStartedTime("MimicDigest", GetGameTime())"

 

should be (some variant of):

 

Quest property MimicDevouredQuest auto ; defined outside the function

MimicDevouredQuest.Start() ; within the function

float property fStartTime = 0.0 ; defined within the related quests' script, and updating to match current game time when initiated if that's what you really want

 

If this is intended to be part of a single script for that quest -- the "start" function will never fire because the script won't be activated without the quest already started.  This is typically dealt with using a "Starter" quest that just sits around waiting for specific event(s) to start the larger quest.  Depending on whether you are using story manager information, that might be a more efficient way to do this.
Reference: https://ck.uesp.net/wiki/Start_-_Quest

 

Conversely if this only ever triggers with a specific creature, this can all be linked to a spell effect on that creature that triggers the quest.

 

You could make this just be a script as a magic effect without using a quest at all - and that would generally work fine in a low-script lag environment, but if the magic effects sits around a long time, it may not fire right, and a quest handler might be the better option, but will require more overall work.

 

Papyrus is neither efficient, nor robust.  Wherever possible, rely on the game's engine (and not papyrus) to do things.

Edited by Seijin8
Posted (edited)

Thanks for the help. Yeah I'm really still trying to figure things out as I go. So some beginner mistakes as I learn the basics of papyrus are kind of a given. Definitely a case of some learned behaviour which is now biting me in the rear. A magic effect to trigger the script sounds like a great option. As for the 30 second timer, is there a better way to trigger it? I kind of figured that basing it on the in-game time would come with few unintended side effects, but I'm now getting the idea that I might have been wrong about that too.

 

The plan was to build a script that does the following:

 

  1. After choosing the "Quick, hide me!" dialogue line, the screen fades out
  2. During the fade-out, an audio file plays that sounds like the mimic devouring the player character.
  3. The player character and the mimic follower are "stored" into another cell.
  4. A chest object is placed where the mimic stood.
  5. A 30 second cooldown starts.
  6. The player camera position is fixed on the chest.
  7. Upon fade-in, the audio file's volume is reduced by half.
  8. 20 seconds into the timer, a message is shown: "I need to get out soon or the mimic will digest me!"
  9. A few seconds before the 30 seconds are up, another message appears: "The mimic has started to digest you"
  10. The player character dies when the 30 seconds are up.
  11. Pressing R during any moment causes another fade-out/fade-in transition and the player and the mimic follower are back in the original location.
  12. I regain control over the player character/the player camera is returned to the player character.

 

I did try to build that into a script. It appears that my first attempt was pretty awful.

Edited by SerpentineStorm
Posted
15 hours ago, SerpentineStorm said:

Thanks for the help. Yeah I'm really still trying to figure things out as I go. So some beginner mistakes as I learn the basics of papyrus are kind of a given. Definitely a case of some learned behaviour which is now biting me in the rear. A magic effect to trigger the script sounds like a great option. As for the 30 second timer, is there a better way to trigger it? I kind of figured that basing it on the in-game time would come with few unintended side effects, but I'm now getting the idea that I might have been wrong about that too.

 

The plan was to build a script that does the following:

[snip]

 

Keeping in mind that basically anything you want to do that is complex is best handled as a quest, this seems a lot like the Brelyna polymorph scene from the College.  Might be handy to look into how the game managed that, since it included camera control and making the PC change into different forms.

 

Going in order:

 

1 & 2) no problem.  The dialogue would trigger the scene whether through a quest or magic effect.

3 & 4) the camera is attched to the PC and cannot be in a different cell.  You'll be able to move the mimic, but not the PC.  Might be able to turn the PC into the chest though.

5 through 9) Straightforward, though I'd recommend a button for fade-to-black advance scene because the 15th time you do this it might get boring given that there's nothing else to be done.

10, 11, 12) Essentially just reversing the prior steps.

 

Nothing here looks too wild to do, and most of the tools should be found in the Brelyna favor quest scene.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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