예제 #1
0
        private static bool ImportArticyPins(ArticyFlowObject source, BaseQuestObject target, bool compileInputScripts, bool compileOutputScripts, Dictionary <ulong, QuestPin> pinIndex)
        {
            FlowObjectPin articyPin;
            QuestPin      pin;
            bool          badScripts = false;

            foreach (GraphPin graphPin in source.Inputs)
            {
                articyPin = (FlowObjectPin)graphPin;
                pin       = new QuestPin(articyPin.Type, articyPin.Id);
                if (compileInputScripts && !string.IsNullOrWhiteSpace(articyPin.Script))
                {
                    if ((pin.Script = CompileScript(articyPin.Script, Quests.InputPinScriptEnvironment, "input pin", articyPin.Id)) == null)
                    {
                        badScripts = true;
                    }
                }
                if (string.IsNullOrEmpty(target.Key))
                {
                    GameDebugger.Log(LogLevel.Debug, "Adding intput pin to '0x{0:X16}'", target.Id);
                }
                else
                {
                    GameDebugger.Log(LogLevel.Debug, "Adding intput pin to '{0}'", target.Key);
                }
                pinIndex.Add(articyPin.Id, pin);
                target.AddInput(pin);
            }

            foreach (GraphPin graphPin in source.Outputs)
            {
                articyPin = (FlowObjectPin)graphPin;
                pin       = new QuestPin(articyPin.Type, articyPin.Id);
                if (compileOutputScripts && !string.IsNullOrWhiteSpace(articyPin.Script))
                {
                    QuestSystemScriptEnvironment env;
                    env = (target is QuestObjective) ? (QuestSystemScriptEnvironment)Quests.OutputPinScriptEnvironment : (QuestSystemScriptEnvironment)Quests.InstructionScriptEnvironment;
                    if ((pin.Script = CompileScript(articyPin.Script, env, "output pin", articyPin.Id)) == null)
                    {
                        badScripts = true;
                    }
                }
                if (string.IsNullOrEmpty(target.Key))
                {
                    GameDebugger.Log(LogLevel.Debug, "Adding output pin to '0x{0:X16}'", target.Id);
                }
                else
                {
                    GameDebugger.Log(LogLevel.Debug, "Adding output pin to '{0}'", target.Key);
                }
                pinIndex.Add(articyPin.Id, pin);
                target.AddOutput(pin);
            }

            return(badScripts);
        }
예제 #2
0
        protected void Lock(QuestPin pin, bool propagate)
        {
            QuestObjectState state = GetState(pin);

            if (state.Locked)
            {
                return;
            }
            state.Locked = true;
            GameDebugger.Log(LogLevel.Debug, "QS: {0} '0x{1:X16}' locked", pin.GetType().Name, pin.Id);

            if (pin.Type == GraphPin.PinType.Input)
            {
                if (m_ActivelyChecked.ContainsKey(pin.Id))
                {
                    GameDebugger.Log(LogLevel.Debug, "QS: Removing {0} '0x{1:X16}' from the list of actively checked objects", pin.GetType().Name, pin.Id);
                    m_ActivelyChecked.Remove(pin.Id);
                }
            }

            foreach (QuestConnection connection in pin.Connections)
            {
                Lock(connection, (connection.Target == pin));                 // propagate locking only on incoming connections
            }

            if (propagate && pin.Type == GraphPin.PinType.Output)
            {
                foreach (QuestPin otherPin in pin.Node.Outputs)
                {
                    if (otherPin == pin)
                    {
                        continue;
                    }
                    Lock(otherPin, false);
                }
                Lock((BaseQuestObject)pin.Node);
            }
        }
