Jump to content

OnDeath event only works sometimes?


kromey

Recommended Posts

Or maybe I'm just way off base on where my problem lies, I don't really know.

 

Sorry for the rather lengthy post, but it's a somewhat complex problem that I'm hoping has a simple solution.

 

I've released my WIP mod Dovahheim, and several players have reported a seemingly identical problem that breaks the initial quest, essentially breaking the whole mod (what little there is so far, anyway). It comes in two forms, although I believe the underlying cause is the same in each:

 

1) Player kills the bandit boss, which should trigger the courier to deliver a letter to them; the courier never shows.

2) Player gets the quest from an NPC, which puts a quest marker over the bandit leader; upon killing him, however, the quest marker remains over his body, and the quest does not advance.

 

I'm unable to replicate the issue at all (the closest I can get is the courier taking his sweet time delivering the letter), and I'm wondering if perhaps someone here can spot something I've overlooked in my quest or my scripts that is failing.

 

The quest itself has 7 stages. Stage 0 is marked as Start Up Stage, which activates it when the player first installs my mod. This quest's script fragment is pretty simple:

; If Robber's Gorge is already cleared, advance to 30
if(Alias_RobbersGorge.GetLocation().IsCleared())
   SetStage(30)
endif

The RobbersGorge alias properly set up as a location alias pointing to (surprise!) Robber's Gorge; all this does is advance the quest to stage 30 immediately if the player's already cleared Robber's Gorge. (I'll get to what stage 30 is in a moment.)

 

I also have created a reference alias pointing to the bandit leader at Robber's Gorge (this NPC is present in vanilla, I didn't add nor modify him), and via that alias have applied the following Papyrus script (based on the defaultOnDeathSetStage script):

scriptName onDeathSetStageConditional extends ReferenceAlias
{Set stage on specificed quest to one of two stages based upon the prerequisite stage.l}

quest property myQST auto ;Points to DHQClearTheCamp (this quest)
{quest to set stage upon}
int property preReqStage auto ;Set to 10
{Stage that must be set for this script to run.}
int property StageToSet auto ;Set to 20
{Set this stage when the actor dies}
int property StageToSetOther auto ;Set to 30
{Set this stage when the actor dies}

EVENT onDeath(actor killer)
if myQST.getStageDone(preReqStage) == TRUE
	myQST.setStage(StageToSet)
else
	myQST.setStage(StageToSetOther)
endif
endEVENT

The idea being that if the player kills the bandit leader without first getting the quest from the NPC (which sets the stage to 10), the quest advances to stage 30 (more on that in a bit), otherwise the quest advances to stage 20 (tells the player to report back to the NPC). I believe this is the root of the issues people are having, that the death of the bandit leader is not properly running this script; it would explain both failure modes that have been reported, although I can't explain why that would happen!

 

Stage 30 uses a line of code copied straight out of the Dawnstar museum quest to dispatch the courier to the player with a letter:

Alias_DHQFryssaNote.GetRef().Enable()
(CourierQuest as WICourierScript).AddItemToContainer(Alias_DHQFryssaNote.GetRef())

The alias DHQFryssaNote points to a note (which was created by first copying the Dawnstar museum invitation the courier delivers to the player) which is initially disabled (to prevent the odd situation where the player might not have killed the bandit leader, but pickpockets the note from the NPC thanking the player for doing exactly that!). This code enables it and then gives it to the courier to deliver to the player.

 

Again, all of this works just fine for me, under all three test scenarios:

1) Player kills the bandit leader (thus "clearing" Robber's Gorge), then installs the mod

2) Player installs the mod, then kills the bandit leader

3) Player installs the mod, gets the quest from the NPC, then kills the bandit leader

 

Under scenarios 1 and 2, the courier (eventually) shows up with the letter and delivers it, asking me to report to the NPC who then thanks and rewards me. Scenario 3 similarly results in the NPC thanking and rewarding me (although slightly different dialog, owing to different route). But lots of folks seem to be having an issue getting the quest to advance for them, which I believe is most likely a result of the OnDeath script not reliably running; it's also possible that there's a separate issue with the courier, but two such distinct events with nearly identical outcomes seems highly unlikely to me.

 

