Jump to content

[LE] Need help advancing quest stage upon item pick up


Recommended Posts

11 minutes ago, scorrp10 said:

Ok, thoughts:

You want a script flagged 'Conditional' attached to your quest, (lets call it SpecialSoulGemQuestScript) and define 3 boolean conditional properties: CapturedDragon(Giant/DragonPricest)Soul, 
Create a 'SpecialSoulTrapKeyword' keyword.
Create a SpecialSoulTrap spell that is a duplicate of 'SoulTrap'   More on this later.

Detection of combat:    Make sure your quest priority is higher than 50.  Take a look at 'CreatureDialogueGiant' quest.  In 'Combat' tab it has a (Hit) item.    Duplicate it in YOUR quest's Combat section, but you probably want to add a condition that subject's combat target is player, and a GetVMQuestVariable condition that checks 'CapturedGiantSoul' is false (0), and a  condition 'HasMagicEffectKeyword'  for 'SpeialSoulTrapKeyword' is 0.
Create 'Hit' category TopicInfos for  Dragon and Dragon priest as well (see their respective CreatureDialogue quests)
To all 3 topicinfos  add a script that has SpecialSoulTrap(Spell)  and PlayerRef(Actor) properties, and goes like:    SpecialSoulTrap.Cast(PlayerRef, akSpeaker)

What the above accomplishes: when a member of giant, dragon or dragonpriest  race is hit in combat, and their target is player, and a respective soul for your quest is not yet collected, and they don't have this effe3ct already, it will have SpecialSoulTrap spell cast on them by player.

Now, more about this spell - you likely want to make it a longer range (100ft) and check 'Disallow Absorb/Reflect' and 'Ignore Resistance' boxes.  Maybe change perk to ConjurationNovice00.

You will see that this spell has a single effect item: Soul Trap, and its effect is 'SoulTrapFFActor', 1 minute duration.  Go ahead and create a duplicate of this MagicEffect, call it 'SpecialSoulTrapFFActor'.  Change the SpecialSoulTrap spell to use this effect instead.

Now, the effect itself:   You likely want to remove all of its conditions, change Minimum skill level to 0, and change base cost and skill usage mult to 0 as well.  Uncheck Hostile, Recover, FX Persist boxes, Check 'NoHit Effect'.   In Keywords, add  SpecialSoulTrapKeyword.   In Target Conditions, remove all conditions.  In Visual Effects and Sounds sections, You want everything set to 'None'.

This effect has two scripts attached:  magicsoultrapfxscript and SayOnHitByMagicEffectScript.    The second one, you can just remove.   But the first one you need to study.    
You basically want to create your own version of this script, with same properties, filled the same,  and attach it instead of the magicsoultrapfxscript.

The OnEffectStart  event can remain the same, or you can add some extra change to make sure that Target is a valid one, and you still need their soul.    (Add your quest as a property to this script)

SpecialSoulGemQuestScript Property MyQuest  Auto 

In OnEffectFinish event,  instead of  "if Caster.TrapSoul(victim) == true" you can do:   "if MyQuest.SpecialTrapSoul(victim, caster) == True"

And in your Quest script, you add a Bool Function SpecialSoulTrap(Actor victim, Actor Caster) which will have something like:

ScriptName SpecialSoulGemQuestScript extends Quest Conditional

Bool Property CapturedGiantSoul Auto Conditional         ;these 3 set to false in properties
Bool Property CapturedDragonSoul Auto Conditional
Bool Property CapturedDragonPriestSoul Auto Conditional
Actor Property PlayerRef Auto 
MiscObject Property EmptySoulGem Auto
MiscObject Property PartialSoulGem Auto
MiscObject Property FilledSoulGem Auto
Race Property GiantRace Auto
Race Property DragonRace Auto
Race Property DragonPriestRace Auto

