#if UNITY_EDITOR using FIMSpace.FEditor; using UnityEditor; #endif using FIMSpace.Generating.Planner.Nodes; using FIMSpace.Graph; using System; using System.Collections.Generic; using UnityEngine; using FIMSpace.Generating.Rules.QuickSolutions; using FIMSpace.Generating.Checker; namespace FIMSpace.Generating.Planning.PlannerNodes { /// /// It's always sub-asset -> it's never project file asset /// public abstract partial class PlannerRuleBase : PGGPlanner_NodeBase { public static bool Debugging = false; /// Warning! Duplicate is refering to root project planner, In the nodes logics you can use CurrentExecutingPlanner for instance planner reference [HideInInspector] public FieldPlanner ParentPlanner; public FieldPlanner CurrentExecutingPlanner { get { return FieldPlanner.CurrentGraphExecutingPlanner; } } [HideInInspector] public ScriptableObject ParentNodesContainer; public string DebuggingInfo { get; protected set; } public Action DebuggingGizmoEvent { get; protected set; } //public virtual string TitleName() { return GetType().Name; } public virtual string Tooltip() { string tooltipHelp = "(" + GetType().Name; return tooltipHelp + ")"; } public override Vector2 NodeSize { get { return new Vector2(232, 90); } } /// PlannerRuleBase by default is true public override bool DrawInputConnector { get { return true; } } public bool GetPlannerPort_IsContainingMultiple(PGGPlannerPort port) { if (port.ContainsMultiplePlanners) return true; return false; } /// /// You can use port.ContainsMultiplePlanners to identify multiple planners port transport /// private static List _multiplePlannersContainer = new List(); public List GetPlannersFromPort(PGGPlannerPort port, bool nullIfNoMultiple = false, bool callRead = true, bool newListInstance = true) { List list; if (newListInstance) list = new List(); else { _multiplePlannersContainer.Clear(); list = _multiplePlannersContainer; } for (int c = 0; c < port.Connections.Count; c++) { var conn = port.Connections[c]; PGGPlannerPort comm = null; if (conn != null) { if (conn.PortReference != null) { if (conn.PortReference == port) UnityEngine.Debug.Log("(Same port - it's wrong)"); else { if (conn.PortReference is PGGPlannerPort) comm = conn.PortReference as PGGPlannerPort; } } } if (comm != null) { if (comm.ContainsMultiplePlanners) { for (int p = 0; p < comm.PlannersList.Count; p++) { if (comm.PlannersList[p].Available) list.Add(comm.PlannersList[p]); } var pl = GetPlannerFromPort(port, callRead); if (pl.Available) if (!list.Contains(pl)) { list.Add(pl); } } else { var pl = GetPlannerFromPort(port, callRead); if (pl) if (pl.Available) list.Add(pl); } } else { var pl = GetPlannerFromPort(port, callRead); if (pl) if (pl.Available) list.Add(pl); } } if (port.Connections.Count == 0) { var pl = GetPlannerFromPort(port, callRead); if (pl) if (pl.Available) list.Add(pl); } port.AssignPlannersList(list); if (list.Count > 0) return list; if (nullIfNoMultiple) return null; else return list; } public static FieldPlanner GetPlannerFromPortS(PGGPlannerPort port, bool callRead = true) { if (callRead) port.GetPortValueCall(); int plannerId = port.GetPlannerIndex(); int duplicateId = port.GetPlannerDuplicateIndex(); FieldPlanner portPlanner = port.GetPlannerFromPort(); if (portPlanner != null) return portPlanner; return GetFieldPlannerByID(plannerId, duplicateId); } public FieldPlanner GetPlannerFromPort(PGGPlannerPort port, bool callRead = true) { if (callRead) port.TriggerReadPort(true); FieldPlanner portPlanner = port.GetPlannerFromPort(); if (portPlanner != null) { return portPlanner; } int plannerId = port.GetPlannerIndex(); int duplicateId = port.GetPlannerDuplicateIndex(); return GetPlannerByID(plannerId, duplicateId); } public CheckerField3D GetCheckerFromPort(PGGPlannerPort port, bool callRead = true) { if (callRead) port.TriggerReadPort(true); CheckerField3D portPlanner = port.GetInputCheckerSafe; if (portPlanner != null) { return portPlanner; } FieldPlanner planner = GetPlannerFromPort(port, callRead); if (planner == null) return null; return planner.LatestChecker; } public FieldPlanner GetPlannerByID(int plannerId, int duplicateId = -1) { FieldPlanner planner = GetFieldPlannerByID(plannerId, duplicateId); if (planner == null) return ParentPlanner; return planner; } public static bool _debug = false; public static FieldPlanner GetFieldPlannerByID(int plannerId, int duplicateId = -1) { FieldPlanner planner = FieldPlanner.CurrentGraphExecutingPlanner; if (planner == null) { planner = null; } BuildPlannerPreset build = null; if (planner != null) build = planner.ParentBuildPlanner; if (build == null) { return null; } if (plannerId >= 0 && plannerId < build.BasePlanners.Count) { planner = build.BasePlanners[plannerId]; if (planner.IsDuplicate == false) if (duplicateId >= 0) if (planner.GetDuplicatesPlannersList() != null) { planner = planner.GetDuplicatesPlannersList()[duplicateId]; } } if (planner.Discarded) { FieldPlanner getPl = planner; if (duplicateId == -1) // if discarded then get first not discarded duplicate planner { if (planner.IsDuplicate == false) for (int i = 0; i < planner.GetDuplicatesPlannersList().Count; i++) { var plan = planner.GetDuplicatesPlannersList()[i]; if (plan == null) continue; if (plan.Available == false) continue; getPl = plan; break; } } return getPl; } return planner; } /// [Base is empty] public virtual void PreGeneratePrepare() { } /// [Base is not empty] Preparing initial debug message public virtual void Prepare(PlanGenerationPrint print) { #if UNITY_EDITOR DebuggingInfo = "Debug Info not Assigned"; #endif } /// [Base is empty] public virtual void Execute(PlanGenerationPrint print, PlannerResult newResult) { // Node Procedures Code } protected void CallOtherExecution(FGraph_NodeBase otherNode, PlanGenerationPrint print) { if (otherNode == null) return; if (ParentPlanner == null) { if (print == null) { if (otherNode is PlannerRuleBase) MG_ModGraph.CallExecution(otherNode as PlannerRuleBase); } return; } if (otherNode is PlannerRuleBase) ParentPlanner.CallExecution(otherNode as PlannerRuleBase, print); } protected void CallOtherExecutionWithConnector(int altId, PlanGenerationPrint print) { for (int c = 0; c < OutputConnections.Count; c++) { if (OutputConnections[c].ConnectionFrom_AlternativeID == altId) { CallOtherExecution(OutputConnections[c].GetOther(this), print); } } } #region Editor related #if UNITY_EDITOR public virtual void OnGUIModify() { } [HideInInspector] public bool _editor_drawRule = true; protected UnityEditor.SerializedObject inspectorViewSO = null; protected virtual void DrawGUIHeader(int i) { if (inspectorViewSO == null) inspectorViewSO = new UnityEditor.SerializedObject(this); EditorGUILayout.BeginHorizontal(FGUI_Resources.BGInBoxLightStyle, GUILayout.Height(20)); // 1 Enabled = EditorGUILayout.Toggle(Enabled, GUILayout.Width(24)); string foldout = FGUI_Resources.GetFoldSimbol(_editor_drawRule); string tip = Tooltip(); if (GUILayout.Button(new GUIContent(foldout + " " + GetDisplayName() + " " + foldout, tip), FGUI_Resources.HeaderStyle)) { bool rmb = false; if (rmb == false) _editor_drawRule = !_editor_drawRule; } int hh = 18; if (i > 0) if (GUILayout.Button(new GUIContent(FGUI_Resources.Tex_ArrowUp), FGUI_Resources.ButtonStyle, GUILayout.Width(18), GUILayout.Height(hh))) { FGenerators.SwapElements(ParentPlanner.FProcedures, i, i - 1); return; } if (i < ParentPlanner.FProcedures.Count - 1) if (GUILayout.Button(new GUIContent(FGUI_Resources.Tex_ArrowDown), FGUI_Resources.ButtonStyle, GUILayout.Width(18), GUILayout.Height(hh))) { FGenerators.SwapElements(ParentPlanner.FProcedures, i, i + 1); return; } if (GUILayout.Button("X", FGUI_Resources.ButtonStyle, GUILayout.Width(24), GUILayout.Height(hh))) { ParentPlanner.RemoveRuleFromPlanner(this); return; } EditorGUILayout.EndHorizontal(); // 1 } protected virtual void DrawGUIFooter() { EditorGUILayout.EndVertical(); if (inspectorViewSO.ApplyModifiedProperties()) { OnStartReadingNode(); } } //public void DrawGUIStack(int i) //{ // DrawGUIHeader(i); // Color preColor = GUI.color; // if (inspectorViewSO != null) // if (inspectorViewSO.targetObject != null) // if (_editor_drawRule) // { // EditorGUILayout.BeginVertical(FGUI_Resources.BGInBoxStyle); // if (Enabled == false) GUI.color = new Color(0.9f, 0.9f, 0.9f, 0.7f); // inspectorViewSO.Update(); // DrawGUIBody(); // DrawGUIFooter(); // } // GUI.color = preColor; //} /// /// Returns true if something changed in GUI - using EditorGUI.BeginChangeCheck(); /// //protected virtual void DrawGUIBody(/*int i*/) //{ // UnityEditor.SerializedProperty sp = inspectorViewSO.GetIterator(); // sp.Next(true); // sp.NextVisible(false); // bool can = sp.NextVisible(false); // if (can) // { // do // { // bool cont = false; // if (cont) continue; // UnityEditor.EditorGUILayout.PropertyField(sp); // } // while (sp.NextVisible(false) == true); // } // // EditorGUILayout.EndVertical(); // // so.ApplyModifiedProperties(); // //} //} #endif #endregion #region Mod Graph Related /// Current executing mod graph (for field modification graph) public SR_ModGraph MG_ModGraph { get { return SR_ModGraph.Graph_ModGraph; } } /// Current executing field mod (for field modification graph) public FieldSpawner MG_Spawner { get { return SR_ModGraph.Graph_Spawner; } } /// Current executing field modificator's spawner public FieldModification MG_Mod { get { return SR_ModGraph.Graph_Mod; } } /// Current executing mod spawner's spawn (for field modification graph) public SpawnData MG_Spawn { get { return SR_ModGraph.Graph_SpawnData; } } /// Current executing field setup preset (for field modification graph) public FieldSetup MG_Preset { get { return SR_ModGraph.Graph_Preset; } } /// Current executing field grid cell (for field modification graph) public FieldCell MG_Cell { get { return SR_ModGraph.Graph_Cell; } } /// Current executing field gridd (for field modification graph) public FGenGraph MG_Grid { get { return SR_ModGraph.Graph_Grid; } } ///// Current executing field mod (for field modification graph) //public Vector3? Graph_RestrictDir { get { return SR_ModGraph.Graph_Mod; } } public ModificatorsPack MGGetParentPack() { SR_ModGraph owner = ParentNodesContainer as SR_ModGraph; if (owner == null) return null; return owner.TryGetParentModPack(); } public UnityEngine.Object MGGetFieldSetup() { SR_ModGraph owner = ParentNodesContainer as SR_ModGraph; if (owner == null) return null; var fs = owner.TryGetParentFieldSetup(); if (fs == null) return null; //if (fs) //{ // if (fs.InstantiatedOutOf) return fs.InstantiatedOutOf; //} return fs; } protected List MGGetVariables(UnityEngine.Object tgt) { if (tgt == null) return null; FieldSetup fs = tgt as FieldSetup; if (fs) { return fs.Variables; } ModificatorsPack mp = tgt as ModificatorsPack; if (mp) { return mp.Variables; } return null; } protected FieldVariable MGGetVariable(UnityEngine.Object tgt, int index) { var variables = MGGetVariables(tgt); if (variables == null) return null; if (variables.ContainsIndex(index)) return variables[index]; return null; } #endregion } }