Jump to content

set quest stage on acquiring item


khulse

Recommended Posts

You know, I think the most annoying thing about papyrus is that the really stupidly simple stuff seems to be the hardest things to figure out.

 

I want to start a quest when an unmodified non-specific vanilla instance of an item is picked up. A bee (critterbeeingredient) to start the quest, to bee specific. Then I want to set the next stage when the character picks up a glowing mushroom. When the player picks up a giant lichen, it moves to the next stage- and so on. Then, the player will craft something and use it. That ends the quest.

 

The problem I'm running into is that I can't figure out how to do this without either specifying a specific instance of an object or having the player talking to an actor (which this quest is not supposed to involve in any way).

 

I think I can start the quest with an sm event node. I know how to set things up so that the quest progresses when the character acquires an alias. So I need to know how to either:

 

1) assign a base item to an alias without it being a specific base item (ANY glowing mushroom, not the Extra Special Dark Green Glowing Mushroom growing in the left nostril of the king of the falmers).

or

2) assign the player to an alias with scrips that will progress the game when a specified non-specific item is picked up

or

3) just assign an [if Game.GetPlayer()picksup(anyoldglowingfungusfromanywhere)/ setstage insertmyquesthere 9000/ endif] several times to the quest script itself.

 

Anyone know how to do this? Thanks in advance.

Edited by khulse
Link to comment
Share on other sites

1) You can't assign forms to aliases. Aliases are always object references or location references.

 

2) To assign the player to an alias, create a new object reference alias. Select "specific reference" "any cell" "player"

 

Once you've done that, you can use the InventoryEventFilter function inside an OnInit() event to make your script only trigger when the player acquires bees (or other items you are interested in).

 

http://www.creationkit.com/AddInventoryEventFilter_-_ObjectReference

 

Note that you can use a formlist as a parameter, so you can detect whenever the player acquires any item in the formlist.

 

Then use OnItemAdded to detect which of the items on your list the player has acquired.

 

http://www.creationkit.com/OnItemAdded_-_ObjectReference

 

3) This would be ugly. I think #2 is the way to go.

 

Alternatively, you can just create an SM Event quest that goes off and then resets itself each time the player acquires one of the items, and then sets the tracking quest to appropriate stage depending on which item is acquired. (It's never been clear to me why you wouldn't do that, honestly, because I have to assume tracking inventory events is a pretty heavy script burden, even properly filtered.)

Edited by lofgren
Link to comment
Share on other sites

Thank you for the quick response!

 

I'm sort of leaning towards #2 myself. A couple of questions-

 

Why is the inventoryeventfilter needed, if you can set the onitemadded to a base object? Or am I missing something?

 

I understand how to set up the onitemadded, but I'm a little fuzzy on what to do with the inventoryeventfilter. Where do I put this in relation to the rest of the script?

 

Do you know of any scripts in the game or good example scripts that have a set up something like this? I'm better at assembling the pieces if I can look at an example.

 

I'm not quite sure I follow your alternative suggestion. Sm event nodes only seem able to activate a quest, not the stages.

 

In any case, thank you for pointing me in the right direction. At least no I have an idea of what I need research :thumbsup:

Link to comment
Share on other sites

The inventoryeventfilter will make it so the script only fires when the actor acquires items you are interested in, rather than any time the actor acquires any item whatsoever. It reduces the amount of resources your script uses and also makes it a little easier to script the ItemAdded event. The inventory event filter function would go in the OnInit() event of the alias or the quest, so it would fire as soon as the alias is filled.

 

To use the SM event node alternative, you would have two quests. One quest would be triggered by the story manager. It would then set the appropriate stage in the second quest, then stop itself and reset so that it would fire again when the next item on the list was acquired. This way you would not need any aliases at all, and the game engine would do more of the work, significantly reducing the size and complexity of scripts.

 

I don't know of any quests that use either method exactly, but I would suggest you look at the Elgrim's Elixirs quest that asks for three ingredients, the quest from Temba Wide Arm to acquire bear skins, or the red nirnroot quest for hints.

Edited by lofgren
Link to comment
Share on other sites

As an analogy, an alias without an inventory filter would be like, "Is that a bee? Is that a bee? Is that a bee? Is that a bee? Is that a bee? Is that a bee?"

 

An alias with an inventory filter would be like, "Let me know when you find a bee."

Link to comment
Share on other sites

An example of a good reason to use an inventory event filter when you are looking for only a few items...

 

If you were to run Hearthfire without the appropriate USKP patches, you would end up with log spam such as the following every time an item is added.

[05/13/2014 - 02:06:23PM] [BYOHHouseBuildingPlayerScript <alias Player on quest BYOHHouseBuilding (0300305D)>]OnItemRemoved [Form < (08032192)>], itemCount=1
[05/13/2014 - 02:06:23PM] [byohhousebuildingscript <BYOHHouseBuilding (0300305D)>] UpdateLogCount
[05/13/2014 - 02:06:23PM] [byohhousebuildingscript <BYOHHouseBuilding (0300305D)>] logcount=0