Bool Function SpecialTrapSoul(Actor Victim, Actor Caster)
  If Caster == PlayerRef && (PlayerRef.GetItemCount(EmptySoulGem) > 0 || PlayerRef.GetItemCount(PartialSoulGem) > 0)
    Bool AddSoul = false
    If Victim.GetRace() == GiantRace
      If !CapturedGiantSoul
        CapturedGiantSoul = true
        AddSoul = true
        SetObjectiveCompleted(30, true)  ; Assume your quest's objective 30 is 'collect giant soul', and was set upon starting this quest stage
      EndIf
    Elseif Victim.GetRace() == DragonRace
      If !CapturedDragonSoul
        CapturedDragonSoul = true
        AddSoul = true
        SetObjectiveCompleted(31, true)  
      EndIf
	Elseif Victim.GetRace() == DragonPriestRace
      If !CapturedDragonPriestSoul
        CapturedDragonPriestSoul = true
        AddSoul = true
        SetObjectiveCompleted(32, true)  
      EndIf
	EndIf
    If AddSoul
      If !CapturedGiantSoul || !CapturedDragonSoul || !CapturedDragonPriestSoul
        If PlayerRef.GetItemCount(EmptySoulGem) > 0
          PlayerRef.RemoveItem(EmptySoulGem, 1, true)
          PlayerRef.AddItem(PartialSoulGem, 1)
        EndIf
      ElseIf CapturedGiantSoul && CapturedDragonSoul && CapturedDragonPriestSoul
        PlayerRef.RemoveItem(PartialSoulGem, 1, true)
        PlayerRef.AddItem(FilledSoulGem, 1)
        ; Here probably want to add some code to advance the quest.
      EndIf
      Return True
    EndIf
  EndIf
  Return False
EndFunction


 

honestly, i did not expect this thorough of an answer. this belongs in the hall of fame of imparting modding knowledge on nexus.

 

eventhough i'm familiar with about 60% of the procedures you've mentioned i'll give it a go and report back.

 

thank you for helping me out. i really appreciate it 😉

Link to comment
Share on other sites

Well, since you want an effect similar to that of Soul Trap, it only makes sense to duplicate the actual soul trap and its effect - with some modifications.     And there are probably a few other methods to determine when a player enters combat with giant  or dragon, but combat dialogue method seemed rather elegant.

Link to comment
Share on other sites

18 hours ago, scorrp10 said:

Ok, thoughts:

You want a script flagged 'Conditional' attached to your quest, (lets call it SpecialSoulGemQuestScript) and define 3 boolean conditional properties: CapturedDragon(Giant/DragonPricest)Soul, 
Create a 'SpecialSoulTrapKeyword' keyword.
Create a SpecialSoulTrap spell that is a duplicate of 'SoulTrap'   More on this later.

Detection of combat:    Make sure your quest priority is higher than 50.  Take a look at 'CreatureDialogueGiant' quest.  In 'Combat' tab it has a (Hit) item.    Duplicate it in YOUR quest's Combat section, but you probably want to add a condition that subject's combat target is player, and a GetVMQuestVariable condition that checks 'CapturedGiantSoul' is false (0), and a  condition 'HasMagicEffectKeyword'  for 'SpeialSoulTrapKeyword' is 0.
Create 'Hit' category TopicInfos for  Dragon and Dragon priest as well (see their respective CreatureDialogue quests)
To all 3 topicinfos  add a script that has SpecialSoulTrap(Spell)  and PlayerRef(Actor) properties, and goes like:    SpecialSoulTrap.Cast(PlayerRef, akSpeaker)

What the above accomplishes: when a member of giant, dragon or dragonpriest  race is hit in combat, and their target is player, and a respective soul for your quest is not yet collected, and they don't have this effe3ct already, it will have SpecialSoulTrap spell cast on them by player.

Now, more about this spell - you likely want to make it a longer range (100ft) and check 'Disallow Absorb/Reflect' and 'Ignore Resistance' boxes.  Maybe change perk to ConjurationNovice00.

You will see that this spell has a single effect item: Soul Trap, and its effect is 'SoulTrapFFActor', 1 minute duration.  Go ahead and create a duplicate of this MagicEffect, call it 'SpecialSoulTrapFFActor'.  Change the SpecialSoulTrap spell to use this effect instead.

Now, the effect itself:   You likely want to remove all of its conditions, change Minimum skill level to 0, and change base cost and skill usage mult to 0 as well.  Uncheck Hostile, Recover, FX Persist boxes, Check 'NoHit Effect'.   In Keywords, add  SpecialSoulTrapKeyword.   In Target Conditions, remove all conditions.  In Visual Effects and Sounds sections, You want everything set to 'None'.

This effect has two scripts attached:  magicsoultrapfxscript and SayOnHitByMagicEffectScript.    The second one, you can just remove.   But the first one you need to study.    
You basically want to create your own version of this script, with same properties, filled the same,  and attach it instead of the magicsoultrapfxscript.

The OnEffectStart  event can remain the same, or you can add some extra change to make sure that Target is a valid one, and you still need their soul.    (Add your quest as a property to this script)

