Skip to content
Snippets Groups Projects
FactManager.cs 16.8 KiB
Newer Older
John Schihada's avatar
John Schihada committed
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static CommunicationEvents;
public class FactManager : MonoBehaviour
{
    private List<int> NextEmpties= new List<int>();
John Schihada's avatar
John Schihada committed
    //Variables for LineMode distinction
    public bool lineModeIsFirstPointSelected = false;
    public Fact lineModeFirstPointSelected = null;

    //Variables for AngleMode distinction
    public bool angleModeIsFirstPointSelected = false;
    public Fact angleModeFirstPointSelected = null;
    public bool angleModeIsSecondPointSelected = false;
    public Fact angleModeSecondPointSelected = null;
    // Start is called before the first frame update
    void Start()
    {
        CommunicationEvents.ToolModeChangedEvent.AddListener(OnToolModeChanged);
        CommunicationEvents.TriggerEvent.AddListener(OnHit);
      //  CommunicationEvents.SnapEvent.AddListener(Rocket);
        //We dont want to have this here anymore...
        //CommunicationEvents.RemoveFactEvent.AddListener(DeleteFact);
John Schihada's avatar
John Schihada committed
    // Update is called once per frame
    void Update()
    {

    }
John Schihada's avatar
John Schihada committed
    PointFact AddPointFact(RaycastHit hit, int id)
        Facts.Insert(id, new PointFact(id, hit.point, hit.normal));
John Schihada's avatar
John Schihada committed
        return Facts.Find(x => x.Id == id) as PointFact;
John Schihada's avatar
John Schihada committed
    LineFact AddLineFact(int pid1, int pid2, int id)
       Facts.Insert(id, new LineFact(id,pid1,pid2));
John Schihada's avatar
John Schihada committed
        return Facts.Find(x => x.Id == id) as LineFact;
John Schihada's avatar
John Schihada committed
    }
John Schihada's avatar
John Schihada committed
    AngleFact AddAngleFact(int pid1, int pid2, int pid3, int id)
        Facts.Insert(id, new AngleFact(id,pid1,pid2,pid3));
John Schihada's avatar
John Schihada committed
        return Facts.Find(x => x.Id == id) as AngleFact;
            NextEmpties.Add(fact.Id);
            //Facts.RemoveAt(fact.Id);
            Facts.Remove(Facts.Find(x => x.Id == fact.Id));
            CommunicationEvents.RemoveFactEvent.Invoke(fact);
        }
    public int GetFirstEmptyID()
    {

        /* for (int i = 0; i < Facts.Length; ++i)
         {
             if (Facts[i] == "")
                 return i;
         }
         return Facts.Length - 1;*/
        int id = NextEmpties[0];
        NextEmpties.RemoveAt(0);
        if (NextEmpties.Count == 0)
            NextEmpties.Add(id + 1);
        Debug.Log("place fact at " + id);

    }

    public void OnToolModeChanged(ToolMode ActiveToolMode)
    {
        //We need to do this somehwere...
        CommunicationEvents.ActiveToolMode = ActiveToolMode;
        switch (ActiveToolMode)
        {
            case ToolMode.MarkPointMode:
                //If MarkPointMode is activated we want to have the ability to mark the point
                //everywhere, independent of already existing facts
                   GameObject gO = fact.Representation;
                   gO.GetComponentInChildren<Collider>().enabled = false;
                }
                break;
            case ToolMode.CreateLineMode:
                //If CreateLineMode is activated we want to have the ability to select points for the Line
                //but we don't want to have the ability to select Lines or Angles
                    GameObject gO = fact.Representation;
                    if (gO.layer == LayerMask.NameToLayer("Line") || gO.layer == LayerMask.NameToLayer("Angle"))
                        gO.GetComponentInChildren<Collider>().enabled = false;
                    else if (gO.layer == LayerMask.NameToLayer("Point"))
                        gO.GetComponentInChildren<Collider>().enabled = true;
                    }
                }
                break;
            case ToolMode.CreateAngleMode:
                //If CreateAngleMode is activated we want to have the ability to select Points for the Angle
                //but we don't want to have the ability to select Lines or Angles
                    GameObject gO = fact.Representation;
                    if (gO.layer == LayerMask.NameToLayer("Line") || gO.layer == LayerMask.NameToLayer("Angle"))
                        gO.GetComponentInChildren<Collider>().enabled = false;
                    else if (gO.layer == LayerMask.NameToLayer("Point"))
                        gO.GetComponentInChildren<Collider>().enabled = true;
                    }
                }
                break;
            case ToolMode.DeleteMode:
                //If DeleteMode is activated we want to have the ability to delete every Fact
                //independent of the concrete type of fact
                    GameObject gO = fact.Representation;
                    gO.GetComponentInChildren<Collider>().enabled = true;
                }
                break;
            case ToolMode.ExtraMode:
