//----------------------------------------------------------------
 //determines the action to be preformed for special cases...that is objects or screen models that
 private void DetermineAction()
 {
     //this if determines if the object in front of the users is a special case (a subclass of the ScreenModel Class)
     ScreenModel SpecialObject = ObjectIsInfront();
     if (SpecialObject != null)
     {
         if (SpecialObject.GetType() != typeof(ScreenModel))
         {
             //gets the action key from the user
             if (((LastMouseState.LeftButton != Mouse.GetState().LeftButton) && (Mouse.GetState().LeftButton == ButtonState.Pressed)) ||
                 ((GamePad.GetState(PlayerIndexValue).IsConnected) && (((GamePad.GetState(PlayerIndexValue).IsButtonDown(Buttons.Y)) && (!GamePadLastState.IsButtonDown(Buttons.Y))))))
             {
                 //switch back reticle, unless dictated by this special method
                 this.ReticleToDraw = SpecialObject.SpecialReticle();
                 //special case of a wall; you can change the wall in forge but not in regular mode
                 if (SpecialObject.GetType() == typeof(Wall))
                     this.ReticleToDraw = ((Wall)SpecialObject).SpecialReticle(IsForgeModeRunning);
                 //not sure why nick did this...but w/e...maybe he just doesn't get polymorphism yet
                 else if (SpecialObject.GetType() == typeof(Door))
                     ((Door)SpecialObject).Action(Content, VisibleObjects, graphics,this);
                 else
                     SpecialObject.Action(this.CurrentRoom, Content, models, graphics);
             }
         }
     }
 }
        //--------------------------------------------------------------------------------------------------------------
        //----------------------------------------------------------------------
        //method that checks if the object is visibly in front of the user
        //when the bool argument is true, it will return values/change the reticle based on an object that has a special action,
        //not whether or not it should be picked up
        public ScreenModel ObjectIsInfront()
        {
            //******CONCEPT: *********
            //1) "Highlights" a single possible object that can be picked up
            //this should be the object that best lines up with the center of the reticle
            ScreenModel TestModel = null;
            //Takes the list of a few objects within the threshold and finds the one that is the shortest distance away
            float? ClosestDist = float.MaxValue;
            //list of screen models that
            ScreenModel TestModelClosest = null;
            //distance between objects, if found
            float? Distance = 0f;
            Ray TestRay = new Ray(CameraPosition, CameraAngle3);
            //Console.WriteLine(TestRay.ToString());
            for (int cntr = 0; cntr < this.NearObjects.Count; cntr++)

            {
                if (((NearObjects[cntr].PickUpable) || (NearObjects[cntr].GetType() == typeof(Door)) || (NearObjects[cntr].GetType() == typeof(ComputerConsole))) || IsForgeModeRunning)
                if (this.NearObjects[cntr].CollisionType == ObjectTypes.Box)
                {
                    //checks bounding boxes, if applicable
                    if (this.NearObjects[cntr].GetType() == typeof(Wall))
                    {
                        foreach (OrientedBoundingBox Box in NearObjects[cntr].MovingBoxes)
                            if ((Distance = Box.Intersects(TestRay)) != null)
                            {
                                TestModel = this.NearObjects[cntr];
                                //3) Checks to see if the object is within a specified distance away using a ray
                                //Uses the position of the model and a direction vector (in front of the camera) to find distance away
                                if ((TestModelClosest != null) && (TestModelClosest.GetType() == typeof(Wall)) && (DataValues.VectorDistance(TestModelClosest.MovingBoxes[0].HalfExtent) > DataValues.VectorDistance(Box.HalfExtent)))
                                {
                                    //stores the closest of the models at the same time as finding models that
                                    //are within the threshold; more effecient than going through yet another list
                                    TestModelClosest = TestModel;
                                    ClosestDist = Distance - DataValues.VectorDistance(Box.HalfExtent);
                                    break;
                                }
                                if ((Distance - DataValues.VectorDistance(Box.HalfExtent) <= DataValues.MaxObjectDistance) && (Distance - DataValues.VectorDistance(Box.HalfExtent) < ClosestDist))
                                {
                                    //stores the closest of the models at the same time as finding models that
                                    //are within the threshold; more effecient than going through yet another list
                                    TestModelClosest = TestModel;
                                    ClosestDist = Distance - DataValues.VectorDistance(Box.HalfExtent);
                                    break;
                                }
                            }
                    }
                    else
                            if (((Distance = this.NearObjects[cntr].GetBoundingBoxes().Intersects(TestRay)) != null))
                            {
                                TestModel = this.NearObjects[cntr];
                                //3) Checks to see if the object is within a specified distance away using a ray
                                //Uses the position of the model and a direction vector (in front of the camera) to find distance away
                                if((TestModelClosest!=null)&&(TestModelClosest.GetType()==typeof(Wall))&&(DataValues.VectorDistance(TestModelClosest.MovingBoxes[0].HalfExtent)>Distance))
                                {
                                    TestModelClosest = TestModel;
                                    ClosestDist = Distance;
                                    break;
                                }
                                if ((Distance <= DataValues.MaxObjectDistance) && (Distance < ClosestDist))
                                {
                                    //stores the closest of the models at the same time as finding models that
                                    //are within the threshold; more effecient than going through yet another list
                                    TestModelClosest = TestModel;
                                    ClosestDist = Distance;
                                    break;
                                }
                            }
                }
                //idk if we still use this but let's just leave it in case...
                else
                {
                    if (TestRay.Intersects(this.NearObjects[cntr].GetBoundingSpheres()) != null)
                    {
                        TestModel = this.NearObjects[cntr];
                        Distance = TestRay.Intersects(TestModel.GetBoundingSpheres());
                        if ((Distance <= DataValues.MaxObjectDistance) && (Distance < ClosestDist))
                        {
                            //stores the closest of the models at the same time as finding models that
                            //are within the threshold; more effecient than going through yet another list
                            TestModelClosest = TestModel;
                            ClosestDist = Distance;
                        }
                    }
                }
            }
            //after one has found the closest, re-assing test model
            TestModel = TestModelClosest;
            //2) Checks object to see if it is of pickupable type
            //or if it's a special object with an action
            if (TestModel == null)
            {
                //object cannot be picked up
                this.ReticleToDraw = DataValues.ReticleType.Normal;
                return (null);
            }
            //Console.WriteLine(TestModel.GetType().ToString());
            //checks if it is in that distance...and is a regular screem model object
            if ((ClosestDist <= DataValues.MaxObjectDistance) && ((TestModel.GetType() == typeof(ScreenModel)) || (TestModel.GetType() == typeof(Wall))) && (TestModel.PickUpable == true))
            {
                //object can be picked up, change the reticle
                this.ReticleToDraw = DataValues.ReticleType.ObjectPickup;
                //return the model
                return (TestModel);
            }
            //checks if it is in that distance if it's a special screen model object
            if ((ClosestDist <= DataValues.MaxObjectDistance) && ((TestModel.GetType() != typeof(ScreenModel)) || (TestModel.GetType() != typeof(Wall))))
            {
                //changes color while holding the object
                this.ReticleToDraw = DataValues.ReticleType.ActionBtn;
                //you can only edit walls in forge world...this hides the reticle when the user is not in forge world
                if (TestModel.GetType() == typeof(Wall))
                    this.ReticleToDraw = ((Wall)TestModel).SpecialReticle(IsForgeModeRunning);
                //return the model
                return (TestModel);
            }
            //or return nothing, our friend null, which will cause an exception to be caught, acting as a general check
            //object cannot be picked up
            if (!this.HoldingObjectTrue)
                this.ReticleToDraw = DataValues.ReticleType.Normal;
            return (null);
        }
        //----------------------------------------------------------------
        //method that allows the user to pick up objects
        public void PickUpObject()
        {
            HoldingObject.Velocity = Vector3.Zero;
            //tells the object that it is being held
            HoldingObject.IsBeingHeld = true;
            HoldingObjectTrue = true;
            float Distance=4f;
            if (this.HoldingObjectDistanceSet)
                if (HoldingObject.CollisionType == ObjectTypes.Box)
                {
                    if (DataValues.VectorDistance(HoldingObject.GetBoundingBoxes().Max - HoldingObject.Position) + 4 > Distance)
                        Distance = 4f + DataValues.VectorDistance(HoldingObject.GetBoundingBoxes().Max - HoldingObject.Position);
                }
                else
                {
                    foreach (ModelMesh Mesh in HoldingObject.MyModel.Meshes)
                        if (Mesh.BoundingSphere.Radius + 4 > Distance)
                            Distance = 4f + Mesh.BoundingSphere.Radius;
                }
            else
                Distance = DataValues.VectorDistance(CameraPosition - HoldingObject.Position - Velocity);
            //Ray TestRay = new Ray(CameraPosition, CameraAngle3);
            HoldingObject.Position = CameraPosition + (Distance * CameraAngle3);

            //HoldingObject.MoveModelBox(Position-HoldingObject.Position);

            //moves model box if this is a box colliding type
            if (HoldingObject.CollisionType == ObjectTypes.Box)
            {
                //first time the last position has to be tracked
                HoldingObjectLastPos = HoldingObject.Position;
            }

            //changes color while holding the object
            this.ReticleToDraw = DataValues.ReticleType.HoldingObj;
        }
        //method that allows the user to drop objects
        public void DropObject()
        {
            //tells the object that it is not being held
            HoldingObject.IsBeingHeld = false;
            //the object is no longer being held
            HoldingObjectTrue = false;
            //set the object to fall; this will be picked up in the update method for this object and thus independent from the user's control
            HoldingObject.IsCurrentlyFalling = true;

            //recreates a bounding box if needed (but bounding sphere always works)
            if (HoldingObject.CollisionType == ObjectTypes.Box)
            {
                //anthony's much easier version
                HoldingObject.BoundingSetup();

                //correction for position
                //---------------------------------------------
                //methods that handle rotation of the bounding box
                //HoldingObject.ConverToOBB();
                //HoldingObject.ConverToABB();
                /*
                //takes the initial position of the bounding box (when loaded)
                Vector3 ChangeVect = HoldingObject.Position - HoldingObject.LocalPos;
                //translates the change for the bounding box
                HoldingObject.MovingBox.Min += ChangeVect;
                HoldingObject.MovingBox.Max += ChangeVect;
                */
                //restores that initial box (current position)
                //HoldingObject.LocalPos = HoldingObject.Position;
                //HoldingObject.LocalBox = HoldingObject.MovingBox;
                //---------------------------------------------
            }
            //changes color back to white...which will get changed next loop cycle anyway....
            this.ReticleToDraw = DataValues.ReticleType.Normal;
        }