예제 #3
0
        public void Tick()
        {
            QuestObjectState state;
            bool             result;

            var values = m_ActivelyChecked.Values;

            IQuestSystemObject[] objects = new IQuestSystemObject[values.Count];
            values.CopyTo(objects, 0);

            GameDebugger.Log(LogLevel.Debug, "QS: TICK");
            foreach (IQuestSystemObject obj in objects)
            {
                state = GetState(obj);
                if (state.Locked)
                {
                    GameDebugger.Log(LogLevel.Warning, "QS: {0} '0x{1:X16}' is in the list of actively checked objects while being locked", obj.GetType().Name, obj.Id);
                    m_ActivelyChecked.Remove(obj.Id);
                    continue;
                }
                GameDebugger.Log(LogLevel.Debug, "QS: Checking {0} '0x{1:X16}'", obj.GetType().Name, obj.Id);
                if (obj is QuestPin)
                {
                    QuestPin pin = (QuestPin)obj;
                    result = CheckCondition(pin, true);
                    if (result && state.Active == QuestObjectState.ActivationState.PartiallyActive)
                    {
                        state.Active = QuestObjectState.ActivationState.Active;
                        GameDebugger.Log(LogLevel.Debug, "QS: Switched {0} '0x{1:X16}' from partially activated to activated", obj.GetType().Name, obj.Id);
                        if (pin.Node is Quest)
                        {
                            Activate((BaseQuestObject)pin.Node);
                        }
                        else
                        {
                            CheckInputsOnActivation((BaseQuestObject)pin.Node);
                        }
                        foreach (QuestConnection connection in pin.Connections)
                        {
                            if (connection.Source == pin)
                            {
                                Activate(connection);
                            }
                        }
                    }
                    else if (!result && state.Active == QuestObjectState.ActivationState.Active)
                    {
                        state.Active = QuestObjectState.ActivationState.PartiallyActive;
                        GameDebugger.Log(LogLevel.Debug, "QS: Switched {0} '0x{1:X16}' from activated to partially activated", obj.GetType().Name, obj.Id);
                        Deactivate((BaseQuestObject)pin.Node);
                        foreach (QuestConnection connection in pin.Connections)
                        {
                            if (connection.Source == pin)
                            {
                                Deactivate(connection);
                            }
                        }
                    }
                }
                else if (obj is QuestCondition)
                {
                    // every tick depending on it's script execution result it switches active either output[0] or output[1] active
                    QuestCondition condition = (QuestCondition)obj;
                    result = CheckCondition(condition, true);
                    if (result)
                    {
                        if (state.CompletionOutput != 0 || state.Completion == QuestObjectState.CompletionState.Incomplete)
                        {
                            if (state.Completion != QuestObjectState.CompletionState.Incomplete)
                            {
                                Deactivate((QuestPin)condition.Outputs[1]);
                                GameDebugger.Log(LogLevel.Debug, "QS: Switching {0} '0x{1:X16}' output from FALSE to TRUE", obj.GetType().Name, obj.Id);
                            }
                            else
                            {
                                GameDebugger.Log(LogLevel.Debug, "QS: Setting {0} '0x{1:X16}' output to TRUE", obj.GetType().Name, obj.Id);
                            }
                            Activate((QuestPin)condition.Outputs[0]);
                            state.CompletionOutput = 0;
                        }
                    }
                    else
                    {
                        if (state.CompletionOutput != 1 || state.Completion == QuestObjectState.CompletionState.Incomplete)
                        {
                            if (state.Completion != QuestObjectState.CompletionState.Incomplete)
                            {
                                Deactivate((QuestPin)condition.Outputs[0]);
                                GameDebugger.Log(LogLevel.Debug, "QS: Switching {0} '0x{1:X16}' output from TRUE to FALSE", obj.GetType().Name, obj.Id);
                            }
                            else
                            {
                                GameDebugger.Log(LogLevel.Debug, "QS: Setting {0} '0x{1:X16}' output to FALSE", obj.GetType().Name, obj.Id);
                            }
                            Activate((QuestPin)condition.Outputs[1]);
                            state.CompletionOutput = 1;
                        }
                    }
                    state.Completion = QuestObjectState.CompletionState.Successful;
                }
                else if (obj is QuestObjective)
                {
                    // every tick rechecks all conditions on output pins
                    QuestObjective objective = (QuestObjective)obj;
                    int            pinIndex  = 0;
                    foreach (QuestPin pin in objective.Outputs)
                    {
                        if (pin.Script == null)
                        {
                            pinIndex++;
                            continue;
                        }
                        result = CheckCondition(pin, false);
                        if (result)
                        {
                            Activate(pin);                     // this will also deactivate previously active pin
                            break;                             // Just in case when there is more than one output that passes the check. We don't want lots of unneeded events, right?
                        }
                        if (pinIndex == state.CompletionOutput && state.Completion != QuestObjectState.CompletionState.Incomplete)
                        {
                            state.Completion = QuestObjectState.CompletionState.Incomplete;
                            GameDebugger.Log(LogLevel.Debug, "QS: event: OnQuestObjectiveIncomplete");
                            if (OnQuestObjectiveIncomplete != null)
                            {
                                OnQuestObjectiveIncomplete.Invoke(new QuestObjectiveIncompleteEventArgs(objective));
                            }
                        }
                        Deactivate(pin);
                        pinIndex++;
                    }
                }
                else
                {
                    GameDebugger.Log(LogLevel.Warning, "QS: {0} '0x{1:X16}' is not supposed to be in the list of actively checked objects", obj.GetType().Name, obj.Id);
                }
            }
        }