Anyone have any ideas?

Link to comment
Share on other sites

I think I saw a thread here a couple days ago describing the same problem with not being able to get the OnDeath event to work, but I can't find it. I remember that the workaround was to use OnDying though.

 

EDIT: Found the thread. It was about another issue but someone in the thread mentioned the same problem and how they got around it.

Edited by fg109
Link to comment
Share on other sites

Was it this one? While that post did mention difficulty with OnDeath, the thread was about errors with IsDead (and looks to me to be a case of using the base ID instead of the reference ID, so of course you're never getting true from IsDead).

 

Anyway, I'll give it a shot using the OnDying event instead, though. Or maybe I'll use states and both events, just to cover my @$$ on this one. Really strange that OnDeath would be so flaky though...

Link to comment
Share on other sites

hey yeah that was me!

 

I struggled with OnDeath events in scripted spells for a good while. In my experience, they fire sometimes but nowhere near 100% of the time.

I could never pin down the reason for the inconsistency either (too much damage dealt? manner of death? alien space bats?)

 

Then I switched to using Ondying events instead and haven't had any problems since. I couldn't tell you a reason for using OnDeath over OnDying in this case, so try OnDying and see if that does it for you.

Link to comment
Share on other sites

I'm actually using both events now, and states to prevent double-firing. Kind of paranoid about both of these events, given how flaky OnDeath is (and how closely OnDying is related to it), so trying to cover all of my bases. Like so (pseudo-code, as I'm at work and without my actual code in front of me):

function SetStage()
       if myQST.getStageDone(preReqStage) == TRUE
               myQST.setStage(StageToSet)
       else
               myQST.setStage(StageToSetOther)
       endif
endfunction

auto state waiting
       event ondeath
               GoToState('done')
               SetStage()
       endevent

       event ondying
               GoToState('done')
               SetStage()
       endevent
endstate

state done
endstate

It works for me, but then again it always did when all I was using was OnDeath. So I'll just have to wait and see if no one else has the same problem.

Link to comment
Share on other sites

In the future I think I'll just use OnDying anywhere where I would normally use OnDeath, as folks seem to have no issue with that. I just wanted to give myself the best possible chance of finally solving this damn bug so that I could move on with the rest of my mod already!
Link to comment
Share on other sites

One question, i didnt scripted that much so i dunno the syntax completely.
int property preReqStage auto ;Set to 10
{Stage that must be set for this script to run.}
int property StageToSet auto ;Set to 20
{Set this stage when the actor dies}
int property StageToSetOther auto ;Set to 30
{Set this stage when the actor dies}

What are you trying to do with the Set to xx? I thought that to set a default value for properties (or everything else) you'd use the =, like "int Property preReqStage auto = 10" for example. That assigns a default value for the property if you dont assign another value in the properties window, but i never heard of the "Set to xx"

Link to comment
Share on other sites

One question, i didnt scripted that much so i dunno the syntax completely.

int property preReqStage auto ;Set to 10
{Stage that must be set for this script to run.}
int property StageToSet auto ;Set to 20
{Set this stage when the actor dies}
int property StageToSetOther auto ;Set to 30
{Set this stage when the actor dies}

What are you trying to do with the Set to xx? I thought that to set a default value for properties (or everything else) you'd use the =, like "int Property preReqStage auto = 10" for example. That assigns a default value for the property if you dont assign another value in the properties window, but i never heard of the "Set to xx"

Oh, sorry that wasn't clear. You're exactly right about how default values are assigned to properties.

 

The comments I added (remember, anything beginning with a ';' character is a comment in Papyrus) are there as a reference to tell you what the properties are being set to in the CK. So via the Properties dialog in the CK, I set preReqStage to 10, StageToSet to 20, etc.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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