SpecialSoulGemQuestScript Property MyQuest  Auto 

In OnEffectFinish event,  instead of  "if Caster.TrapSoul(victim) == true" you can do:   "if MyQuest.SpecialTrapSoul(victim, caster) == True"

And in your Quest script, you add a Bool Function SpecialSoulTrap(Actor victim, Actor Caster) which will have something like:

ScriptName SpecialSoulGemQuestScript extends Quest Conditional

Bool Property CapturedGiantSoul Auto Conditional         ;these 3 set to false in properties
Bool Property CapturedDragonSoul Auto Conditional
Bool Property CapturedDragonPriestSoul Auto Conditional
Actor Property PlayerRef Auto 
MiscObject Property EmptySoulGem Auto
MiscObject Property PartialSoulGem Auto
MiscObject Property FilledSoulGem Auto
Race Property GiantRace Auto
Race Property DragonRace Auto
Race Property DragonPriestRace Auto

Bool Function SpecialTrapSoul(Actor Victim, Actor Caster)
  If Caster == PlayerRef && (PlayerRef.GetItemCount(EmptySoulGem) > 0 || PlayerRef.GetItemCount(PartialSoulGem) > 0)
    Bool AddSoul = false
    If Victim.GetRace() == GiantRace
      If !CapturedGiantSoul
        CapturedGiantSoul = true
        AddSoul = true
        SetObjectiveCompleted(30, true)  ; Assume your quest's objective 30 is 'collect giant soul', and was set upon starting this quest stage
      EndIf
    Elseif Victim.GetRace() == DragonRace
      If !CapturedDragonSoul
        CapturedDragonSoul = true
        AddSoul = true
        SetObjectiveCompleted(31, true)  
      EndIf
	Elseif Victim.GetRace() == DragonPriestRace
      If !CapturedDragonPriestSoul
        CapturedDragonPriestSoul = true
        AddSoul = true
        SetObjectiveCompleted(32, true)  
      EndIf
	EndIf
    If AddSoul
      If !CapturedGiantSoul || !CapturedDragonSoul || !CapturedDragonPriestSoul
        If PlayerRef.GetItemCount(EmptySoulGem) > 0
          PlayerRef.RemoveItem(EmptySoulGem, 1, true)
          PlayerRef.AddItem(PartialSoulGem, 1)
        EndIf
      ElseIf CapturedGiantSoul && CapturedDragonSoul && CapturedDragonPriestSoul
        PlayerRef.RemoveItem(PartialSoulGem, 1, true)
        PlayerRef.AddItem(FilledSoulGem, 1)
        ; Here probably want to add some code to advance the quest.
      EndIf
      Return True
    EndIf
  EndIf
  Return False
EndFunction


 

ok so i implemented this fully. but now i've encountered an issue with your script,

 

it seems that you created the function, based on the fact that each of the stages (killing giant, dragonpriest, dragon) is a quest objective whereas i set them as as quest stages. so whenever i for example get the giant's soul, the quest advances to the next stage where i have to get the dragonpriests's soul and then the dragon's. each of them is an stage of its own.

 

to fix that i modified your script, giving each stage a separate function, and wrote this based on your script:

Bool Function VesselOfSoulsPartiallyFilled(Actor Victim, Actor Caster)
  If Caster == PlayerRef && (PlayerRef.GetItemCount(EmptyVessel) > 0 || PlayerRef.GetItemCount(PartiallyFilledVessel) > 0)
    Bool AddSoul = false
    If Victim.GetRace() == GiantRace
      If !CapturedGiantSoul
        CapturedGiantSoul = true
        AddSoul = true
        Setstage(63)
      EndIf
    EndIf
EndIf
EndFunction

Bool Function VesselOfSoulsModeratelyFilled(Actor Victim, Actor Caster)    
  If Caster == PlayerRef && (PlayerRef.GetItemCount(PartiallyFilledVessel) > 0 || PlayerRef.GetItemCount(ModeratelyFilledVessel) > 0)
    Bool AddSoul = false        
    If Victim.GetRace() == DragonPriestRace
      If !CapturedDragonPriestSoul
        CapturedDragonPriestSoul = true
        AddSoul = true
        Setstage(66)
      EndIf
    EndIf
EndIf
EndFunction    

