Beispiel #1
0
 /// <summary>
 /// Initialisierung des Planeten
 /// </summary>
 /// <param name="size">Größe des Planeten in Blocks</param>
 /// <param name="generator">Instanz des Map-Generators</param>
 /// <param name="seed">Seed des Zufallsgenerators</param>
 public Planet(int id, int universe, Index3 size, int seed)
 {
     Id = id;
     Universe = universe;
     Size = size;
     Seed = seed;
 }
Beispiel #2
0
 public Coordinate(int planet, Index3 block, Vector3 position)
 {
     Planet = planet;
     this.block = block;
     this.position = position;
     this.Normalize();
 }
Beispiel #3
0
 public Chunk(Index3 pos, int planet)
 {
     blocks = new IBlock[CHUNKSIZE_X * CHUNKSIZE_Y * CHUNKSIZE_Z];
     Index = pos;
     Planet = planet;
     ChangeCounter = 0;
 }
Beispiel #4
0
        public Chunk(Index3 pos, int planet)
        {
            Blocks = new ushort[CHUNKSIZE_X * CHUNKSIZE_Y * CHUNKSIZE_Z];
            MetaData = new int[CHUNKSIZE_X * CHUNKSIZE_Y * CHUNKSIZE_Z];
            Resources = new ushort[CHUNKSIZE_X * CHUNKSIZE_Y * CHUNKSIZE_Z][];

            Index = pos;
            Planet = planet;
            ChangeCounter = 0;
        }
Beispiel #5
0
 /// <summary>
 /// Initialisierung des Planeten
 /// </summary>
 /// <param name="id">ID des Planeten</param>
 /// <param name="universe">ID des Universums</param>
 /// <param name="size">Größe des Planeten in Zweierpotenzen Chunks</param>
 /// <param name="generator">Instanz des Map-Generators</param>
 /// <param name="seed">Seed des Zufallsgenerators</param>
 public Planet(int id, int universe, Index3 size, int seed)
 {
     Id = id;
     Universe = universe;
     Size = new Index3(
         (int)Math.Pow(2, size.X),
         (int)Math.Pow(2, size.Y),
         (int)Math.Pow(2, size.Z));
     Seed = seed;
 }
Beispiel #6
0
        public void Release(Index3 idx)
        {
            var flat = FlatIndex(idx.X, idx.Y, idx.Z);

            var chunk = _chunks[flat];

            if (chunk != null)
            {
                _saveDelegate(idx, chunk);
                _chunks[flat] = null;
            }
        }
 /// <summary>
 /// Setzt den Zentrums-Chunk für diesen lokalen Cache.
 /// </summary>
 /// <param name="planet">Der Planet, auf dem sich der Chunk befindet</param>
 /// <param name="index">Die Koordinaten an der sich der Chunk befindet</param>
 /// <param name="successCallback">Routine die Aufgerufen werden soll, falls das setzen erfolgreich war oder nicht</param>
 public void SetCenter(IPlanet planet, Index3 index, Action<bool> successCallback = null)
 {
     if (_loadingTask != null && !_loadingTask.IsCompleted)
     {
         _cancellationToken.Cancel();
         _cancellationToken = new CancellationTokenSource();
         _loadingTask = _loadingTask.ContinueWith(_ => InternalSetCenter(_cancellationToken.Token, planet, index, successCallback));
     }
     else
     {
         _cancellationToken = new CancellationTokenSource();
         _loadingTask = Task.Factory.StartNew(() => InternalSetCenter(_cancellationToken.Token, planet, index, successCallback));
     }
 }
Beispiel #8
0
        public void UpdatePosition(int i, int j, int k)
        {
            _center = new Index3(_center.X + i, _center.Y + j, _center.Z + k);

            if (_loadingTask != null && !_loadingTask.IsCompleted)
            {
                _cancellationToken.Cancel();
                _cancellationToken = new CancellationTokenSource();
                _loadingTask = _loadingTask.ContinueWith(_ => Reload(_cancellationToken.Token));
            }
            else
            {
                _cancellationToken = new CancellationTokenSource();
                _loadingTask = Task.Factory.StartNew(() => Reload(_cancellationToken.Token));
            }
        }
