public static bool SlotIsValid(int slot, List <Marble> marbles, out Marble marbleToBeRemoved) { marbleToBeRemoved = null; if (Selected == null || SlotContainsMarble(slot, marbles) != false) { return(false); } int nextSlot = NextSlotRight(slot) ?? -1; if ((marbleToBeRemoved = GetMarbleInSlot(nextSlot, marbles)) != null && Selected == GetMarbleInSlot(NextSlotRight(nextSlot) ?? -1, marbles)) { return(true); } nextSlot = NextSlotUp(slot) ?? -1; if ((marbleToBeRemoved = GetMarbleInSlot(nextSlot, marbles)) != null && Selected == GetMarbleInSlot(NextSlotUp(nextSlot) ?? -1, marbles)) { return(true); } nextSlot = NextSlotLeft(slot) ?? -1; if ((marbleToBeRemoved = GetMarbleInSlot(nextSlot, marbles)) != null && Selected == GetMarbleInSlot(NextSlotLeft(nextSlot) ?? -1, marbles)) { return(true); } nextSlot = NextSlotDown(slot) ?? -1; if ((marbleToBeRemoved = GetMarbleInSlot(nextSlot, marbles)) != null && Selected == GetMarbleInSlot(NextSlotDown(nextSlot) ?? -1, marbles)) { return(true); } return(false); }
public static bool?SlotContainsMarble(int slot, List <Marble> marbles, out Marble marble) { if (slot < 0 || slot >= STARTING_COUNT) { marble = null; return(null); } foreach (Marble m in marbles) { if (m.PositionSlot == slot && m.Alive) { marble = m; return(true); } } marble = null; return(false); }
public static bool UpdateAllSlots(int shaderID, int mouseX, int mouseY, ref Inp.KeyboardState newKeyboardState, ref Inp.MouseState newMouseState, ref Inp.MouseState oldMouseState, MarbleSelection marbleSelection, Rectangle clientRectangle, Camera camera, ref Matrix4 projection, ref Matrix4 view, List <Marble> marbles, List <MarbleMove> moves, ref int undoLevel, bool spinningMarbles, bool animateMoves, ref Marble lastMarbleRemovedForWin) { if (Game.FlashTicksAreAscending) { Game.FlashTicks++; if (Game.FlashTicks > Game.MAX_FLASH_TICKS) { Game.FlashTicks -= 2; Game.FlashTicksAreAscending = false; } } else { Game.FlashTicks--; if (Game.FlashTicks < 0) { Game.FlashTicks = 1; Game.FlashTicksAreAscending = true; } } if (Selected != null) { SelectionAnimationTick++; if (SelectionAnimationTick > MAX_SELECTION_ANIMATION_TICK) { SelectionAnimationTick = 0; } } Marble oldSelected = Selected; for (int i = 1; i < Game.LIGHT_COUNT; i++) { Game.SetLightEnabled(shaderID, i, false); } HighlightedSlot = null; if (marbleSelection == MarbleSelection.None || (marbleSelection == MarbleSelection.Mouse && (mouseX < 0 || mouseY < 0 || mouseX > clientRectangle.Width || mouseY > clientRectangle.Height))) { foreach (Marble m in marbles) { m.Update(shaderID, spinningMarbles); } return(false); } Marble highlightedMarble = null; float closestMarbleDistance = float.MaxValue; float distance = float.NaN; //Vector2 mousePosNDC = MousePositionInNDC(); //float rotY = (float)Math.Atan(-mousePosNDC.Y * Math.Tan(VerticalFieldOfView / 2f)); //float rotX = -(float)Math.Atan(mousePosNDC.X * Math.Tan(HorizontalFieldOfView(VerticalFieldOfView) / 2f)); //float rot = (float)Math.Atan(mousePosNDC.Length * (float)Math.Tan(VerticalFieldOfView / 2f)); //float rotY = (float)Math.Atan(-mousePosNDC.Y * (float)Math.Tan(VerticalFieldOfView / 2f)); //float rotX = -(float)Math.Atan(mousePosNDC.X * (float)Math.Tan(HorizontalFieldOfView(VerticalFieldOfView) / 2f)); //Matrix4 xRotation = Matrix4.CreateFromAxisAngle(CameraUp(), rotX); //Vector3 ray = Vector3.Transform(CameraForward(), xRotation); //ray = Vector3.Transform(ray, Matrix4.CreateFromAxisAngle(CameraRight(), rotY)); //Vector3 ray = Vector3.TransformPerspective(CameraForward(), Matrix4.CreateFromAxisAngle(CameraUp(), rotX) * Matrix4.CreateFromAxisAngle(CameraRight(), rotY)); Vector3 ray; if (marbleSelection == MarbleSelection.Mouse) { ray = Utils.MousePickRay(mouseX, mouseY, clientRectangle, ref projection, ref view); } else { ray = camera.Forward; } bool pickHad = false; //Vector3 ray = Vector3.Transform(CameraForward(), Matrix4.CreateRotationZ(HorizontalFieldOfView(VerticalFieldOfView) / 2f)); //Vector3 ray = Vector3.Transform(CameraForward(), Matrix4.CreateRotationZ(MousePositionInNDC().X * -(float)Math.Tan(HorizontalFieldOfView(VerticalFieldOfView) / VerticalFieldOfView / MathHelper.PiOver2))); List <int> emptySlots = new List <int>(); for (int i = 0; i < STARTING_COUNT; i++) { emptySlots.Add(i); } Vector3 raySource = marbleSelection == MarbleSelection.Mouse ? camera.Position : camera.FocusPoint; foreach (Marble m in marbles) { if (!m.Alive) { continue; } emptySlots.Remove(m.PositionSlot); Vector3 marblePos = m.Position(); if (MouseIsOver(marblePos, 1f, raySource, ray, ref distance, closestMarbleDistance)) { pickHad = true; highlightedMarble = m; HighlightedSlot = m.PositionSlot; closestMarbleDistance = distance; } } if (Selected != null) { emptySlots.RemoveAll(i => !SlotIsValid(i, marbles)); foreach (int i in emptySlots) { if (MouseIsOver(Position(i), 0.375f, raySource, ray, ref distance, closestMarbleDistance)) { pickHad = true; highlightedMarble = null; HighlightedSlot = i; closestMarbleDistance = distance; } } if (!pickHad) { foreach (int i in emptySlots) { if (MouseIsOver(Position(i), 1f, raySource, ray, ref distance, closestMarbleDistance)) { //pickHad = true; HighlightedSlot = i; closestMarbleDistance = distance; } } } } bool moveMade = false; if (newMouseState.LeftButton == Inp.ButtonState.Pressed && oldMouseState.LeftButton == Inp.ButtonState.Released) { if (HighlightedSlot != null) { bool shift = newKeyboardState.IsKeyDown(Inp.Key.ShiftLeft) || newKeyboardState.IsKeyDown(Inp.Key.ShiftRight); //marbles.Remove(GetMarbleInSlot(HighlightedSlot.Value, marbles)); Marble marbleToBeRemoved; if (!shift && marbles.Count(m => m.Alive) == STARTING_COUNT) { if (animateMoves) { highlightedMarble.AnimateFromSlot = highlightedMarble.PositionSlot; highlightedMarble.AnimationTick = MAX_ANIMATION_TICKS; highlightedMarble.AnimatingAsInitialRemoval = true; } highlightedMarble.Alive = false; if (undoLevel > 0) { moves.RemoveRange(moves.Count - undoLevel, undoLevel); undoLevel = 0; } moves.Add(new MarbleMove(highlightedMarble.PositionSlot, -1, -1, highlightedMarble.Type)); } else if (SlotIsValid(HighlightedSlot.Value, marbles, out marbleToBeRemoved)) { // Remove a marble if (undoLevel > 0) { moves.RemoveRange(moves.Count - undoLevel, undoLevel); undoLevel = 0; } moves.Add(new MarbleMove(Selected.PositionSlot, marbleToBeRemoved.PositionSlot, HighlightedSlot.Value, marbleToBeRemoved.Type)); if (animateMoves) { Selected.AnimateFromSlot = Selected.PositionSlot; Selected.AnimationTick = 0; marbleToBeRemoved.AnimateFromSlot = marbleToBeRemoved.PositionSlot; marbleToBeRemoved.AnimationTick = 0; } Selected.PositionSlot = HighlightedSlot.Value; marbleToBeRemoved.Alive = false; moveMade = true; //if (!Selected.CanMove(marbles)) Selected = null; if (marbles.Count(m => m.Alive) == 1) { lastMarbleRemovedForWin = marbleToBeRemoved; } } else if (shift) { camera.FocusPoint = highlightedMarble.Position(); } else if (highlightedMarble == Selected) { Selected = null; } else { Selected = highlightedMarble; } } else { Selected = null; } } foreach (Marble m in marbles) { m.Update(shaderID, spinningMarbles); } if (Selected != oldSelected) { SelectionAnimationTick = 0; } return(moveMade); }