Bool Function VesselOfSoulsFilled(Actor Victim, Actor Caster)    
  If Caster == PlayerRef && (PlayerRef.GetItemCount(ModeratelyFilledVessel) > 0 || PlayerRef.GetItemCount(VesselOfSouls) > 0)
    Bool AddSoul = false    
    If Victim.GetRace() == DragonRace
      If !CapturedDragonSoul
        CapturedDragonSoul = true
        AddSoul = true
        Setstage(70)
      EndIf
    EndIf
EndIf
EndFunction    

with "Partiallyfilledvessel", "moderatelyfilledvessel" and "vesselofsoulsfilled" being 3 stages of the soul gem.

 

but i have encountered 2 problems now:

A. i don't know how to implement this part of your script into each function separately:

    If AddSoul
      If !CapturedGiantSoul || !CapturedDragonSoul || !CapturedDragonPriestSoul
        If PlayerRef.GetItemCount(EmptySoulGem) > 0
          PlayerRef.RemoveItem(EmptySoulGem, 1, true)
          PlayerRef.AddItem(PartialSoulGem, 1)
        EndIf
      ElseIf CapturedGiantSoul && CapturedDragonSoul && CapturedDragonPriestSoul
        PlayerRef.RemoveItem(PartialSoulGem, 1, true)
        PlayerRef.AddItem(FilledSoulGem, 1)
        ; Here probably want to add some code to advance the quest.
      EndIf
      Return True
    EndIf
  EndIf
  Return False
EndFunction

 

and B. you said i should add this line: 

MyQuest.SpecialTrapSoul(victim, caster) == True

to my soultrap effect, problem being, if i replace the "specialtrapsoul" function name with one of the 3 functions, i need to write this whole part of that script for the "OnEffectFinish" event again, and the creationkit(or notepad++) doesn't recognize 3 separate "OnEffectFinish" events in the same script.

 

what should i do ? (i hope i explained it well enough for you to recognize the two issues).

Edited by ThalmorJusticiar7th
Link to comment
Share on other sites

My assumption was that giant, dragon and dragon priest  could be obtained in any order.    Are you saying you want them in a specific sequence?   I.e. when a player is after a giant, dragon and priest kills will not count?

In this case, you can skip having the 'soul captured' properties.    Then in the combat dialogue conditions, you  check for a specific quest stage (i.e. voice type = giant and quest stage = 60)

The Effect script should not really change.     You still call  SpecialTrapSoul(victim, caster), but that function now becomes different.

; assuming corresponding objectives are numbered 31, 32, 33

Bool Function SpecialTrapSoul(Actor Victim, Actor Caster)
  If Caster == PlayerRef
    If GetStage() == 60 && Victim.GetRace() == GiantRace
      Return AdvanceCollectionStage(EmptySoulGem, PartialSoulGem, 63, 31)
    ElseIf GetStage() == 63 && Victim.GetRace() == DragonPriestRace
      Return AdvanceCollectionStage(PartialSoulGem, ModerateSoulGem, 66, 32)
    ElseIf GetStage() == 60 && Victim.GetRace() == DragonRace
      Return AdvanceCollectionStage(ModerateSoulGem, FilledSoulGem, 70, 33) ; <<<  THE EDITED LINE, updated gem names
    EndIf
  EndIf
  Return false
EndFunction

Bool Function AdvanceCollectionStage(MiscObject OldSoulGem, MiscObject NewSoulGem, Int NewStage, Int Objective)
  If PlayerRef.GetItemCount(OldSoulGem) > 0
    PlayerRef.RemoveItem(OldSoulGem, 1, true)
    PlayerRef.AddItem(NewSoulGem, 1)
    SetObjectiveCompleted(Objective, true)
    SetStage(NewStage)
    Return true
  EndIf
  Return false
EndFunction

 

Link to comment
Share on other sites

39 minutes ago, scorrp10 said:

The Effect script should not really change.     You still call  SpecialTrapSoul(victim, caster), but that function now becomes different.

by should not change, do you mean i should use vanilla script or that the current script that i've set up would not change following me editing the scripts with the new ones you provided ? also which one of the 2 functions should go in that: "OnEffectFinish" event ? the first one or the second one ?

 

in otherwords, which one i should put there ?

this:

if MyQuestRef.Specialtrapsoul(victim, caster) == True 

or this ?

if MyQuestRef.AdvanceCollectionStage(victim, caster) == True 

 

also, what are the oldsoulgem & newsoulgem supposed to be here ? new properties ? or should i leave them as is, because they are undefined, or did you mean emptysoulgem & partialfilled as you wrote in the above script ?