Beispiel #9
0
 /// <summary>
 /// Ermittelt die kürzeste Entfernung zum Ziel auf den normalisierten Achsen.
 /// </summary>
 /// <param name="destination">Ziel</param>
 /// <param name="size">Normalisierungsgröße</param>
 /// <returns>Entfernung</returns>
 public Index3 ShortestDistanceXYZ(Index3 destination, Index3 size)
 {
     return new Index3(
         ShortestDistanceX(destination.X, size.X),
         ShortestDistanceY(destination.Y, size.Y),
         ShortestDistanceZ(destination.Z, size.Z));
 }
Beispiel #10
0
 /// <summary>
 /// Überschreibt den Block an der angegebenen Koordinate.
 /// </summary>
 /// <param name="index">Koordinate des Blocks innerhalb des Chunks</param>
 /// <param name="block">Der neue Block oder null, fall der Block geleert werden soll</param>
 public void SetBlock(Index3 index, ushort block, int meta = 0)
 {
     SetBlock(index.X, index.Y, index.Z, block);
 }
Beispiel #11
0
 public IChunk Get(Index3 idx)
 {
     return _chunks[FlatIndex(idx.X, idx.Y, idx.Z)];
 }
Beispiel #12
0
 /// <summary>
 /// Normalisiert die Y-Achse auf die angegebene Größe.
 /// </summary>
 /// <param name="size">3D-Größe (Y-Anzeil wird genommen)</param>
 public void NormalizeY(Index3 size)
 {
     NormalizeY(size.Y);
 }
Beispiel #13
0
 /// <summary>
 /// Initialisierung
 /// </summary>
 /// <param name="value">Initialwerte (X und Y Anteil wird übernommen)</param>
 public Index2(Index3 value) : this(value.X, value.Y) {}
Beispiel #14
0
        /// <summary>
        /// Kollisionsmethode, in der die Selektion der Blöcke vom Spieler aus geprüft wird
        /// </summary>
        /// <param name="collisionBoxes">Kollisionsboxen des Blocks</param>
        /// <param name="boxPosition">Die Position, wo sich die BoundingBox befindet</param>
        /// <param name="ray">Der Selektionsstrahl, der vom Spieler ausgeht</param>
        /// <param name="collisionAxis">Welche Achse von der Kollision betroffen ist</param>
        /// <returns>Die Entfernung zwischen der Kollision und der Kollisionsbox der Entität</returns>
        public static float? Intersect(BoundingBox[] collisionBoxes, Index3 boxPosition, Ray ray, out Axis? collisionAxis)
        {
            Vector3 min = new Vector3(1, 1, 1);
            float raylength = Player.SELECTIONRANGE * 2;
            float? minDistance = null;
            bool collided = false;

            foreach (var localBox in collisionBoxes)
            {
                BoundingBox box = new BoundingBox(localBox.Min + boxPosition, localBox.Max + boxPosition);

                float? distance = ray.Intersects(box);
                if (!distance.HasValue) continue;

                if (!minDistance.HasValue || minDistance > distance)
                {
                    minDistance = distance;
                }

                Vector3 boxCorner = new Vector3(
                        ray.Direction.X > 0 ? box.Min.X : box.Max.X,
                        ray.Direction.Y > 0 ? box.Min.Y : box.Max.Y,
                        ray.Direction.Z > 0 ? box.Min.Z : box.Max.Z);

                Vector3 n = (boxCorner - ray.Position) / (ray.Direction * raylength);
                min = new Vector3(Math.Min(min.X, n.X), Math.Min(min.Y, n.Y), Math.Min(min.Z, n.Z));
                collided = true;
            }

            if (collided)
            {
                float max = -5f;
                Axis? axis = null;

                // Fall X
                if (min.X < 1f && min.X > max)
                {
                    max = min.X;
                    axis = Axis.X;
                }

                // Fall Y
                if (min.Y < 1f && min.Y > max)
                {
                    max = min.Y;
                    axis = Axis.Y;
                }

                // Fall Z
                if (min.Z < 1f && min.Z > max)
                {
                    max = min.Z;
                    axis = Axis.Z;
                }

                collisionAxis = axis;
                if (axis.HasValue)
                    return max * raylength;
                return null;
            }
            else
            {
                collisionAxis = null;
                return null;
            }
        }
