Example #1
0
        /// <summary>
        /// Inverts the given color
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public static Color Invert(this Color col)
        {
            col.R = (byte)FastMath.FastClamp(255 - col.R, 0, 255);
            col.G = (byte)FastMath.FastClamp(255 - col.G, 0, 255);
            col.B = (byte)FastMath.FastClamp(255 - col.B, 0, 255);

            return(col);
        }
Example #2
0
        public Player(ulong id) : base(id, Vector3.Zero)
        {
            base.eyePosition = new Vector3(0, 1.45f, 0);
            _coll            = BoundingBoxExtensions.FromSize(.6f, 1.8f, 0.6f);
            inventory        = new Inventory(9 * 4 + 4 + 1);      //Inventory storage + armor + offhand

            //init inventory
            for (int i = 0; i < inventory.items.Length; i++)
            {
                inventory.items[i].ItemCount = 1;
                inventory.items[i].ItemID    = (ushort)FastMath.FastClamp(i + 1, 0, 7);
            }
        }
        public void Rotate(float xAxis, float yAxis)
        {
            if (!float.IsNaN(xAxis))
            {
                Yaw += xAxis;
            }

            if (!float.IsNaN(Yaw))
            {
                Pitch = FastMath.FastClamp(Pitch + yAxis, -1.547501f, 1.532499f);
            }

            //Check angles

            /*float x = rotation.X % 360;
            *  float y = rotation.Y % 360;
            *  float z = rotation.Z % 360;*/
        }
        public override void Draw()
        {
            if (base.screenVisible)
            {
                _size = UiStateManager.MeasureString(text);

                UiTexture img = TextureManager.GetUiUv("button_disabled");
                UiStateManager.Draw9SplicedButton(img, this);

                //Draw the button
                if (enabled)
                {
                    img = TextureManager.GetUiUv("button_neutral");
                    if (isHovered && Parent.FocusedComponent != null && Parent.FocusedComponent == this)
                    {
                        if (isClicked)
                        {
                            img = TextureManager.GetUiUv("button_clicked");
                        }
                        else
                        {
                            img = TextureManager.GetUiUv("button_hover");
                        }
                    }
                    if (isSliding)
                    {
                        UiStateManager.Draw9SplicedButton(img, new Point(HandleWidth * GameSettings.UIScale, size.Y), new Point(FastMath.FastClamp(InputManager.MouseX + MouseOffset.X, location.X, location.X + size.X - HandleWidth * GameSettings.UIScale), location.Y));
                    }
                    else
                    {
                        //location.X = component.location.X + % of slider value * component.size.X
                        handleX = FastMath.FastClamp(location.X + (_value * size.X / (_maxValue - _minValue)), location.X, location.X + size.X - HandleWidth * GameSettings.UIScale);
                        UiStateManager.Draw9SplicedButton(img, new Point(HandleWidth * GameSettings.UIScale, size.Y), new Point(handleX, location.Y));
                    }
                    UiStateManager.DrawText(location.X + size.X / 2 - _size.X / 2, location.Y + size.Y / 2 - _size.Y / 2, buttonColor, text);
                }
                else
                {
                    UiStateManager.Draw9SplicedButton(img, new Point(HandleWidth * GameSettings.UIScale, size.Y), new Point(FastMath.FastClamp(location.X + (_value * size.X / (_maxValue - _minValue)), location.X, location.X + size.X - HandleWidth * GameSettings.UIScale), location.Y));
                    UiStateManager.DrawText(location.X + size.X / 2 - _size.X / 2, location.Y + size.Y / 2 - _size.Y / 2, buttonDisabledColor, text);
                }
            }
        }
Example #5
0
        public void DrawText(string text, Color color, int leftMostCharacter, int caretPosition, bool CaretVisible)
        {
            string finalString = text.Substring(leftMostCharacter);

            DrawStringClip(size.X - 2 * paddingX + location.X, UiStateManager.gameFont, finalString,
                           new Vector2(location.X + paddingX * GameSettings.UIScale, location.Y + paddingY * GameSettings.UIScale), color,
                           0.0f, Vector2.Zero, new Vector2(GameSettings.UITextScale), SpriteEffects.None, 0);

            if (CaretVisible)
            {
                Vector2 textWidth = UiStateManager.gameFont.MeasureString("L");

                UiStateManager.DrawImage(new Rectangle(
                                             location.X + paddingX * GameSettings.UIScale +
                                             (int)UiStateManager.gameFont.MeasureString(text.Substring(leftMostCharacter, caretPosition - leftMostCharacter)).X, //Width

                                             location.Y + paddingY,
                                             2 * GameSettings.UIScale,
                                             FastMath.FastClamp((int)(textWidth.Y * GameSettings.UIScale), 0, size.Y - 2 * paddingY)),

                                         TextureLoader.getWhitePixel(),
                                         placeholderColor);
            }
        }