예제 #4
0
 protected void Lock(QuestPin pin)
 {
     Lock(pin, true);
 }
예제 #5
0
        protected void Activate(QuestPin pin)
        {
            QuestObjectState state = GetState(pin);

            if (state.Locked || state.Active != QuestObjectState.ActivationState.Inactive)
            {
                return;
            }
            bool lockPin = false;

            if (pin.Type == GraphPin.PinType.Input)
            {
                if (pin.Script != null)
                {
                    GameDebugger.Log(LogLevel.Debug, "QS: Partially activated pin '0x{0:X16}'", pin.Id);
                    GameDebugger.Log(LogLevel.Debug, "QS: Adding pin '0x{0:X16}' to the list of actively checked objects", pin.Id);
                    state.Active = QuestObjectState.ActivationState.PartiallyActive;
                    m_ActivelyChecked.Add(pin.Id, pin);
                }
                else
                {
                    state.Active = QuestObjectState.ActivationState.Active;
                    GameDebugger.Log(LogLevel.Debug, "QS: Activated pin '0x{0:X16}'", pin.Id);
                    if (pin.Node is Quest)
                    {
                        Activate((BaseQuestObject)pin.Node);
                    }
                    else
                    {
                        CheckInputsOnActivation((BaseQuestObject)pin.Node);
                    }
                }
            }
            else
            {
                state.Active = QuestObjectState.ActivationState.Active;
                GameDebugger.Log(LogLevel.Debug, "QS: Activated pin '0x{0:X16}'", pin.Id);

                if (pin.Node is Quest || pin.Node is QuestObjective)
                {
                    QuestObjectState nodeState = GetState((IQuestSystemObject)pin.Node);
                    int pinIndex = 0;
                    foreach (QuestPin testPin in pin.Node.Outputs)
                    {
                        if (testPin == pin)
                        {
                            GameDebugger.Log(LogLevel.Debug, "QS: Detected pin index: {0}", pinIndex);
                            break;
                        }
                        pinIndex++;
                    }

                    if (nodeState.Completion == QuestObjectState.CompletionState.Incomplete || nodeState.CompletionOutput != pinIndex)
                    {
                        if (nodeState.Completion != QuestObjectState.CompletionState.Incomplete)
                        {
                            Deactivate((QuestPin)pin.Node.Outputs[nodeState.CompletionOutput]);
                            GameDebugger.Log(LogLevel.Debug, "QS: Switching {0} '0x{1:X16}' completion state from {2} to {3}", pin.Node.GetType().Name, ((IQuestSystemObject)pin.Node).Id, nodeState.CompletionOutput, pinIndex);
                        }
                        else
                        {
                            GameDebugger.Log(LogLevel.Debug, "QS: Setting {0} '0x{1:X16}' completion state to {2}", pin.Node.GetType().Name, ((IQuestSystemObject)pin.Node).Id, pinIndex);
                        }
                        nodeState.CompletionOutput = (byte)pinIndex;
                        nodeState.Completion       = pin.IsFailureOutput ? QuestObjectState.CompletionState.Failed : QuestObjectState.CompletionState.Successful;

                        if (pin.Node is Quest)
                        {
                            lockPin = true;
                            GameDebugger.Log(LogLevel.Debug, "QS: event: OnQuestComplete");
                            if (OnQuestComplete != null)
                            {
                                OnQuestComplete.Invoke(new QuestCompleteEventArgs((Quest)pin.Node, pinIndex, pin.IsFailureOutput));
                            }
                        }
                        else
                        {
                            GameDebugger.Log(LogLevel.Debug, "QS: event: OnQuestObjectiveComplete");
                            if (OnQuestObjectiveComplete != null)
                            {
                                OnQuestObjectiveComplete.Invoke(new QuestObjectiveCompleteEventArgs((QuestObjective)pin.Node, pinIndex, pin.IsFailureOutput));
                            }
                        }
                    }
                }

                if (!(pin.Node is QuestObjective))                  // quest objectives have conditions instead of instructions on outputs
                {
                    ExecuteScript(pin);
                }
            }

            // activate all outgoing connections
            if (state.Active == QuestObjectState.ActivationState.Active)
            {
                foreach (QuestConnection connection in pin.Connections)
                {
                    if (connection.Source == pin)
                    {
                        Activate(connection);
                    }
                }
            }

            // locking the pin must be done in the end otherwise it will not activate connections (they will be already locked)
            if (lockPin)
            {
                Lock(pin);
            }
        }