Beispiel #15
0
 /// <summary>
 /// Überschreibt den Block an der angegebenen Koordinate.
 /// </summary>
 /// <param name="index">Koordinate des Blocks innerhalb des Chunks</param>
 /// <param name="block">Der neue Block oder null, fall der Block geleert werden soll</param>
 public void SetBlock(Index3 index, ushort block, int meta = 0)
 {
     SetBlock(index.X, index.Y, index.Z, block);
 }
Beispiel #16
0
 public ChunkLoader(IChunkCache cache, int range, Index3 center)
 {
     _center = center;
     _maxRange = range;
     _cache = cache;
 }
 public void SetBlockMeta(Index3 index, int meta)
 {
     IChunk chunk = GetChunk(index.X >> Chunk.LimitX, index.Y >> Chunk.LimitY, index.Z >> Chunk.LimitZ);
     if (chunk != null)
         chunk.SetBlockMeta(index.X, index.Y, index.Z, meta);
 }
        public int GetBlockMeta(Index3 index, int meta)
        {
            IChunk chunk = GetChunk(index.X >> Chunk.LimitX, index.Y >> Chunk.LimitY, index.Z >> Chunk.LimitZ);
            if (chunk != null)
                return chunk.GetBlockMeta(index.X, index.Y, index.Z);

            return 0;
        }
 public IChunk GetChunk(Index3 index)
 {
     return GetChunk(index.X, index.Y, index.Z);
 }
Beispiel #20
0
 /// <summary>
 /// Normalisiert die Y-Achse auf die angegebene Größe.
 /// </summary>
 /// <param name="size">3D-Größe (Y-Anzeil wird genommen)</param>
 public void NormalizeY(Index3 size)
 => NormalizeY(size.Y);
Beispiel #21
0
 /// <summary>
 /// Initialisierung
 /// </summary>
 /// <param name="index">3D-Basis</param>
 public Index3(Index3 index) : this(index.X, index.Y, index.Z) { }
Beispiel #22
0
 /// <summary>
 /// Liefet den Block an der angegebenen Koordinate zurück.
 /// </summary>
 /// <param name="index">Koordinate des Blocks innerhalb des Chunkgs</param>
 /// <returns>Block oder null, falls es dort keinen Block gibt.</returns>
 public ushort GetBlock(Index3 index)
 {
     return GetBlock(index.X, index.Y, index.Z);
 }
Beispiel #23
0
 /// <summary>
 /// Normalisiert den Wert von X und Y auf den angegebenen Grenzbereich.
 /// </summary>
 /// <param name="index">Der zu normalisierende Index2</param>
 /// <param name="size">3D Size</param>
 public static Index2 NormalizeXY(Index2 index,Index3 size)
 {
     index.NormalizeXY(size);
     return index;
 }
Beispiel #24
0
 /// <summary>
 /// Initialisierung
 /// </summary>
 /// <param name="value">Initialwerte (X und Y Anteil wird übernommen)</param>
 public Index2(Index3 value) : this(value.X, value.Y)
 {
 }
Beispiel #25
0
 /// <summary>
 /// Normalisiert den ChunkIndex auf die gegebenen Limits.
 /// </summary>
 /// <param name="limit"></param>
 public void NormalizeChunkIndexXY(Index3 limit)
 {
     Index3 index = ChunkIndex;
     index.NormalizeXY(limit);
     ChunkIndex = index;
 }