Example #6
0
        public void GetCaretUnderMouse()
        {
            //Calculate the character index of where we clicked
            int relativeX = InputManager.MouseX - location.X;             //mouse relative to the textbox

            //now that we have the position of the cursor, calculate the index of the caret
            //get the string on screen
            string renderStr = text.Substring(scrollPosition);

            int selectedIndex = scrollPosition;

            for (int i = 0; i < renderStr.Length; i++)
            {
                var txVisible   = renderStr.Substring(0, i + 1);
                var currentChar = renderStr.Substring(i, FastMath.FastClamp(i + 1, 0, 1));

                var txtSize   = UiStateManager.MeasureString(txVisible);
                var charWidth = UiStateManager.MeasureString(currentChar);

                if (txtSize.X + charWidth.X < relativeX)
                {
                    selectedIndex++;
                }
                if (txtSize.X + charWidth.X >= relativeX)
                {
                    this.caretPosition = selectedIndex;
                    break;
                }

                if (i == renderStr.Length - 1)
                {
                    this.caretPosition = renderStr.Length;
                    break;
                }
            }
        }
        public void Update()
        {
            try
            {
                long ProcessingTime = 0L;

                while (ThreadManager.RunChunkManagerThread)
                {
                    ProcessingTime = (long)DateTime.UtcNow.TimeOfDay.TotalMilliseconds;
                    Profiler.Start("Chunk Manager Update", Color.MediumPurple);

                    #region Legacy Infinite Terrain Code

                    //Update the tick counters

                    //Handle loading and unloading

                    //First unload all bad chunks
                    //Bad being they are too far away
                    //Also keep them in a temporary Vector3Int array representing chunk positions of loaded chunks

                    #region Block Updates
                    //Sync block updates
                    lock (updates)
                    {
                        lock (LoadedChunkPositions)
                        {
                            Logger.info(-1, "Update Count: " + updates.Count);

                            updatedBlocks = !(updates.Count == 0);
                            for (int i = 0; i < updates.Count; i++)
                            {
                                int targetX = int.MinValue, targetY = int.MinValue, targetZ = int.MinValue;

                                #region Chunk Hedging

                                if (updates[i].X == 0)
                                {
                                    targetX = updates[i].ChunkPos.X - 1;
                                    targetY = targetY == int.MinValue ? updates[i].ChunkPos.Y : targetY;
                                    targetZ = targetZ == int.MinValue ? updates[i].ChunkPos.Z : targetZ;
                                }
                                if (updates[i].X == Chunk.CHUNK_SIZE - 1)
                                {
                                    targetX = updates[i].ChunkPos.X + 1;
                                    targetY = targetY == int.MinValue ? updates[i].ChunkPos.Y : targetY;
                                    targetZ = targetZ == int.MinValue ? updates[i].ChunkPos.Z : targetZ;
                                }

                                if (updates[i].Y == 0)
                                {
                                    targetX = targetX == int.MinValue ? updates[i].ChunkPos.X : targetX;
                                    targetY = updates[i].ChunkPos.Y - 1;
                                    targetZ = targetZ == int.MinValue ? updates[i].ChunkPos.Z : targetZ;
                                }
                                if (updates[i].Y == Chunk.CHUNK_SIZE - 1)
                                {
                                    targetX = targetX == int.MinValue ? updates[i].ChunkPos.X : targetX;
                                    targetY = updates[i].ChunkPos.Y + 1;
                                    targetZ = targetZ == int.MinValue ? updates[i].ChunkPos.Z : targetZ;
                                }

                                if (updates[i].Z == 0)
                                {
                                    targetX = targetX == int.MinValue ? updates[i].ChunkPos.X : targetX;
                                    targetY = targetY == int.MinValue ? updates[i].ChunkPos.Y : targetY;
                                    targetZ = updates[i].ChunkPos.Z - 1;
                                }
                                if (updates[i].Z == Chunk.CHUNK_SIZE - 1)
                                {
                                    targetX = targetX == int.MinValue ? updates[i].ChunkPos.X : targetX;
                                    targetY = targetY == int.MinValue ? updates[i].ChunkPos.Y : targetY;
                                    targetZ = updates[i].ChunkPos.Z + 1;
                                }
                                #endregion

                                Vector3Int targetPosX = new Vector3Int(targetX, updates[i].ChunkPos.Y, updates[i].ChunkPos.Z);
                                Vector3Int targetPosY = new Vector3Int(updates[i].ChunkPos.X, targetY, updates[i].ChunkPos.Z);
                                Vector3Int targetPosZ = new Vector3Int(updates[i].ChunkPos.X, updates[i].ChunkPos.Y, targetZ);

                                if (LoadedChunkPositions.Contains(updates[i].ChunkPos))
                                {
                                    if (chunks[ChunkIndexMapping[updates[i].ChunkPos]].isLoaded && chunks.Count <= ChunkIndexMapping[updates[i].ChunkPos])
                                    {
                                        chunks[ChunkIndexMapping[updates[i].ChunkPos]].SetBlock(updates[i].BlockID, updates[i].X, updates[i].Y, updates[i].Z, updates[i].Reason);
                                    }
                                }

                                if (LoadedChunkPositions.Contains(targetPosX))
                                {
                                    if (chunks[ChunkIndexMapping[targetPosX]].isLoaded && chunks.Count <= ChunkIndexMapping[targetPosX])
                                    {
                                        chunks[ChunkIndexMapping[targetPosX]].UpdateNeeded = true;
                                    }
                                }

                                if (LoadedChunkPositions.Contains(targetPosY))
                                {
                                    if (chunks[ChunkIndexMapping[targetPosY]].isLoaded && chunks.Count <= ChunkIndexMapping[targetPosY])
                                    {
                                        chunks[ChunkIndexMapping[targetPosY]].UpdateNeeded = true;
                                    }
                                }

                                if (LoadedChunkPositions.Contains(targetPosZ))
                                {
                                    if (chunks[ChunkIndexMapping[targetPosZ]].isLoaded && chunks.Count <= ChunkIndexMapping[targetPosZ])
                                    {
                                        chunks[ChunkIndexMapping[targetPosZ]].UpdateNeeded = true;
                                    }
                                }
                            }
                            updates.Clear();
                        }
                    }
                    #endregion

                    #region Unloading
                    lock (LoadedChunkPositions)
                    {
                        for (int i = 0; i < chunks.Count; i++)
                        {
                            if (chunks[i].isLoaded)
                            {
                                if (previousPlayerChunk != playerChunk)
                                {
                                    Profiler.Start("Chunk Unload", Color.Red);
                                    //Calculate distance in the form of a cube
                                    Vector3Int chunkPos = new Vector3Int(chunks[i].posX, chunks[i].posY, chunks[i].posZ);

                                    //GameClient.LOGGER.info(0, "Currently dealing with chunk (" + chunkPos.X + " " + chunkPos.Y + " " + chunkPos.Z + ")!");

                                    if (LoadedChunkPositions.Contains(chunkPos) &&
                                        chunkPos.X > playerChunk.X + SimulationDistance || chunkPos.X < playerChunk.X - SimulationDistance - 1 ||
                                        chunkPos.Y > playerChunk.Y + SimulationDistance || chunkPos.Y < playerChunk.Y - SimulationDistance - 1 ||
                                        chunkPos.Z > playerChunk.Z + SimulationDistance || chunkPos.Z < playerChunk.Z - SimulationDistance - 1

                                        //Max world bounds
                                        || chunkPos.X > WorldWidth || chunkPos.X < -WorldWidth - 1 ||
                                        chunkPos.Y > MaxChunksY || chunkPos.Y < 0 ||
                                        chunkPos.Z > WorldWidth || chunkPos.Z < -WorldWidth - 1)
                                    {
                                        UnloadChunk(chunks[i].posX, chunks[i].posY, chunks[i].posZ);
                                    }
                                    else
                                    {
                                        //Add to LoadedChunkPositions
                                        if (!LoadedChunkPositions.Contains(chunkPos))
                                        {
                                            LoadedChunkPositions.Add(chunkPos);
                                        }
                                    }
                                    Profiler.Stop("Chunk Unload");

                                    Profiler.Start("Chunk Manager Update", Color.MediumPurple);

                                    //Update the chunk
                                    chunks[i].Update();
                                }
                            }
                        }
                        #endregion

                        #region Loading
                        //Now that we've unloaded all chunks, we can see which chunks we need to load
                        byte numberOfChunksLoadedThisFrame = 0;

                        //This algorithm loads all chunks on the z axis, then the x axis and lastly the y axis
                        //It only load 1 z layer every frame (a layer is anything from 1 chunk to RENDER_DISTANCE chunks
                        if (numberOfChunksLoaded < SimulationArea + 1)
                        {
                            for (int i = 0; i < LoadDistance; i++)
                            {
                                Profiler.Start("Chunk Load Math", Color.DarkOliveGreen);

                                //Calculate the bounds of chunks that can be loaded
                                int minX = MathHelper.Clamp(playerChunk.X - i, playerChunk.X - SimulationDistance, playerChunk.X + SimulationDistance);
                                int minY = MathHelper.Clamp(playerChunk.Y - i, playerChunk.Y - SimulationDistance, playerChunk.Y + SimulationDistance);
                                int minZ = MathHelper.Clamp(playerChunk.Z - i, playerChunk.Z - SimulationDistance, playerChunk.Z + SimulationDistance);

                                int maxX = MathHelper.Clamp(playerChunk.X + i, playerChunk.X - SimulationDistance, playerChunk.X + SimulationDistance);
                                int maxY = MathHelper.Clamp(playerChunk.Y + i, playerChunk.Y - SimulationDistance, playerChunk.Y + SimulationDistance);
                                int maxZ = MathHelper.Clamp(playerChunk.Z + i, playerChunk.Z - SimulationDistance, playerChunk.Z + SimulationDistance);

                                //World boundaries. Chunks cant be loaded outside these boundaries
                                minX = MathHelper.Clamp(minX, -WorldWidth, WorldWidth);
                                minY = MathHelper.Clamp(minY, 0, MaxChunksY);
                                minZ = MathHelper.Clamp(minZ, -WorldWidth, WorldWidth);

                                maxX = MathHelper.Clamp(maxX, -WorldWidth, WorldWidth);
                                maxY = MathHelper.Clamp(maxY, 0, MaxChunksY);
                                maxZ = MathHelper.Clamp(maxZ, -WorldWidth, WorldWidth);

                                Profiler.Stop("Chunk Load Math");

                                for (int y = minY; y < maxY; y++)
                                {
                                    for (int x = minX; x < maxX; x++)
                                    {
                                        for (int z = minZ; z < maxZ; z++)
                                        {
                                            Profiler.Start("Chunk Load", Color.Ivory);

                                            Vector3Int chunkPos = new Vector3Int(x, y, z);

                                            //Check if we should load this chunk (if its within simulation distance & isn't inside LoadedChunkPositions>)
                                            if (!LoadedChunkPositions.Contains(chunkPos) &&
                                                chunkPos.X < playerChunk.X + SimulationDistance && chunkPos.X > playerChunk.X - SimulationDistance &&
                                                chunkPos.Y < playerChunk.Y + SimulationDistance && chunkPos.Y > playerChunk.Y - SimulationDistance &&
                                                chunkPos.Z < playerChunk.Z + SimulationDistance && chunkPos.Z > playerChunk.Z - SimulationDistance

                                                //Max world bounds
                                                && chunkPos.X < WorldWidth && chunkPos.X > -WorldWidth &&
                                                chunkPos.Y < MaxChunksY && chunkPos.Y > -1 &&
                                                chunkPos.Z < WorldWidth && chunkPos.Z > -WorldWidth)
                                            {
                                                Profiler.Stop("Chunk Load");

                                                //Chunk is unloaded. So load it
                                                Profiler.Start("Chunk Generation", Color.DeepPink);

                                                //Chunk NextChunkToLoad = SolidChunk.Generate(chunkPos.X, chunkPos.Y, chunkPos.Z, 1);
                                                Chunk NextChunkToLoad = FetchChunk(chunkPos.X, chunkPos.Y, chunkPos.Z);
                                                RegisterChunk(NextChunkToLoad);

                                                Profiler.Stop("Chunk Generation");

                                                Profiler.Start("Chunk Load", Color.Ivory);

                                                //RegisterChunk(FetchChunk(chunkPos.X, chunkPos.Y, chunkPos.Z));

                                                numberOfChunksLoaded++;
                                                numberOfChunksLoadedThisFrame++;

                                                Profiler.Stop("Chunk Load");

                                                //If we loaded more than the maximum number of chunks, stop loading chunks this frame to keep a playable framerate
                                                if (numberOfChunksLoadedThisFrame > MaximumChunksToLoadPerFrame)
                                                {
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                Profiler.Stop("Chunk Load");
                                            }
                                        }

                                        //If we loaded more than the maximum number of chunks, stop loading chunks this frame to keep a playable framerate
                                        if (numberOfChunksLoadedThisFrame > MaximumChunksToLoadPerFrame)
                                        {
                                            break;
                                        }
                                    }

                                    //Break the loop if we loaded a single chunk
                                    if (numberOfChunksLoadedThisFrame > 0)
                                    {
                                        break;
                                    }
                                }

                                //Break the loop if we loaded a single chunk
                                if (numberOfChunksLoadedThisFrame > 0)
                                {
                                    break;
                                }
                            }

                            if (numberOfChunksLoadedThisFrame < 1)
                            {
                                LoadDistance++;
                            }
                            if (LoadDistance > SimulationDistance)
                            {
                                LoadDistance = 2;
                            }
                        }
                    }

                    previousPlayerChunk = playerChunk;
                    #endregion

                    #endregion

                    #region Fixed Terrain Code

                    /*byte numberOfChunksLoadedThisFrame = 0;
                     *
                     * //This algorithm loads all chunks on the z axis, then the x axis and lastly the y axis
                     * //It only load 1 z layer every frame (a layer is anything from 1 chunk to RENDER_DISTANCE chunks
                     * if (numberOfChunksLoaded <= SimulationArea)
                     * {
                     *      Profiler.Start("Chunk Load Loop");
                     *
                     *      for (int i = 0; i < LoadDistance; i++)
                     *      {
                     *              Profiler.Start("Chunk Load Math", Color.DarkOliveGreen);
                     *
                     *              //Calculate the bounds of chunks that can be loaded
                     *              int minX = playerChunk.X - i;
                     *              int minY = playerChunk.Y - i;
                     *              int minZ = playerChunk.Z - i;
                     *
                     *              int maxX = playerChunk.X + i;
                     *              int maxY = playerChunk.Y + i;
                     *              int maxZ = playerChunk.Z + i;
                     *
                     *              //World boundaries. Chunks cant be loaded outside these boundaries
                     *              minX = MathHelper.Clamp(minX, -8, 8);
                     *              minY = MathHelper.Clamp(minY, 0, 16);
                     *              minZ = MathHelper.Clamp(minZ, -8, 8);
                     *
                     *              maxX = MathHelper.Clamp(maxX, -8, 8);
                     *              maxY = MathHelper.Clamp(maxY, 0, 16);
                     *              maxZ = MathHelper.Clamp(maxZ, -8, 8);
                     *
                     *              Profiler.Stop("Chunk Load Math");
                     *
                     *              for (int y = minY; y < maxY; y++)
                     *              {
                     *                      for (int x = minX; x < maxX; x++)
                     *                      {
                     *                              for (int z = minZ; z < maxZ; z++)
                     *                              {
                     *                                      Profiler.Start("Chunk Load", Color.Ivory);
                     *
                     *                                      Vector3Int chunkPos = new Vector3Int(x, y, z);
                     *
                     *                                      //Check if we should load this chunk (if its within simulation distance & isn't inside LoadedChunkPositions>)
                     *                                      if (!LoadedChunkPositions.Contains(chunkPos) &&
                     *                                              chunkPos.X < playerChunk.X + SimulationDistance && chunkPos.X > playerChunk.X - SimulationDistance
                     *                                              && chunkPos.Y < playerChunk.Y + SimulationDistance && chunkPos.Y > playerChunk.Y - SimulationDistance
                     *                                              && chunkPos.Z < playerChunk.Z + SimulationDistance && chunkPos.Z > playerChunk.Z - SimulationDistance
                     *
                     *                                              //Max world bounds
                     *                                              && chunkPos.X < WorldWidth && chunkPos.X > -WorldWidth
                     *                                              && chunkPos.Y < MaxChunksY && chunkPos.Y > -1
                     *                                              && chunkPos.Z < WorldWidth && chunkPos.Z > -WorldWidth)
                     *                                      {
                     *                                              //Chunk is unloaded. So load it
                     *                                              Profiler.Start("Chunk Generation", Color.DeepPink);
                     *                                              Chunk NextChunkToLoad = SolidChunk.Generate(chunkPos.X, chunkPos.Y, chunkPos.Z, 1);
                     *                                              RegisterChunk(NextChunkToLoad);
                     *                                              Profiler.Stop("Chunk Generation");
                     *
                     *                                              //RegisterChunk(FetchChunk(chunkPos.X, chunkPos.Y, chunkPos.Z));
                     *
                     *                                              numberOfChunksLoaded++;
                     *                                              numberOfChunksLoadedThisFrame++;
                     *
                     *                                              Profiler.Stop("Chunk Load");
                     *
                     *                                              //If we loaded more than the maximum number of chunks, stop loading chunks this frame to keep a playable framerate
                     *                                              if (numberOfChunksLoadedThisFrame > MaximumChunksToLoadPerFrame)
                     *                                              {
                     *                                                      break;
                     *                                              }
                     *                                      }
                     *                                      else
                     *                                      {
                     *                                              Profiler.Stop("Chunk Load");
                     *                                      }
                     *                              }
                     *
                     *                              //If we loaded more than the maximum number of chunks, stop loading chunks this frame to keep a playable framerate
                     *                              if (numberOfChunksLoadedThisFrame > MaximumChunksToLoadPerFrame)
                     *                              {
                     *                                      break;
                     *                              }
                     *                      }
                     *
                     *                      //Break the loop if we loaded a single chunk
                     *                      if (numberOfChunksLoadedThisFrame > 0)
                     *                      {
                     *                              break;
                     *                      }
                     *              }
                     *
                     *              //Break the loop if we loaded a single chunk
                     *              if (numberOfChunksLoadedThisFrame > 0)
                     *              {
                     *                      break;
                     *              }
                     *      }
                     *
                     *      if (numberOfChunksLoadedThisFrame < 1)
                     *      {
                     *              LoadDistance++;
                     *      }
                     *      if (LoadDistance > SimulationDistance)
                     *      {
                     *              LoadDistance = 2;
                     *      }
                     * }*/
                    #endregion

                    SyncCache();

                    Profiler.Stop("Chunk Manager Update");
                    ProcessingTime = (long)DateTime.UtcNow.TimeOfDay.TotalMilliseconds - ProcessingTime;

                    //Wait 1/60 - the time elapsed, clamped between 0 and int.max
                    Thread.Sleep(FastMath.FastClamp((int)(50 - ProcessingTime), 50, int.MaxValue));
                }
            }
            catch (ThreadAbortException ex)
            {
                //Thread aborting!
                Logger.fatal(-1, "Thread \"" + Thread.CurrentThread.Name + "\" aborted! This is usually normal!");
            }
        }
        public override void onUpdate()
        {
            //only handle the update if the button is enabled and the parent screen is visible
            if (screenVisible && render)
            {
                //hovering logic (checks if the slider is hovered)
                if (isMouseHovering() && selectable && enabled)
                {
                    Parent.FocusedComponent = this;

                    if (isMouseHovering(new Point(FastMath.FastClamp(location.X + (_value * size.X / (_maxValue - _minValue)), location.X, location.X + size.X - HandleWidth * GameSettings.UIScale), location.Y), new Point(HandleWidth * GameSettings.UIScale, size.Y)))
                    {
                        if (isHovered == false)
                        {
                            isHovered = true;
                            if (OnHover != null)
                            {
                                OnHover.Invoke(null, null);
                            }
                        }
                    }

                    if (InputManager.IsPressed("gui.click"))
                    {
                        if (isClicked == false)
                        {
                            isClicked = true;
                            if (OnClicked != null)
                            {
                                OnClicked.Invoke(null, null);
                            }
                        }
                    }

                    if (InputManager.Released("gui.click"))
                    {
                        if (isClicked && Parent.FocusedComponent != null && Parent.FocusedComponent == this)
                        {
                            isClicked = false;
                            if (OnReleased != null)
                            {
                                OnReleased.Invoke(null, null);
                            }
                        }
                    }

                    if (isClicked)
                    {
                        if (isSliding == false)
                        {
                            //If we are hovering on the handle then:
                            if (isMouseHovering(new Point(FastMath.FastClamp(location.X + (_value * size.X / (_maxValue - _minValue)), location.X, location.X + size.X - HandleWidth * GameSettings.UIScale), location.Y), new Point(HandleWidth * GameSettings.UIScale, size.Y)))
                            {
                                MouseOffset = new Point(handleX - InputManager.MouseX, location.Y - InputManager.MouseY);
                            }
                            //We are not hovering on the handle, so assume its half the width
                            else
                            {
                                MouseOffset = new Point(-HandleWidth * GameSettings.UIScale / 2, location.Y - InputManager.MouseY);
                            }
                            isSliding = true;
                        }
                    }
                }
                //unhover logic
                else
                {
                    if (isHovered)
                    {
                        isHovered = false;
                    }
                    if (!InputManager.IsPressed("gui.click"))
                    {
                        if (isClicked == true)
                        {
                            isClicked = false;
                            if (OnClicked != null)
                            {
                                OnClicked.Invoke(null, null);
                            }
                            if (OnReleased != null)
                            {
                                OnReleased.Invoke(null, null);
                            }
                        }
                    }
                }

                if (isClicked == false || Parent.FocusedComponent != this)
                {
                    isSliding = false;
                }

                //Handle the slider position
                if (isSliding)
                {
                    //Get the mouse relative to the component
                    int localPosition = InputManager.MouseX - location.X;

                    float coef  = (float)(_maxValue) / (float)(size.X - 3);
                    int   value = (int)(localPosition * coef);
                    value = FastMath.FastClamp(value, 0, _maxValue);

                    if (value != _value)
                    {
                        _value = value;

                        if (OnValueChanged != null)
                        {
                            OnValueChanged.Invoke(null, null);
                        }
                    }
                }
            }
        }
Example #9
0
        public override void onUpdate()
        {
            //only handle the update if the button is enabled and the parent screen is visible
            if (screenVisible && render)
            {
                #region Mouse Logic
                //hovering logic (checks if the slider is hovered)
                if (isMouseHovering() && selectable && enabled)
                {
                    var prevPosition = caretPosition;
                    Mouse.SetCursor(MouseCursor.IBeam);

                    Parent.FocusedComponent = this;

                    if (isHovered == false)
                    {
                        isHovered = true;
                        if (OnHover != null)
                        {
                            OnHover.Invoke(null, null);
                        }
                    }

                    #region Focusing Logic
                    if (InputManager.IsPressed("gui.click"))
                    {
                        if (isClicked == false)
                        {
                            isClicked = true;
                            if (OnClicked != null)
                            {
                                OnClicked.Invoke(null, null);
                            }
                            isEditing = true;
                        }

                        #region Mouse Highlighting Logic
                        if (isEditing)
                        {
                            GetCaretUnderMouse();

                            if (selectedCaretPositionTMP == -1)
                            {
                                selectedCaretPositionTMP = caretPosition;
                            }
                            if (selectedCaretPositionTMP != caretPosition)
                            {
                                //is holding
                                selectedPosition = selectedCaretPositionTMP;
                            }
                        }
                        #endregion
                    }
                    #endregion

                    #region Double Click Logic
                    if (InputManager.Released("gui.click"))
                    {
                        if (isClicked && Parent.FocusedComponent != null && Parent.FocusedComponent == this)
                        {
                            isClicked = false;
                            if (OnReleased != null)
                            {
                                OnReleased.Invoke(null, null);
                            }

                            selectedCaretPositionTMP = -1;
                            caretTimer = 0f;

                            //empty text boxes shouldnt crash
                            if (text.Length > 0)
                            {
                                //Double click logic
                                if (previousClickTime - timingMachine > 0f && previousClickTime - timingMachine <= 0.5f)                                 //Check the time frame
                                {
                                    if (selectedPosition == -1)
                                    {
                                        //If we moved more than 5 pixels from the last click in any direction then it doesnt count as a double click
                                        if (prevMouseLocation.X - 5 <= InputManager.MouseX && prevMouseLocation.X + 5 >= InputManager.MouseX &&
                                            prevMouseLocation.Y - 5 <= InputManager.MouseY && prevMouseLocation.Y + 5 >= InputManager.MouseY)
                                        {
                                            GetCaretUnderMouse();

                                            //Get the bounds of the current word
                                            int end = IndexOfNextCharAfterWhitespace();
                                            caretPosition = end;

                                            int start = IndexOfLastCharBeforeWhitespace();
                                            selectedPosition = start;

                                            timingMachine     = 0f;
                                            previousClickTime = 0f;
                                        }
                                    }
                                    else
                                    {
                                        selectedPosition = -1;
                                    }
                                }

                                timingMachine = previousClickTime;
                            }

                            prevMouseLocation = new Point(InputManager.MouseX, InputManager.MouseY);
                        }
                    }
                    #endregion

                    if (InputManager.PressedStart("gui.click"))
                    {
                        selectedPosition = -1;
                    }
                }

                #region Unhover Logic
                else
                {
                    if (!isMouseHovering() && Parent.FocusedComponent == this)
                    {
                        Mouse.SetCursor(MouseCursor.Arrow);
                    }

                    if (isHovered)
                    {
                        isHovered = false;
                    }
                    if (!InputManager.IsPressed("gui.click"))
                    {
                        if (isClicked == true)
                        {
                            isClicked = false;
                            if (OnClicked != null)
                            {
                                OnClicked.Invoke(null, null);
                            }
                            if (OnReleased != null)
                            {
                                OnReleased.Invoke(null, null);
                            }
                            caretTimer = 0f;
                            isEditing  = false;
                        }
                    }
                }
                #endregion
                #endregion

                caretTimer += Time.DeltaTime;

                #region Losing Focus to Another Component
                if (isEditing)
                {
                    previousClickTime += Time.DeltaTime;
                }

                if (Parent.FocusedComponent != this)
                {
                    if (Parent.FocusedComponent != null)
                    {
                        previousComponent = Parent.FocusedComponent;
                    }
                    else
                    {
                        isEditing = false;
                    }
                }

                //Focusing logic (on click on unfocused = unfocused)
                if (InputManager.Released("gui.click"))
                {
                    if (!isMouseHovering())
                    {
                        isEditing   = false;
                        timingChars = 0f;
                    }
                }
                #endregion

                #region Keyboard Handling
                //Get Textbox input
                if (isEditing)
                {
                    bool isShiftPressed = InputManager.IsPressed("misc.shift") || InputManager.IsPressed("misc.shift.alt");
                    bool isControlHeld  = InputManager.IsPressed("misc.control") || InputManager.IsPressed("misc.control.alt");
                    bool isAltHeld      = InputManager.IsPressed("misc.alternate") || InputManager.IsPressed("misc.alternate.alt");

                    #region Misc Input Handling

                    #region Caret Movement
                    timingChars += Time.DeltaTime;
                    if (InputManager.Released("misc.left") || InputManager.Released("misc.right"))
                    {
                        timingChars = 0f;
                    }

                    //Arrow hold timings
                    if ((timingChars < 1f && timingChars % 0.5f < 0.1f) ||                  //First second delay
                        (timingChars > 1f && timingChars < 2f && timingChars % 0.25f < 0.1f) ||                          //Second second delay
                        (timingChars > 2f && timingChars < 3f && timingChars % 0.1f < 0.05f))                             //Hold delay
                    {
                        //Movement
                        if (InputManager.IsPressed("misc.left") && !isAltHeld)                         //Left Arrow
                        {
                            if (isShiftPressed)
                            {
                                if (selectedPosition == -1)
                                {
                                    selectedPosition = FastMath.FastClamp(caretPosition, 0, text.Length);
                                }
                            }
                            else
                            {
                                if (selectedPosition != -1)
                                {
                                    caretPosition    = Math.Min(caretPosition, selectedPosition);
                                    selectedPosition = -1;
                                    caretPosition++;
                                }
                            }
                            if (isControlHeld)
                            {
                                caretPosition = IndexOfLastCharBeforeWhitespace() + 1;
                            }

                            caretPosition = FastMath.FastClamp(caretPosition - 1, 0, text.Length);                             //Minimum position = 0
                        }

                        if (InputManager.IsPressed("misc.right") && !isAltHeld)                         //Right Arrow
                        {
                            if (isShiftPressed)
                            {
                                if (selectedPosition == -1)
                                {
                                    selectedPosition = FastMath.FastClamp(caretPosition, 0, text.Length);
                                }
                            }
                            else
                            {
                                if (selectedPosition != -1)
                                {
                                    caretPosition    = Math.Max(caretPosition, selectedPosition);
                                    selectedPosition = -1;
                                    caretPosition--;
                                }
                            }
                            if (isControlHeld)
                            {
                                caretPosition = IndexOfNextCharAfterWhitespace() - 1;
                            }

                            caretPosition = FastMath.FastClamp(caretPosition + 1, 0, text.Length);                              //Maximum position = text.Length
                        }
                    }

                    //Home key
                    if (InputManager.Released("misc.home"))
                    {
                        caretPosition = 0;
                    }

                    //End key
                    if (InputManager.Released("misc.end"))
                    {
                        caretPosition = text.Length;
                    }

                    #endregion

                    #region Clipboard (Copy / Cut / Paste)
                    //Control things
                    if (isControlHeld)
                    {
                        //CTRL + A
                        if (InputManager.Released("misc.A"))
                        {
                            selectedPosition = 0;
                            caretPosition    = text.Length;
                        }

                        //Clipboard
                        if (InputManager.Released("misc.X"))
                        {
                            if (text.Length > 0)
                            {
                                if (selectedPosition != -1)
                                {
                                    //Get the selected text
                                    string toCopy = text.Substring(Math.Min(selectedPosition, caretPosition), Math.Max(selectedPosition, caretPosition));

                                    Clipboard.SetText(toCopy);

                                    //Same logic as backspace / delete
                                    Replace(Math.Min(selectedPosition, caretPosition), Math.Max(selectedPosition, caretPosition), string.Empty);
                                    if (selectedPosition < caretPosition)
                                    {
                                        caretPosition -= caretPosition - selectedPosition;
                                    }
                                    selectedPosition = -1;
                                }
                            }
                        }
                        if (InputManager.Released("misc.C"))
                        {
                            if (text.Length > 0)
                            {
                                if (selectedPosition != -1)
                                {
                                    int min = Math.Min(selectedPosition, caretPosition);
                                    int max = Math.Max(selectedPosition, caretPosition);

                                    //Get the selected text
                                    string toCopy = text.Substring(min, max - min);
                                    Clipboard.SetText(toCopy);
                                }
                            }
                        }
                        if (InputManager.Released("misc.V"))
                        {
                            string toAdd = Clipboard.GetText();

                            //remove newlines
                            toAdd = toAdd.Replace("\n", string.Empty);
                            toAdd = toAdd.Replace("\r", string.Empty);
                            toAdd = toAdd.Replace("\t", string.Empty);

                            //Append the clipboard text
                            if (text.Length > 0)
                            {
                                if (selectedPosition == -1)
                                {
                                    text = text.Substring(0, caretPosition) + toAdd + text.Substring(caretPosition);
                                    //caretPosition += toAdd.Length;
                                }
                                else
                                {
                                    Replace(Math.Min(selectedPosition, caretPosition), Math.Max(selectedPosition, caretPosition), toAdd.ToString());
                                    if (selectedPosition < caretPosition)
                                    {
                                        caretPosition -= caretPosition - selectedPosition;
                                    }
                                    selectedPosition = -1;
                                }
                            }
                            else
                            {
                                text += toAdd;
                            }

                            caretPosition += toAdd.Length;
                        }
                    }
                    #endregion

                    //Escape means lose focus
                    if (InputManager.Released("misc.pause"))
                    {
                        //lose focus
                        isEditing = false;

                        //reset the cursor
                        Mouse.SetCursor(MouseCursor.Arrow);

                        //reset
                        GameClient.CurrentCharacter = (char)0;
                        GameClient.CurrentKey       = Keys.None;
                        return;
                    }

                    #region Text Removal

                    if (GameClient.CurrentKey == Keys.Back)                     //Backspace
                    {
                        //If no highlighted text
                        if (selectedPosition == -1 || text.Length == 0)
                        {
                            text          = text.Substring(0, Math.Max(0, caretPosition - 1)) + text.Substring(Math.Min(caretPosition, text.Length));
                            caretPosition = FastMath.FastClamp(caretPosition, 0, text.Length);
                        }
                        else
                        {
                            Replace(Math.Min(selectedPosition, caretPosition), Math.Max(selectedPosition, caretPosition), string.Empty);
                            if (selectedPosition < caretPosition)
                            {
                                caretPosition -= caretPosition - selectedPosition;
                            }
                            selectedPosition = -1;
                        }
                    }

                    if (GameClient.CurrentKey == Keys.Delete)                     //Delete?
                    {
                        //If no highlighted text
                        if (selectedPosition == -1)
                        {
                            text          = text.Substring(0, caretPosition) + text.Substring(Math.Min(caretPosition + 1, text.Length));
                            caretPosition = FastMath.FastClamp(caretPosition, 0, text.Length);
                        }
                        else
                        {
                            Replace(Math.Min(selectedPosition, caretPosition), Math.Max(selectedPosition, caretPosition), string.Empty);
                            if (selectedPosition < caretPosition)
                            {
                                caretPosition -= caretPosition - selectedPosition;
                            }
                            selectedPosition = -1;
                        }
                    }
                    #endregion
                    #endregion

                    #region Input Handling
                    //Appending text
                    if (!(GameClient.CurrentKey == Keys.Back ||
                          GameClient.CurrentKey == Keys.Delete ||
                          GameClient.CurrentKey == Keys.Escape ||
                          GameClient.CurrentKey == Keys.Tab))                          //If the current key isn't a printable character
                    {
                        #region Regular Text Input
                        if (GameClient.CurrentKey != Keys.None)
                        {
                            //Append the character
                            if (text.Length > 0)
                            {
                                if (selectedPosition == -1)
                                {
                                    text = text.Substring(0, caretPosition) + GameClient.CurrentCharacter + text.Substring(caretPosition);
                                }
                                else
                                {
                                    Replace(Math.Min(selectedPosition, caretPosition), Math.Max(selectedPosition, caretPosition), GameClient.CurrentCharacter.ToString());
                                    if (selectedPosition < caretPosition)
                                    {
                                        caretPosition -= caretPosition - selectedPosition;
                                    }
                                    selectedPosition = -1;
                                }
                            }
                            else
                            {
                                text += GameClient.CurrentCharacter;
                            }

                            caretPosition++;
                        }
                        #endregion
                        #region Modifier Characters
                        else if (GameClient.CurrentCharacter != '\0')
                        {
                            char toAdd = GameClient.CurrentCharacter;

                            //if uppercase
                            if (isShiftPressed)
                            {
                                toAdd = char.ToUpper(toAdd);
                            }

                            //Caps Lock
#if DESKTOP
                            if (InputManager.IsPressed("misc.capslock"))
                            {
                                toAdd = char.ToUpper(toAdd);
                            }
#endif

                            //Append the character
                            if (text.Length > 0)
                            {
                                if (selectedPosition == -1)
                                {
                                    text = text.Substring(0, caretPosition) + toAdd + text.Substring(caretPosition);
                                }
                                else
                                {
                                    Replace(Math.Min(selectedPosition, caretPosition), Math.Max(selectedPosition, caretPosition), toAdd.ToString());
                                    if (selectedPosition < caretPosition)
                                    {
                                        caretPosition -= caretPosition - selectedPosition;
                                    }
                                    selectedPosition = -1;
                                }
                            }
                            else
                            {
                                text += toAdd;
                            }

                            caretPosition++;
                        }
                        #endregion
                    }
                    #endregion

                    //Reset
                    GameClient.CurrentCharacter = (char)0;
                    GameClient.CurrentKey       = Keys.None;
                }
                #endregion
                else
                {
                    //Reset highlighting
                    selectedPosition = -1;
                }
            }
        }