Пример #1
0
        void FloodFrom(Region tregion, Vector3i start, double maxRad, HashSet <Vector3i> locs)
        {
            Queue <Vector3i>             toCheck = new Queue <Vector3i>(128);
            Dictionary <Vector3i, Chunk> chks    = new Dictionary <Vector3i, Chunk>(128); // TODO: Arbitrary constant.

            toCheck.Enqueue(start);
            while (toCheck.Count > 0)
            {
                Vector3i c = toCheck.Dequeue();
                if ((c.ToLocation() - start.ToLocation()).LengthSquared() > maxRad * maxRad)
                {
                    continue;
                }
                if (tregion.GetBlockMaterial(chks, c.ToLocation()) != Material.AIR)
                {
                    continue;
                }
                if (locs.Contains(c))
                {
                    continue;
                }
                locs.Add(c);
                foreach (Vector3i dir in FloodDirs)
                {
                    toCheck.Enqueue(c + dir);
                }
            }
        }
Пример #2
0
 public bool TryChunk(Vector3i cworldPos, int posMult, Chunk chi = null) // TODO: Efficiency?
 {
     if (pkick)
     {
         return(false);
     }
     if (!ChunksAwareOf.ContainsKey(cworldPos) || ChunksAwareOf[cworldPos].LOD > posMult) // TODO: Efficiency - TryGetValue?
     {
         double dist  = (cworldPos.ToLocation() * Chunk.CHUNK_SIZE - LoadRelPos).LengthSquared();
         bool   async = chi == null && dist > (Chunk.CHUNK_SIZE * Chunk.CHUNK_SIZE * 2 * 2);
         if (async)
         {
             TheRegion.LoadChunk_Background(cworldPos, (chn) =>
             {
                 if (!pkick && chn != null)
                 {
                     ChunkNetwork.SendPacket(new ChunkInfoPacketOut(chn, posMult));
                 }
             });
         }
         else
         {
             Chunk chk = chi != null ? chi : TheRegion.LoadChunk(cworldPos);
             ChunkNetwork.SendPacket(new ChunkInfoPacketOut(chk, posMult));
         }
         ChunksAwareOf.Remove(cworldPos);
         ChunksAwareOf.Add(cworldPos, new ChunkAwarenessInfo()
         {
             ChunkPos = cworldPos, LOD = posMult
         });
         return(true);
     }
     return(false);
 }
Пример #3
0
            public void GenerateTrees(SimpleGeneratorCore sgc, Vector3i chunkPos, int Seed, int seed, int seed3, int seed4, int seed5)
            {
                Trees         = new List <KeyValuePair <Vector2i, int> >();
                ChunkPosition = chunkPos;
                CPos          = chunkPos.ToLocation() * Chunk.CHUNK_SIZE;
                MTRandom random = new MTRandom((ulong)chunkPos.GetHashCode());
                // TODO: Biome basis!
                int c = 0;

                if (random.Next(1, 5) == 1)
                {
                    if (random.Next(1, 5) == 1)
                    {
                        if (random.Next(1, 5) == 1)
                        {
                            c = random.Next(1, 3);
                        }
                        else
                        {
                            c = random.Next(1, 2);
                        }
                    }
                    else
                    {
                        c = 1;
                    }
                }
                for (int i = 0; i < c; i++)
                {
                    Trees.Add(new KeyValuePair <Vector2i, int>(new Vector2i(random.Next(Chunk.CHUNK_SIZE), random.Next(Chunk.CHUNK_SIZE)), random.Next()));
                }
            }
