Page 1 of 2

Questions about splitscreen logic

Posted: Wed Mar 16, 2022 4:03 pm
by splinedrew
Hello there!

So I am currently using both Quest Machine and Dialogue System for a split-screen game. I have followed most of the logic I could find on the forums, specifically this thread: https://www.pixelcrushers.com/phpbb/vie ... f=3&t=4349

My basic setup is that each player has their own UI panel, which is where they have the necessary individual dialogue and quest related components. I am using Rewired for inputs which is all working great. That forum thread above didn't quite cover the quest machine components so I thought I would ask a few questions here. So far I have Player 1, Player 2, NPC 1 for P1, and NPC 1 for P2 as actors.

To start, I want the game to have shared bigger quests, and then smaller individual quests that they could get from various NPCs. The game starts by giving a shared quest to both players. Now I found this code to give each player the quest:

Code: Select all

    public Quest questAsset;
    public QuestJournal questJournal;

    void Start()
    {
        // Make a copy of the quest for the quester:
        var questInstance = questAsset.Clone();

        // Add the copy to the quester and activate it:
        var questerTextInfo = new QuestParticipantTextInfo(questJournal.id, questJournal.displayName, questJournal.image, null);
        questInstance.AssignQuester(questerTextInfo);
        questInstance.timesAccepted = 1;
        questJournal.deletedStaticQuests.Remove(StringField.GetStringValue(questInstance.id));
        questJournal.AddQuest(questInstance);
        questInstance.SetState(QuestState.Active);
        QuestMachineMessages.RefreshUIs(questInstance);
    }
This appears to work great, but where I run into the problem is running this code in the dialogue tree:

Code: Select all

SetQuestNodeState("LeavingHome","Find Sarah","success")
This only seems to update the "LeavingHome" quest for the first player. I am guessing it is because there are multiple instances named "LeavingHome" and it is only updating the first one. As a test, I modified the script and assigned the same Quest Instance to both players, and this resolved the issue of only updating one of the quests. But the problem is that if the Quest Journal is opened for one of the players, and they tick the checkbox on the quest so that they can now focus on a different quest, the other player is also affected by that choice - which is undesirable. Is there some way of running that SetQuestNodeState on all of the instances of that quest?

I will likely have a few more questions as I continue integrating this!

Thanks!

Re: Questions about splitscreen logic

Posted: Wed Mar 16, 2022 4:56 pm
by Tony Li
Hi,

The SetQuestNodeState() function is the simplified version that you can use when there's only one quester.

Since you have multiple questers, you'll need to use SetQuesterQuestNodeState(). It takes the same parameters plus the quester ID. So instead of:

Code: Select all

SetQuestNodeState("LeavingHome","Find Sarah","success")
you'd use:

Code: Select all

SetQuestNodeState("LeavingHome", "Find Sarah", "success", "Player1");
SetQuestNodeState("LeavingHome", "Find Sarah", "success", "Player2");
(Assuming your player quester IDs are "Player1" and "Player2".)

The full list of available QM+DS functions starts on page 2 of the Dialogue System Support.pdf guide.

Re: Questions about splitscreen logic

Posted: Wed Mar 16, 2022 11:34 pm
by splinedrew
That did the trick! Thanks!

Re: Questions about splitscreen logic

Posted: Thu Mar 17, 2022 9:36 am
by Tony Li
Glad to help!

Re: Questions about splitscreen logic

Posted: Thu Aug 31, 2023 5:24 pm
by splinedrew
I had one more question about split screen logic. I couldn't find any good compass assets that will work with split screen so I am making it custom. I am wondering how to best handle enabling and disabling objects when a quest node becomes active.

My initial thought was to add a Lua function that is called from the actions menu in the active and inactive state in the quest, but is there a way to specify the quester ID?
ID.JPG
ID.JPG (52.99 KiB) Viewed 1670 times
Or is there a better approach to this?

Re: Questions about splitscreen logic

Posted: Thu Aug 31, 2023 8:23 pm
by Tony Li
Hi,

You can write a quest action. Duplicate QuestActionTemplate.cs and add your code where the comments indicate. Briefly: Add a string or StringField to specify your quester/quest entity ID. In the OnExecute() method, use QuestMachineMessages.FindGameObjectWithID() to find the GameObject so you can changes its active/inactive state. You'll probably also want to add an Active Saver or Multi Active Saver component to an active GameObject in the scene and assign your target GameObject to keep track of its active/inactive state in saved games.

Re: Questions about splitscreen logic

Posted: Thu Aug 31, 2023 8:41 pm
by splinedrew
That's all good and I like that I can add a custom action! The problem sort of still remains for me. In my quests, the same quest can be assigned to either P1 or P2. How do I know in my custom action if P1 or P2 was the recipient of the quest?

Basically if P1 gets the quest, I need to turn on the HUD indicator for just P1. Likewise for P2. I can't fill in the ID field, because I don't know who is actually getting the quest. I hope this makes sense! Splitscreen is so complicated lol.
IDpart2.JPG
IDpart2.JPG (52.91 KiB) Viewed 1663 times

Re: Questions about splitscreen logic

Posted: Thu Aug 31, 2023 9:23 pm
by Tony Li
Got it. In that case, your custom action can check which player's QuestJournal contains the quest. The quest action has a quest property. Check which player's QuestJournal's questList contains the quest.

Re: Questions about splitscreen logic

Posted: Fri Sep 01, 2023 7:05 am
by splinedrew
Ah shoot so I got it working with what you suggested, but when the quest is toggled off in the Quest Journal UI, nothing currently happens/the POI remains active. Do you have any ideas on an approach for this?

Re: Questions about splitscreen logic

Posted: Fri Sep 01, 2023 8:17 am
by Tony Li
Hi,

Add a script that implements IMessageHandler, and listen for QuestMachineMessages.QuestTrackToggleChangedMessage.

This post explains how to use IMessageHandler to listen for messages. The example listens for quest state changes, but you'd use the same approach to listen for QuestMachineMessages.QuestTrackToggleChangedMessage instead.

When the script receives that message, check if the quest is in this player's QuestJournal.questList. If so, toggle the POIs accordingly.