Jump to content

Vanilla quest journal quest objectives


Recommended Posts

I'm looking for a way to supplement quest objectives of some vanilla quests and was wondering if I could get some guidance about what's even possible.

While I'm not trying to re-write objectives, I do want to add one of my own that would be dynamic in the sense that I would have to run some code to determine which among a set of strings I would be inserting. This would then sit below the original quest objective for that quest.

So the first part would be to understand how to fill an alias with a string.

The second part is how to display this without affecting the original quest's operations.

edit: so for (1), I think I create an alias and then type the desired text into the Alias Name, clicking on 'stores text'. But what I'm not clear about is if that instantiates -- ie gets stamped into the quest journal so that alias is free to use again for a different quest's journal entry. I'm assuming yes ?

Edited by csbx
Link to comment
Share on other sites

Don't know about modifying objectives for existing quests...

For inserting arbitrary text in an objective, the way to go is an alias with the "stores text" flag.  You also need a Form (a static), and a reference of that form (in aaaMarkers for example since you never need to see it).  The text is actually stored on the form, not the reference, but you need a reference to place in the alias.

Static property	myTextHolder Auto
ObjectReference property myTextHolderRef Auto ; instance of myTextHolder
ReferenceAlias property myTextHolderAlias Auto

myTextHolder.setName( "Whatever text you like!")
myTextHolderAlias.clear() ; Not sure this is required
myTextHolderAlias.forceRefTo( myTextHolderRef)

 The alias will need to be in the same quest as the objective.  Normally of type "Specific Reference", unfilled, optional.

Oh, almost forgot!  You need SKSE!

I use this in a book, and it takes multipage text without problems.  In objectives you will likely encounter display limits.

 

Link to comment
Share on other sites

Posted (edited)

That's great - it turns out that injecting into a book actually makes more sense for what I'm doing, so this is perfect. Thanks again !

As soon as I figure out why my CK-PE isn't compiling / seeing the skse psc files I'll get right to work..

Edited by csbx
Link to comment
Share on other sites

In my example code, I did not include all the relevant context:

Script myQuestScript extends Quest

Static property	myTextHolder Auto
ObjectReference property myTextHolderRef Auto ; instance of myTextHolder
ReferenceAlias property myTextHolderAlias Auto

function updateText( string newText)
	myTextHolder.setName( newText)
	myTextHolderAlias.clear() ; Not sure this is required
	myTextHolderAlias.forceRefTo( myTextHolderRef)
endfunction

 

Link to comment
Share on other sites

  • 3 weeks later...
Posted (edited)
On 3/17/2024 at 7:22 AM, xkkmEl said:

In my example code, I did not include all the relevant context:

Script myQuestScript extends Quest

Static property	myTextHolder Auto
ObjectReference property myTextHolderRef Auto ; instance of myTextHolder
ReferenceAlias property myTextHolderAlias Auto

function updateText( string newText)
	myTextHolder.setName( newText)
	myTextHolderAlias.clear() ; Not sure this is required
	myTextHolderAlias.forceRefTo( myTextHolderRef)
endfunction

 

I've made significant progress on my mod but am still having a hard time making this work as expected. As of now what I have is the note the player receives from the NPC has the correct text on it, but as soon as the alias is cleared, the note becomes [...] again. I'm sure this has something to do with 'stores text' and 'uses stored text' but I've tried several permutations across the letter alias and the textholder alias and nothing solves it. As of now I have:

3 aliases, in order:

1) npc who gives you note (optional, allow reserved, find matching ref using conditions--always fills ok

2) textholderAlias (stores text, with specific reference pointing to misc object ref in AAA markers with base object with text in name field)

and 3) letter alias (create ref. to object -> my letter; create at ( my npc alias), uses stored text, stores text, initially disabled, optional)

Any idea ?

Edit: annoyingly enough, I went through this independently written tutorial for doing something similar to see if I was crazy, and I had exactly the same result: https://wiki.beyondskyrim.org/wiki/Arcane_University:Dynamic_Book_Entries

I'm trying to use this idea in a context where the quest is repeatable so I need the text to be 'instantiated' into the note / book so that the quest can be stopped then started again for another note whilst keeping the original note (with different text) intact. Perhaps this is the difference between the tutorial above and what I'm trying to do.

Edited by csbx
Link to comment
Share on other sites

The text only remains as long as the alias... Nothing to be done about it...  This method will not work for setting text in books without a host alias... I know of no method for doing non-numeric text replacement without an alias...

I should also have mentioned that this text installed with setName is only valid until the player saves and reloads... you need to reapply the text onPlayerLoadGame...

I use a quest just to hold the single instance of my book, so I can control how long it remains valid, and to hold the refresh function called from onPlayerLoadGame.  If you read the book too fast after restoring, you see the original text... which I have set to "(updating...)".

I also use that trick in dialogues (for the player options), where it is somewhat simpler in that it does not have to survive save/restore cycles.

You could try to use the book's "onRead" event to put it back into the alias, but I believe it will not act fast enough to work.

Link to comment
Share on other sites

