Jump to content

Dialogue quest problem with stages


ramilow

Recommended Posts

I am preparing a quest, but I have a problem with dialogues at various stages. I would like the dialogue with the NPC to start after doing something, e.g. taking a letter or talking with another NPC.
E.g. Taking a letter is 20

The conversation is 30.

Talking with another NPC is 40

Talking with NPC is 45
I tried to set it in Conditions, and adding in Result Script SetObjectiveDisplayer/Completed and setstage Quest ID.

I was looking for a solution but I don't know what I'm doing wrong. Either the dialogue doesn't start and the quest stops, or it is available from the very beginning and automatically advances the quest, skipping the previous point.
I don't know where the problem is, because I was able to set the start of the quest correctly (the dialogue starts after exceeding a certain point, the quest starts only after its completion).
By the way, what condition is needed for the NPC to start a dialogue? I mean both crossing the line and stage in quest.

Theoretically, the quest is simple - it comes down to getting subsequent letters in given locations and dialogues with the NPC who ordered the quest. Along the way, there are dialogues with other NPCs that are supposed to allow you to do the task differently, but now I want to do it with the simplest method, and then complicate it.

Link to comment
Share on other sites

Have you seen the "Dialogue and Lipsynch" section of the wiki "Getting started creating mods using GECK" article?

 

Your basic approach seems sound. How are you structuring your dialog conditions, and the related result script? Give us an example. Please explain any variables used but not defined in the example, as to where they are initialized or set. (In-line comments are fine.)

 

(Often being forced to explain a process to someone else will show you where you went wrong.)

 

-Dubious-

Link to comment
Share on other sites

Not sure but it sounds like you have a Quest Stage result script , that sets it to the next Quest Stage ?

Which that set up will effectively act like 1 Quest Stage with 2 script frame blocks.