Пример #4
0
        public override void Populate(int seed, int seed2, int seed3, int seed4, int seed5, Chunk chunk)
        {
            double scale = chunk.OwningRegion.TheWorld.GeneratorScale;

            scale *= scale;
            Location cCenter = (chunk.WorldPosition.ToLocation() + new Location(0.5, 0.5, 0.5)) * Constants.CHUNK_WIDTH;

            if (cCenter.LengthSquared() > scale * 4.0)
            {
                // TODO: Is this excessive?
                for (int i = 0; i < chunk.BlocksInternal.Length; i++)
                {
                    chunk.BlocksInternal[i] = BlockInternal.AIR;
                }
                return;
            }
            double   one_over_scale = 1.0 / scale;
            Vector3i cLow           = chunk.WorldPosition * Constants.CHUNK_WIDTH;

            for (int x = 0; x < Constants.CHUNK_WIDTH; x++)
            {
                for (int y = 0; y < Constants.CHUNK_WIDTH; y++)
                {
                    for (int z = 0; z < Constants.CHUNK_WIDTH; z++)
                    {
                        Vector3i current = cLow + new Vector3i(x, y, z);
                        double   distSq  = current.ToLocation().LengthSquared();
                        double   rel     = distSq * one_over_scale;
                        if (rel > 1.0)
                        {
                            chunk.SetBlockAt(x, y, z, BlockInternal.AIR);
                        }
                        else if (rel > (0.9 * 0.9))
                        {
                            chunk.SetBlockAt(x, y, z, new BlockInternal((ushort)Material.DIRT, 0, 0, 0));
                        }
                        // TODO: More layers?
                        else
                        {
                            chunk.SetBlockAt(x, y, z, new BlockInternal((ushort)Material.STONE, 0, 0, 0));
                        }
                    }
                }
            }
        }
Пример #5
0
            public void Generate(SimpleGeneratorCore sgc, Vector3i chunkPos, int Seed, int seed2, int seed3, int seed4, int seed5)
            {
                List <MountainData> mountains = sgc.GenMountainPositionsAround(new Vector2i(chunkPos.X, chunkPos.Y), Seed);

                ChunkPosition = chunkPos;
                CPos          = chunkPos.ToLocation() * Chunk.CHUNK_SIZE;
                Heights       = new double[Chunk.CHUNK_SIZE * Chunk.CHUNK_SIZE];
                for (int x = 0; x < Chunk.CHUNK_SIZE; x++)
                {
                    for (int y = 0; y < Chunk.CHUNK_SIZE; y++)
                    {
                        // Prepare basics
                        int    cx      = (int)CPos.X + x;
                        int    cy      = (int)CPos.Y + y;
                        double hheight = sgc.GetHeight(Seed, seed2, seed3, seed4, seed5, cx, cy, mountains, true);
                        Heights[y * Chunk.CHUNK_SIZE + x] = hheight;
                    }
                }
            }