The reason this happens is that Bethesda intended to use an inventory filter but forgot to fill the property value. Because there was nothing to filter, it ends up looking at every item that gets passed into the player inventory. In essence the house building script was going.. Is that a log? Is that a log? Is that a log? etc...

After USKP filled that property, it shuts up and only does its thing when it is a log.

 

Here is a quick example, it might even do what you want... but I'm sure it could be improved upon

 

 

ScriptName SomeScript Extends ReferenceAlias

FormList Property TargetItems Auto ;list of 4 items
Int ItemsGotten = 0

Event OnInit()
	AddInventoryEventFilter(TargetItems)
EndEvent

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
	If GetOwningQuest.GetStage() < 20 && GetOwningQuest.GetStage() > 10
		If akBaseItem == TargetItems.GetAt(0)
			;first object found
			GetOwningQuest().SetStage(11)
			ItemsGotten += 1
		ElseIf akBaseItem == TargetItems.GetAt(1)
			;second object found
			GetOwningQuest().SetStage(12)
			ItemsGotten += 1
		ElseIf akBaseItem == TargetItems.GetAt(2)
			;third object found
			GetOwningQuest().SetStage(13)
			ItemsGotten += 1
		ElseIf akBaseItem == TargetItems.GetAt(3)
			;fourth object found
			GetOwningQuest().SetStage(14)
			ItemsGotten += 1
		EndIf
		If ItemsGotten == 4
			GetOwningQuest().SetStage(20) ;go on to the next step
		EndIf
	EndIf
EndEvent 

 

 

 

Link to comment
Share on other sites

That makes sense. I'll make sure to include an inventory even filter so I don't gum up peoples games with pointless script activity.

 

@IsharaMeridan That's pretty close to what I have managed to put together, but it clarifies several things for me. Thank you very much.

 

@lofgren It doesn't really matter if they remove the items. The idea is that they are 'researching' a formula. Each stage identifies a component, and gives a hint at what the next component needs to be. Once they have everything identified, the player can see the recipe and finish the quest any time they like by making the item. I'll be 'locking' each stage as they go so they don't wind of changing stages every time they pick up one of the items. That would get a little annoying.

Link to comment
Share on other sites

Would this work?

 

 

ScriptName myspecialrecipescript Extends ReferenceAlias

MiscObject Property itemAAA Auto Conditional
Ingredient Property itemBBB Auto Conditional
Ingredient Property itemCCC Auto Conditional
Ingredient Property itemDDD Auto Conditional
MiscObject Property itemEEE Auto Conditional
MiscObject Property itemXXX Auto Conditional

Quest Property myspecialrecipe Auto Conditional

Event OnInit()
AddInventoryEventFilter(itemAAA)
EndEvent

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
If akBaseItem == itemAAA && GetOwningQuest.GetStage() == 10
RemoveInventoryEventFilter(itemAAA)
AddInventoryEventFilter(itemBBB)
GetOwningQuest().SetStage(20)
;
ElseIf akBaseItem == itemBBB && GetOwningQuest.GetStage() == 20
RemoveInventoryEventFilter(itemBBB)
AddInventoryEventFilter(itemCCC)
GetOwningQuest().SetStage(30)
;
ElseIf akBaseItem == itemCCC && GetOwningQuest.GetStage() == 30
RemoveInventoryEventFilter(itemCCC)
AddInventoryEventFilter(itemDDD)
GetOwningQuest().SetStage(40)
;
ElseIf akBaseItem == itemDDD && GetOwningQuest.GetStage() == 40
RemoveInventoryEventFilter(itemDDD)
AddInventoryEventFilter(itemEEE)
GetOwningQuest().SetStage(50)
;
ElseIf akBaseItem == itemEEE && GetOwningQuest.GetStage() == 50
RemoveInventoryEventFilter(itemEEE)
AddInventoryEventFilter(itemXXX)
GetOwningQuest().SetStage(60)
;
ElseIf akBaseItem == itemXXX && GetOwningQuest.GetStage() == 60
RemoveInventoryEventFilter(itemXXX)
GetOwningQuest().SetStage(70)
endif
endevent

 

 

Note on the formatting: For some reason all the indents most people use make my eyes cross. This is much easier to read for me. Will it still work set up this way? In some game modding it seems to matter, in some it doesn't.

Edited by khulse
Link to comment
Share on other sites

whether or not spaces matter depends on the compiler. Luckily for papyrus they do not, so space it however you feel comfortable.

 

Your inventory filter should be set to a formlist that contains each of these items. right now you are only looking for the first ingredient on the list, so the conditions for subsequent ingredients will never be true.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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