If you have more chained together like that. Then they still act like 1 stage , but have as many frame reads as you have result scripts. Which makes for an interesting use of quest stages and their result scripts (I'll have to remember that for later use) But obviously it's not your intended use.

 

So if I have this right ?

 

While I'm sure you want to keep your stages and objectives. I would move your dialogue condition to checking a QuestVariable. Which you just put a script on the quest and only have variables. Or if you have a script on it already. Just put another variable in it or a few , depending on how complicated your chain of events needs to be.

Then you have your Dialogue and Quest Stage result scripts , change that/those variable(s).

And then you can get creative with the comparisons on the variables in the conditions. Also have multiple conditions. Sometimes you may want 2 so you use "AND" with the first. But sometimes you may want this or that condition , so you use "OR"

 

Hope that helps. But like dubious said ... explaining it more detailed will help.

Link to comment
Share on other sites

It looked like this. I split the welcome dialogs and those related to the quest into two quests in GECK (one for ordinary dialogs and the other for quest related dialogs).

 

Dialogue after crossing the line (it's in Greetings)

setstage Quest 10
SetObjectiveDisplayed Quest 10 1

 

Dialogue make start a quest (It's in Topic, but he is the last to follow the whole dialogue)

StartQuest Quest
SetObjectiveCompleted Quest 10 1
SetObjectiveDisplayed Quest 20 1

 

Then the problems begin.
I set the condition that the quest goes to the next point (conversation) after taking the letter. The conversation starts the next stage of the quest.

For Dialogue looks that:

SetObjectiveDisplayed Quest 30 1 when start dialogue and SetObjectiveCompleted 30 after last line of dialogue.

Then the stage with getting the next letter is to start. I planned to add a dialogue with another NPC, but first I wanted to solve an earlier problem so as not to complicate things.

The problem is as I described earlier. In Result Script I tried to move setstage to the final line of dialogue that starts, but it does nothing.
When I set GetQuestVariable to == 30 in Conditions, the dialogue does not start. If it is set to <30, it is ahead of the quest with taking the letter.


I was wondering if it wasn't the Quest script fault, where I pre-set the stages for GetQuestVariable.

By the way, although the first dialogue works without a problem, how do you set it so that the NPC starts it when the player crosses the line, or performs a specific action (conversation with another NPC, picking up an item)?

Edited by ramilow
Link to comment
Share on other sites

"Quest stage" is too coarse a filter for ALL your purposes.

 

I look at it this way:

 

A "Quest" is like a book.

A "Quest Stage" is a chapter in that book.

All the things that happen in the chapter should use variables to control who, what, when, where, and how. (Your script logic is the "why".)

* Cross a line (Activator: start the book/quest)

* Chapter1: Dialog presents objective (initializes objective status variable)

* Objective obtained (first step: update objective status variable)

... (There might be other Dialog lines in here by the same or other actors related to this objective only.)

* Objective delivered (final step: update objective status variable to indicate completed)

* Objective status indicates next dialog step is "true". (This might update the Quest Stage, indicating the "Chapter" is done)

* Chapter2: Dialog presents new objective (objective status variable)

repeat as needed until Quest stage condition is met; update Stage

Repeat the entire process.

 

This approach has several advantages:

* It keeps each "objective" modular: isolated from the other objectives as much as possible.

* It's own variables permits fine control over the progress of the objective, without confusing it with other objectives.

* It allows "nesting" of similar logic structure as many levels deep as the objective complexity.

* It's infinitely (up to game limits) expandable.

* While you can re-use variables from one objective to another, remember that variables defined in a "parent" script are available to those in a "child" script (one called into being by a "parent"). Those defined in a "child script" do not propagate back upwards to the parent. (Persistence of values in a "child script" between "calls" is a different matter.)

 

Bear in mind the bit Mktavish pointed out about "single vs multi-frame" blocks. One of the reasons I consider a "Quest Stage" like a "chapter" is because that is where I typically put down a book to go do something else. Always remember that while your logic may be sequential, the player may not follow that exact sequence.

 

Again, use variables to tell yourself that the player has done something "significant" such as perform a specific action. Then your "book" quest script which is running every game frame checks for the various chapter and objective variables to become "true" and performs the necessary housekeeping so things progress. Otherwise they get skipped to minimize processing in an "If ... ElseIf ... ElseIf ... Else ... EndIf" block.

 

Not clear what you mean by "pre-set the stages for GetQuestVariable." You define the stage variable in the Quest script, but assign it the appropriate values at particular stages. Otherwise how do you know that you actually reached that stage? (Or I'm completely misreading the statement.)

 

-Dubious-

Edited by dubiousintent
Link to comment
Share on other sites

In terms of Conditions, I meant Function Parameters for GetQuestVariable. By setting Value to == 30 the dialogue did not start despite meeting the previous conditions. When I used <30, the dialogue started skipping the previous stages.

The easiest way would be to use the tutorial, but I did not find any that was built like this. If I learn this, I'll do it myself XD
For now, I'm trying to build a quest in the simplest form from stage to stage, and then I want to expand it, for example, letters or NPCs appear only at a given stage. Other changes will be considered when the quest is finished and tested.

Should I set some conditions in the quest script? I did so when I wanted the letter to push the quest further.

Link to comment
Share on other sites

 

Not clear what you mean by "pre-set the stages for GetQuestVariable." You define the stage variable in the Quest script, but assign it the appropriate values at particular stages. Otherwise how do you know that you actually reached that stage? (Or I'm completely misreading the statement.)

 

-Dubious-

 

Not sure but it sounded like ramilow is confusing quest stage with a quest variable.

So I am just going to point that out , and leave the rest of explaining to you , since you look to be doing just fine without me further confusing it.

I'll inject if need be :ninja:

Link to comment
Share on other sites

Yeaaaah. :confused: We've all had that problem. (Might want to check out the thread 'Print out "GetStage" value?' Note that "GetStage" always reports the highest stage reached; not the "current" stage. Hence it is not to be considered strictly sequential as to the current situation within the quest logic.)

Think of the "Stage" as a bookmark. Useful for marking generally where you left off, but not for "which line of dialog" in the page. It appears to me it's intended primary use is for tracking by scripts OTHER than it's own Main Script (such as the "Quest Log").

I suggest you set your privately defined QuestStageVariable along with the "Stage" itself when the appropriate "CurrentChapter" progress variable value is reached, and have your main "Book" Quest Script check for changes in that QuestStageVariable instead of calling the "GetStage" function for each check. You could use "Stage" as a broad filter, but you have less control over it than it would appear at first and the "GetStage" function is less efficient for checking every frame in a Game Block. That should be relegated to called scripts as necessary.

Over time I've come to the conclusion that it's a "best practice" to avoid using a function within another function or condition if at all possible. It is a widely accepted general efficiency "best practice" to try to save the result of a single function call to a variable and check the result variable when needed instead re-calling the function again. (Functions use more computer cycles than just reading a variable.)

But that is not always possible and then you have to consider that the "condition test" is a function itself and often cannot initially tell if you are referring to another function name or a variable. For this reason it is often necessary to encapsulate the "condition", as in "If (GetQuestVariable MS40.convo == 0)", to help it parse the parameters properly. (See "TIP Best Practice Encapsulation Parens Brackets and Braces".) If you are still having problems getting an "equivalence" test to work while a "inequality" does, please post an specific example so we can check the syntax/punctuation. But try debug printing out the values you are testing first. (See "TIP Debugging data to file".) You know what you expect, but that is not always what you are getting and the condition is functioning perfectly.

-Dubious-

Link to comment
Share on other sites

It turns out that it is harder than I thought :happy:

I was supposed to write a longer post about the problem, but I solved it differently, maybe. I changed GetQuestVariable to GetStage, retaining in Result Script (End):
SetObjectiveDisplayed Quest 30 1
The last dialog has SetObjectiveCompletedQuest 30 1 added and goes to the next stage, so for now everything is fine :) But is this a good solution?
I'm still thinking about the conditions for the NPC to initiate the dialogue first.

Link to comment
Share on other sites

Whatever "works" and gives you the result you want reliably is "good". There are many ways to resolve any particular problem.

 

Edit: Late thought. I suspect (but do not know for certain) that "GetQuestVariable" is intended for use in scripts OTHER than the current quest. I base this upon the requirement for the "QuestID:ref" parameter. Normally the identity of the current script (in this case "quest') context is inherited and assumed. Requiring an identifier for a quest in the condition function makes sense when that assumption is not valid. As pointed out in the description: otherwise you do not need a function at all; the condition can just use the fully qualified variable (i.e. "QuestID.VarName").

 

...
I'm still thinking about the conditions for the NPC to initiate the dialogue first.


You said "I would like the dialogue with the NPC to start after doing something, e.g. taking a letter or talking with another NPC." Assuming you do NOT want it to be dependent upon having a specific prior conversation in YOUR quest (which would just be the same "set a flag variable" within the quest itself as any other objective), you can use a "token" (an unplayable, therefore invisible, piece of equipment) as that "flag". (An example of the use of a "token" is in the GECKWiki tutorial Adding an Options Menu. "Tokens" can also be used to store information on an Actor. See ActorValue.) That "token" can be given in some other script (and the player doesn't even have to know about it). Your "Questgiver" can then use the presence of that token in the player's inventory as the "condition" to initiate the quest dialog. (This is mentioned at the end of "TIP Standard Dialog".)

-Dubious-

Edited by dubiousintent
Link to comment
Share on other sites

  • Recently Browsing   0 members

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