Пример #6
0
        /// <summary>
        /// Finds a path from the start to the end, if one exists.
        /// Current implementation is A-Star (A*).
        /// Thanks to fullwall for the reference sources this was originally built from.
        /// Possibly safe for Async usage.
        /// </summary>
        /// <param name="startloc">The starting location.</param>
        /// <param name="endloc">The ending location.</param>
        /// <param name="maxRadius">The maximum radius to search through.</param>
        /// <param name="goaldist">The maximum distance from the goal allowed.</param>
        /// <param name="cts">A cancellation token, if any.</param>
        /// <returns>The shortest path, as a list of blocks to travel through.</returns>
        public List <Location> FindPath(Location startloc, Location endloc, double maxRadius, double goaldist, CancellationTokenSource cts = null)
        {
            // TODO: Improve async safety!
            startloc = startloc.GetBlockLocation() + new Location(0.5, 0.5, 1.0);
            endloc   = endloc.GetBlockLocation() + new Location(0.5, 0.5, 1.0);
            double mrsq = maxRadius * maxRadius;
            double gosq = goaldist * goaldist;

            if (startloc.DistanceSquared(endloc) > mrsq)
            {
                cts.Cancel();
                return(null);
            }
            PathFindNodeSet              nodes;
            PriorityQueue <PFEntry>      open;
            Dictionary <Vector3i, Chunk> map;

            lock (PFNodeSetLock)
            {
                if (PFNodeSet.Count == 0)
                {
                    nodes = null;
                    open  = null;
                    map   = null;
                }
                else
                {
                    nodes = PFNodeSet.Pop();
                    open  = PFQueueSet.Pop();
                    map   = PFMapSet.Pop();
                }
            }
            if (nodes == null)
            {
                nodes = new PathFindNodeSet()
                {
                    Nodes = new PathFindNode[8192]
                };
                open = new PriorityQueue <PFEntry>(8192);
                map  = new Dictionary <Vector3i, Chunk>(1024);
            }
            int nloc  = 0;
            int start = GetNode(nodes, ref nloc, startloc.ToVec3i(), 0.0, 0.0, -1);
            // TODO: Grab these from a stack too?
            Dictionary <Vector3i, PathFindNode> closed  = new Dictionary <Vector3i, PathFindNode>();
            Dictionary <Vector3i, PathFindNode> openset = new Dictionary <Vector3i, PathFindNode>();
            PFEntry pfet;

            pfet.Nodes = nodes;
            pfet.ID    = start;
            open.Enqueue(ref pfet, 0.0);
            openset[startloc.ToVec3i()] = nodes.Nodes[start];
            while (open.Count > 0)
            {
                if (cts.IsCancellationRequested)
                {
                    return(null);
                }
                int          nextid = open.Dequeue().ID;
                PathFindNode next   = nodes.Nodes[nextid];
                if (openset.TryGetValue(next.Internal, out PathFindNode pano) && pano.F < next.F)
                {
                    continue;
                }
                openset.Remove(next.Internal);
                if (next.Internal.ToLocation().DistanceSquared(endloc) < gosq)
                {
                    open.Clear();
                    map.Clear();
                    lock (PFNodeSetLock)
                    {
                        PFNodeSet.Push(nodes);
                        PFQueueSet.Push(open);
                        PFMapSet.Push(map);
                    }
                    return(Reconstruct(nodes.Nodes, nextid));
                }
                if (closed.TryGetValue(next.Internal, out PathFindNode pfn) && pfn.F < next.F)
                {
                    continue;
                }
                closed[next.Internal] = next;
                foreach (Vector3i neighbor in PathFindNode.Neighbors)
                {
                    Vector3i neighb = next.Internal + neighbor;
                    if (startloc.DistanceSquared(neighb.ToLocation()) > mrsq)
                    {
                        continue;
                    }
                    // Note: Add `&& fbv.F <= next.F)` to enhance precision of results... but it makes invalid searches take forever.
                    if (closed.TryGetValue(neighb, out PathFindNode fbv))
                    {
                        continue;
                    }
                    // Note: Add `&& pfv.F <= next.F)` to enhance precision of results... but it makes invalid searches take forever.
                    if (openset.TryGetValue(neighb, out PathFindNode pfv))
                    {
                        continue;
                    }
                    // TODO: Check solidity from very solid entities too!
                    if (GetBlockMaterial(map, neighb).GetSolidity() != MaterialSolidity.NONSOLID) // TODO: Better solidity check
                    {
                        continue;
                    }
                    if (GetBlockMaterial(map, neighb + new Vector3i(0, 0, -1)).GetSolidity() == MaterialSolidity.NONSOLID &&
                        GetBlockMaterial(map, neighb + new Vector3i(0, 0, -2)).GetSolidity() == MaterialSolidity.NONSOLID &&
                        GetBlockMaterial(map, next.Internal + new Vector3i(0, 0, -1)).GetSolidity() == MaterialSolidity.NONSOLID &&
                        GetBlockMaterial(map, next.Internal + new Vector3i(0, 0, -2)).GetSolidity() == MaterialSolidity.NONSOLID)
                    {
                        continue;
                    }
                    int     node = GetNode(nodes, ref nloc, neighb, next.G + 1.0, next.F + 1.0 + neighb.ToLocation().Distance(endloc), nextid);
                    PFEntry tpfet;
                    tpfet.Nodes = nodes;
                    tpfet.ID    = node;
                    open.Enqueue(ref tpfet, nodes.Nodes[node].F);
                    openset[neighb] = nodes.Nodes[node];
                }
            }
            open.Clear();
            map.Clear();
            lock (PFNodeSetLock)
            {
                PFNodeSet.Push(nodes);
                PFQueueSet.Push(open);
                PFMapSet.Push(map);
            }
            cts.Cancel();
            return(null);
        }
