diff --git a/Assets/Fungus/Scripts/Components/SaveManager.cs b/Assets/Fungus/Scripts/Components/SaveManager.cs index 3cb35099..575a1e33 100644 --- a/Assets/Fungus/Scripts/Components/SaveManager.cs +++ b/Assets/Fungus/Scripts/Components/SaveManager.cs @@ -108,7 +108,12 @@ namespace Fungus { if (saveHistory.NumSavePoints > 0) { - saveHistory.Rewind(); + // Can't rewind the first save point (new_game) + if (saveHistory.NumSavePoints > 1) + { + saveHistory.Rewind(); + } + saveHistory.LoadLatestSavePoint(); } } diff --git a/Assets/Fungus/Scripts/Components/SaveMenu.cs b/Assets/Fungus/Scripts/Components/SaveMenu.cs index 4d50e301..3af6f583 100644 --- a/Assets/Fungus/Scripts/Components/SaveMenu.cs +++ b/Assets/Fungus/Scripts/Components/SaveMenu.cs @@ -72,22 +72,34 @@ namespace Fungus // Assume that the first scene that contains the SaveMenu is also the scene to load on restart. startScene = SceneManager.GetActiveScene().name; - var saveManager = FungusManager.Instance.SaveManager; if (!saveMenuActive) { saveMenuGroup.alpha = 0f; } + var saveManager = FungusManager.Instance.SaveManager; + if (autoStartGame && saveManager.NumSavePoints == 0) { - SavePointLoaded.NotifyEventHandlers(NewGameSavePointKey); + StartNewGame(); } CheckSavePointKeys(); } + protected virtual void StartNewGame() + { + var saveManager = FungusManager.Instance.SaveManager; + + // Create an initial save point + saveManager.AddSavePoint(NewGameSavePointKey, ""); + + // Start game execution + SavePointData.ExecuteBlocks(NewGameSavePointKey); + } + protected virtual void Update() { var saveManager = FungusManager.Instance.SaveManager; @@ -104,7 +116,7 @@ namespace Fungus } if (rewindButton != null) { - rewindButton.interactable = saveManager.NumSavePoints > 1; + rewindButton.interactable = saveManager.NumSavePoints > 0; } if (forwardButton != null) { @@ -158,7 +170,8 @@ namespace Fungus } SceneManager.sceneLoaded -= OnSceneLoaded; - SavePointLoaded.NotifyEventHandlers(NewGameSavePointKey); + + StartNewGame(); } #region Public methods @@ -233,7 +246,7 @@ namespace Fungus PlayClickSound(); var saveManager = FungusManager.Instance.SaveManager; - if (saveManager.NumSavePoints > 1) + if (saveManager.NumSavePoints > 0) { saveManager.Rewind(); } diff --git a/Assets/Fungus/Scripts/Editor/EventHandlerEditor.cs b/Assets/Fungus/Scripts/Editor/EventHandlerEditor.cs index ed4ab72b..12978d87 100644 --- a/Assets/Fungus/Scripts/Editor/EventHandlerEditor.cs +++ b/Assets/Fungus/Scripts/Editor/EventHandlerEditor.cs @@ -9,6 +9,36 @@ namespace Fungus.EditorUtils [CustomEditor (typeof(EventHandler), true)] public class EventHandlerEditor : Editor { + protected virtual void DrawProperties() + { + SerializedProperty iterator = serializedObject.GetIterator(); + bool enterChildren = true; + while (iterator.NextVisible(enterChildren)) + { + enterChildren = false; + + if (iterator.name == "m_Script") + { + continue; + } + + EditorGUILayout.PropertyField(iterator, true, new GUILayoutOption[0]); + } + } + + protected virtual void DrawHelpBox() + { + EventHandler t = target as EventHandler; + EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(t.GetType()); + if (info != null && + info.HelpText.Length > 0) + { + EditorGUILayout.HelpBox(info.HelpText, MessageType.Info); + } + } + + #region Public members + /// /// Returns the class attribute info for an event handler class. /// @@ -33,29 +63,13 @@ namespace Fungus.EditorUtils // Doing so could cause block.commandList to contain null entries. // To avoid this we manually display all properties, except for m_Script. serializedObject.Update(); - SerializedProperty iterator = serializedObject.GetIterator(); - bool enterChildren = true; - while (iterator.NextVisible(enterChildren)) - { - enterChildren = false; - - if (iterator.name == "m_Script") - { - continue; - } - - EditorGUILayout.PropertyField(iterator, true, new GUILayoutOption[0]); - } - EventHandler t = target as EventHandler; - EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(t.GetType()); - if (info != null && - info.HelpText.Length > 0) - { - EditorGUILayout.HelpBox(info.HelpText, MessageType.Info); - } + DrawProperties(); + DrawHelpBox(); serializedObject.ApplyModifiedProperties(); } + + #endregion } } diff --git a/Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs b/Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs new file mode 100644 index 00000000..2957dc17 --- /dev/null +++ b/Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs @@ -0,0 +1,29 @@ +using UnityEngine; +using UnityEditor; +using Rotorz.ReorderableList; + +namespace Fungus.EditorUtils +{ + [CustomEditor (typeof(SavePointLoaded), true)] + public class SavePointLoadedEditor : EventHandlerEditor + { + protected SerializedProperty savePointKeysProp; + + protected virtual void OnEnable() + { + savePointKeysProp = serializedObject.FindProperty("savePointKeys"); + } + + public override void DrawInspectorGUI() + { + serializedObject.Update(); + + ReorderableListGUI.Title("Save Point Keys"); + ReorderableListGUI.ListField(savePointKeysProp); + + DrawHelpBox(); + + serializedObject.ApplyModifiedProperties(); + } + } +} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs.meta b/Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs.meta new file mode 100644 index 00000000..94ccf3b2 --- /dev/null +++ b/Assets/Fungus/Scripts/Editor/SavePointLoadedEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 395934d0b0e6a48a396a25348aeaade5 +timeCreated: 1484049679 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fungus/Scripts/EventHandlers/SavePointLoaded.cs b/Assets/Fungus/Scripts/EventHandlers/SavePointLoaded.cs index 0d848e43..9d2a61cb 100644 --- a/Assets/Fungus/Scripts/EventHandlers/SavePointLoaded.cs +++ b/Assets/Fungus/Scripts/EventHandlers/SavePointLoaded.cs @@ -8,17 +8,22 @@ namespace Fungus { [EventHandlerInfo("Scene", "Save Point Loaded", - "Execute this block when a saved point is loaded.")] + "Execute this block when a saved point is loaded. Use the 'new_game' key to handle game start.")] public class SavePointLoaded : EventHandler { [Tooltip("Block will execute if the Save Key of the loaded save point matches this save key.")] - [SerializeField] protected string savePointKey = ""; + [SerializeField] protected List savePointKeys = new List(); protected void OnSavePointLoaded(string _savePointKey) { - if (string.Compare(savePointKey, _savePointKey, true) == 0) + for (int i = 0; i < savePointKeys.Count; i++) { - ExecuteBlock(); + var key = savePointKeys[i]; + if (string.Compare(key, _savePointKey, true) == 0) + { + ExecuteBlock(); + break; + } } } diff --git a/Assets/Fungus/Scripts/Utils/SaveHistory.cs b/Assets/Fungus/Scripts/Utils/SaveHistory.cs index edee9705..0225b5ee 100644 --- a/Assets/Fungus/Scripts/Utils/SaveHistory.cs +++ b/Assets/Fungus/Scripts/Utils/SaveHistory.cs @@ -39,6 +39,9 @@ namespace Fungus /// public void AddSavePoint(string savePointKey, string savePointDescription) { + // Creating a new Save Point invalidates all rewound Save Points, so delete them. + ClearRewoundSavePoints(); + string sceneName = SceneManager.GetActiveScene().name; var savePointData = SavePointData.Encode(savePointKey, savePointDescription, sceneName); savePoints.Add(savePointData); diff --git a/Assets/Fungus/Scripts/Utils/SavePointData.cs b/Assets/Fungus/Scripts/Utils/SavePointData.cs index df77a30e..28664ce3 100644 --- a/Assets/Fungus/Scripts/Utils/SavePointData.cs +++ b/Assets/Fungus/Scripts/Utils/SavePointData.cs @@ -35,44 +35,7 @@ namespace Fungus ExecuteBlocks(savePointData.savePointKey); } - - protected static void ExecuteBlocks(string savePointKey) - { - SavePointLoaded.NotifyEventHandlers(savePointKey); - - // Execute any block containing a SavePoint command matching the save key, with Resume From Here enabled - var savePoints = Object.FindObjectsOfType(); - for (int i = 0; i < savePoints.Length; i++) - { - var savePoint = savePoints[i]; - if (savePoint.ResumeFromHere && - string.Compare(savePoint.SavePointKey, savePointKey, true) == 0) - { - int index = savePoint.CommandIndex; - var block = savePoint.ParentBlock; - var flowchart = savePoint.GetFlowchart(); - flowchart.ExecuteBlock(block, index + 1); - - // Assume there's only one SavePoint using this key - break; - } - } - - // Execute any block containing a Label matching the save key - var labels = Object.FindObjectsOfType