From c6b19076c0c9673a91d49f4828479021e3415305 Mon Sep 17 00:00:00 2001 From: MaZiFAU <marco.alexander.zimmer@fau.de> Date: Wed, 31 Aug 2022 21:56:48 +0200 Subject: [PATCH] + Added AllowedGadgets in Stage; + Redone Gadget Logging; --- Assets/Scripts/GenerateDemoFiles.cs | 8 +- Assets/Scripts/GlobalBehaviour.cs | 9 +- .../InteractionEngine/FactHandling/Fact.cs | 2 +- .../FactHandling/FactManager.cs | 16 +- .../FactHandling/FactOrganizer.cs | 145 +++++++++--------- .../InteractionEngine/Gadgets/AngleTool.cs | 7 +- .../InteractionEngine/Gadgets/Gadget.cs | 91 ++++++++--- .../Gadgets/GadgetManager.cs | 18 ++- .../InteractionEngine/Gadgets/LineTool.cs | 7 +- .../InteractionEngine/Gadgets/LotTool.cs | 7 +- .../InteractionEngine/Gadgets/Pendulum.cs | 4 + .../InteractionEngine/Gadgets/Pointer.cs | 4 + .../InteractionEngine/Gadgets/PoleTool.cs | 4 + .../InteractionEngine/Gadgets/Remover.cs | 6 +- .../Scripts/InteractionEngine/Gadgets/Tape.cs | 4 + Assets/Scripts/Loading/Stage.cs | 31 ++-- Assets/Stages/TechDemo A.JSON | 2 +- Assets/Stages/TechDemo B.JSON | 2 +- 18 files changed, 235 insertions(+), 132 deletions(-) diff --git a/Assets/Scripts/GenerateDemoFiles.cs b/Assets/Scripts/GenerateDemoFiles.cs index 6203e440..cf03341e 100644 --- a/Assets/Scripts/GenerateDemoFiles.cs +++ b/Assets/Scripts/GenerateDemoFiles.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Linq; using System.Collections.Generic; using UnityEngine; using static CommunicationEvents; @@ -57,6 +57,9 @@ public static void GenerateDemoA() new List<SolutionOrganizer.SubSolution> { new SolutionOrganizer.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()) }; + // Set Gadgets + StageStatic.stage.AllowedGadgets = null; + // Save StageStatic.SetMode(StageStatic.Mode.Create); StageStatic.stage.store(); @@ -106,6 +109,9 @@ public static void GenerateDemoB() new SolutionOrganizer.SubSolution(null, new List<int> { 1 }, new List<int> { 0 }, new LineFactHightComparer()), }; + // Set Gadgets + StageStatic.stage.AllowedGadgets = new() { new Pointer(), new Tape(), new AngleTool(), new LineTool(), new LotTool(), new Pendulum(), new Remover() }; + // Save StageStatic.SetMode(StageStatic.Mode.Create); StageStatic.stage.store(); diff --git a/Assets/Scripts/GlobalBehaviour.cs b/Assets/Scripts/GlobalBehaviour.cs index e60f48d7..b99b7145 100644 --- a/Assets/Scripts/GlobalBehaviour.cs +++ b/Assets/Scripts/GlobalBehaviour.cs @@ -36,9 +36,6 @@ public class GlobalBehaviour : MonoBehaviour void Awake() { - - // GenerateDemoFiles.GenerateAll(); - hintAnimationStartColor = _hintAnimationStartColor; hintAnimationEndColor = _hintAnimationEndColor; hintAnimationDuration = _hintAnimationDuration; @@ -50,8 +47,12 @@ void Awake() GadgetLaserDistance = _GadgetLaserDistance; GadgetPhysicalDistance = _GadgetPhysicalDistance; + //DontDestroyOnLoad(gameObject); + } + private void Start() + { + //GenerateDemoFiles.GenerateAll(); StageStatic.ShallowLoadStages(); - //DontDestroyOnLoad(gameObject); } } diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs index 4b9ef857..347c8c6c 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs @@ -125,7 +125,7 @@ public string Id { /// </value> public string Label { get { // in case of renamed dependables - return (_Facts.FactDict.Count == 0 && this is not PointFact) // JsonSerialization toggle && allow first (Point)Fact to be created + return (_Facts.GetNumberOfFacts() == 0 && this is not PointFact) // JsonSerialization toggle && allow first (Point)Fact to be created || (hasCustomLabel && _CustomLabel != null) ? _CustomLabel : generateLabel(); diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs index f299c9a5..dec8045d 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs @@ -16,12 +16,12 @@ public static class FactManager /// <param name="fact">to be added</param> /// <param name="exists"><c>true</c> iff <paramref name="fact"/> already has a equivalent counterpart in <paramref name="fact._Facts"/></param> /// \copydetails FactManager - public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep, Type gadget, string scroll_label) + public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep, Gadget gadget, string scroll_label) { return StageStatic.stage.factState[ StageStatic.stage.factState.Add( fact, out exists, samestep - , gadget ?? (scroll_label == null ? GadgetManager.ActiveGadgetInd.GetType() : null) + , gadget ?? (scroll_label == null ? GadgetManager.ActiveGadget : null) , scroll_label )]; } @@ -29,7 +29,7 @@ public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep, /// \copybrief FactManager <summary></summary> /// <param name="hit"><c>RaycastHit</c> where and how (orientation) to spawn <see cref="PointFact"/></param> /// \copydetails FactManager - public static PointFact AddPointFact(RaycastHit hit, bool samestep = false, Type gadget = null, string scroll_label = null) + public static PointFact AddPointFact(RaycastHit hit, bool samestep = false, Gadget gadget = null, string scroll_label = null) { return (PointFact) AddFactIfNotFound( new PointFact(hit.point, hit.normal, StageStatic.stage.factState) @@ -40,7 +40,7 @@ public static PointFact AddPointFact(RaycastHit hit, bool samestep = false, Type /// <param name="point">where to spawn <see cref="PointFact"/></param> /// <param name="normal">how (orientation) to spawn <see cref="PointFact"/></param> /// \copydetails FactManager - public static PointFact AddPointFact(Vector3 point, Vector3 normal, bool samestep = false, Type gadget = null, string scroll_label = null) + public static PointFact AddPointFact(Vector3 point, Vector3 normal, bool samestep = false, Gadget gadget = null, string scroll_label = null) { return (PointFact) AddFactIfNotFound( new PointFact(point, normal, StageStatic.stage.factState) @@ -51,7 +51,7 @@ public static PointFact AddPointFact(Vector3 point, Vector3 normal, bool sameste /// <param name="pid"><see cref="Fact.Id"/> of <see cref="PointFact"/> which lies on <paramref name="lid"/></param> /// <param name="lid"><see cref="Fact.Id"/> of <see cref="LineFact"/> on which <paramref name="pid"/> lies</param> /// \copydetails FactManager - public static OnLineFact AddOnLineFact(string pid, string lid, bool samestep = false, Type gadget = null, string scroll_label = null) + public static OnLineFact AddOnLineFact(string pid, string lid, bool samestep = false, Gadget gadget = null, string scroll_label = null) { return (OnLineFact)AddFactIfNotFound( new OnLineFact(pid, lid, StageStatic.stage.factState) @@ -62,7 +62,7 @@ public static OnLineFact AddOnLineFact(string pid, string lid, bool samestep = f /// <param name="pid1"><see cref="Fact.Id"/> of first <see cref="PointFact"/> defining a <see cref="LineFact"/></param> /// <param name="pid2"><see cref="Fact.Id"/> of second <see cref="PointFact"/> defining a <see cref="LineFact"/></param> /// \copydetails FactManager - public static LineFact AddLineFact(string pid1, string pid2, bool samestep = false, Type gadget = null, string scroll_label = null) + public static LineFact AddLineFact(string pid1, string pid2, bool samestep = false, Gadget gadget = null, string scroll_label = null) { return (LineFact)AddFactIfNotFound( new LineFact(pid1, pid2, StageStatic.stage.factState) @@ -76,7 +76,7 @@ public static LineFact AddLineFact(string pid1, string pid2, bool samestep = fal /// <param name="pid1"><see cref="Fact.Id"/> of first <see cref="PointFact"/> defining a <see cref="RayFact"/></param> /// <param name="pid2"><see cref="Fact.Id"/> of second <see cref="PointFact"/> defining a <see cref="RayFact"/></param> /// \copydetails FactManager - public static RayFact AddRayFact(string pid1, string pid2, bool samestep = false, Type gadget = null, string scroll_label = null) + public static RayFact AddRayFact(string pid1, string pid2, bool samestep = false, Gadget gadget = null, string scroll_label = null) { RayFact rayFact = (RayFact)AddFactIfNotFound( new RayFact(pid1, pid2, StageStatic.stage.factState) @@ -119,7 +119,7 @@ void AddHitIfOnLine(RaycastHit hit) /// <param name="pid2"><see cref="Fact.Id"/> of second <see cref="PointFact"/> defining a <see cref="AngleFact"/></param> /// <param name="pid3"><see cref="Fact.Id"/> of third <see cref="PointFact"/> defining a <see cref="AngleFact"/></param> /// \copydetails FactManager - public static AngleFact AddAngleFact(string pid1, string pid2, string pid3, bool samestep = false, Type gadget = null, string scroll_label = null) + public static AngleFact AddAngleFact(string pid1, string pid2, string pid3, bool samestep = false, Gadget gadget = null, string scroll_label = null) { return (AngleFact)AddFactIfNotFound( new AngleFact(pid1, pid2, pid3, StageStatic.stage.factState) diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs index db02c11b..8307c441 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs @@ -20,31 +20,43 @@ /// </summary> public class FactOrganizer : IJSONsavable<FactOrganizer> { + /// <summary> + /// - <c>Key</c>: <see cref="Gadget"/> Used Gadget + /// - <c>Value</c>: <see cref="int"/> First occurence of gadget in Workflow + /// </summary> + protected Dictionary<Gadget, int> GadgetWorkflowDict = new(); + /// <summary> + /// - <c>Key</c>: <see cref="int"/> First occurence of gadget in Workflow + /// - <c>Value</c>: <see cref="Gadget"/> Used Gadget + /// </summary> + [JsonProperty] + protected Dictionary<int, Gadget> WorkflowGadgetDict = new() { {-1, null } }; + /// <summary> /// - <c>Key</c>: <see cref="Fact.Id"/> /// - <c>Value</c>: <see cref="Fact"/> /// </summary> [JsonProperty] - protected internal Dictionary<string, Fact> FactDict; + protected Dictionary<string, Fact> FactDict; /// <summary> /// - <c>Key</c>: <see cref="Fact.Id"/> /// - <c>Value</c>: <see cref="meta"/> /// </summary> [JsonProperty] - protected internal Dictionary<string, meta> MetaInf = new(); + protected Dictionary<string, meta> MetaInf = new(); /// <summary> /// Keeps track of insertion/ deletion/ etc. operations for <see cref="undo"/> and <see cref="redo"/> /// </summary> [JsonProperty] - protected internal List<stepnote> Workflow = new(); + protected List<stepnote> Workflow = new(); /// <summary> /// Notes position in <see cref="Workflow"/> for <see cref="undo"/> and <see cref="redo"/>; the pointed to element is non-acitve /// </summary> [JsonProperty] - protected internal int marker = 0; + protected int marker = 0; /// <summary> /// Backlock logic redundant - for convinience. @@ -53,7 +65,7 @@ public class FactOrganizer : IJSONsavable<FactOrganizer> /// <seealso cref="stepnote"/> /// </summary> [JsonProperty] - protected internal int worksteps = 0; + protected int worksteps = 0; /// <summary> /// Backlock logic redundant - for convinience. /// Keeps track of number of steps in <see cref="Workflow"/>, which are not set active. @@ -61,13 +73,13 @@ public class FactOrganizer : IJSONsavable<FactOrganizer> /// <seealso cref="stepnote"/> /// </summary> [JsonProperty] - protected internal int backlog = 0; + protected int backlog = 0; /// <summary> /// Set to <c>true</c> if recently been resetted. /// </summary> [JsonProperty] - protected internal bool soft_resetted = false; + protected bool soft_resetted = false; /// <summary> /// If set to <c>true</c>, <see cref="Remove(string, bool)"/> and <see cref="Add(Fact, out bool, bool)"/> will invoke <see cref="CommunicationEvents.RemoveFactEvent"/> and <see cref="CommunicationEvents.AddFactEvent"/> respectively. @@ -126,6 +138,18 @@ protected internal struct stepnote /// <summary> distincts creation and deletion </summary> public bool creation; + /// <summary> + /// keeps track with wich <see cref="Gadget"/> the <see cref="Fact"/> is created + /// <c>-1</c> iff its not the case + /// </summary> + public int gadget_rank; + + /// <summary> + /// keeps track with wich <see cref="Scroll"/> the <see cref="Fact"/> is created + /// <c>null</c> iff its not the case + /// </summary> + public string scroll_label; + /// <summary> /// Initiator @@ -134,11 +158,12 @@ protected internal struct stepnote /// <param name="samestep">sets <see cref="samestep"/></param> /// <param name="creation">sets <see cref="creation"/></param> /// <param name="that"><see cref="FactOrganizer"/> of which <c>this</c> will be added in its <see cref="FactOrganizer.Workflow"/></param> - public stepnote(string Id, bool samestep, bool creation, FactOrganizer that) + public stepnote(FactOrganizer that, string Id, bool samestep, bool creation, Gadget gadget, string scroll_label) { this.Id = Id; this.samestep = samestep; this.creation = creation; + this.scroll_label = scroll_label; if (samestep) // steplink = !first_steptail ? previous.steplink : steproot @@ -150,6 +175,15 @@ public stepnote(string Id, bool samestep, bool creation, FactOrganizer that) // steproot sets steplink after itself (end of steptail) this.steplink = that.marker + 1; + if (gadget == null) + this.gadget_rank = -1; + else { + if (!that.GadgetWorkflowDict.ContainsKey(gadget)) { + that.GadgetWorkflowDict.Add(gadget, that.MetaInf[Id].workflow_id); + that.WorkflowGadgetDict.Add(that.MetaInf[Id].workflow_id, gadget); + } + this.gadget_rank = that.GadgetWorkflowDict[gadget]; + } } } @@ -171,37 +205,15 @@ protected internal struct meta /// </summary> public bool active; - /// <summary> - /// keeps track with wich <see cref="Gadget"/> the <see cref="Fact"/> is created - /// <c>null</c> iff its not the case - /// </summary> - public Type gadget { - get => _gadget; - set => _gadget = - value == null ? null : - Gadget.GadgetTypes.Contains(value) ? value : - typeof(Gadget.UndefinedGadget); - } - private Type _gadget; - - /// <summary> - /// keeps track with wich <see cref="Scroll"/> the <see cref="Fact"/> is created - /// <c>null</c> iff its not the case - /// </summary> - public string scroll_label; - /// <summary> /// Initiator /// </summary> /// <param name="workflow_id">sets <see cref="workflow_id"/></param> /// <param name="active">sets <see cref="active"/></param> - public meta(int workflow_id, bool active, Type gadget, string scroll_label) + public meta(int workflow_id, bool active) { this.workflow_id = workflow_id; this.active = active; - this.scroll_label = scroll_label; - _gadget = null; //Compiler Restriction - this.gadget = gadget; } } @@ -276,13 +288,13 @@ public static T ReInitializeFactOrganizer<T> old_to_new.Add(sn.Id, add.Id); } - target.Add(add, out _, sn.samestep, source.MetaInf[sn.Id].gadget, source.MetaInf[sn.Id].scroll_label); + target.Add(add, out _, sn.samestep, source.WorkflowGadgetDict[sn.gadget_rank], sn.scroll_label); } else if (old_to_new.ContainsKey(sn.Id)) // Remove { Fact remove = target.FactDict[old_to_new[sn.Id]]; - target.Remove(remove, sn.samestep); + target.Remove(remove, sn.samestep, source.WorkflowGadgetDict[sn.gadget_rank]); } } @@ -301,20 +313,14 @@ public static T ReInitializeFactOrganizer<T> /// </summary> /// <param name="id">a <see cref="Fact.Id"/> in <see cref="FactDict"/></param> /// <returns><c><see cref="FactDict"/>[<paramref name="id"/>]</c></returns> - public Fact this[string id] - { - get { return FactDict[id]; } - } + public Fact this[string id] { get => FactDict[id]; } /// <summary> /// wrappes <c><see cref="FactDict"/>.ContainsKey(<paramref name="id"/>)</c> /// </summary> /// <param name="id">a <see cref="Fact.Id"/></param> /// <returns><c><see cref="FactDict"/>.ContainsKey(<paramref name="id"/>)</c></returns> - public bool ContainsKey(string id) - { - return FactDict.ContainsKey(id); - } + public bool ContainsKey(string id) => FactDict.ContainsKey(id); /// <summary> /// Looks up if there is a <paramref name="label"/> <see cref="Fact.Label"/> in <see cref="FactDict"/>.Values @@ -366,7 +372,7 @@ private bool FindEquivalent(Fact search, out string found, out bool exact) /// <param name="note">to be added</param> private void WorkflowAdd(stepnote note) { - PruneWorkflow(); + PruneWorkflow(note); if (note.samestep) // update steplink of steproot @@ -388,7 +394,7 @@ private void WorkflowAdd(stepnote note) /// set current (displayed) state in stone, a.k.a. <see cref="Fact.delete(bool)">delete</see> non <see cref="meta.active"/> <see cref="Fact">Facts</see> for good; /// resets <see cref="undo">un</see>-<see cref="redo"/> parameters /// </summary> - private void PruneWorkflow() + private void PruneWorkflow(stepnote not_me) { /*if (soft_resetted) this.hardreset(false); // musn't clear @@ -404,7 +410,14 @@ private void PruneWorkflow() { stepnote last = Workflow[i]; - if (last.creation // may be zombie + if (last.gadget_rank == MetaInf[last.Id].workflow_id + && last.gadget_rank != not_me.gadget_rank) + { // Remove Gadget, if its the first time it's beeing used + GadgetWorkflowDict.Remove(WorkflowGadgetDict[last.gadget_rank]); + WorkflowGadgetDict.Remove(last.gadget_rank); + } + + if (last.Id != not_me.Id // may be zombie && MetaInf[last.Id].workflow_id == i) // remove for good, if original creation gets pruned { @@ -428,7 +441,7 @@ private void PruneWorkflow() /// <param name="samestep">set <c>true</c> if <see cref="Fact"/> creation happens as a subsequent/ consequent step of multiple <see cref="Fact"/> creations and/or deletions, /// and you whish that these are affected by a single <see cref="undo"/>/ <see cref="redo"/> step</param> /// <returns><see cref="Fact.Id"/> of <paramref name="value"/> or <see cref="FindEquivalent(Fact, out string, out bool)">found</see> <see cref="Fact"/> iff <paramref name="exists"/>==<c>true</c></returns> - public string Add(Fact value, out bool exists, bool samestep, Type gadget, string scroll_label) + public string Add(Fact value, out bool exists, bool samestep, Gadget gadget, string scroll_label) { soft_resetted = false; #pragma warning disable IDE0018 // Inlinevariablendeklaration @@ -445,16 +458,9 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget, strin // desired outcome already achieved return key; - if (MetaInf[key].workflow_id >= marker) - // check for zombie-status: everything >= marker will be pruned - { - // protect zombie from beeing pruned - stepnote zombie = Workflow[MetaInf[key].workflow_id]; - zombie.creation = false; // this stepnote entry will be deleted, but will not trigger deletion - Workflow[MetaInf[key].workflow_id] = zombie; - // set new init location - MetaInf[key] = new meta(marker, true, gadget, scroll_label); - } + if (MetaInf[key].workflow_id > marker) + // update meta data: everything >= marker will be pruned (except this Fact) + MetaInf[key] = new meta(marker, true); } else @@ -462,10 +468,10 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget, strin { key = value.Id; FactDict.Add(key, value); - MetaInf.Add(key, new meta(marker, true, gadget, scroll_label)); + MetaInf.Add(key, new meta(marker, true)); } - WorkflowAdd(new stepnote(key, samestep, true, this)); + WorkflowAdd(new stepnote(this, key, samestep, true, gadget, scroll_label)); return key; } @@ -478,8 +484,8 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget, strin /// <param name="samestep">set <c>true</c> if <see cref="Fact"/> deletion happens as a subsequent/ consequent step of multiple <see cref="Fact"/> creations and/or deletions, /// and you whish that these are affected by a single <see cref="undo"/>/ <see cref="redo"/> step</param> /// <returns><c>true</c> iff <paramref name="value"/><see cref="Fact.Id">.Id</see> was found.</returns> - public bool Remove(Fact value, bool samestep = false) - => this.Remove(value.Id, samestep); + public bool Remove(Fact value, bool samestep, Gadget gadget) + => this.Remove(value.Id, samestep, gadget); /// \copybrief Remove(Fact, bool) /// <remarks>this will not <see cref="Fact.delete(bool)">delete</see> a <see cref="Fact"/>, but sets it <see cref="meta.active">inactive</see> for later <see cref="Fact.delete(bool)">deletion</see> when <see cref="PruneWorkflow">pruned</see>.</remarks> @@ -487,7 +493,7 @@ public bool Remove(Fact value, bool samestep = false) /// <param name="samestep">set <c>true</c> if <see cref="Fact"/> deletion happens as a subsequent/ consequent step of multiple <see cref="Fact"/> creations and/or deletions, /// and you whish that these are affected by a single <see cref="undo"/>/ <see cref="redo"/> step</param> /// <returns><c>true</c> iff <paramref name="value"/> was found.</returns> - public bool Remove(string key, bool samestep = false) + public bool Remove(string key, bool samestep, Gadget gadget) //no reset check needed (impossible state) { if (!FactDict.ContainsKey(key)) @@ -503,7 +509,7 @@ public bool Remove(string key, bool samestep = false) if (deletethis.Count > 0) { - yeetusdeletus(deletethis, samestep); + yeetusdeletus(deletethis, samestep, gadget); } return true; @@ -551,11 +557,11 @@ public bool safe_dependencies(string key, out List<string> dependencies) /// </summary> /// <param name="deletereverse">to be <see cref="Remove(string, bool)">removed</see>, but without checking for (recursive) dependencies</param> /// <param name="samestep">see <see cref="Remove(string, bool).samestep"/>. Only applies to last (first iteration) element of <paramref name="deletereverse"/>; for everything else <paramref name="samestep"/> will be set to <c>true</c>.</param> - private void yeetusdeletus(List<string> deletereverse, bool samestep = false) + private void yeetusdeletus(List<string> deletereverse, bool samestep, Gadget gadget) { for (int i = deletereverse.Count - 1; i >= 0; i--, samestep = true) { - WorkflowAdd(new stepnote(deletereverse[i], samestep, false, this)); + WorkflowAdd(new stepnote(this, deletereverse[i], samestep, false, gadget, null)); } } @@ -577,9 +583,9 @@ private void reversestep(int pos, bool samestep = false) i >= stop; i--, samestep = true) { if (Workflow[i].creation) - Remove(Workflow[i].Id, samestep); + Remove(Workflow[i].Id, samestep, null); else if (!MetaInf[Workflow[i].Id].active) - WorkflowAdd(new stepnote(Workflow[i].Id, samestep, true, this)); + WorkflowAdd(new stepnote(this, Workflow[i].Id, samestep, true, null, null)); } } @@ -832,14 +838,15 @@ public bool DynamiclySolved( return MissingElementsCount == 0; } - public IEnumerable<Type> GetUsedGadgets() - => MetaInf.Values.Where(inf => inf.active & inf.gadget != null).Select(inf => inf.gadget).Distinct(); + public IEnumerable<Gadget> GetUsedGadgets() => GadgetWorkflowDict.Keys; - public int GetNumberOfGadgets() => GetUsedGadgets().Count(); + public int GetNumberOfGadgets() => GadgetWorkflowDict.Count; public IEnumerable<string> GetUsedScrolls() - => MetaInf.Values.Where(inf => inf.active && inf.scroll_label != null).Select(inf => inf.scroll_label).Distinct(); + => Workflow.Where(sn => MetaInf[sn.Id].active && sn.scroll_label != null).Select(sn => sn.scroll_label).Distinct(); public int GetNumberOfScrolls() => GetUsedScrolls().Count(); + public int GetNumberOfFacts() => FactDict.Count; + } \ No newline at end of file diff --git a/Assets/Scripts/InteractionEngine/Gadgets/AngleTool.cs b/Assets/Scripts/InteractionEngine/Gadgets/AngleTool.cs index ec80cebd..330f60ee 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/AngleTool.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/AngleTool.cs @@ -1,7 +1,12 @@ -using UnityEngine; +using Newtonsoft.Json; +using UnityEngine; public class AngleTool : Gadget { + /// \copydoc Gadget.s_type + [JsonProperty] + protected static new string s_type = "AngleTool"; + //Variables for AngleMode distinction private int PointNr = 0; private readonly PointFact[] AnglePoints = new PointFact[3]; diff --git a/Assets/Scripts/InteractionEngine/Gadgets/Gadget.cs b/Assets/Scripts/InteractionEngine/Gadgets/Gadget.cs index 7e3beb99..ae69b469 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/Gadget.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/Gadget.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using JsonSubTypes; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -9,8 +10,26 @@ /// Base class for all Gadgets to derive from. /// A Gadget is a tool for the player (and level editor) to interact with the GameWorld. /// </summary> +[JsonConverter(typeof(JsonSubtypes), "s_type")] +[JsonSubtypes.KnownSubType(typeof(Pointer), "Pointer")] +[JsonSubtypes.KnownSubType(typeof(Tape), "Tape")] +[JsonSubtypes.KnownSubType(typeof(LineTool), "LineTool")] +[JsonSubtypes.KnownSubType(typeof(LotTool), "LotTool")] +[JsonSubtypes.KnownSubType(typeof(AngleTool), "AngleTool")] +[JsonSubtypes.KnownSubType(typeof(Pendulum), "Pendulum")] +[JsonSubtypes.KnownSubType(typeof(PoleTool), "PoleTool")] +[JsonSubtypes.KnownSubType(typeof(Remover), "Remover")] +[JsonSubtypes.FallBackSubType(typeof(UndefinedGadget))] public abstract class Gadget { + /// <value> + /// [ClassName] for JSON de-/serialization. + /// Set in every non-abstract subclass of Gadget. + /// Also add JsonSubtypes.KnownSubType attribute for deserialization to Gadget! + /// </value> + [JsonProperty] + protected static /*new*/ string s_type = "ERROR: set s_type in T:Gadget"; // In the subtype! NOT here! + /// <summary>Used to map to a T:Gadget </summary> /// <remarks>Do NOT rename elements! Do NOT change values! Deserialization relies on it!</remarks> public enum GadgetIDs @@ -40,24 +59,24 @@ public enum GadgetIDs /// <summary> Position in tool belt. </summary> /// <remarks>Set in Inspector or <see cref="Awake"/></remarks> - public int Rank; + public int Rank = int.MinValue; /// <summary> Tool Name </summary> /// <remarks>Set in Inspector or <see cref="Awake"/></remarks> - public string UiName; + public string UiName = null; /// <summary> Maximum range for this Tool. For consistency use GadgetDistances in <see cref="GlobalBehaviour"/>.</summary> /// <remarks>Set in Inspector or <see cref="Awake"/></remarks> - public float MaxRange; - public float MaxHeight; + public float MaxRange = float.NegativeInfinity; + public float MaxHeight = float.NegativeInfinity; /// <summary>Which sprite to use</summary> - public int ButtonIndx; - public int MaterialIndx; + public int ButtonIndx = -1; + public int MaterialIndx = -1; /// <summary>Layers to ignore for this gadget by default.</summary> /// <remarks>Set in Inspector</remarks> - public LayerMask IgnoreLayerMask; - public LayerMask SecondaryLayerMask; + public LayerMask IgnoreLayerMask = -1; + public LayerMask SecondaryLayerMask = -1; - //protected List<Vector3> LinePositions = new(); + private bool init_success = false; /// <summary> /// Collection of <c>Type</c>s of *all* available <see cref="Gadget"/>s to choose from. @@ -67,33 +86,59 @@ public enum GadgetIDs public Gadget() { + Init(true); + } + + public void Init(bool overrite) + { + if ( init_success + || GadgetManager.DataContainerGadgetDict == null) + return; + Type this_type = this.GetType(); - if (!GadgetTypeToIDs.ContainsKey(this_type)) { + if (!GadgetTypeToIDs.ContainsKey(this_type)) + { Debug.LogError("No " + this_type.ToString() + "in Dictionary<Type, GadgetIDs> GadgetTypeToIDs!"); return; } var GadgetID = GadgetTypeToIDs[this_type]; - if (!GadgetManager.DataContainerGadgetDict.ContainsKey(GadgetID)) { - Debug.LogError("No " + GadgetID.ToString() + "in assigned "+ typeof(DataContainerGadgetCollection).Name +"!"); + if (!GadgetManager.DataContainerGadgetDict.ContainsKey(GadgetID)) + { + Debug.LogError("No " + GadgetID.ToString() + "in assigned " + typeof(DataContainerGadgetCollection).Name + "!"); return; } var data_cache = GadgetManager.DataContainerGadgetDict[GadgetID]; - Rank = data_cache.Rank; - UiName = data_cache.UiName; - MaxRange = data_cache.MaxRange; - MaxHeight = data_cache.MaxHeight; - IgnoreLayerMask = data_cache.IgnoreLayerMask; - SecondaryLayerMask = data_cache.SecondaryLayerMask; - ButtonIndx = data_cache.ButtonIndx < GadgetManager.ButtonSprites.Length - ? data_cache.ButtonIndx : 0; - MaterialIndx = data_cache.MaterialIndx < GadgetManager.Materials.Length - ? data_cache.MaterialIndx : 0; + if (overrite || Rank == int.MinValue) + Rank = data_cache.Rank; + if (overrite || UiName == null) + UiName = data_cache.UiName; + if (overrite || MaxRange == float.NegativeInfinity) + MaxRange = data_cache.MaxRange; + if (overrite || MaxHeight == float.NegativeInfinity) + MaxHeight = data_cache.MaxHeight; + if (overrite || IgnoreLayerMask == -1) + IgnoreLayerMask = data_cache.IgnoreLayerMask; + if (overrite || SecondaryLayerMask == -1) + SecondaryLayerMask = data_cache.SecondaryLayerMask; + if (overrite || ButtonIndx < 0) + ButtonIndx = + data_cache.ButtonIndx < GadgetManager.ButtonSprites.Length + && data_cache.ButtonIndx >= 0 + ? data_cache.ButtonIndx : 0; + if (overrite || MaterialIndx < 0) + MaterialIndx = + data_cache.MaterialIndx < GadgetManager.Materials.Length + && data_cache.MaterialIndx >= 0 + ? data_cache.MaterialIndx : 0; + + init_success = true; } public void Awake() { + Init(false); _Awake(); } diff --git a/Assets/Scripts/InteractionEngine/Gadgets/GadgetManager.cs b/Assets/Scripts/InteractionEngine/Gadgets/GadgetManager.cs index 2882016c..04dd41f3 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/GadgetManager.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/GadgetManager.cs @@ -84,20 +84,28 @@ private void Awake() activeGadgetScaleFactor = 1.5f; else if (UIconfig.FrameITUIversion == 2) activeGadgetScaleFactor = 2.1f; + } + void Start() + { + gadgets = ( + StageStatic.stage.AllowedGadgets == null + || StageStatic.stage.AllowedGadgets.Count == 0 + ? Gadget.GadgetTypes + .Where(t => t != typeof(Gadget.UndefinedGadget)) + .Select(t => (Gadget)Activator.CreateInstance(t)) + : StageStatic.stage.AllowedGadgets + ).OrderBy(g => g.Rank).ToArray(); - gadgets = Gadget.GadgetTypes.Select(t => (Gadget) Activator.CreateInstance(t)).OrderBy(g => g.Rank).ToArray(); buttons = new Button[gadgets.Length]; - for (int i = 0; i < gadgets.Length; i++) { + for (int i = 0; i < gadgets.Length; i++) + { gadgets[i].Awake(); //gadgets[i].Start(); CreateButton(i); } - } - void Start() - { ActiveGadgetInd = 0; buttons[0].transform.localScale *= activeGadgetScaleFactor; OnHit = gadgets[0].Hit; diff --git a/Assets/Scripts/InteractionEngine/Gadgets/LineTool.cs b/Assets/Scripts/InteractionEngine/Gadgets/LineTool.cs index a8026a93..d5e8aa44 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/LineTool.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/LineTool.cs @@ -1,10 +1,15 @@ -using System.Collections; +using Newtonsoft.Json; +using System.Collections; using System.Collections.Generic; using UnityEngine; using static CommunicationEvents; public class LineTool : Gadget { + /// \copydoc Gadget.s_type + [JsonProperty] + protected static new string s_type = "LineTool"; + //Variables for LineMode distinction private bool LineModeIsFirstPointSelected = false; private Fact LineModeFirstPointSelected = null; diff --git a/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs b/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs index 4c4e0fc0..0727a40f 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs @@ -1,4 +1,5 @@ -using System.Collections; +using Newtonsoft.Json; +using System.Collections; using System.Collections.Generic; using UnityEngine; using static CommunicationEvents; @@ -6,6 +7,10 @@ public class LotTool : Gadget //constructs a Perpendicular between a Line and a Point { + /// \copydoc Gadget.s_type + [JsonProperty] + protected static new string s_type = "LotTool"; + //Variables for LineMode distinction private bool LotModeIsPointSelected = false; private bool LotModeIsLineSelected = false; diff --git a/Assets/Scripts/InteractionEngine/Gadgets/Pendulum.cs b/Assets/Scripts/InteractionEngine/Gadgets/Pendulum.cs index a7bd1946..1d1f6e3e 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/Pendulum.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/Pendulum.cs @@ -6,6 +6,10 @@ public class Pendulum : Gadget //Acts as a Pendulum starting at a Point { + /// \copydoc Gadget.s_type + [Newtonsoft.Json.JsonProperty] + protected static new string s_type = "Pendulum"; + public override void _Enable() { ActivateLineDrawing(); diff --git a/Assets/Scripts/InteractionEngine/Gadgets/Pointer.cs b/Assets/Scripts/InteractionEngine/Gadgets/Pointer.cs index 757cac17..8db5bc07 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/Pointer.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/Pointer.cs @@ -5,6 +5,10 @@ public class Pointer : Gadget { + /// \copydoc Gadget.s_type + [Newtonsoft.Json.JsonProperty] + protected static new string s_type = "Pointer"; + public override void _Hit(RaycastHit hit) { string pid = FactManager.AddPointFact(hit).Id; diff --git a/Assets/Scripts/InteractionEngine/Gadgets/PoleTool.cs b/Assets/Scripts/InteractionEngine/Gadgets/PoleTool.cs index 72c5e705..ef8c8686 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/PoleTool.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/PoleTool.cs @@ -6,6 +6,10 @@ public class PoleTool : Gadget //Acts as a Pendulum starting at a Point { + /// \copydoc Gadget.s_type + [Newtonsoft.Json.JsonProperty] + protected static new string s_type = "PoleTool"; + public float poleHeight = 1f; public override void _Enable() diff --git a/Assets/Scripts/InteractionEngine/Gadgets/Remover.cs b/Assets/Scripts/InteractionEngine/Gadgets/Remover.cs index b596545f..02b06706 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/Remover.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/Remover.cs @@ -5,9 +5,13 @@ public class Remover : Gadget { + /// \copydoc Gadget.s_type + [Newtonsoft.Json.JsonProperty] + protected static new string s_type = "Remover"; + public override void _Hit(RaycastHit hit) { var hid = hit.transform.GetComponent<FactObject>()?.URI; - StageStatic.stage.factState.Remove(hid); + StageStatic.stage.factState.Remove(hid, false, this); } } diff --git a/Assets/Scripts/InteractionEngine/Gadgets/Tape.cs b/Assets/Scripts/InteractionEngine/Gadgets/Tape.cs index 41b99c25..44dfccb8 100644 --- a/Assets/Scripts/InteractionEngine/Gadgets/Tape.cs +++ b/Assets/Scripts/InteractionEngine/Gadgets/Tape.cs @@ -5,6 +5,10 @@ public class Tape : Gadget { + /// \copydoc Gadget.s_type + [Newtonsoft.Json.JsonProperty] + protected static new string s_type = "Tape"; + //Variables for TapeMode distinction private bool TapeModeIsFirstPointSelected = false; private Fact TapeModeFirstPointSelected = null; diff --git a/Assets/Scripts/Loading/Stage.cs b/Assets/Scripts/Loading/Stage.cs index d8e59ac7..8891c205 100644 --- a/Assets/Scripts/Loading/Stage.cs +++ b/Assets/Scripts/Loading/Stage.cs @@ -42,12 +42,16 @@ public class Stage: IJSONsavable<Stage> [JSONsavable.JsonAutoPreProcess, JSONsavable.JsonAutoPostProcess] public SolutionOrganizer solution = null; + /// <summary> + /// A single class containing all savegame-data. + /// Stored seperately. + /// </summary> [JsonIgnore, JSONsavable.JsonSeparate] public SaveGame savegame = null; public List<PlayerRecord> solution_approches = new(); public List<string> AllowedScrolls = new(); - public List<Type> AllowedGadgets = new(); + public List<Gadget> AllowedGadgets = new(); #region makros/shortcuts @@ -61,7 +65,7 @@ public class Stage: IJSONsavable<Stage> /// <summary> Current Stage progress.</summary> [JsonIgnore] public PlayerRecord player_record { - get => savegame?.player_record; + get => savegame.player_record ??= new(record_name); set => (savegame ??= new()) .player_record = value; } @@ -94,7 +98,7 @@ public FactOrganizer factState { #endregion makros/shortcuts /// <summary> Returns a name for <see cref="player_record.name"/> which needs to be uniquified once put into <see cref="player_record_list"/> (e.g. by <see cref="push_record(double, bool) adding '_i'"/>).</summary> - private string record_name { get { return name + "_save"; } } + private string record_name { get => name + "_save"; } /// <summary> Wether <see cref="player_record.factState"/> (<see langword="false"/>) or <see cref="solution"/> (<see langword="true"/>) is exposed and drawn.</summary> [JsonIgnore] @@ -453,7 +457,7 @@ public class SaveGame : IJSONsavable<SaveGame> public string path { get; set; } [JSONsavable.JsonAutoPreProcess, JSONsavable.JsonAutoPostProcess] - public PlayerRecord player_record = new(); + public PlayerRecord player_record = null; public Dictionary<string, PlayerRecord> player_record_list = new(); //entries are "PostProcess"ed when accessed/Cloned @@ -464,6 +468,12 @@ static SaveGame() public SaveGame() { } string IJSONsavable<SaveGame>._IJGetName(string name) => name + "_save"; + SaveGame IJSONsavable<SaveGame>._IJPostProcess(SaveGame payload) + { + if ((payload.player_record_list ??= new()).Count == 0) + payload.player_record = null; + return payload; + } } @@ -502,7 +512,7 @@ public PlayerRecord() { } /// <param name="name">sets <see cref="name"/></param> public PlayerRecord(string name) { this.name = name; - factState = new FactOrganizer(); + factState = new FactOrganizer() { invoke = true }; } /// <summary> @@ -517,17 +527,8 @@ public PlayerRecord Clone() solved = this.solved, seconds = this.seconds }; - ret.factState = FactOrganizer.ReInitializeFactOrganizer<FactOrganizer>(this.factState, false, out _); + ret.factState = IJSONsavable<FactOrganizer>.postprocess(this.factState); return ret; } -} - - -public class SolutionApproach: IJSONsavable<SolutionApproach> -{ - public string name { get; set; } = null; - public string path { get; set; } = null; - - //public PlayerRecord } \ No newline at end of file diff --git a/Assets/Stages/TechDemo A.JSON b/Assets/Stages/TechDemo A.JSON index 7756b07e..066220d7 100644 --- a/Assets/Stages/TechDemo A.JSON +++ b/Assets/Stages/TechDemo A.JSON @@ -1 +1 @@ -{"category":"Demo Category","number":1,"description":"Tree Stage","scene":"RiverWorld","use_install_folder":true,"solution":{"ValidationSet":[{"MasterIDs":["http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact649"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineFactHightDirectionComparer"}],"FactDict":{"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact647":{"s_type":"PointFact","Point":{"x":0.0,"y":0.0,"z":0.0,"magnitude":0.0,"sqrMagnitude":0.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact647","Label":"A","hasCustomLabel":false,"LabelId":1},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact648":{"s_type":"PointFact","Point":{"x":0.0,"y":6.0,"z":0.0,"normalized":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":6.0,"sqrMagnitude":36.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact648","Label":"B","hasCustomLabel":false,"LabelId":2},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact649":{"s_type":"LineFact","Distance":6.0,"Pid1":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact647","Pid2":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact648","Dir":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact649","Label":"[AB]","hasCustomLabel":false,"LabelId":0}},"MetaInf":{"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact647":{"workflow_id":0,"active":true},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact648":{"workflow_id":1,"active":true},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact649":{"workflow_id":2,"active":true}},"Workflow":[{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact647","samestep":false,"steplink":3,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact648","samestep":true,"steplink":0,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact649","samestep":true,"steplink":0,"creation":true}],"marker":3,"worksteps":1,"backlog":0,"soft_resetted":false,"invoke":true,"MaxLabelId":2,"UnusedLabelIds":[],"name":null,"path":null},"name":"TechDemo A","path":null} \ No newline at end of file +{"category":"Demo Category","number":1,"description":"Tree Stage","scene":"RiverWorld","use_install_folder":true,"solution":{"ValidationSet":[{"MasterIDs":["http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1320"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineFactHightDirectionComparer"}],"WorkflowGadgetDict":{"-1":null},"FactDict":{"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1318":{"s_type":"PointFact","Point":{"x":0.0,"y":0.0,"z":0.0,"magnitude":0.0,"sqrMagnitude":0.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1318","Label":"A","hasCustomLabel":false,"LabelId":1},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1319":{"s_type":"PointFact","Point":{"x":0.0,"y":6.0,"z":0.0,"normalized":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":6.0,"sqrMagnitude":36.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1319","Label":"B","hasCustomLabel":false,"LabelId":2},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1320":{"s_type":"LineFact","Distance":6.0,"Pid1":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1318","Pid2":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1319","Dir":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1320","Label":"[AB]","hasCustomLabel":false,"LabelId":0}},"MetaInf":{"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1318":{"workflow_id":0,"active":true},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1319":{"workflow_id":1,"active":true},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1320":{"workflow_id":2,"active":true}},"Workflow":[{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1318","samestep":false,"steplink":3,"creation":true,"gadget_rank":-1,"scroll_label":null},{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1319","samestep":true,"steplink":0,"creation":true,"gadget_rank":-1,"scroll_label":null},{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1320","samestep":true,"steplink":0,"creation":true,"gadget_rank":-1,"scroll_label":null}],"marker":3,"worksteps":1,"backlog":0,"soft_resetted":false,"invoke":true,"MaxLabelId":2,"UnusedLabelIds":[],"name":null,"path":null},"solution_approches":[],"AllowedScrolls":[],"AllowedGadgets":null,"name":"TechDemo A","path":null} \ No newline at end of file diff --git a/Assets/Stages/TechDemo B.JSON b/Assets/Stages/TechDemo B.JSON index 63d816df..e6206127 100644 --- a/Assets/Stages/TechDemo B.JSON +++ b/Assets/Stages/TechDemo B.JSON @@ -1 +1 @@ -{"category":"Demo Category","number":2,"description":"River Stage","scene":"RiverWorld","use_install_folder":true,"solution":{"ValidationSet":[{"MasterIDs":["http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact652"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineFactHightDirectionComparer"},{"MasterIDs":["http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact652"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineSpanningOverRiverWorldComparer"},{"MasterIDs":[],"SolutionIndex":[1],"RelationIndex":[0],"ComparerString":"LineFactHightComparer"}],"FactDict":{"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact650":{"s_type":"PointFact","Point":{"x":0.0,"y":0.0,"z":0.0,"magnitude":0.0,"sqrMagnitude":0.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact650","Label":"A","hasCustomLabel":false,"LabelId":1},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact651":{"s_type":"PointFact","Point":{"x":0.0,"y":6.0,"z":0.0,"normalized":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":6.0,"sqrMagnitude":36.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact651","Label":"B","hasCustomLabel":false,"LabelId":2},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact652":{"s_type":"LineFact","Distance":6.0,"Pid1":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact650","Pid2":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact651","Dir":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact652","Label":"[AB]","hasCustomLabel":false,"LabelId":0}},"MetaInf":{"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact650":{"workflow_id":0,"active":true},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact651":{"workflow_id":1,"active":true},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact652":{"workflow_id":2,"active":true}},"Workflow":[{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact650","samestep":false,"steplink":3,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact651","samestep":true,"steplink":0,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact652","samestep":true,"steplink":0,"creation":true}],"marker":3,"worksteps":1,"backlog":0,"soft_resetted":false,"invoke":true,"MaxLabelId":2,"UnusedLabelIds":[],"name":null,"path":null},"name":"TechDemo B","path":null} \ No newline at end of file +{"category":"Demo Category","number":2,"description":"River Stage","scene":"RiverWorld","use_install_folder":true,"solution":{"ValidationSet":[{"MasterIDs":["http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1323"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineFactHightDirectionComparer"},{"MasterIDs":["http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1323"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineSpanningOverRiverWorldComparer"},{"MasterIDs":[],"SolutionIndex":[1],"RelationIndex":[0],"ComparerString":"LineFactHightComparer"}],"WorkflowGadgetDict":{"-1":null},"FactDict":{"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1321":{"s_type":"PointFact","Point":{"x":0.0,"y":0.0,"z":0.0,"magnitude":0.0,"sqrMagnitude":0.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1321","Label":"A","hasCustomLabel":false,"LabelId":1},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1322":{"s_type":"PointFact","Point":{"x":0.0,"y":6.0,"z":0.0,"normalized":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":6.0,"sqrMagnitude":36.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1322","Label":"B","hasCustomLabel":false,"LabelId":2},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1323":{"s_type":"LineFact","Distance":6.0,"Pid1":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1321","Pid2":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1322","Dir":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1323","Label":"[AB]","hasCustomLabel":false,"LabelId":0}},"MetaInf":{"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1321":{"workflow_id":0,"active":true},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1322":{"workflow_id":1,"active":true},"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1323":{"workflow_id":2,"active":true}},"Workflow":[{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1321","samestep":false,"steplink":3,"creation":true,"gadget_rank":-1,"scroll_label":null},{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1322","samestep":true,"steplink":0,"creation":true,"gadget_rank":-1,"scroll_label":null},{"Id":"http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact1323","samestep":true,"steplink":0,"creation":true,"gadget_rank":-1,"scroll_label":null}],"marker":3,"worksteps":1,"backlog":0,"soft_resetted":false,"invoke":true,"MaxLabelId":2,"UnusedLabelIds":[],"name":null,"path":null},"solution_approches":[],"AllowedScrolls":[],"AllowedGadgets":[{"s_type":"Pointer","Rank":1,"UiName":"Pointer","MaxRange":"Infinity","MaxHeight":"Infinity","ButtonIndx":1,"MaterialIndx":0,"IgnoreLayerMask":{"value":24066},"SecondaryLayerMask":{"value":0}},{"s_type":"Tape","Rank":2,"UiName":"Tape","MaxRange":2.5,"MaxHeight":2.5,"ButtonIndx":2,"MaterialIndx":0,"IgnoreLayerMask":{"value":96770},"SecondaryLayerMask":{"value":0}},{"s_type":"AngleTool","Rank":3,"UiName":"Angle Tool","MaxRange":"Infinity","MaxHeight":"Infinity","ButtonIndx":3,"MaterialIndx":1,"IgnoreLayerMask":{"value":96770},"SecondaryLayerMask":{"value":0}},{"s_type":"LineTool","Rank":4,"UiName":"Line Tool","MaxRange":"Infinity","MaxHeight":"Infinity","ButtonIndx":4,"MaterialIndx":0,"IgnoreLayerMask":{"value":96770},"SecondaryLayerMask":{"value":0}},{"s_type":"LotTool","Rank":5,"UiName":"Lot Tool","MaxRange":"Infinity","MaxHeight":"Infinity","ButtonIndx":5,"MaterialIndx":0,"IgnoreLayerMask":{"value":86530},"SecondaryLayerMask":{"value":0}},{"s_type":"Pendulum","Rank":6,"UiName":"Pendulum","MaxRange":"Infinity","MaxHeight":"Infinity","ButtonIndx":6,"MaterialIndx":0,"IgnoreLayerMask":{"value":96770},"SecondaryLayerMask":{"value":1}},{"s_type":"Remover","Rank":8,"UiName":"Delete Fact","MaxRange":"Infinity","MaxHeight":"Infinity","ButtonIndx":8,"MaterialIndx":0,"IgnoreLayerMask":{"value":115219},"SecondaryLayerMask":{"value":0}}],"name":"TechDemo B","path":null} \ No newline at end of file -- GitLab