Пример #7
0
 /// <summary>
 /// Ticks the region, including all primary calculations and lighting updates.
 /// </summary>
 public void TickWorld(double delta)
 {
     rTicks++;
     if (rTicks >= CVars.r_shadowpace.ValueI)
     {
         Vector3i playerChunkPos = TheRegion.ChunkLocFor(Player.GetPosition());
         if (playerChunkPos != SunChunkPos) // TODO: Or sun/planet angle changed!
         {
             SunChunkPos = playerChunkPos;
             Location corPos = (SunChunkPos.ToLocation() * Constants.CHUNK_WIDTH) + new Location(Constants.CHUNK_WIDTH * 0.5);
             TheSun.Direction = Utilities.ForwardVector_Deg(SunAngle.Yaw, SunAngle.Pitch);
             TheSun.Reposition(corPos - TheSun.Direction * 30 * 6);
             TheSunClouds.Direction = TheSun.Direction;
             TheSunClouds.Reposition(TheSun.EyePos);
             PlanetDir           = Utilities.ForwardVector_Deg(PlanetAngle.Yaw, PlanetAngle.Pitch);
             ThePlanet.Direction = PlanetDir;
             ThePlanet.Reposition(corPos - ThePlanet.Direction * 30 * 6);
             Vector3 tsd = TheSun.Direction.ToBVector();
             Vector3 tpd = PlanetDir.ToBVector();
             Quaternion.GetQuaternionBetweenNormalizedVectors(ref tsd, ref tpd, out Quaternion diff);
             PlanetSunDist = (float)Quaternion.GetAngleFromQuaternion(ref diff) / (float)Utilities.PI180;
             if (PlanetSunDist < 75)
             {
                 TheSun.InternalLights[0].color = new OpenTK.Vector3((float)Math.Min(SunLightDef.X * (PlanetSunDist / 15), 1),
                                                                     (float)Math.Min(SunLightDef.Y * (PlanetSunDist / 20), 1), (float)Math.Min(SunLightDef.Z * (PlanetSunDist / 60), 1));
                 TheSunClouds.InternalLights[0].color = new OpenTK.Vector3((float)Math.Min(CloudSunLightDef.X * (PlanetSunDist / 15), 1),
                                                                           (float)Math.Min(CloudSunLightDef.Y * (PlanetSunDist / 20), 1), (float)Math.Min(CloudSunLightDef.Z * (PlanetSunDist / 60), 1));
                 //ThePlanet.InternalLights[0].color = new OpenTK.Vector3(0, 0, 0);
             }
             else
             {
                 TheSun.InternalLights[0].color       = ClientUtilities.Convert(SunLightDef);
                 TheSunClouds.InternalLights[0].color = ClientUtilities.Convert(CloudSunLightDef);
                 //ThePlanet.InternalLights[0].color = ClientUtilities.Convert(PlanetLightDef * Math.Min((PlanetSunDist / 180f), 1f));
             }
             PlanetLight = PlanetSunDist / 180f;
             if (SunAngle.Pitch < 10 && SunAngle.Pitch > -30)
             {
                 float rel = 30 + (float)SunAngle.Pitch;
                 if (rel == 0)
                 {
                     rel = 0.00001f;
                 }
                 rel = 1f - (rel / 40f);
                 rel = Math.Max(Math.Min(rel, 1f), 0f);
                 float rel2 = Math.Max(Math.Min(rel * 1.5f, 1f), 0f);
                 TheSun.InternalLights[0].color       = new OpenTK.Vector3(TheSun.InternalLights[0].color.X * rel2, TheSun.InternalLights[0].color.Y * rel, TheSun.InternalLights[0].color.Z * rel);
                 TheSunClouds.InternalLights[0].color = new OpenTK.Vector3(TheSunClouds.InternalLights[0].color.X * rel2, TheSunClouds.InternalLights[0].color.Y * rel, TheSunClouds.InternalLights[0].color.Z * rel);
                 MainWorldView.DesaturationAmount     = (1f - rel) * 0.75f;
                 MainWorldView.ambient = BaseAmbient * ((1f - rel) * 0.5f + 0.5f);
                 sl_min   = 0.2f - (1f - rel) * (0.2f - 0.05f);
                 sl_max   = 0.8f - (1f - rel) * (0.8f - 0.15f);
                 SkyColor = SkyApproxColDefault * rel;
             }
             else if (SunAngle.Pitch >= 10)
             {
                 TheSun.InternalLights[0].color       = new OpenTK.Vector3(0, 0, 0);
                 TheSunClouds.InternalLights[0].color = new OpenTK.Vector3(0, 0, 0);
                 MainWorldView.DesaturationAmount     = 0.75f;
                 MainWorldView.ambient = BaseAmbient * 0.5f;
                 sl_min   = 0.05f;
                 sl_max   = 0.15f;
                 SkyColor = Location.Zero;
             }
             else
             {
                 sl_min = 0.2f;
                 sl_max = 0.8f;
                 MainWorldView.DesaturationAmount     = 0f;
                 MainWorldView.ambient                = BaseAmbient;
                 TheSun.InternalLights[0].color       = ClientUtilities.Convert(SunLightDef);
                 TheSunClouds.InternalLights[0].color = ClientUtilities.Convert(CloudSunLightDef);
                 SkyColor = SkyApproxColDefault;
             }
             shouldRedrawShadows = true;
         }
         rTicks = 0;
     }
     TheRegion.TickWorld(delta);
 }