Beispiel #26
0
        /// <summary>
        /// Prüft, ob die Kollisionsbox einer Entität mit den Kollisionsboxen eines Blocks kollidieren
        /// </summary>
        /// <param name="collisionBoxes">Kollisionsboxen des Blocks</param>
        /// <param name="boxPosition">Die Position, wo sich der Block befindet</param>
        /// <param name="player">Die Kollisionsbox einer Entität</param>
        /// <param name="move">Die befegungsrichtung der Entität</param>
        /// <param name="collisionAxis">Welche Achse von der Kollision betroffen ist</param>
        /// <returns>Die Entfernung zwischen der Kollision und der Kollisionsbox der Entität</returns>
        public static float? Intersect(BoundingBox[] collisionBoxes, Index3 boxPosition, BoundingBox player, Vector3 move, out Axis? collisionAxis)
        {
            Vector3 playerCorner = new Vector3(
                        (move.X > 0 ? player.Max.X : player.Min.X),
                        (move.Y > 0 ? player.Max.Y : player.Min.Y),
                        (move.Z > 0 ? player.Max.Z : player.Min.Z));

            Vector3 targetPosition = playerCorner + move;

            Vector3 playerMin = player.Min + move;
            Vector3 playerMax = player.Max + move;

            Vector3 min = new Vector3(1, 1, 1);
            bool collided = false;

            foreach (var localBox in collisionBoxes)
            {
                Vector3 boxMin = localBox.Min + new Vector3(boxPosition.X, boxPosition.Y, boxPosition.Z);
                Vector3 boxMax = localBox.Max + new Vector3(boxPosition.X, boxPosition.Y, boxPosition.Z);

                bool collide =
                    playerMin.X <= boxMax.X && playerMax.X >= boxMin.X &&
                    playerMin.Y <= boxMax.Y && playerMax.Y >= boxMin.Y &&
                    playerMin.Z <= boxMax.Z && playerMax.Z >= boxMin.Z;

                if (!collide) continue;

                Vector3 boxCorner = new Vector3(
                        move.X > 0 ? boxMin.X : boxMax.X,
                        move.Y > 0 ? boxMin.Y : boxMax.Y,
                        move.Z > 0 ? boxMin.Z : boxMax.Z);

                Vector3 n = (boxCorner - playerCorner) / move;
                min = new Vector3(Math.Min(min.X, n.X), Math.Min(min.Y, n.Y), Math.Min(min.Z, n.Z));
                collided = true;
            }

            if (collided)
            {
                float max = 0f;
                Axis? axis = null;

                // Fall X
                if (min.X < 1f && min.X > max)
                {
                    max = min.X;
                    axis = Axis.X;
                }

                // Fall Y
                if (min.Y < 1f && min.Y > max)
                {
                    max = min.Y;
                    axis = Axis.Y;
                }

                // Fall Z
                if (min.Z < 1f && min.Z > max)
                {
                    max = min.Z;
                    axis = Axis.Z;
                }

                collisionAxis = axis;
                if (axis.HasValue)
                    return max;
                return null;
            }
            else
            {
                collisionAxis = null;
                return null;
            }
        }
Beispiel #27
0
 /// <summary>
 /// Normalisiert die X-Achse auf die angegebene Größe.
 /// </summary>
 /// <param name="size">3D-Größe (X-Anzeil wird genommen)</param>
 public void NormalizeX(Index3 size)
 => NormalizeX(size.X);
Beispiel #28
0
 /// <summary>
 /// Normalisiert die X-Achse auf die angegebene Größe.
 /// </summary>
 /// <param name="size">3D-Größe (X-Anzeil wird genommen)</param>
 public void NormalizeX(Index3 size)
 {
     NormalizeX(size.X);
 }
Beispiel #29
0
 /// <summary>
 /// Normalisiert den Wert von X und Y auf den angegebenen Grenzbereich.
 /// </summary>
 /// <param name="index">Der zu normalisierende Index2</param>
 /// <param name="size">3D Size</param>
 public static Index2 NormalizeXY(Index2 index, Index3 size)
 {
     index.NormalizeXY(size);
     return(index);
 }
Beispiel #30
0
 public void EnsureLoaded(Index3 idx)
 {
     var flat = FlatIndex(idx.X, idx.Y, idx.Z);
     if (_chunks[flat] == null)
         _chunks[flat] = _loadDelegate(idx);
 }
Beispiel #31
0
 /// <summary>
 /// Ermittelt die kürzeste Entfernung zum Ziel auf den normalisierten Achsen.
 /// </summary>
 /// <param name="destination">Ziel</param>
 /// <param name="size">Normalisierungsgröße</param>
 /// <returns>Entfernung</returns>
 public Index3 ShortestDistanceXY(Index3 destination, Index2 size)
 {
     return new Index3(
         ShortestDistanceX(destination.X, size.X),
         ShortestDistanceY(destination.Y, size.Y),
         destination.Z - Z);
 }
