ORK integration

Announcements, support questions, and discussion for Quest Machine.
dlevel
Posts: 135
Joined: Wed Nov 16, 2016 6:17 pm

Re: ORK integration

Post by dlevel »

1) To generate quests I call GenerateQuests() from this script:
But this one is not called after I load the game since the player already has his dailies so it skips it in the script I use to check if the dailies are available. So in the video the 2nd time I go to the quest giver board, it doesn't run this generator, should it run it again to re-create the quests?

Save key changing didn't help.

Code: Select all

using System.Collections;
using System.Collections.Generic;
using PixelCrushers.QuestMachine;
using UnityEngine;




[RequireComponent(typeof(QuestGeneratorEntity))]
public class QuestUtilities : MonoBehaviour
{
    [Header("Monster Entity Type")]
    public EntityType monsterType;
    [Header("Amount of Kill Enemies")]
    public int minEnemies;
    public int maxEnemies;
    [Header("Quest ID to manipulate")]    
    public string questIdName;
    public string questerID;
    [Header("Quests to Add")]
    public List<Quest> quests;

    void Start()
    {
        GetComponent<QuestGeneratorEntity>().updateWorldModel += UpdateWorldModel;
    }

    void UpdateWorldModel(WorldModel worldModel)
    {
        
        foreach (var fact in worldModel.facts)
        {
            if (IsMonster(fact.entityType))
            {
                int rndEntities = Random.Range(minEnemies, maxEnemies);
                fact.count = Mathf.Max(fact.count, rndEntities);
                Debug.Log("MONSTER: " + fact.count + " " + fact.entityType.name + " in " + fact.domainType.name);                
            }
            
        }
    }

    private bool IsMonster(EntityType entityType)
    {
        var checkedEntities = new List<EntityType>();
        return IsMonsterRecursive(entityType, checkedEntities);
    }

    private bool IsMonsterRecursive(EntityType entityType, List<EntityType> checkedEntities)
    {
        if (entityType == null || checkedEntities.Contains(entityType)) return false;
        checkedEntities.Add(entityType);
        if (entityType == monsterType) return true;
        foreach (var parent in entityType.parents)
        {
            if (IsMonsterRecursive(parent, checkedEntities)) return true;
        }
        return false;
    }

    public void QuestAdd()
    {
        var generator = GetComponent<QuestGiver>();

        foreach (var quest in quests)
        {
            string questID = quest.id.text;
            if (generator.ContainsQuest(questID))
            {
                Debug.Log("Quest: " + questID + " already exists");
            }
            else
            {
                generator.AddQuest(quest);
            }
        }
    }

    public void QuestStateWaiting()
    {
        QuestMachine.SetQuestState(questIdName, QuestState.WaitingToStart, null);
        Debug.Log("Quest " + questIdName + " changed state to WaitingToStart");
    }

    public void QuestStateAbandon()
    {
        QuestMachine.SetQuestState(questIdName, QuestState.Abandoned, null);
        Debug.Log("Quest " + questIdName + " changed state to Abandoned");
    }

    public List<DomainType> domainTypes;
    //Start is called before the first frame update
    
    //Use this if the Domain is generated in runtime so it can attache a Domain entity
    public void AddMyDomains()
    {

        var generator = GetComponent<QuestGeneratorEntity>();
        var domains = new List<QuestDomain>(generator.domains);
        foreach (var domain in FindObjectsOfType<QuestDomain>())
        {
            var wantThisDomain = domainTypes.Contains(domain.domainType);
            var alreadyHaveThisDomain = domains.Find(x => x.domainType == domain.domainType) != null;
            if (wantThisDomain && !alreadyHaveThisDomain)
            {
                domains.Add(domain);
            }
        }
        generator.domains = domains.ToArray();
        //generator.GenerateQuest();     

    }

    public void GenerateQuests()
    {
        StartCoroutine("GenerateQuestCoroutine");
    }

    IEnumerator GenerateQuestCoroutine()
    {
        yield return new WaitForSeconds(1);
        var generator = GetComponent<QuestGeneratorEntity>();
        yield return new WaitForSeconds(1); generator.GenerateQuest();
        yield return new WaitForSeconds(1); generator.GenerateQuest();
        yield return new WaitForSeconds(1); generator.GenerateQuest();
        //yield return new WaitForSeconds(0.1f); generator.GenerateQuest();
        //yield return new WaitForSeconds(0.1f); generator.GenerateQuest();
    }
}
edit:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using PixelCrushers;
using PixelCrushers.QuestMachine;
using UnityEngine;
using ORKFramework;

