예제 #1
0
        private Color GetBiomeColor(byte biomeId)
        {
            var biome = _biomeUtils.GetBiome(biomeId);
            var c     = biome.Grass;

            //if (Mode == DisplayMode.BiomeFoilage)
            {
                //   c = biome.Foliage;
            }

            int r = (int)((c >> 16) & 0xff);
            int g = (int)((c >> 8) & 0xff);
            int b = (int)c & 0xff;

            //Debug.WriteLine("Biome {0}: {1} {2}", biomeId, biome.Grass, biome.Foliage);

            return(Color.FromArgb(r, g, b));
        }
예제 #2
0
        private Biome GetBiome(float x, float z)
        {
            x /= CoordinateScale;
            z /= CoordinateScale;

            var mX = x + BiomeModifierX.GetValue(x, z);
            var mZ = z + BiomeModifierZ.GetValue(x, z);

            var temp = TempNoise.GetValue(mX, mZ) * 3.024F;
            var rain = RainNoise.GetValue(mX, mZ);

            if (temp < -1f)
            {
                temp = -(temp % 1);
            }
            if (rain < 0)
            {
                rain = -rain;
            }

            return(BiomeUtils.GetBiome(temp, rain));
        }
예제 #3
0
        public virtual void AttemptMobSpawn(BlockCoordinates packCoord, Random random, bool canSpawnPassive, bool canSpawnHostile)
        {
            if (Level.Dimension != Dimension.Overworld)
            {
                return;
            }

            if (Level.Players.Count(player => player.Value.IsSpawned && Vector3.Distance(packCoord, player.Value.KnownPosition) < 24) != 0)
            {
                //if (Log.IsDebugEnabled)
                //	Log.Debug($"Can't spawn entity because players within 24 blocks distance: {blockCoordinates}");
                return;
            }

            if (!canSpawnHostile && !canSpawnPassive)
            {
                // Mob cap reached on all creatures
                return;
            }

            for (int c = 0; c < 2; c++)
            {
                int maxPackSize         = int.MaxValue;
                int numberOfSpawnedMobs = 0;

                EntityType entityType = EntityType.None;

                bool doSpawnHostile = false;
                bool doSpawnPassive = false;
                if (c == 0)
                {
                    if (!canSpawnHostile)
                    {
                        continue;
                    }
                    doSpawnHostile = true;
                }
                else if (c == 1)
                {
                    if (!canSpawnPassive)
                    {
                        continue;
                    }
                    doSpawnPassive = true;
                }

                for (int j = 0; j < 3; j++)
                {
                    int x = packCoord.X;
                    int y = packCoord.Y;
                    int z = packCoord.Z;

                    // The next 3 (k, x and z) random construct heavily weigh the coordinates toward center of pack-origin
                    int k = random.Next(1, 5);
                    for (int i = 0; i < k && numberOfSpawnedMobs < maxPackSize; i++)
                    {
                        x += random.Next(6) - random.Next(6);
                        z += random.Next(6) - random.Next(6);

                        var spawnBlock = Level.GetBlock(x, y - 1, z);
                        //FIXME: The following is wrong. It shouldn't be the same for all mobs and need to be moved into some sort of
                        // entity-based "CanSpawn()" method. But performance need to be handled too, and this is way faster right now.
                        if (spawnBlock is Grass || spawnBlock is Sand || spawnBlock is Gravel || (doSpawnHostile && spawnBlock.IsSolid && !spawnBlock.IsTransparent))
                        {
                            if (entityType == EntityType.None)
                            {
                                entityType = SelectEntityType(spawnBlock, random, doSpawnHostile, doSpawnPassive);
                                if (entityType == EntityType.None)
                                {
                                    if (Log.IsDebugEnabled && doSpawnHostile)
                                    {
                                        Log.Debug($"Failed to spawn because found no proper entity types for biome {BiomeUtils.GetBiome(spawnBlock.BiomeId).Name}");
                                    }
                                    break;
                                }

                                maxPackSize = entityType == EntityType.Wolf ? 8 : entityType == EntityType.Rabbit ? 2 + random.Next(1) : entityType == EntityType.Horse ? 2 + random.Next(5) : entityType == EntityType.Enderman ? 1 + random.Next(4) : 4;
                            }

                            var firstBlock = Level.GetBlock(x, y, z);
                            if (!firstBlock.IsSolid && !(firstBlock is Stationary) && !(firstBlock is Flowing))
                            {
                                if (doSpawnPassive && PassiveMobs.Contains(entityType) &&
                                    Level.GetSubtractedLight(firstBlock.Coordinates, 0) >= 9)
                                {
                                    var secondBlock = Level.GetBlock(x, y + 2, z);
                                    if ((spawnBlock is Grass || (entityType == EntityType.Rabbit && spawnBlock is Sand)) && !secondBlock.IsSolid)
                                    {
                                        var yaw = random.Next(360);

                                        if (Spawn(new PlayerLocation(x + 0.5, y, z + 0.5, yaw + 15, yaw), entityType, random))
                                        {
                                            if (Log.IsDebugEnabled)
                                            {
                                                Log.Warn($"Spawned {entityType}");
                                            }
                                            //Level.StrikeLightning(new PlayerLocation(x + 0.5, y, z + 0.5, yaw + 15, yaw));
                                            //Level.SetBlock(new StainedGlass() { Metadata = (byte)firstBlock.SkyLight, Coordinates = firstBlock.Coordinates + BlockCoordinates.Down });
                                            ++numberOfSpawnedMobs;
                                        }
                                        else
                                        {
                                            if (Log.IsDebugEnabled)
                                            {
                                                Log.Debug($"Failed to spawn {entityType} because area not clear");
                                            }
                                        }
                                    }
                                }
                                else if (doSpawnHostile && HostileMobs.Contains(entityType) && Level.GetSubtractedLight(firstBlock.Coordinates) < random.Next(8))
                                {
                                    var secondBlock = Level.GetBlock(x, y + 1, z);
                                    if (!secondBlock.IsSolid)
                                    {
                                        var yaw = random.Next(360);

                                        if (Spawn(new PlayerLocation(x + 0.5, y, z + 0.5, yaw + 15, yaw), entityType, random))
                                        {
                                            //Level.SetBlock(new StainedGlass() { Metadata = (byte) firstBlock.SkyLight, Coordinates = firstBlock.Coordinates + BlockCoordinates.Down });
                                            //Log.Warn($"Spawned {entityType} at {firstBlock.Coordinates} at light level on bottom={firstBlock.SkyLight} amd top={secondBlock.SkyLight}, world time={Level.CurrentWorldTime}");

                                            ++numberOfSpawnedMobs;
                                        }
                                        else
                                        {
                                            if (Log.IsDebugEnabled)
                                            {
                                                Log.Debug($"Failed to spawn {entityType} because area not clear");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
        public void UpdateLevel()
        {
            Invoke(new MethodInvoker(delegate()
            {
                var chunks = _level.GetLoadedChunks();
                if (chunks.Length == 0)
                {
                    return;
                }

                if (!Monitor.TryEnter(_busy))
                {
                    return;
                }

                var showProgress = _lastUpdateDuration > ShowUpdateProgressThreshold;

                try
                {
                    Busy();

                    var sw = Stopwatch.StartNew();

                    var minChunkX = chunks.Min(c => c.x);
                    var minChunkZ = chunks.Min(c => c.z);

                    var maxChunkX = chunks.Max(c => c.x);
                    var maxChunkZ = chunks.Max(c => c.z);

                    var imageWidth  = (maxChunkX - minChunkX + 1) * 16;
                    var imageHeight = (maxChunkZ - minChunkZ + 1) * 16;

                    var offsetX = Math.Abs(minChunkX * 16);
                    var offsetZ = Math.Abs(minChunkZ * 16);

                    var tot = chunks.Length;

                    Bitmap image;
                    bool usingBase = false;

                    if (_baseImage != null &&
                        imageWidth == _baseImage.Width && imageHeight == _baseImage.Height &&
                        minChunkX == _minChunk.X && minChunkZ == _minChunk.Z &&
                        maxChunkX == _maxChunk.X && maxChunkZ == _maxChunk.Z
                        )
                    {
                        image     = (Bitmap)_baseImage.Clone();
                        usingBase = true;

                        if (tot == _lastChunkCount)
                        {
                            return;
                        }
                    }
                    else
                    {
                        image = new Bitmap(imageWidth, imageHeight);
                    }

                    _lastChunkCount = tot;


                    if (showProgress)
                    {
                        ShowProgress(tot);
                    }

                    var i = 0;
                    foreach (var chunk in chunks)
                    {
                        lock (_chunkSync)
                        {
                            var coords = new ChunkCoordinates(chunk.x, chunk.z);
                            if (_validChunks.Contains(coords))
                            {
                                if (!chunk.isDirty && usingBase)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                _validChunks.Add(coords);
                            }
                        }

                        if (showProgress)
                        {
                            UpdateProgress(i, "Drawing Bitmap");
                        }
                        i++;
                        //Debug.WriteLine("Processing Chunk {0}/{1}", i, tot);
                        for (int x = 0; x < 16; x++)
                        {
                            for (int z = 0; z < 16; z++)
                            {
                                var iX = offsetX + chunk.x * 16 + x;
                                var iZ = offsetZ + chunk.z * 16 + z;

                                //Debug.WriteLine(string.Format("{0} {1} {2} {3} {4} {5} {6} {7}", iX, iZ, imageWidth, imageHeight, offsetX, offsetZ, chunk.x, chunk.z, x, z));
                                var biomeId = chunk.GetBiome(x, z);
                                var color   = GetBiomeColor(biomeId);

                                if (Mode == DisplayMode.Rainfall)
                                {
                                    color = HeatMap.GetColor(0.33M, 0.66M, 1M,
                                                             (decimal)(_biomeUtils.GetBiome(biomeId).Downfall /
                                                                       BiomeMapUtil.MaxBiomeDownfall));
                                }
                                else if (Mode == DisplayMode.Temperature)
                                {
                                    color = HeatMap.GetColor(0.33M, 0.66M, 1M,
                                                             (decimal)(_biomeUtils.GetBiome(biomeId).Temperature /
                                                                       BiomeMapUtil.MaxBiomeTemperature));
                                }

                                image.SetPixel(iX, iZ, color);
                            }
                        }
                    }

                    _baseImage = (Bitmap)image.Clone();

                    foreach (var player in _level.Players.Values.ToArray())
                    {
                        var pX = offsetX + (int)player.KnownPosition.X;
                        var pZ = offsetX + (int)player.KnownPosition.Z;

                        //Debug.WriteLine("Player at " + pX + "," + pZ);
                        var r = 2;

                        for (int x = -r; x <= r; x++)
                        {
                            for (int z = -r; z <= r; z++)
                            {
                                image.SetPixel(pX + x, pZ + z, Color.Black);
                            }
                        }
                    }

                    sw.Stop();
                    _lastUpdateDuration = sw.Elapsed;

                    _minChunk = new ChunkCoordinates(minChunkX, minChunkZ);
                    _maxChunk = new ChunkCoordinates(maxChunkX, maxChunkZ);

                    UpdateImage();

                    //Debug.WriteLine("Drawing Image");
                    statusChunks.Text = tot + " Chunks";
                }
                catch (Exception ex)
                {
                    Log.Error("Exception during bitmap update", ex);
                }
                finally
                {
                    Monitor.Exit(_busy);

                    Busy(false);

                    if (showProgress)
                    {
                        HideProgress();
                    }
                }
            }));
        }