Beispiel #32
0
        /// <summary>
        /// Gibt alle möglichen Flächen eines Blockes zurück
        /// </summary>
        /// <param name="pos">Position des Blockes</param>
        /// <param name="movevector">Bewegungsvector</param>
        /// <returns>Liste aller beteiligten Flächen</returns>
        public static IEnumerable<CollisionPlane> GetBlockCollisionPlanes(Index3 pos, Vector3 movevector)
        {
            //Ebene X
            if (movevector.X > 0)
            {
                yield return new CollisionPlane(
                    new Vector3(pos.X, pos.Y, pos.Z),
                    new Vector3(pos.X, pos.Y + 1f, pos.Z + 1f),
                    new Vector3(-1, 0, 0));
            }
            else if (movevector.X < 0)
            {
                yield return new CollisionPlane(
                    new Vector3(pos.X + 1f, pos.Y, pos.Z),
                    new Vector3(pos.X + 1f, pos.Y + 1f, pos.Z + 1f),
                    new Vector3(1, 0, 0));
            }

            //Ebene Y
            if (movevector.Y > 0)
            {
                yield return new CollisionPlane(
                    new Vector3(pos.X, pos.Y, pos.Z),
                    new Vector3(pos.X + 1f, pos.Y, pos.Z + 1f),
                    new Vector3(0, -1, 0));
            }
            else if (movevector.Y < 0)
            {
                yield return new CollisionPlane(
                    new Vector3(pos.X , pos.Y + 1f, pos.Z),
                    new Vector3(pos.X + 1f, pos.Y + 1f, pos.Z + 1f),
                    new Vector3(0, 1, 0));
            }

            //Ebene Z
            if (movevector.Z > 0)
            {
                yield return new CollisionPlane(
                    new Vector3(pos.X, pos.Y , pos.Z ),
                    new Vector3(pos.X + 1f, pos.Y + 1f , pos.Z ),
                    new Vector3(0,0, -1));
            }
            else if (movevector.Z < 0)
            {
                yield return new CollisionPlane(
                    new Vector3(pos.X , pos.Y  , pos.Z + 1f),
                    new Vector3(pos.X + 1f, pos.Y +1f, pos.Z + 1f),
                    new Vector3(0, 0, 1));
            }
        }
Beispiel #33
0
 /// <summary>
 /// Liefet den Block an der angegebenen Koordinate zurück.
 /// </summary>
 /// <param name="index">Koordinate des Blocks innerhalb des Chunkgs</param>
 /// <returns>Block oder null, falls es dort keinen Block gibt.</returns>
 public ushort GetBlock(Index3 index)
 {
     return(GetBlock(index.X, index.Y, index.Z));
 }
Beispiel #34
0
        /// <summary>
        /// Normalisiert die vorhandenen Parameter auf den Position-Wertebereich von [0...1] und die damit verbundene Verschiebung im Block.
        /// </summary>
        private void Normalize()
        {
            Index3 shift = new Index3(
                (int)Math.Floor(position.X),
                (int)Math.Floor(position.Y),
                (int)Math.Floor(position.Z));

            block += shift;
            position = position - shift;
        }
Beispiel #35
0
 /// <summary>
 /// Normalisiert die Z-Achse auf die angegebene Größe.
 /// </summary>
 /// <param name="size">3D-Size</param>
 public void NormalizeZ(Index3 size)
 {
     NormalizeZ(size.Z);
 }
Beispiel #36
0
 /// <summary>
 /// Normalisiert die X-, Y- und Z-Achse auf die angegebene Größe.
 /// </summary>
 /// <param name="size">Maximalwert für X, Y und Z</param>
 public void NormalizeXYZ(Index3 size)
 {
     NormalizeXYZ(size.X, size.Y, size.Z);
 }
Beispiel #37
0
 /// <summary>
 /// Liefert den Index des Blocks im abgeflachten Block-Array der angegebenen 3D-Koordinate zurück. Sollte die Koordinate ausserhalb
 /// der Chunkgrösse liegen, wird dies gewrapt.
 /// </summary>
 /// <param name="position">Die aktuelle Blockposition</param>
 /// <returns>Index innerhalb des flachen Arrays</returns>
 public static int GetFlatIndex(Index3 position)
 {
     return(((position.Z & (CHUNKSIZE_Z - 1)) << (LimitX + LimitY))
            | ((position.Y & (CHUNKSIZE_Y - 1)) << LimitX)
            | (position.X & (CHUNKSIZE_X - 1)));
 }