Skip to content
Snippets Groups Projects
Commit c6b19076 authored by Marco Zimmer's avatar Marco Zimmer
Browse files

+ Added AllowedGadgets in Stage; + Redone Gadget Logging;

parent 011f5825
Branches
No related tags found
No related merge requests found
Showing
with 235 additions and 132 deletions
using System.Collections; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using static CommunicationEvents; using static CommunicationEvents;
...@@ -57,6 +57,9 @@ public static void GenerateDemoA() ...@@ -57,6 +57,9 @@ public static void GenerateDemoA()
new List<SolutionOrganizer.SubSolution> new List<SolutionOrganizer.SubSolution>
{ new SolutionOrganizer.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()) }; { new SolutionOrganizer.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()) };
// Set Gadgets
StageStatic.stage.AllowedGadgets = null;
// Save // Save
StageStatic.SetMode(StageStatic.Mode.Create); StageStatic.SetMode(StageStatic.Mode.Create);
StageStatic.stage.store(); StageStatic.stage.store();
...@@ -106,6 +109,9 @@ public static void GenerateDemoB() ...@@ -106,6 +109,9 @@ public static void GenerateDemoB()
new SolutionOrganizer.SubSolution(null, new List<int> { 1 }, new List<int> { 0 }, new LineFactHightComparer()), 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 // Save
StageStatic.SetMode(StageStatic.Mode.Create); StageStatic.SetMode(StageStatic.Mode.Create);
StageStatic.stage.store(); StageStatic.stage.store();
......
...@@ -36,9 +36,6 @@ public class GlobalBehaviour : MonoBehaviour ...@@ -36,9 +36,6 @@ public class GlobalBehaviour : MonoBehaviour
void Awake() void Awake()
{ {
// GenerateDemoFiles.GenerateAll();
hintAnimationStartColor = _hintAnimationStartColor; hintAnimationStartColor = _hintAnimationStartColor;
hintAnimationEndColor = _hintAnimationEndColor; hintAnimationEndColor = _hintAnimationEndColor;
hintAnimationDuration = _hintAnimationDuration; hintAnimationDuration = _hintAnimationDuration;
...@@ -50,8 +47,12 @@ void Awake() ...@@ -50,8 +47,12 @@ void Awake()
GadgetLaserDistance = _GadgetLaserDistance; GadgetLaserDistance = _GadgetLaserDistance;
GadgetPhysicalDistance = _GadgetPhysicalDistance; GadgetPhysicalDistance = _GadgetPhysicalDistance;
//DontDestroyOnLoad(gameObject);
}
private void Start()
{
//GenerateDemoFiles.GenerateAll();
StageStatic.ShallowLoadStages(); StageStatic.ShallowLoadStages();
//DontDestroyOnLoad(gameObject);
} }
} }
...@@ -125,7 +125,7 @@ public string Id { ...@@ -125,7 +125,7 @@ public string Id {
/// </value> /// </value>
public string Label { public string Label {
get { // in case of renamed dependables 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) || (hasCustomLabel && _CustomLabel != null)
? _CustomLabel ? _CustomLabel
: generateLabel(); : generateLabel();
......
...@@ -16,12 +16,12 @@ public static class FactManager ...@@ -16,12 +16,12 @@ public static class FactManager
/// <param name="fact">to be added</param> /// <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> /// <param name="exists"><c>true</c> iff <paramref name="fact"/> already has a equivalent counterpart in <paramref name="fact._Facts"/></param>
/// \copydetails FactManager /// \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[ return StageStatic.stage.factState[
StageStatic.stage.factState.Add( StageStatic.stage.factState.Add(
fact, out exists, samestep fact, out exists, samestep
, gadget ?? (scroll_label == null ? GadgetManager.ActiveGadgetInd.GetType() : null) , gadget ?? (scroll_label == null ? GadgetManager.ActiveGadget : null)
, scroll_label , scroll_label
)]; )];
} }
...@@ -29,7 +29,7 @@ public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep, ...@@ -29,7 +29,7 @@ public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep,
/// \copybrief FactManager <summary></summary> /// \copybrief FactManager <summary></summary>
/// <param name="hit"><c>RaycastHit</c> where and how (orientation) to spawn <see cref="PointFact"/></param> /// <param name="hit"><c>RaycastHit</c> where and how (orientation) to spawn <see cref="PointFact"/></param>
/// \copydetails FactManager /// \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( return (PointFact) AddFactIfNotFound(
new PointFact(hit.point, hit.normal, StageStatic.stage.factState) new PointFact(hit.point, hit.normal, StageStatic.stage.factState)
...@@ -40,7 +40,7 @@ public static PointFact AddPointFact(RaycastHit hit, bool samestep = false, Type ...@@ -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="point">where to spawn <see cref="PointFact"/></param>
/// <param name="normal">how (orientation) to spawn <see cref="PointFact"/></param> /// <param name="normal">how (orientation) to spawn <see cref="PointFact"/></param>
/// \copydetails FactManager /// \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( return (PointFact) AddFactIfNotFound(
new PointFact(point, normal, StageStatic.stage.factState) new PointFact(point, normal, StageStatic.stage.factState)
...@@ -51,7 +51,7 @@ public static PointFact AddPointFact(Vector3 point, Vector3 normal, bool sameste ...@@ -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="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> /// <param name="lid"><see cref="Fact.Id"/> of <see cref="LineFact"/> on which <paramref name="pid"/> lies</param>
/// \copydetails FactManager /// \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( return (OnLineFact)AddFactIfNotFound(
new OnLineFact(pid, lid, StageStatic.stage.factState) new OnLineFact(pid, lid, StageStatic.stage.factState)
...@@ -62,7 +62,7 @@ public static OnLineFact AddOnLineFact(string pid, string lid, bool samestep = f ...@@ -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="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> /// <param name="pid2"><see cref="Fact.Id"/> of second <see cref="PointFact"/> defining a <see cref="LineFact"/></param>
/// \copydetails FactManager /// \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( return (LineFact)AddFactIfNotFound(
new LineFact(pid1, pid2, StageStatic.stage.factState) new LineFact(pid1, pid2, StageStatic.stage.factState)
...@@ -76,7 +76,7 @@ public static LineFact AddLineFact(string pid1, string pid2, bool samestep = fal ...@@ -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="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> /// <param name="pid2"><see cref="Fact.Id"/> of second <see cref="PointFact"/> defining a <see cref="RayFact"/></param>
/// \copydetails FactManager /// \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( RayFact rayFact = (RayFact)AddFactIfNotFound(
new RayFact(pid1, pid2, StageStatic.stage.factState) new RayFact(pid1, pid2, StageStatic.stage.factState)
...@@ -119,7 +119,7 @@ void AddHitIfOnLine(RaycastHit hit) ...@@ -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="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> /// <param name="pid3"><see cref="Fact.Id"/> of third <see cref="PointFact"/> defining a <see cref="AngleFact"/></param>
/// \copydetails FactManager /// \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( return (AngleFact)AddFactIfNotFound(
new AngleFact(pid1, pid2, pid3, StageStatic.stage.factState) new AngleFact(pid1, pid2, pid3, StageStatic.stage.factState)
......
...@@ -20,31 +20,43 @@ ...@@ -20,31 +20,43 @@
/// </summary> /// </summary>
public class FactOrganizer : IJSONsavable<FactOrganizer> 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> /// <summary>
/// - <c>Key</c>: <see cref="Fact.Id"/> /// - <c>Key</c>: <see cref="Fact.Id"/>
/// - <c>Value</c>: <see cref="Fact"/> /// - <c>Value</c>: <see cref="Fact"/>
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
protected internal Dictionary<string, Fact> FactDict; protected Dictionary<string, Fact> FactDict;
/// <summary> /// <summary>
/// - <c>Key</c>: <see cref="Fact.Id"/> /// - <c>Key</c>: <see cref="Fact.Id"/>
/// - <c>Value</c>: <see cref="meta"/> /// - <c>Value</c>: <see cref="meta"/>
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
protected internal Dictionary<string, meta> MetaInf = new(); protected Dictionary<string, meta> MetaInf = new();
/// <summary> /// <summary>
/// Keeps track of insertion/ deletion/ etc. operations for <see cref="undo"/> and <see cref="redo"/> /// Keeps track of insertion/ deletion/ etc. operations for <see cref="undo"/> and <see cref="redo"/>
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
protected internal List<stepnote> Workflow = new(); protected List<stepnote> Workflow = new();
/// <summary> /// <summary>
/// Notes position in <see cref="Workflow"/> for <see cref="undo"/> and <see cref="redo"/>; the pointed to element is non-acitve /// Notes position in <see cref="Workflow"/> for <see cref="undo"/> and <see cref="redo"/>; the pointed to element is non-acitve
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
protected internal int marker = 0; protected int marker = 0;
/// <summary> /// <summary>
/// Backlock logic redundant - for convinience. /// Backlock logic redundant - for convinience.
...@@ -53,7 +65,7 @@ public class FactOrganizer : IJSONsavable<FactOrganizer> ...@@ -53,7 +65,7 @@ public class FactOrganizer : IJSONsavable<FactOrganizer>
/// <seealso cref="stepnote"/> /// <seealso cref="stepnote"/>
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
protected internal int worksteps = 0; protected int worksteps = 0;
/// <summary> /// <summary>
/// Backlock logic redundant - for convinience. /// Backlock logic redundant - for convinience.
/// Keeps track of number of steps in <see cref="Workflow"/>, which are not set active. /// Keeps track of number of steps in <see cref="Workflow"/>, which are not set active.
...@@ -61,13 +73,13 @@ public class FactOrganizer : IJSONsavable<FactOrganizer> ...@@ -61,13 +73,13 @@ public class FactOrganizer : IJSONsavable<FactOrganizer>
/// <seealso cref="stepnote"/> /// <seealso cref="stepnote"/>
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
protected internal int backlog = 0; protected int backlog = 0;
/// <summary> /// <summary>
/// Set to <c>true</c> if recently been resetted. /// Set to <c>true</c> if recently been resetted.
/// </summary> /// </summary>
[JsonProperty] [JsonProperty]
protected internal bool soft_resetted = false; protected bool soft_resetted = false;
/// <summary> /// <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. /// 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 ...@@ -126,6 +138,18 @@ protected internal struct stepnote
/// <summary> distincts creation and deletion </summary> /// <summary> distincts creation and deletion </summary>
public bool creation; 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> /// <summary>
/// Initiator /// Initiator
...@@ -134,11 +158,12 @@ protected internal struct stepnote ...@@ -134,11 +158,12 @@ protected internal struct stepnote
/// <param name="samestep">sets <see cref="samestep"/></param> /// <param name="samestep">sets <see cref="samestep"/></param>
/// <param name="creation">sets <see cref="creation"/></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> /// <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.Id = Id;
this.samestep = samestep; this.samestep = samestep;
this.creation = creation; this.creation = creation;
this.scroll_label = scroll_label;
if (samestep) if (samestep)
// steplink = !first_steptail ? previous.steplink : steproot // steplink = !first_steptail ? previous.steplink : steproot
...@@ -150,6 +175,15 @@ public stepnote(string Id, bool samestep, bool creation, FactOrganizer that) ...@@ -150,6 +175,15 @@ public stepnote(string Id, bool samestep, bool creation, FactOrganizer that)
// steproot sets steplink after itself (end of steptail) // steproot sets steplink after itself (end of steptail)
this.steplink = that.marker + 1; 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 ...@@ -171,37 +205,15 @@ protected internal struct meta
/// </summary> /// </summary>
public bool active; 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> /// <summary>
/// Initiator /// Initiator
/// </summary> /// </summary>
/// <param name="workflow_id">sets <see cref="workflow_id"/></param> /// <param name="workflow_id">sets <see cref="workflow_id"/></param>
/// <param name="active">sets <see cref="active"/></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.workflow_id = workflow_id;
this.active = active; this.active = active;
this.scroll_label = scroll_label;
_gadget = null; //Compiler Restriction
this.gadget = gadget;
} }
} }
...@@ -276,13 +288,13 @@ public static T ReInitializeFactOrganizer<T> ...@@ -276,13 +288,13 @@ public static T ReInitializeFactOrganizer<T>
old_to_new.Add(sn.Id, add.Id); 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)) else if (old_to_new.ContainsKey(sn.Id))
// Remove // Remove
{ {
Fact remove = target.FactDict[old_to_new[sn.Id]]; 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> ...@@ -301,20 +313,14 @@ public static T ReInitializeFactOrganizer<T>
/// </summary> /// </summary>
/// <param name="id">a <see cref="Fact.Id"/> in <see cref="FactDict"/></param> /// <param name="id">a <see cref="Fact.Id"/> in <see cref="FactDict"/></param>
/// <returns><c><see cref="FactDict"/>[<paramref name="id"/>]</c></returns> /// <returns><c><see cref="FactDict"/>[<paramref name="id"/>]</c></returns>
public Fact this[string id] public Fact this[string id] { get => FactDict[id]; }
{
get { return FactDict[id]; }
}
/// <summary> /// <summary>
/// wrappes <c><see cref="FactDict"/>.ContainsKey(<paramref name="id"/>)</c> /// wrappes <c><see cref="FactDict"/>.ContainsKey(<paramref name="id"/>)</c>
/// </summary> /// </summary>
/// <param name="id">a <see cref="Fact.Id"/></param> /// <param name="id">a <see cref="Fact.Id"/></param>
/// <returns><c><see cref="FactDict"/>.ContainsKey(<paramref name="id"/>)</c></returns> /// <returns><c><see cref="FactDict"/>.ContainsKey(<paramref name="id"/>)</c></returns>
public bool ContainsKey(string id) public bool ContainsKey(string id) => FactDict.ContainsKey(id);
{
return FactDict.ContainsKey(id);
}
/// <summary> /// <summary>
/// Looks up if there is a <paramref name="label"/> <see cref="Fact.Label"/> in <see cref="FactDict"/>.Values /// 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) ...@@ -366,7 +372,7 @@ private bool FindEquivalent(Fact search, out string found, out bool exact)
/// <param name="note">to be added</param> /// <param name="note">to be added</param>
private void WorkflowAdd(stepnote note) private void WorkflowAdd(stepnote note)
{ {
PruneWorkflow(); PruneWorkflow(note);
if (note.samestep) if (note.samestep)
// update steplink of steproot // update steplink of steproot
...@@ -388,7 +394,7 @@ private void WorkflowAdd(stepnote note) ...@@ -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; /// 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 /// resets <see cref="undo">un</see>-<see cref="redo"/> parameters
/// </summary> /// </summary>
private void PruneWorkflow() private void PruneWorkflow(stepnote not_me)
{ {
/*if (soft_resetted) /*if (soft_resetted)
this.hardreset(false); // musn't clear this.hardreset(false); // musn't clear
...@@ -404,7 +410,14 @@ private void PruneWorkflow() ...@@ -404,7 +410,14 @@ private void PruneWorkflow()
{ {
stepnote last = Workflow[i]; 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) && MetaInf[last.Id].workflow_id == i)
// remove for good, if original creation gets pruned // remove for good, if original creation gets pruned
{ {
...@@ -428,7 +441,7 @@ private void PruneWorkflow() ...@@ -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, /// <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> /// 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> /// <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; soft_resetted = false;
#pragma warning disable IDE0018 // Inlinevariablendeklaration #pragma warning disable IDE0018 // Inlinevariablendeklaration
...@@ -445,16 +458,9 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget, strin ...@@ -445,16 +458,9 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget, strin
// desired outcome already achieved // desired outcome already achieved
return key; return key;
if (MetaInf[key].workflow_id >= marker) if (MetaInf[key].workflow_id > marker)
// check for zombie-status: everything >= marker will be pruned // update meta data: everything >= marker will be pruned (except this Fact)
{ MetaInf[key] = new meta(marker, true);
// 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);
}
} }
else else
...@@ -462,10 +468,10 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget, strin ...@@ -462,10 +468,10 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget, strin
{ {
key = value.Id; key = value.Id;
FactDict.Add(key, value); 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; return key;
} }
...@@ -478,8 +484,8 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget, strin ...@@ -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, /// <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> /// 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> /// <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) public bool Remove(Fact value, bool samestep, Gadget gadget)
=> this.Remove(value.Id, samestep); => this.Remove(value.Id, samestep, gadget);
/// \copybrief Remove(Fact, bool) /// \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> /// <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) ...@@ -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, /// <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> /// 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> /// <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) //no reset check needed (impossible state)
{ {
if (!FactDict.ContainsKey(key)) if (!FactDict.ContainsKey(key))
...@@ -503,7 +509,7 @@ public bool Remove(string key, bool samestep = false) ...@@ -503,7 +509,7 @@ public bool Remove(string key, bool samestep = false)
if (deletethis.Count > 0) if (deletethis.Count > 0)
{ {
yeetusdeletus(deletethis, samestep); yeetusdeletus(deletethis, samestep, gadget);
} }
return true; return true;
...@@ -551,11 +557,11 @@ public bool safe_dependencies(string key, out List<string> dependencies) ...@@ -551,11 +557,11 @@ public bool safe_dependencies(string key, out List<string> dependencies)
/// </summary> /// </summary>
/// <param name="deletereverse">to be <see cref="Remove(string, bool)">removed</see>, but without checking for (recursive) dependencies</param> /// <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> /// <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) 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) ...@@ -577,9 +583,9 @@ private void reversestep(int pos, bool samestep = false)
i >= stop; i--, samestep = true) i >= stop; i--, samestep = true)
{ {
if (Workflow[i].creation) if (Workflow[i].creation)
Remove(Workflow[i].Id, samestep); Remove(Workflow[i].Id, samestep, null);
else if (!MetaInf[Workflow[i].Id].active) 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( ...@@ -832,14 +838,15 @@ public bool DynamiclySolved(
return MissingElementsCount == 0; return MissingElementsCount == 0;
} }
public IEnumerable<Type> GetUsedGadgets() public IEnumerable<Gadget> GetUsedGadgets() => GadgetWorkflowDict.Keys;
=> MetaInf.Values.Where(inf => inf.active & inf.gadget != null).Select(inf => inf.gadget).Distinct();
public int GetNumberOfGadgets() => GetUsedGadgets().Count(); public int GetNumberOfGadgets() => GadgetWorkflowDict.Count;
public IEnumerable<string> GetUsedScrolls() 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 GetNumberOfScrolls() => GetUsedScrolls().Count();
public int GetNumberOfFacts() => FactDict.Count;
} }
\ No newline at end of file
using UnityEngine; using Newtonsoft.Json;
using UnityEngine;
public class AngleTool : Gadget public class AngleTool : Gadget
{ {
/// \copydoc Gadget.s_type
[JsonProperty]
protected static new string s_type = "AngleTool";
//Variables for AngleMode distinction //Variables for AngleMode distinction
private int PointNr = 0; private int PointNr = 0;
private readonly PointFact[] AnglePoints = new PointFact[3]; private readonly PointFact[] AnglePoints = new PointFact[3];
......
using Newtonsoft.Json; using JsonSubTypes;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
...@@ -9,8 +10,26 @@ ...@@ -9,8 +10,26 @@
/// Base class for all Gadgets to derive from. /// Base class for all Gadgets to derive from.
/// A Gadget is a tool for the player (and level editor) to interact with the GameWorld. /// A Gadget is a tool for the player (and level editor) to interact with the GameWorld.
/// </summary> /// </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 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> /// <summary>Used to map to a T:Gadget </summary>
/// <remarks>Do NOT rename elements! Do NOT change values! Deserialization relies on it!</remarks> /// <remarks>Do NOT rename elements! Do NOT change values! Deserialization relies on it!</remarks>
public enum GadgetIDs public enum GadgetIDs
...@@ -40,24 +59,24 @@ public enum GadgetIDs ...@@ -40,24 +59,24 @@ public enum GadgetIDs
/// <summary> Position in tool belt. </summary> /// <summary> Position in tool belt. </summary>
/// <remarks>Set in Inspector or <see cref="Awake"/></remarks> /// <remarks>Set in Inspector or <see cref="Awake"/></remarks>
public int Rank; public int Rank = int.MinValue;
/// <summary> Tool Name </summary> /// <summary> Tool Name </summary>
/// <remarks>Set in Inspector or <see cref="Awake"/></remarks> /// <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> /// <summary> Maximum range for this Tool. For consistency use GadgetDistances in <see cref="GlobalBehaviour"/>.</summary>
/// <remarks>Set in Inspector or <see cref="Awake"/></remarks> /// <remarks>Set in Inspector or <see cref="Awake"/></remarks>
public float MaxRange; public float MaxRange = float.NegativeInfinity;
public float MaxHeight; public float MaxHeight = float.NegativeInfinity;
/// <summary>Which sprite to use</summary> /// <summary>Which sprite to use</summary>
public int ButtonIndx; public int ButtonIndx = -1;
public int MaterialIndx; public int MaterialIndx = -1;
/// <summary>Layers to ignore for this gadget by default.</summary> /// <summary>Layers to ignore for this gadget by default.</summary>
/// <remarks>Set in Inspector</remarks> /// <remarks>Set in Inspector</remarks>
public LayerMask IgnoreLayerMask; public LayerMask IgnoreLayerMask = -1;
public LayerMask SecondaryLayerMask; public LayerMask SecondaryLayerMask = -1;
//protected List<Vector3> LinePositions = new(); private bool init_success = false;
/// <summary> /// <summary>
/// Collection of <c>Type</c>s of *all* available <see cref="Gadget"/>s to choose from. /// Collection of <c>Type</c>s of *all* available <see cref="Gadget"/>s to choose from.
...@@ -67,33 +86,59 @@ public enum GadgetIDs ...@@ -67,33 +86,59 @@ public enum GadgetIDs
public Gadget() public Gadget()
{ {
Init(true);
}
public void Init(bool overrite)
{
if ( init_success
|| GadgetManager.DataContainerGadgetDict == null)
return;
Type this_type = this.GetType(); 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!"); Debug.LogError("No " + this_type.ToString() + "in Dictionary<Type, GadgetIDs> GadgetTypeToIDs!");
return; return;
} }
var GadgetID = GadgetTypeToIDs[this_type]; var GadgetID = GadgetTypeToIDs[this_type];
if (!GadgetManager.DataContainerGadgetDict.ContainsKey(GadgetID)) { if (!GadgetManager.DataContainerGadgetDict.ContainsKey(GadgetID))
{
Debug.LogError("No " + GadgetID.ToString() + "in assigned " + typeof(DataContainerGadgetCollection).Name + "!"); Debug.LogError("No " + GadgetID.ToString() + "in assigned " + typeof(DataContainerGadgetCollection).Name + "!");
return; return;
} }
var data_cache = GadgetManager.DataContainerGadgetDict[GadgetID]; var data_cache = GadgetManager.DataContainerGadgetDict[GadgetID];
if (overrite || Rank == int.MinValue)
Rank = data_cache.Rank; Rank = data_cache.Rank;
if (overrite || UiName == null)
UiName = data_cache.UiName; UiName = data_cache.UiName;
if (overrite || MaxRange == float.NegativeInfinity)
MaxRange = data_cache.MaxRange; MaxRange = data_cache.MaxRange;
if (overrite || MaxHeight == float.NegativeInfinity)
MaxHeight = data_cache.MaxHeight; MaxHeight = data_cache.MaxHeight;
if (overrite || IgnoreLayerMask == -1)
IgnoreLayerMask = data_cache.IgnoreLayerMask; IgnoreLayerMask = data_cache.IgnoreLayerMask;
if (overrite || SecondaryLayerMask == -1)
SecondaryLayerMask = data_cache.SecondaryLayerMask; SecondaryLayerMask = data_cache.SecondaryLayerMask;
ButtonIndx = data_cache.ButtonIndx < GadgetManager.ButtonSprites.Length if (overrite || ButtonIndx < 0)
ButtonIndx =
data_cache.ButtonIndx < GadgetManager.ButtonSprites.Length
&& data_cache.ButtonIndx >= 0
? data_cache.ButtonIndx : 0; ? data_cache.ButtonIndx : 0;
MaterialIndx = data_cache.MaterialIndx < GadgetManager.Materials.Length if (overrite || MaterialIndx < 0)
MaterialIndx =
data_cache.MaterialIndx < GadgetManager.Materials.Length
&& data_cache.MaterialIndx >= 0
? data_cache.MaterialIndx : 0; ? data_cache.MaterialIndx : 0;
init_success = true;
} }
public void Awake() public void Awake()
{ {
Init(false);
_Awake(); _Awake();
} }
......
...@@ -84,20 +84,28 @@ private void Awake() ...@@ -84,20 +84,28 @@ private void Awake()
activeGadgetScaleFactor = 1.5f; activeGadgetScaleFactor = 1.5f;
else if (UIconfig.FrameITUIversion == 2) else if (UIconfig.FrameITUIversion == 2)
activeGadgetScaleFactor = 2.1f; 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]; 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].Awake();
//gadgets[i].Start(); //gadgets[i].Start();
CreateButton(i); CreateButton(i);
} }
}
void Start()
{
ActiveGadgetInd = 0; ActiveGadgetInd = 0;
buttons[0].transform.localScale *= activeGadgetScaleFactor; buttons[0].transform.localScale *= activeGadgetScaleFactor;
OnHit = gadgets[0].Hit; OnHit = gadgets[0].Hit;
......
using System.Collections; using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using static CommunicationEvents; using static CommunicationEvents;
public class LineTool : Gadget public class LineTool : Gadget
{ {
/// \copydoc Gadget.s_type
[JsonProperty]
protected static new string s_type = "LineTool";
//Variables for LineMode distinction //Variables for LineMode distinction
private bool LineModeIsFirstPointSelected = false; private bool LineModeIsFirstPointSelected = false;
private Fact LineModeFirstPointSelected = null; private Fact LineModeFirstPointSelected = null;
......
using System.Collections; using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using static CommunicationEvents; using static CommunicationEvents;
...@@ -6,6 +7,10 @@ ...@@ -6,6 +7,10 @@
public class LotTool : Gadget public class LotTool : Gadget
//constructs a Perpendicular between a Line and a Point //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 //Variables for LineMode distinction
private bool LotModeIsPointSelected = false; private bool LotModeIsPointSelected = false;
private bool LotModeIsLineSelected = false; private bool LotModeIsLineSelected = false;
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
public class Pendulum : Gadget public class Pendulum : Gadget
//Acts as a Pendulum starting at a Point //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() public override void _Enable()
{ {
ActivateLineDrawing(); ActivateLineDrawing();
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
public class Pointer : Gadget public class Pointer : Gadget
{ {
/// \copydoc Gadget.s_type
[Newtonsoft.Json.JsonProperty]
protected static new string s_type = "Pointer";
public override void _Hit(RaycastHit hit) public override void _Hit(RaycastHit hit)
{ {
string pid = FactManager.AddPointFact(hit).Id; string pid = FactManager.AddPointFact(hit).Id;
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
public class PoleTool : Gadget public class PoleTool : Gadget
//Acts as a Pendulum starting at a Point //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 float poleHeight = 1f;
public override void _Enable() public override void _Enable()
......
...@@ -5,9 +5,13 @@ ...@@ -5,9 +5,13 @@
public class Remover : Gadget public class Remover : Gadget
{ {
/// \copydoc Gadget.s_type
[Newtonsoft.Json.JsonProperty]
protected static new string s_type = "Remover";
public override void _Hit(RaycastHit hit) public override void _Hit(RaycastHit hit)
{ {
var hid = hit.transform.GetComponent<FactObject>()?.URI; var hid = hit.transform.GetComponent<FactObject>()?.URI;
StageStatic.stage.factState.Remove(hid); StageStatic.stage.factState.Remove(hid, false, this);
} }
} }
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
public class Tape : Gadget public class Tape : Gadget
{ {
/// \copydoc Gadget.s_type
[Newtonsoft.Json.JsonProperty]
protected static new string s_type = "Tape";
//Variables for TapeMode distinction //Variables for TapeMode distinction
private bool TapeModeIsFirstPointSelected = false; private bool TapeModeIsFirstPointSelected = false;
private Fact TapeModeFirstPointSelected = null; private Fact TapeModeFirstPointSelected = null;
......
...@@ -42,12 +42,16 @@ public class Stage: IJSONsavable<Stage> ...@@ -42,12 +42,16 @@ public class Stage: IJSONsavable<Stage>
[JSONsavable.JsonAutoPreProcess, JSONsavable.JsonAutoPostProcess] [JSONsavable.JsonAutoPreProcess, JSONsavable.JsonAutoPostProcess]
public SolutionOrganizer solution = null; public SolutionOrganizer solution = null;
/// <summary>
/// A single class containing all savegame-data.
/// Stored seperately.
/// </summary>
[JsonIgnore, JSONsavable.JsonSeparate] [JsonIgnore, JSONsavable.JsonSeparate]
public SaveGame savegame = null; public SaveGame savegame = null;
public List<PlayerRecord> solution_approches = new(); public List<PlayerRecord> solution_approches = new();
public List<string> AllowedScrolls = new(); public List<string> AllowedScrolls = new();
public List<Type> AllowedGadgets = new(); public List<Gadget> AllowedGadgets = new();
#region makros/shortcuts #region makros/shortcuts
...@@ -61,7 +65,7 @@ public class Stage: IJSONsavable<Stage> ...@@ -61,7 +65,7 @@ public class Stage: IJSONsavable<Stage>
/// <summary> Current Stage progress.</summary> /// <summary> Current Stage progress.</summary>
[JsonIgnore] [JsonIgnore]
public PlayerRecord player_record { public PlayerRecord player_record {
get => savegame?.player_record; get => savegame.player_record ??= new(record_name);
set => (savegame ??= new()) set => (savegame ??= new())
.player_record = value; .player_record = value;
} }
...@@ -94,7 +98,7 @@ public FactOrganizer factState { ...@@ -94,7 +98,7 @@ public FactOrganizer factState {
#endregion makros/shortcuts #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> /// <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> /// <summary> Wether <see cref="player_record.factState"/> (<see langword="false"/>) or <see cref="solution"/> (<see langword="true"/>) is exposed and drawn.</summary>
[JsonIgnore] [JsonIgnore]
...@@ -453,7 +457,7 @@ public class SaveGame : IJSONsavable<SaveGame> ...@@ -453,7 +457,7 @@ public class SaveGame : IJSONsavable<SaveGame>
public string path { get; set; } public string path { get; set; }
[JSONsavable.JsonAutoPreProcess, JSONsavable.JsonAutoPostProcess] [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 public Dictionary<string, PlayerRecord> player_record_list = new(); //entries are "PostProcess"ed when accessed/Cloned
...@@ -464,6 +468,12 @@ static SaveGame() ...@@ -464,6 +468,12 @@ static SaveGame()
public SaveGame() { } public SaveGame() { }
string IJSONsavable<SaveGame>._IJGetName(string name) => name + "_save"; 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() { } ...@@ -502,7 +512,7 @@ public PlayerRecord() { }
/// <param name="name">sets <see cref="name"/></param> /// <param name="name">sets <see cref="name"/></param>
public PlayerRecord(string name) { public PlayerRecord(string name) {
this.name = name; this.name = name;
factState = new FactOrganizer(); factState = new FactOrganizer() { invoke = true };
} }
/// <summary> /// <summary>
...@@ -517,17 +527,8 @@ public PlayerRecord Clone() ...@@ -517,17 +527,8 @@ public PlayerRecord Clone()
solved = this.solved, solved = this.solved,
seconds = this.seconds seconds = this.seconds
}; };
ret.factState = FactOrganizer.ReInitializeFactOrganizer<FactOrganizer>(this.factState, false, out _); ret.factState = IJSONsavable<FactOrganizer>.postprocess(this.factState);
return ret; return ret;
} }
} }
\ No newline at end of file
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
{"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} {"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 \ 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?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} {"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 \ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment