Exemple #1
0
        public Flow(string name, Story story, Dictionary <string, object> jObject)
        {
            this.name      = name;
            this.callStack = new CallStack(story);
            this.callStack.SetJsonToken((Dictionary <string, object>)jObject ["callstack"], story);
            this.outputStream   = Json.JArrayToRuntimeObjList((List <object>)jObject ["outputStream"]);
            this.currentChoices = Json.JArrayToRuntimeObjList <Choice>((List <object>)jObject ["currentChoices"]);

            // choiceThreads is optional
            object jChoiceThreadsObj;

            jObject.TryGetValue("choiceThreads", out jChoiceThreadsObj);
            LoadFlowChoiceThreads((Dictionary <string, object>)jChoiceThreadsObj, story);
        }
        void LoadJsonObj(Dictionary <string, object> jObject)
        {
            object jSaveVersion = null;

            if (!jObject.TryGetValue("inkSaveVersion", out jSaveVersion))
            {
                throw new StoryException("ink save format incorrect, can't load.");
            }
            else if ((int)jSaveVersion < kMinCompatibleLoadVersion)
            {
                throw new StoryException("Ink save format isn't compatible with the current version (saw '" + jSaveVersion + "', but minimum is " + kMinCompatibleLoadVersion + "), so can't load.");
            }

            callStack.SetJsonToken((Dictionary <string, object>)jObject ["callstackThreads"], story);
            variablesState.SetJsonToken((Dictionary <string, object>)jObject["variablesState"]);

            evaluationStack = Json.JArrayToRuntimeObjList((List <object>)jObject ["evalStack"]);

            _outputStream = Json.JArrayToRuntimeObjList((List <object>)jObject ["outputStream"]);
            OutputStreamDirty();

            _currentChoices = Json.JArrayToRuntimeObjList <Choice>((List <object>)jObject ["currentChoices"]);

            object currentDivertTargetPath;

            if (jObject.TryGetValue("currentDivertTarget", out currentDivertTargetPath))
            {
                var divertPath = new Path(currentDivertTargetPath.ToString());
                divertedPointer = story.PointerAtPath(divertPath);
            }

            _visitCounts = Json.JObjectToIntDictionary((Dictionary <string, object>)jObject["visitCounts"]);
            _turnIndices = Json.JObjectToIntDictionary((Dictionary <string, object>)jObject["turnIndices"]);

            currentTurnIndex = (int)jObject ["turnIdx"];
            storySeed        = (int)jObject ["storySeed"];

            // Not optional, but bug in inkjs means it's actually missing in inkjs saves
            object previousRandomObj = null;

            if (jObject.TryGetValue("previousRandom", out previousRandomObj))
            {
                previousRandom = (int)previousRandomObj;
            }
            else
            {
                previousRandom = 0;
            }

            object jChoiceThreadsObj = null;

            jObject.TryGetValue("choiceThreads", out jChoiceThreadsObj);
            var jChoiceThreads = (Dictionary <string, object>)jChoiceThreadsObj;

            foreach (var c in _currentChoices)
            {
                var foundActiveThread = callStack.ThreadWithIndex(c.originalThreadIndex);
                if (foundActiveThread != null)
                {
                    c.threadAtGeneration = foundActiveThread.Copy();
                }
                else
                {
                    var jSavedChoiceThread = (Dictionary <string, object>)jChoiceThreads[c.originalThreadIndex.ToString()];
                    c.threadAtGeneration = new CallStack.Thread(jSavedChoiceThread, story);
                }
            }
        }
Exemple #3
0
        void LoadJsonObj(Dictionary <string, object> jObject)
        {
            object jSaveVersion = null;

            if (!jObject.TryGetValue("inkSaveVersion", out jSaveVersion))
            {
                throw new Exception("ink save format incorrect, can't load.");
            }
            else if ((int)jSaveVersion < kMinCompatibleLoadVersion)
            {
                throw new Exception("Ink save format isn't compatible with the current version (saw '" + jSaveVersion + "', but minimum is " + kMinCompatibleLoadVersion + "), so can't load.");
            }

            // Flows: Always exists in latest format (even if there's just one default)
            // but this dictionary doesn't exist in prev format
            object flowsObj = null;

            if (jObject.TryGetValue("flows", out flowsObj))
            {
                var flowsObjDict = (Dictionary <string, object>)flowsObj;

                // Single default flow
                if (flowsObjDict.Count == 1)
                {
                    _namedFlows = null;
                }

                // Multi-flow, need to create flows dict
                else if (_namedFlows == null)
                {
                    _namedFlows = new Dictionary <string, Flow>();
                }

                // Multi-flow, already have a flows dict
                else
                {
                    _namedFlows.Clear();
                }

                // Load up each flow (there may only be one)
                foreach (var namedFlowObj in flowsObjDict)
                {
                    var name    = namedFlowObj.Key;
                    var flowObj = (Dictionary <string, object>)namedFlowObj.Value;

                    // Load up this flow using JSON data
                    var flow = new Flow(name, story, flowObj);

                    if (flowsObjDict.Count == 1)
                    {
                        _currentFlow = new Flow(name, story, flowObj);
                    }
                    else
                    {
                        _namedFlows[name] = flow;
                    }
                }

                if (_namedFlows != null && _namedFlows.Count > 1)
                {
                    var currFlowName = (string)jObject["currentFlowName"];
                    _currentFlow = _namedFlows[currFlowName];
                }
            }

            // Old format: individually load up callstack, output stream, choices in current/default flow
            else
            {
                _namedFlows       = null;
                _currentFlow.name = kDefaultFlowName;
                _currentFlow.callStack.SetJsonToken((Dictionary <string, object>)jObject ["callstackThreads"], story);
                _currentFlow.outputStream   = Json.JArrayToRuntimeObjList((List <object>)jObject ["outputStream"]);
                _currentFlow.currentChoices = Json.JArrayToRuntimeObjList <Choice>((List <object>)jObject ["currentChoices"]);

                object jChoiceThreadsObj = null;
                jObject.TryGetValue("choiceThreads", out jChoiceThreadsObj);
                _currentFlow.LoadFlowChoiceThreads((Dictionary <string, object>)jChoiceThreadsObj, story);
            }

            OutputStreamDirty();

            variablesState.SetJsonToken((Dictionary <string, object>)jObject["variablesState"]);
            variablesState.callStack = _currentFlow.callStack;

            evaluationStack = Json.JArrayToRuntimeObjList((List <object>)jObject ["evalStack"]);


            object currentDivertTargetPath;

            if (jObject.TryGetValue("currentDivertTarget", out currentDivertTargetPath))
            {
                var divertPath = new Path(currentDivertTargetPath.ToString());
                divertedPointer = story.PointerAtPath(divertPath);
            }

            _visitCounts = Json.JObjectToIntDictionary((Dictionary <string, object>)jObject["visitCounts"]);
            _turnIndices = Json.JObjectToIntDictionary((Dictionary <string, object>)jObject["turnIndices"]);

            currentTurnIndex = (int)jObject ["turnIdx"];
            storySeed        = (int)jObject ["storySeed"];

            // Not optional, but bug in inkjs means it's actually missing in inkjs saves
            object previousRandomObj = null;

            if (jObject.TryGetValue("previousRandom", out previousRandomObj))
            {
                previousRandom = (int)previousRandomObj;
            }
            else
            {
                previousRandom = 0;
            }
        }