Пример #8
0
        void ChunkMarchAndSend()
        {
            // TODO: is this the most efficient it can be?
            int maxChunks   = TheServer.CVars.n_chunkspertick.ValueI;
            int chunksFound = 0;

            if (LoadRelPos.IsNaN() || LoadRelDir.IsNaN() || LoadRelDir.LengthSquared() < 0.1f)
            {
                return;
            }
            Matrix             proj     = Matrix.CreatePerspectiveFieldOfViewRH(Max_FOV * (double)Utilities.PI180, 1, 0.5f, 3000f);
            Matrix             view     = Matrix.CreateLookAtRH((LoadRelPos - LoadRelDir * 8).ToBVector(), (LoadRelPos + LoadRelDir * 8).ToBVector(), new Vector3(0, 0, 1));
            Matrix             combined = view * proj;
            BFrustum           bfs      = new BFrustum(combined);
            Vector3i           start    = TheRegion.ChunkLocFor(LoadRelPos);
            HashSet <Vector3i> seen     = new HashSet <Vector3i>();
            Queue <Vector3i>   toSee    = new Queue <Vector3i>();

            toSee.Enqueue(start);
            while (toSee.Count > 0)
            {
                Vector3i cur = toSee.Dequeue();
                seen.Add(cur);
                if (Math.Abs(cur.X - start.X) > (ViewRadiusInChunks + ViewRadExtra5) ||
                    Math.Abs(cur.Y - start.Y) > (ViewRadiusInChunks + ViewRadExtra5) ||
                    Math.Abs(cur.Z - start.Z) > (ViewRadiusInChunks + ViewRadExtra5Height))
                {
                    continue;
                }
                if (Math.Abs(cur.X - start.X) <= ViewRadiusInChunks &&
                    Math.Abs(cur.Y - start.Y) <= ViewRadiusInChunks &&
                    Math.Abs(cur.Z - start.Z) <= ViewRadiusInChunks)
                {
                    if (TryChunk(cur, 1))
                    {
                        chunksFound++;
                        if (chunksFound > maxChunks)
                        {
                            return;
                        }
                    }
                }
                else if (Math.Abs(cur.X - start.X) <= (ViewRadiusInChunks + ViewRadExtra2) &&
                         Math.Abs(cur.Y - start.Y) <= (ViewRadiusInChunks + ViewRadExtra2) &&
                         Math.Abs(cur.Z - start.Z) <= (ViewRadiusInChunks + ViewRadExtra2Height))
                {
                    if (TryChunk(cur, 2))
                    {
                        chunksFound++;
                        if (chunksFound > maxChunks)
                        {
                            return;
                        }
                    }
                }
                else
                {
                    if (TryChunk(cur, 5))
                    {
                        chunksFound++;
                        if (chunksFound > maxChunks)
                        {
                            return;
                        }
                    }
                }
                for (int i = 0; i < MoveDirs.Length; i++)
                {
                    Vector3i t = cur + MoveDirs[i];
                    if (!seen.Contains(t) && !toSee.Contains(t))
                    {
                        //toSee.Enqueue(t);
                        for (int j = 0; j < MoveDirs.Length; j++)
                        {
                            if (Vector3.Dot(MoveDirs[j].ToVector3(), LoadRelDir.ToBVector()) < -0.8f) // TODO: Wut?
                            {
                                continue;
                            }
                            Vector3i nt = cur + MoveDirs[j];
                            if (!seen.Contains(nt) && !toSee.Contains(nt))
                            {
                                bool  val = false;
                                Chunk ch  = TheRegion.GetChunk(t);
                                if (ch == null)
                                {
                                    val = true;
                                }
                                // TODO: Oh, come on!
                                else if (MoveDirs[i].X == -1)
                                {
                                    if (MoveDirs[j].X == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XP_XM];
                                    }
                                    else if (MoveDirs[j].Y == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XP_YM];
                                    }
                                    else if (MoveDirs[j].Y == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XP_YP];
                                    }
                                    else if (MoveDirs[j].Z == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZM_XP];
                                    }
                                    else if (MoveDirs[j].Z == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_XP];
                                    }
                                }
                                else if (MoveDirs[i].X == 1)
                                {
                                    if (MoveDirs[j].X == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XP_XM];
                                    }
                                    else if (MoveDirs[j].Y == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XM_YM];
                                    }
                                    else if (MoveDirs[j].Y == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XM_YP];
                                    }
                                    else if (MoveDirs[j].Z == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZM_XM];
                                    }
                                    else if (MoveDirs[j].Z == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_XM];
                                    }
                                }
                                else if (MoveDirs[i].Y == -1)
                                {
                                    if (MoveDirs[j].Y == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.YP_YM];
                                    }
                                    else if (MoveDirs[j].X == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XM_YP];
                                    }
                                    else if (MoveDirs[j].X == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XP_YP];
                                    }
                                    else if (MoveDirs[j].Z == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZM_YP];
                                    }
                                    else if (MoveDirs[j].Z == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_YP];
                                    }
                                }
                                else if (MoveDirs[i].Y == 1)
                                {
                                    if (MoveDirs[j].Y == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.YP_YM];
                                    }
                                    else if (MoveDirs[j].X == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XM_YP];
                                    }
                                    else if (MoveDirs[j].X == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.XP_YP];
                                    }
                                    else if (MoveDirs[j].Z == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZM_YP];
                                    }
                                    else if (MoveDirs[j].Z == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_YP];
                                    }
                                }
                                else if (MoveDirs[i].Z == -1)
                                {
                                    if (MoveDirs[j].Z == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_ZM];
                                    }
                                    else if (MoveDirs[j].X == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_XM];
                                    }
                                    else if (MoveDirs[j].X == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_XP];
                                    }
                                    else if (MoveDirs[j].Y == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_YM];
                                    }
                                    else if (MoveDirs[j].Y == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_YP];
                                    }
                                }
                                else if (MoveDirs[i].Z == 1)
                                {
                                    if (MoveDirs[j].Z == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZP_ZM];
                                    }
                                    else if (MoveDirs[j].X == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZM_XM];
                                    }
                                    else if (MoveDirs[j].X == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZM_XP];
                                    }
                                    else if (MoveDirs[j].Y == -1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZM_YM];
                                    }
                                    else if (MoveDirs[j].Y == 1)
                                    {
                                        val = ch.Reachability[(int)ChunkReachability.ZM_YP];
                                    }
                                }
                                if (val)
                                {
                                    Location min = nt.ToLocation() * Chunk.CHUNK_SIZE;
                                    if (bfs.ContainsBox(min, min + new Location(Chunk.CHUNK_SIZE)))
                                    {
                                        toSee.Enqueue(nt);
                                    }
                                    else
                                    {
                                        seen.Add(nt);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #9
0
 // TODO: Efficiency?
 public bool TryChunk(Vector3i cworldPos, int posMult, Chunk chi = null)
 {
     if (pkick)
     {
         return false;
     }
     if (!ChunksAwareOf.ContainsKey(cworldPos) || ChunksAwareOf[cworldPos].LOD > posMult) // TODO: Efficiency - TryGetValue?
     {
         double dist = (cworldPos.ToLocation() * Chunk.CHUNK_SIZE - LoadRelPos).LengthSquared();
         bool async = chi == null && dist > (Chunk.CHUNK_SIZE * Chunk.CHUNK_SIZE * 2 * 2);
         if (async)
         {
             TheRegion.LoadChunk_Background(cworldPos, (chn) =>
             {
                 if (!pkick && chn != null)
                 {
                     ChunkNetwork.SendPacket(new ChunkInfoPacketOut(chn, posMult));
                 }
             });
         }
         else
         {
             Chunk chk = chi != null ? chi : TheRegion.LoadChunk(cworldPos);
             ChunkNetwork.SendPacket(new ChunkInfoPacketOut(chk, posMult));
         }
         ChunksAwareOf.Remove(cworldPos);
         ChunksAwareOf.Add(cworldPos, new ChunkAwarenessInfo() { ChunkPos = cworldPos, LOD = posMult });
         return true;
     }
     return false;
 }