Bool Function AdvanceCollectionStage(MiscObject OldSoulGem, MiscObject NewSoulGem, Int NewStage, Int Objective)
  If PlayerRef.GetItemCount(OldSoulGem) > 0
    PlayerRef.RemoveItem(OldSoulGem, 1, true)
    PlayerRef.AddItem(NewSoulGem, 1)
    SetObjectiveCompleted(Objective, true)
    SetStage(NewStage)
    Return true
  EndIf
  Return false
EndFunction

 

and finally, what do you even mean by this ? i get seting the condition for the specific quest stage part, but what is voice type ? and is "i.e" a part of the code ? (a bit more explanation would be awesome)

Quote

Then in the combat dialogue conditions, you  check for a specific quest stage (i.e. voice type = giant and quest stage = 60)

Edited by ThalmorJusticiar7th
Link to comment
Share on other sites

Strange, edit did not save, I just redone it.    In any case, I just attached a working section of your quest - it is actually made for SSE, but you should be able to get the gist.

An 'empty vessel' gem is in a holder on Farengar's desk in ragonsReach.   Picking it up starts the quest, giving you "Kill a Giant" objective   (EmptyVesselPickupScript)

The quest has 'Hit' event combat dialogue defined for giant, dragon, and dragon priest, with conditions that quest needs to be on proper stage, and mob's target must be player, and  mod should not have an effect with 'SpecialSoulTrap' keyword.

When the dialogue fires, the attached script fragments (TIF_*) will cast the special soul trap spell on the target, applying the special SoulTrap effect.  (SpecialSoulTrapEffectScript)

When the target dies and effect finishes, it will call  'CompleteSoulTrap' function in the quest's  SoulCollectionQuestScript.    This function in turn will use the ApplySoulCollection function to replace the item in player's inventory and advance the quest stage.    Quest's stage fragments handle the displaying of objectives.

About your earlier question- "i.e."   stands for "in example", and is NOT part of the code.

If you say, look at Combat section of CreatureDialogueGiant  quest, you will see that its 'Hit' topic uses following condition:
image.thumb.png.3c361fd66087de5a8e05f8bd0d21e0d1.png

To make sure that this dialogue is spoken only by a creature with 'CrGiantVoice' voicetype (that is, a Giant)

SoulCollection.7z

Link to comment
Share on other sites

33 minutes ago, scorrp10 said:

Strange, edit did not save, I just redone it.    In any case, I just attached a working section of your quest - it is actually made for SSE, but you should be able to get the gist.

An 'empty vessel' gem is in a holder on Farengar's desk in ragonsReach.   Picking it up starts the quest, giving you "Kill a Giant" objective   (EmptyVesselPickupScript)

The quest has 'Hit' event combat dialogue defined for giant, dragon, and dragon priest, with conditions that quest needs to be on proper stage, and mob's target must be player, and  mod should not have an effect with 'SpecialSoulTrap' keyword.

When the dialogue fires, the attached script fragments (TIF_*) will cast the special soul trap spell on the target, applying the special SoulTrap effect.  (SpecialSoulTrapEffectScript)

When the target dies and effect finishes, it will call  'CompleteSoulTrap' function in the quest's  SoulCollectionQuestScript.    This function in turn will use the ApplySoulCollection function to replace the item in player's inventory and advance the quest stage.    Quest's stage fragments handle the displaying of objectives.

About your earlier question- "i.e."   stands for "in example", and is NOT part of the code.

If you say, look at Combat section of CreatureDialogueGiant  quest, you will see that its 'Hit' topic uses following condition:
image.thumb.png.3c361fd66087de5a8e05f8bd0d21e0d1.png

To make sure that this dialogue is spoken only by a creature with 'CrGiantVoice' voicetype (that is, a Giant)

SoulCollection.7z 5.47 kB · 0 downloads

thanks for doing this. but wasn't your original 2 comments sufficient ? i was just done implementing what you said, based on your explanation on Giant/dragon/dragonpriest combat tab's hit quest, and based on that second post where you wrote the two scripts for me.

 

i will still take a look at your script in the file your attached to your comment to learn stuff from it. but is there anything new that you've added there that i should change from the original script ?

 

also i knew i.e wasn't supposed to be a part of the script and you probably just slipped it in there by mistake. just double checked to make sure.

 

again, thank you for all of your help. and let me know if should add anything new to the script for your last post (before this one).

Link to comment
Share on other sites

  • Recently Browsing   0 members

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