For the use case you described, people usually provide for a limited number of occurences, and create that number of aliases.  You can easily provide a few hundreds aliases and not really have to worry about anyone overflowing your provision.

Spoiler
Static property textHolderForm Auto
string[] property savedText Auto

int bookCount = 0

event OnInit
	savedText = new String[100]
endevent

ObjectReference function newBook( string text)
		ReferenceAlias a = getAlias( bookCount) as ReferenceAlias
		ObjectReference r = Game.getPlayer().placeAtMe( textHolderForm, 1, True)
		savedText[bookCount] = text
		textHolderForm.setName( text)
		a.clear()
		a.forceRefTo( r)
		return r
endfunction

function refreshOnPlayerLoadGame()
	int i = getNumAliases() ; 100
	while i
		i -= 1
		ReferenceAlias a = getAlias( i) as ReferenceAlias
		if a && savedText[i]
			textHolderForm.setName( savedText[i])
			ObjectReference r = a.getReference()
			a.clear()
			a.forceRefTo( r)
		endif
	endwhile
endfunction

 

Or some such....

Link to comment
Share on other sites

1 hour ago, xkkmEl said:

For the use case you described, people usually provide for a limited number of occurences, and create that number of aliases.  You can easily provide a few hundreds aliases and not really have to worry about anyone overflowing your provision.

  Reveal hidden contents
Static property textHolderForm Auto
string[] property savedText Auto

int bookCount = 0

event OnInit
	savedText = new String[100]
endevent

ObjectReference function newBook( string text)
		ReferenceAlias a = getAlias( bookCount) as ReferenceAlias
		ObjectReference r = Game.getPlayer().placeAtMe( textHolderForm, 1, True)
		savedText[bookCount] = text
		textHolderForm.setName( text)
		a.clear()
		a.forceRefTo( r)
		return r
endfunction

function refreshOnPlayerLoadGame()
	int i = getNumAliases() ; 100
	while i
		i -= 1
		ReferenceAlias a = getAlias( i) as ReferenceAlias
		if a && savedText[i]
			textHolderForm.setName( savedText[i])
			ObjectReference r = a.getReference()
			a.clear()
			a.forceRefTo( r)
		endif
	endwhile
endfunction

 

Or some such....

Thanks a lot -  I made the brash assumption that you could 'instantiate' text into a note/book and it would just sit as an object in the world / be baked into saves. The workaround you outline is pretty clear and I'll get to work on that.

I notice that the mod Missives offers a means (every time you look at the associated note !) of 'throwing away' the note. I guess I'll implement something like this or otherwise let the player know they're 'over-writing' previous notes. 

I had implemented a fixed book system to handle all of this--which involved hundreds of notes in the CK - but this dynamic approach is still probably in the end a little tidier.

Thanks again - you've been a great help.

Link to comment
Share on other sites

Posted (edited)
On 4/2/2024 at 8:49 AM, xkkmEl said:

For the use case you described, people usually provide for a limited number of occurences, and create that number of aliases.  You can easily provide a few hundreds aliases and not really have to worry about anyone overflowing your provision.

  Reveal hidden contents
Static property textHolderForm Auto
string[] property savedText Auto

int bookCount = 0

event OnInit
	savedText = new String[100]
endevent

ObjectReference function newBook( string text)
		ReferenceAlias a = getAlias( bookCount) as ReferenceAlias
		ObjectReference r = Game.getPlayer().placeAtMe( textHolderForm, 1, True)
		savedText[bookCount] = text
		textHolderForm.setName( text)
		a.clear()
		a.forceRefTo( r)
		return r
endfunction

function refreshOnPlayerLoadGame()
	int i = getNumAliases() ; 100
	while i
		i -= 1
		ReferenceAlias a = getAlias( i) as ReferenceAlias
		if a && savedText[i]
			textHolderForm.setName( savedText[i])
			ObjectReference r = a.getReference()
			a.clear()
			a.forceRefTo( r)
		endif
	endwhile
endfunction

 

Or some such....

Since you are obviously pretty knowledgeable about this setname/forceRefTo approach to filling aliases, I was wondering if you knew off-hand, why this method of filling an alias might produce results that I describe in this thread: 

The short of it is that the repeatable BQ01 quest is (as it should) producing distinct bounty letters for each quest iteration, but only the vanilla aliases (steward, jarl, location) are correctly instantiating / persisting in each letter;  the alias (with text) that I add using the method you showed me has the alias of the first bounty letter update to the newly filled alias instead of it remaining the same. Ie the note shouldn't change once  the player receives it, but in my case it is--and only for that one non-vanilla alias.

I realize you said above that the text only lasts as long as the alias and that a new bounty quest means re-setting the alias. But why does all the other info (location, jarl etc.) in the 1st bounty letter retain, whilst my alias doesn't ?

Edited by csbx
Link to comment
Share on other sites

I am rather surprised the BQ01 letters retain their text.  I had not thought that possible.

Most likely, you'll find that the created letters do remember who/what oref was in the text replacement alias when it was created, but not the text itself.  So it will not work with the setName method.  In my own use, it is clear that despite the flag's name, "store text", the text itself is not stored in the created book.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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