public class QuestListener : MonoBehaviour, IMessageHandler
{
    void OnEnable()
    {
        MessageSystem.AddListener(this, QuestMachineMessages.QuestStateChangedMessage, string.Empty);
    }
    void OnDisable()
    {
        MessageSystem.RemoveListener(this);
    }

    public void OnMessage(MessageArgs messageArgs)
    {
        if (messageArgs.values[0] == null) // If value 0 is null, this refer to main quest, not node.
        {
            var questState = (QuestState)(messageArgs.values[1]);
            Debug.Log("Quest 1" + messageArgs.parameter + " change to state: " + questState);
            if (questState == QuestState.Successful)
            {
                Debug.Log("Quest Succeed");
                ORK.Game.Variables.Set("questState", "Success");
                ORK.GlobalEvents.CallGlobalEvent(208, null);
            }
            else if (questState == QuestState.Active)
            {
                Debug.Log("Quest Activated");
                ORK.Game.Variables.Set("questState", "Active");
                ORK.GlobalEvents.CallGlobalEvent(208, null);
            }
            else if (questState == QuestState.WaitingToStart)
            {
                Debug.Log("Quest WaitingToStart");
                ORK.Game.Variables.Set("questState", "Wait");
                //ORK.GlobalEvents.CallGlobalEvent(208, null);
            }
            else if (questState == QuestState.Abandoned)
            {
                ORK.Game.Variables.Set("questState", "Abandoned");
                Debug.Log("Quest Abandoned");
                ORK.GlobalEvents.CallGlobalEvent(208, null);
            }
            else if (questState == QuestState.Failed)
            {
                Debug.Log("Quest Activated");
                ORK.Game.Variables.Set("questState", "Failed");
                ORK.GlobalEvents.CallGlobalEvent(208, null);
            }
        }
    }
}
}
so this is what I get after loading for the quests the player hasn't picked up yet (this debug is in the script above line 24) so it seems it changes to disabled after loading, so it is saved but somehow not in a WaitingToStart state:

Code: Select all

Quest 1Kill 100 Dark Spiders 5a2e9d7b-7d13-4e3f-83cb-3a5ed26f8fa6 change to state: Disabled
UnityEngine.Debug:Log(Object)
QuestListener:OnMessage(MessageArgs) (at Assets/Scripts/QuestListener.cs:24)
PixelCrushers.MessageSystem:SendMessageWithTarget(Object, Object, String, String, Object[]) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Message System/MessageSystem.cs:338)
PixelCrushers.MessageSystem:SendMessage(Object, String, StringField, Object[]) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Message System/MessageSystem.cs:438)
PixelCrushers.QuestMachine.QuestMachineMessages:QuestStateChanged(Object, StringField, QuestState) (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Utility/QuestMachineMessages.cs:160)
PixelCrushers.QuestMachine.Quest:SetState(QuestState, Boolean) (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest/Quest.cs:875)
PixelCrushers.QuestMachine.Quest:DestroyInstance(Quest) (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest/Quest.cs:639)
PixelCrushers.QuestMachine.QuestListContainer:DeleteQuest(Quest) (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest MonoBehaviours/Quest List/QuestListContainer.cs:231)
PixelCrushers.QuestMachine.QuestListContainer:DestroyQuestInstances() (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest MonoBehaviours/Quest List/QuestListContainer.cs:149)
PixelCrushers.QuestMachine.QuestListContainer:OnDestroy() (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest MonoBehaviours/Quest List/QuestListContainer.cs:130)
PixelCrushers.QuestMachine.QuestGiver:OnDestroy() (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest MonoBehaviours/Quest List/QuestGiver.cs:218)
PixelCrushers.QuestMachine.ORKSupport.QuestGiverForORK:OnDestroy() (at Assets/Pixel Crushers/Quest Machine/Third Party Support/ORK Framework Support/Scripts/Quest List MonoBehaviours/QuestGiverForORK.cs:43)

which is exactly what happens when I stop playing on unity editor, every quest is also turns disabled in the listener:
https://ibb.co/pPvJPpw




