Aller au contenu

Plot with multiple nonlinear objectives


  • Veuillez vous connecter pour répondre
18 réponses à ce sujet

#1
Guest_dewkl_*

Guest_dewkl_*
  • Guests
I have a quest where the PC needs to gather a few ingredients and administer them at a location. These ingredients can be obtained in any order. How do you make the quest log update when (e.g) two items of three is found?

If the quest was to find one item I guess I could just update to another plot when it was found, but with 3 items I would need 6 plots at least for the log to "count them" properly.

Modifié par dewkl, 20 avril 2010 - 05:49 .


#2
TimelordDC

TimelordDC
  • Members
  • 923 messages
You could have 3 main flags and 3 defined flags.

The 3 main flags could update generic journal entries, eg: You have recovered two of the required ingredients.

The 3 main flags would be -> HAVE_1_ITEM, HAVE_2_ITEMS, HAVE_3_ITEMS

The 3 defined flags would be -> CHECK_1_ITEM, CHECK_2_ITEMS, CHECK_3_ITEMS

Whenever the player picks up one of the ingredients, you can check the defined flags (you need to have checks in each defined flag's case statement to check for the item combinations) and update the corresponding main flag.



Even if you want to have unique journal entries, you would still need the above defined flags for the appropriate main flag to be updated and you would end up with 7 main flags (1 for each item, 3 for item pairs and 1 for all items)

#3
Sunjammer

Sunjammer
  • Members
  • 925 messages
You might also be able to create unique entries using child plots for each of the three items. This wouldn't reduce the number of flags (in fact it would do more) but it would allow you to display exactly which items they have found and are still looking for as bullet points to the main plot. Since I need this for the "Thankless Tasks" plot in Mage of the Blood I should probably look into this.

#4
Guest_dewkl_*

Guest_dewkl_*
  • Guests
I'm trying to find tutorials on plot/quest creation but I can't find anything. I don't get it, for a game that is so heavily structured around these plots I'd expect to see at least a few of them. Maybe I'm looking at the wrong places. What I don't understand is this;

1. How do I tell the plot that the player has picked up one of the items? Could this work? (I'm getting "variable defined without type" at line 18 for some reason. Did I forget to include some header? How do I know which headers to include anyway?)

2. How do I know if the player already has one item when he's picking up a new one?

This is getting close to scripting but I think this is better than starting a new thread. Thanks for the replies.

Modifié par dewkl, 20 avril 2010 - 10:25 .


#5
Sunjammer

Sunjammer
  • Members
  • 925 messages
I don't know if you have had a look at the plot flags article I wrote during the Toolset Beta. It covers the basics and you can see the code in action in the Little Red Riding Hood Redux module (a link to the DADBDATA file can be found on the discussion tab).

I'm half way through creating a new demo module "Joe Versus The Brecilian" (in honour of our volcano-related woes here in Europe) which will demonstrate collecting 3 different items. I should have finished it before this time tomorrow.

Modifié par Sunjammer, 20 avril 2010 - 11:46 .


#6
TimelordDC

TimelordDC
  • Members
  • 923 messages
First, you have to define the plot and create plot flags. Check the tutorial here - http://social.biowar.../index.php/Plot
Sunjammer also had a draft page with the plots and explanation from LRRHR. I can't find it on the wiki but you can download it from his signature to see a simple example of how it is done. Also, check his recently released tutorial modules in this thread - http://social.biowar...5/index/2325413

In short,
your plot should have the following main flags:
- have_1_item
- have_2_items
- have_3_items
It should also have the following defined flags:
- check_have_1_item
- check_have_2_items
- check_have_all_items

Once you have a plot created, you can add the following code in your script:
WR_SetPlotFlag(PLOT_NAME, FLAG_NAME, flag_value);
Substitute your plot_name, plot_flag and flag_value (which will likely be true in your case)

Assuming you have a plot written called fetch_ingredients, your script should be like this:
#include "events_h"
#include "utility_h"
#include "wrappers_h"
#include "plt_fetch_ingredients"

void main()
{
    event   evEvent         = GetCurrentEvent();
    int     nEventType      = GetEventType(evEvent);
    int     bEventHandled   = FALSE;

    switch(nEventType)
    {
        case EVENT_TYPE_INVENTORY_ADDED:     
        {      
            object oOldOwner = GetEventCreator(evEvent);
            int bImmediate = GetEventInteger(evEvent, 0);
            object oItem = GetEventObject(evEvent, 0);
            
            // check which item and set plot flag
            if (GetTag(oItem) == "item_tag_1" || GetTag(oItem) == "item_tag_2" || GetTag(oItem) == "item_tag_3")
            {
                if (WR_GetPlotFlag(plt_fetch_ingredients, check_3_items) == TRUE) // have all items
                {
                    WR_SetPlotFlag(plt_fetch_ingredients, have_3_items, TRUE);
                }
                else if (WR_GetPlotFlag(plt_fetch_ingredients, check_2_items) == TRUE) // have 2 items
                {
                    WR_SetPlotFlag(plt_fetch_ingredients, have_2_items, TRUE);
                }
                else
                {
                    WR_SetPlotFlag(plt_fetch_ingredients, have_1_item, TRUE);
                }
                bEventHandled = TRUE;
                break;
         }  
    }
}

You need to handle the defined flags in the plot script. You can check the wiki or the single-player campaign for an example and go from there. In short, you have to check for which items the player has in the defined flag case constructs. So, check_3_items should check for all three, check_2_items should check for 2-item combinations and check for 1-item should check for one item.
It would also be a better idea to set the SEND_ITEM_ACQUIRED_EVENT (or something similar, I forget exactly which) in the item variable list and use that to have the above script. The script above will fire for every item.

Modifié par TimelordDC, 20 avril 2010 - 11:46 .


#7
Sunjammer

Sunjammer
  • Members
  • 925 messages

dewkl wrote...

1. How do I tell the plot that the player has picked up one of the items? Could this work? (I'm getting "variable defined without type" at line 18 for some reason. Did I forget to include some header? How do I know which headers to include anyway?)

I'm afraid that's not going to work. To tell when a player has picked up an item you have to a) set the ITEM_SEND_ACQUIRED_EVENT local variable on the item's blueprint and then B) catch the EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED event in your module event script.

The error is because you declared the event variable as evEvent and then referred to it in line 18 onwards as just ev.

dewkl wrote...

2. How do I know if the player already has one item when he's picking up a new one?

If you count the number of items with that tag (assuming it is unique) then in the aforementioned EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED event and they have 2 (or more) then you know they already had 1. The CountItemsByTag function should do that for you.

Modifié par Sunjammer, 20 avril 2010 - 11:47 .


#8
TimelordDC

TimelordDC
  • Members
  • 923 messages
Lol, stepping on each other's toes :)

#9
Sunjammer

Sunjammer
  • Members
  • 925 messages
Just time for a work-in-progress image showing the plot and subplot structure before I toddle off to bed.

#10
Proleric

Proleric
  • Members
  • 2 346 messages
That's a good example of using parent-child plots to format the journal.

I've been using that for a while now, so I put some snippets in the wiki.

#11
Guest_dewkl_*

Guest_dewkl_*
  • Guests
Thanks for all the replies, this is very helpful. I have a few questions. I tried using TimelordDC's script.

Where and how do you call this script? If I understood what Sunjammer said correctly I can't just set the script to the item. I tried that but it won't fire, I'm guessing this is reserved for use items (?).

Module script, is that the same script that the module starts with? (chargen and so forth) Won't it be a bit redundant to have the EVENT_TYPE_INVENTORY_ADDED-event in the EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED-event?

I looked at your (Sunjammer) wiki-entry when I was writing the post. I'm going to download the example module(s), I just need to figure out how to safely open them in the editor.

Modifié par dewkl, 21 avril 2010 - 04:29 .


#12
TimelordDC

TimelordDC
  • Members
  • 923 messages
I don't know why Sunjammer said EVENT_TYPE_INVENTORY_ADDED won't work. EVENT_TYPE_INVENTORY_ADDED should be added to player_core in this case. If you don't want to modify that, you should do what Sunjammer posted about the EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED event in the module script.

If you do decide to use EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED, you should check the event parameters in the wiki and modify the script accordingly.



Even after doing all that, you should still set up the plot script to handle the various defined flags.

#13
Guest_dewkl_*

Guest_dewkl_*
  • Guests
How exactly do you integrate this into the player_core or module script? Doesn't this mean it will check for this every single time an item is added to the inventory?

#14
TimelordDC

TimelordDC
  • Members
  • 923 messages
If you include it in player_core, yes.



If you use EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED in module script, it will check only for those items which have the ITEM_SEND_ACQUIRED_EVENT variable in the item's variable list set.

#15
Guest_dewkl_*

Guest_dewkl_*
  • Guests
I ended up putting it in the module with the campaign item event. I think I got everything working but it simply won't update my quest journal;
WR_SetPlotFlag("plt_cs_quest01", HAVE_1_ITEM, TRUE);

HAVE_1_ITEM is a main flag (entry type: plot). I'm able to update it by using variables, but not by scripting.

Modifié par dewkl, 21 avril 2010 - 08:08 .


#16
Sunjammer

Sunjammer
  • Members
  • 925 messages
Remove the quotes around plt_cs_quest01 and make it upper case as it is a constant that holds the plot's GUID. For example the include file generated by my sj_gathering_main plot looks like:

const string PLT_SJ_GATHERING_MAIN = "227DEAD0C9834C1E9FDFE3C1C3E5F547";
    const int SJ_GATHERING_MAIN_AVAILABLE = 0;
    const int SJ_GATHERING_MAIN_OFFERED = 1;
    const int SJ_GATHERING_MAIN_ACCEPTED = 2;
    const int SJ_GATHERING_MAIN_COMPLETE = 3;
    const int SJ_GATHERING_MAIN_REWARDED = 4;
    const int SJ_GATHERING_MAIN_HAS_ALL_PLANTS = 256;

Modifié par Sunjammer, 21 avril 2010 - 11:06 .


#17
Sunjammer

Sunjammer
  • Members
  • 925 messages
I've been running behind all night but I finally got a chance to finish the new demo and upload it. You can find it here. As usual both B2B and B2P files are provided.

Modifié par Sunjammer, 22 avril 2010 - 01:57 .


#18
Guest_dewkl_*

Guest_dewkl_*
  • Guests
Great, thanks. I'll definitely have a look at it right away. I'm a bit curious though, is there any reason why this can't be done by scripting?

I could just set three IF-operators using CountItemsByTag and get all this done in 6 sentences rather than having to deal with defined flags at all. I feel this is not the right way to do it, so I'll do it the proper way. It sure would be simpler though.

Modifié par dewkl, 23 avril 2010 - 12:52 .


#19
TimelordDC

TimelordDC
  • Members
  • 923 messages
If the ingredients all have the same tag and you are entering generic journal messages (1 item has been found, 2 items have been found) and there is no possibility that the item can be equipped (in which case you have to check party members) or stashed somewhere; then the 6 lines of code can work.

Plots are just an easier way of doing things; not always but most of the time.