John Schihada's avatar
John Schihada committed
                /*foreach (Fact fact in Facts)
John Schihada's avatar
John Schihada committed
                */
    //automatic 90 degree angle construction
    public void Rocket(RaycastHit hit)
    {

        int idA, idB, idC;

        //usual point
        idA = this.GetFirstEmptyID();
        CommunicationEvents.AddFactEvent.Invoke(this.AddPointFact(hit, idA));

        //second point
        idB = this.GetFirstEmptyID();
        var shiftedHit = hit;
        var playerPos = Camera.main.transform.position;
        playerPos.y = hit.point.y;
        shiftedHit.point = playerPos;
        CommunicationEvents.AddFactEvent.Invoke(this.AddPointFact(shiftedHit, idB));

        //third point with unknown height
        idC = this.GetFirstEmptyID();
        var skyHit = hit;
        skyHit.point += Vector3.up * 20;
        CommunicationEvents.AddFactEvent.Invoke(this.AddPointFact(skyHit, idC));

        //lines
        CommunicationEvents.AddFactEvent.Invoke(this.AddLineFact(idA, idB, this.GetFirstEmptyID()));
        //lines
        CommunicationEvents.AddFactEvent.Invoke(this.AddLineFact(idA, idC, this.GetFirstEmptyID()));

        //90degree angle
        CommunicationEvents.AddFactEvent.Invoke(this.AddAngleFact(idB,idA,idC, GetFirstEmptyID()));
    public void SmallRocket(RaycastHit hit,  int idA)
    {
        //enable collider to measure angle to the treetop
     


        int idB = this.GetFirstEmptyID();
        CommunicationEvents.AddFactEvent.Invoke(this.AddPointFact(hit, idB));
        Facts[idB].Representation.GetComponentInChildren<Collider>().enabled = true;
        //third point with unknown height
        int idC = this.GetFirstEmptyID();
        var skyHit = hit;
        skyHit.point = (Facts[idA] as PointFact).Point+ Vector3.up * 20;
        CommunicationEvents.AddFactEvent.Invoke(this.AddPointFact(skyHit, idC));
        //lines
        CommunicationEvents.AddFactEvent.Invoke(this.AddLineFact(idA, idB, this.GetFirstEmptyID()));
        //lines
        CommunicationEvents.AddFactEvent.Invoke(this.AddLineFact(idA, idC, this.GetFirstEmptyID()));
        //90degree angle
        CommunicationEvents.AddFactEvent.Invoke(this.AddAngleFact(idB, idA, idC, GetFirstEmptyID()));
    public void OnHit(RaycastHit hit)
    {
John Schihada's avatar
John Schihada committed
        switch (ActiveToolMode)
John Schihada's avatar
John Schihada committed
            //If Left-Mouse-Button was pressed in MarkPointMode
            case ToolMode.MarkPointMode:
                CommunicationEvents.AddFactEvent.Invoke(this.AddPointFact(hit, this.GetFirstEmptyID()));
                break;
            //If Left-Mouse-Button was pressed in CreateLineMode
            case ToolMode.CreateLineMode:
                //Check if an existing Point was hit
                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point"))
                {
                    Fact tempFact = Facts[hit.transform.GetComponent<FactObject>().Id];
John Schihada's avatar
John Schihada committed
                    if (this.lineModeIsFirstPointSelected)
John Schihada's avatar
John Schihada committed
                        //Event for end of line-drawing in "ShinyThings"
                        CommunicationEvents.StopLineDrawingEvent.Invoke(null);
John Schihada's avatar
John Schihada committed
                        //Create LineFact
John Schihada's avatar
John Schihada committed
                        CommunicationEvents.AddFactEvent.Invoke(this.AddLineFact(this.lineModeFirstPointSelected.Id, tempFact.Id, this.GetFirstEmptyID()));
                        this.lineModeIsFirstPointSelected = false;
                        this.lineModeFirstPointSelected = null;
John Schihada's avatar
John Schihada committed
                    else
                    {
                        //Activate LineDrawing for preview
                        this.lineModeIsFirstPointSelected = true;
                        this.lineModeFirstPointSelected = tempFact;
                        //Event for start line-drawing in "ShinyThings"
                        CommunicationEvents.StartLineDrawingEvent.Invoke(this.lineModeFirstPointSelected);
                //if we want to spawn a new point
                else if (Input.GetKey(KeyCode.LeftShift))
                {
                    if (this.lineModeIsFirstPointSelected)
                    {

                        CommunicationEvents.StopLineDrawingEvent.Invoke(null);
                        SmallRocket(hit, this.lineModeFirstPointSelected.Id);
                        this.lineModeIsFirstPointSelected = false;
                        this.lineModeFirstPointSelected = null;
                    }
                }

                //if we hit the top snap zone
                else if (hit.transform.gameObject.tag=="SnapZone")
                {
                    if (this.lineModeIsFirstPointSelected)
                    {

                        RaycastHit downHit;

                        if (Physics.Raycast(hit.transform.gameObject.transform.position-Vector3.down*2,Vector3.down, out downHit))
                        {
                            int idA = downHit.transform.gameObject.GetComponent<FactObject>().Id;
                            int idB = this.lineModeFirstPointSelected.Id;
                            int idC = GetFirstEmptyID();
                            CommunicationEvents.AddFactEvent.Invoke(this.AddPointFact(hit, idC));
                            //Event for end of line-drawing in "ShinyThings"
                            CommunicationEvents.StopLineDrawingEvent.Invoke(null);
                            //Create LineFact
                            CommunicationEvents.AddFactEvent.Invoke(this.AddAngleFact(idA, idB, idC, GetFirstEmptyID()));
                            this.lineModeIsFirstPointSelected = false;
                            this.lineModeFirstPointSelected = null;
                        }
                    }
                }

                //If no Point was hit
John Schihada's avatar
John Schihada committed
                else
                {
                    if (this.lineModeIsFirstPointSelected)
John Schihada's avatar
John Schihada committed
                        //Deactivate LineDrawing and first point selection
                        this.lineModeIsFirstPointSelected = false;
                        this.lineModeFirstPointSelected = null;
                        //Event for end of line-drawing in "ShinyThings"
                        CommunicationEvents.StopLineDrawingEvent.Invoke(null);
John Schihada's avatar
John Schihada committed
                    //TODO: Hint that only a line can be drawn between already existing points
                }
                break;
            //If Left-Mouse-Button was pressed in CreateAngleMode
            case ToolMode.CreateAngleMode:
                //Check if an existing Point was hit
                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point"))
John Schihada's avatar
John Schihada committed
                {
                    Fact tempFact = Facts[hit.transform.GetComponent<FactObject>().Id];

                    //If two points were already selected and now the third point got selected
                    if (this.angleModeIsFirstPointSelected && this.angleModeIsSecondPointSelected)
John Schihada's avatar
John Schihada committed
                    {
                        //Event for end of curve-drawing in "ShinyThings"
John Schihada's avatar
John Schihada committed
                        CommunicationEvents.StopCurveDrawingEvent.Invoke(null);
                        //Create AngleFact
                        //Check if new Point is equal to one of the previous points -> if true -> cancel
                        if (!(angleModeFirstPointSelected.Id == tempFact.Id || angleModeSecondPointSelected.Id == tempFact.Id))
                            CommunicationEvents.AddFactEvent.Invoke(this.AddAngleFact(((PointFact)angleModeFirstPointSelected).Id, ((PointFact)angleModeSecondPointSelected).Id, ((PointFact)tempFact).Id, GetFirstEmptyID()));
                        this.angleModeIsFirstPointSelected = false;
                        this.angleModeFirstPointSelected = null;
                        this.angleModeIsSecondPointSelected = false;
                        this.angleModeSecondPointSelected = null;
John Schihada's avatar
John Schihada committed
                    }
                    //If only one point was already selected
                    else if (this.angleModeIsFirstPointSelected && !this.angleModeIsSecondPointSelected) {
                        //Check if the 2 selected points are the same: If not
                        if (this.angleModeFirstPointSelected.Id != tempFact.Id)
                        {
                            this.angleModeIsSecondPointSelected = true;
                            this.angleModeSecondPointSelected = tempFact;

                            //Event for start of curve-drawing in "ShinyThings"
                            //Create new LineFact with the 2 points
                            LineFact tempLineFact = new LineFact();
                            tempLineFact.Pid1 = this.angleModeFirstPointSelected.Id;
                            tempLineFact.Pid2 = this.angleModeSecondPointSelected.Id;
                            CommunicationEvents.StartCurveDrawingEvent.Invoke(tempLineFact);
                        }
                        else {
                            this.angleModeFirstPointSelected = null;
                            this.angleModeIsFirstPointSelected = false;
                        }
                    }
                    //If no point was selected before
John Schihada's avatar
John Schihada committed
                    else
                    {
                        //Save the first point selected
                        this.angleModeIsFirstPointSelected = true;
                        this.angleModeFirstPointSelected = tempFact;
John Schihada's avatar
John Schihada committed
                else
                {
                    if (this.angleModeIsFirstPointSelected && this.angleModeIsSecondPointSelected)
John Schihada's avatar
John Schihada committed
                    {
                        //Event for end of curve-drawing in "ShinyThings"
John Schihada's avatar
John Schihada committed
                        CommunicationEvents.StopCurveDrawingEvent.Invoke(null);
                    }

                    //Reset Angle-Preview-Attributes
                    this.angleModeIsFirstPointSelected = false;
                    this.angleModeFirstPointSelected = null;
                    this.angleModeIsSecondPointSelected = false;
                    this.angleModeSecondPointSelected = null;

                    //TODO: Hint that only an angle can be created between 3 already existing points
John Schihada's avatar
John Schihada committed
                }
John Schihada's avatar
John Schihada committed
                break;
            //If Left-Mouse-Button was pressed in DeleteMode
            case ToolMode.DeleteMode:
                //Search for the Fact that was hit
                //If the hit GameObject was a Point/Line/Angle
John Schihada's avatar
John Schihada committed
                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point") || hit.transform.gameObject.layer == LayerMask.NameToLayer("Line") || hit.transform.gameObject.layer == LayerMask.NameToLayer("Angle"))
                {
John Schihada's avatar
John Schihada committed
                    //Search for the suitable fact from the List
                    this.DeleteFact(Facts.Find(x => x.Id == hit.transform.GetComponent<FactObject>().Id));
John Schihada's avatar
John Schihada committed
                }
                break;
            //If Left-Mouse-Button was pressed in ExtraMode
            case ToolMode.ExtraMode:
                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point")) {
                    var menu = GameObject.Instantiate(SmartMenu);
                    menu.GetComponent<SmartMenu>().FactManager = this;
John Schihada's avatar
John Schihada committed
                    menu.GetComponent<Canvas>().worldCamera = Camera.main;
                    menu.transform.SetParent(hit.transform);
                    menu.transform.localPosition = Vector3.up - Camera.main.transform.forward;
                }
                else
                {
                    PointFact fact = AddPointFact(hit, GetFirstEmptyID());
                    CommunicationEvents.AddFactEvent.Invoke(fact);
                }
                break;