2) Sorry I didn't understood that.

https://ibb.co/BKZ57c1
https://ibb.co/qnD1vpf

here is how the rewards are setup. What happened is that after players got the new update with 1.2.10 QM, they rewarded with old rewards, and from their reports I understand they rewarded with as many rewards as ALL the quests they did before the new version, like 1 month quests for some people, so it was a pretty bad bug. Are these kept somewhere?

Again, it happened after updating to 1.2.10, which added some new stuff regarding old quests journal etc. which maybe triggered something. It is important we find the reason so it's not happen again, cause I feel a bit unconfortable for this to happen cause I'm live, it's a huge bug.


3) Using the generation script above, I don't get exp and general reward multipliers, tried in both parents and childs
User avatar
Tony Li
Posts: 20734
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Hi,

> Job board's "Waiting To Start" quests missing after loading game

When a scene is unloaded, it destroys all of its GameObjects. Each GameObject destroys all of its components.

When a QuestGiver (or QuestGiverForORK) component is destroyed, it sets all of its quests' states to Disabled.

Here's a debug version of the ORKQuestMachineSaveData script:

QM_ORK_SaveDataDebug_2020-10-13.unitypackage

If you tick the Debug checkbox, then when you save or load, it will log an atrocious save data string to the Console that looks something like this:

Code: Select all

ORKQuestMachineSaveData.SaveGame: {"m_sceneName":"Demo","m_list":[{"key":"Carrot","sceneIndex":-1,"data":""},{"key":"Rabbit","sceneIndex":-1,"data":""},{"key":"Orc","sceneIndex":-1,"data":""},{"key":"Knight","sceneIndex":-1,"data":"{\"staticQuestIds\":[],\"staticQuestData\":[],\"proceduralQuests\":[\"{\\\"isInstance\\\":true,\\\"id\\\":\\\"Kill 3 Orcs 89da7033-5b74-447b-91f5-473d7cd73985\\\",\\\"displayName\\\":\\\"Kill 3 Orcs\\\",\\\"iconPath\\\":\\\"orc0001\\\",\\\"group\\\":\\\"\\\",\\\"labels\\\":[],\\\"giver\\\":\\\"Knight\\\",\\\"isTrackable\\\":true,\\\"track\\\":true,\\\"isAbandonable\\\":false,\\\"rememberIfAbandoned\\\":false,\\\"autostartConditionSet\\\":{\\\"conds\\\":[],\\\"mode\\\":0,\\\"min\\\":0,\\\"numTrue\\\":0},\\\"offerConditionSet\\\":{\\\"conds\\\":[],\\\"mode\\\":0,\\\"min\\\":0,\\\"numTrue\\\":0},\\\"offerUnmetContentList\\\":[],\\\"offerContentList\\\":[{\\\"t\\\":\\\"Head\\\",\\\"s\\\":\\\"1;Kill 3 Orcs;1\\\"},{\\\"t\\\":\\\"Body\\\",\\\"s\\\":\\\"There's grave danger. We must step forward for the safety of our people. Enter The Forest and {kill} 3 Orcs.\\\"},{\\\"t\\\":\\\"Head\\\",\\\"s\\\":\\\"1;Rewards;0\\\"},{\\\"t\\\":\\\"Body\\\",\\\"s\\\":\\\"15 XP\\\"},{\\\"t\\\":\\\"Body\\\",\\\"s\\\":\\\"15 Coins\\\"}],\\\"maxTimes\\\":1,\\\"timesAccepted\\\":0,\\\"cooldownSecs\\\":3600.0,\\\"cooldownSecsRemain\\\":0.0,\\\"state\\\":0,\\\"stateInfoList\\\":[{\\\"acn\\\":[],\\\"dlg\\\":[],\\\"jrl\\\":[],\\\"hud\\\":[]},{\\\"acn\\\":[],\\\"dlg\\\":[{\\\"t\\\":\\\"Head\\\",\\\"s\\\":\\\"1;Kill 3 Orcs;1\\\"}],\\\"jrl\\\":[{\\\"t\\\":\\\"Head\\\",\\\"s\\\":\\\"1;Kill 3 Orcs;
Look for your quest ID ("Kill 3 Orcs 89da7033-5b74-447b-91f5-473d7cd73985" in the example above). Right after that, look for the first occurrence of "state". In the example above, it's:

Code: Select all

"state\\\":0
The 0 is the code for WaitingToStart. If it's 5, that means Disabled.


> Players get all rewards

If you examine a generated quest in the Quest Editor window, are any reward actions assigned to the Disabled state by any chance? They should only be assigned to the Successful state.

This is the change in 1.2.10: If the Quest Journal component's Remember Completed Quests checkbox (in Save Settings) is not ticked, it will remove any quests from the journal that are in the Successful or Failed state.

Prior to 1.2.10, quests were not removed. In other words, prior to 1.2.10, the Remember Completed Quests checkbox value was ignored.

If you want to go back to the behavior in 1.2.9 and earlier, tick Remember Completed Quests.
dlevel
Posts: 135
Joined: Wed Nov 16, 2016 6:17 pm

Re: ORK integration

Post by dlevel »

1) Well that is odd, the ORKQuestMachineSaveData.cs is not included in the package, and also is not mentioned on the ork_framework manual :) so I see in the comments it might not needed since the save system does most, but in my case this part of the save didn't work, so a heads up for other, so now it seems that it works!

Just to be sure, Save System and ORKQuestMachineSaveData should both be in the Quest Machine game object, correct?


2) there is nothing assigned to the failed in the auto generated quests:

https://ibb.co/RQxnGBP

Well I guess something bugged when the quests removed after the update, maybe the removal of the new version triggered a give reward again?

3) Using the generation script above, I don't get exp and general reward multipliers (that I change in the entities), tried in both parents and childs
User avatar
Tony Li
Posts: 20734
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Hi,
dlevel wrote: Wed Oct 14, 2020 6:23 am1) Well that is odd, the ORKQuestMachineSaveData.cs is not included in the package, and also is not mentioned on the ork_framework manual :) so I see in the comments it might not needed since the save system does most, but in my case this part of the save didn't work, so a heads up for other, so now it seems that it works!

Just to be sure, Save System and ORKQuestMachineSaveData should both be in the Quest Machine game object, correct?
Yes. That's correct. Here's a version of the package that includes ORKQuestMachineSaveData. It also includes checkboxes on QuestJournalForORK and QuestGiverForORK that let you tell these components that ORKQuestMachineSaveData will save the data. This way QuestJournalForORK and QuestGiverForORK won't also save the data, which would make the save file unnecessarily bigger.

QM_ORKSupport_2020-10-14.unitypackage

The package also has an update for reward systems. (See below.)
dlevel wrote: Wed Oct 14, 2020 6:23 am2) there is nothing assigned to the failed in the auto generated quests:

https://ibb.co/RQxnGBP

Well I guess something bugged when the quests removed after the update, maybe the removal of the new version triggered a give reward again?
From the information available, I'm afraid I can't determine what happened. If you can reproduce the issue and send me a reproduction project, I'll get to the bottom of it.
dlevel wrote: Wed Oct 14, 2020 6:23 am3) Using the generation script above, I don't get exp and general reward multipliers (that I change in the entities), tried in both parents and childs
In the updated package, the ORK reward systems now observe multipliers.
dlevel
Posts: 135
Joined: Wed Nov 16, 2016 6:17 pm

Re: ORK integration

Post by dlevel »

Awesome thank you! We finally found all the mystery issues behind my saves :)
User avatar
Tony Li
Posts: 20734
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Great! Thank you for your patience and understanding as we worked through it.
hardercore
Posts: 9
Joined: Sun Aug 23, 2020 12:21 am

Re: ORK integration

Post by hardercore »

I'm having an issue where a quest isn't picking up ORK global variable conditions for offer condition. When I use the step debugger I never see "IsConditionMet" called. I'm sure this variable is being set (I print it out) and I've tried toggling the value from needing False to needing True. Neither work.

I added a call to Tick() after base.StartChecking(trueAction); in ORKVariableQuestCondition and it works but I'm worried this will mess other things up.
User avatar
Tony Li
Posts: 20734
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Hi @hardercore,

The Quest Machine Extras page has an updated ORK integration package that fixes that bug.
hardercore
Posts: 9
Joined: Sun Aug 23, 2020 12:21 am

Re: ORK integration

Post by hardercore »

Thanks!
User avatar
Tony Li
Posts: 20734
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Happy to help!
Post Reply