コード例 #1
0
        public WeatherSimulationRegion(WeatherSystemBase ws, int regionX, int regionZ)
        {
            this.ws      = ws;
            this.regionX = regionX;
            this.regionZ = regionZ;

            int regsize = ws.api.World.BlockAccessor.RegionSize;

            cloudTilebasePosX = (regionX * regsize) / ws.CloudTileSize;
            cloudTilebasePosZ = (regionZ * regsize) / ws.CloudTileSize;


            regionCenterPos = new BlockPos(regionX * regsize + regsize / 2, 0, regionZ * regsize + regsize / 2);


            Rand = new LCGRandom(ws.api.World.Seed);
            Rand.InitPositionSeed(regionX / 3, regionZ / 3);
            weatherData.Ambient = new AmbientModifier().EnsurePopulated();

            if (ws.api.Side == EnumAppSide.Client)
            {
                capi = ws.api as ICoreClientAPI;

                weatherData.Ambient.FogColor = capi.Ambient.Base.FogColor.Clone();
            }
            else
            {
                wsServer = ws as WeatherSystemServer;
            }

            ReloadPatterns(ws.api.World.Seed);
        }
コード例 #2
0
        public WeatherSimulationRegion(WeatherSystemBase ws, int regionX, int regionZ)
        {
            this.ws                 = ws;
            this.regionX            = regionX;
            this.regionZ            = regionZ;
            this.SnowAccumSnapshots = new RingArray <SnowAccumSnapshot>((int)(ws.api.World.Calendar.DaysPerYear * ws.api.World.Calendar.HoursPerDay) + 1);


            int regsize = ws.api.World.BlockAccessor.RegionSize;

            LastUpdateTotalHours = ws.api.World.Calendar.TotalHours;

            cloudTilebasePosX = (regionX * regsize) / ws.CloudTileSize;
            cloudTilebasePosZ = (regionZ * regsize) / ws.CloudTileSize;

            regionCenterPos = new BlockPos(regionX * regsize + regsize / 2, 0, regionZ * regsize + regsize / 2);


            Rand = new LCGRandom(ws.api.World.Seed);
            Rand.InitPositionSeed(regionX / 3, regionZ / 3);
            weatherData.Ambient = new AmbientModifier().EnsurePopulated();

            if (ws.api.Side == EnumAppSide.Client)
            {
                capi = ws.api as ICoreClientAPI;

                weatherData.Ambient.FogColor = capi.Ambient.Base.FogColor.Clone();
            }
            else
            {
                wsServer = ws as WeatherSystemServer;
            }

            ReloadPatterns(ws.api.World.Seed);
        }
コード例 #3
0
        public override void GeneratePartial(IServerChunk[] chunks, int chunkX, int chunkZ, int chunkdX, int chunkdZ)
        {
            int fromChunkx = chunkX + chunkdX;
            int fromChunkz = chunkZ + chunkdZ;

            int fromBaseX = fromChunkx * chunksize;
            int fromBaseZ = fromChunkz * chunksize;

            subDepositsToPlace.Clear();

            float qfac = 1f;// chunks.Length / 8f;

            for (int i = 0; i < Deposits.Length; i++)
            {
                DepositVariant variant = Deposits[i];

                /*if (variant.Code != "sphalerite" || chunkdX != 0 || chunkdZ != 0)
                 * {
                 *  continue;
                 * }*/

                float quantityFactor = variant.WithOreMap ? variant.GetOreMapFactor(fromChunkx, fromChunkz) : 1;

                float qModified = qfac * variant.TriesPerChunk * quantityFactor * chanceMultiplier;
                int   quantity  = (int)qModified;
                quantity += chunkRand.NextInt(100) < 100 * (qModified - quantity) ? 1 : 0;

                while (quantity-- > 0)
                {
                    tmpPos.Set(fromBaseX + chunkRand.NextInt(chunksize), -99, fromBaseZ + chunkRand.NextInt(chunksize));
                    long crseed = chunkRand.NextInt(10000000);
                    depositRand.SetWorldSeed(crseed);
                    depositRand.InitPositionSeed(fromChunkx, fromChunkz);

                    GenDeposit(chunks, chunkX, chunkZ, tmpPos, variant);
                }
            }

            foreach (var val in subDepositsToPlace)
            {
                depositRand.SetWorldSeed(chunkRand.NextInt(10000000));
                depositRand.InitPositionSeed(fromChunkx, fromChunkz);

                val.Value.GeneratorInst.GenDeposit(blockAccessor, chunks, chunkX, chunkZ, val.Key, ref subDepositsToPlace);
            }
        }
コード例 #4
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            rnd.InitPositionSeed(chunkX, chunkZ);

            IMapChunk mapChunk = chunks[0].MapChunk;

            IntDataMap2D forestMap  = mapChunk.MapRegion.ForestMap;
            IntDataMap2D shrubMap   = mapChunk.MapRegion.ShrubMap;
            IntDataMap2D climateMap = mapChunk.MapRegion.ClimateMap;
            int          rlX        = chunkX % regionChunkSize;
            int          rlZ        = chunkZ % regionChunkSize;

            float facS = (float)shrubMap.InnerSize / regionChunkSize;

            shrubUpLeft   = shrubMap.GetUnpaddedInt((int)(rlX * facS), (int)(rlZ * facS));
            shrubUpRight  = shrubMap.GetUnpaddedInt((int)(rlX * facS + facS), (int)(rlZ * facS));
            shrubBotLeft  = shrubMap.GetUnpaddedInt((int)(rlX * facS), (int)(rlZ * facS + facS));
            shrubBotRight = shrubMap.GetUnpaddedInt((int)(rlX * facS + facS), (int)(rlZ * facS + facS));

            // A region has 16 chunks
            // Size of the forest map is RegionSize / TerraGenConfig.forestMapScale  => 32*16 / 32  = 16 pixel
            // rlX, rlZ goes from 0..16 pixel
            // facF = 16/16 = 1
            // Get 4 pixels for chunkx, chunkz, chunkx+1 and chunkz+1 inside the map
            float facF = (float)forestMap.InnerSize / regionChunkSize;

            forestUpLeft   = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF));
            forestUpRight  = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF));
            forestBotLeft  = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF + facF));
            forestBotRight = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF + facF));

            float facC = (float)climateMap.InnerSize / regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC + facC));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC + facC));

            heightmap = chunks[0].MapChunk.RainHeightMap;


            structuresIntersectingChunk.Clear();
            api.World.BlockAccessor.WalkStructures(chunkBase.Set(chunkX * chunksize, 0, chunkZ * chunksize), chunkend.Set(chunkX * chunksize + chunksize, chunkMapSizeY * chunksize, chunkZ * chunksize + chunksize), (struc) =>
            {
                if (struc.Code.StartsWith("trader"))
                {
                    structuresIntersectingChunk.Add(struc);
                }
            });

            if (TerraGenConfig.GenerateVegetation)
            {
                genPatches(chunkX, chunkZ, false);
                genShrubs(chunkX, chunkZ);
                genTrees(chunkX, chunkZ);
                genPatches(chunkX, chunkZ, true);
            }
        }
コード例 #5
0
 protected virtual void GenChunkColumn(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
 {
     for (int dx = -chunkRange; dx <= chunkRange; dx++)
     {
         for (int dz = -chunkRange; dz <= chunkRange; dz++)
         {
             chunkRand.InitPositionSeed(chunkX + dx, chunkZ + dz);
             GeneratePartial(chunks, chunkX, chunkZ, dx, dz);
         }
     }
 }
コード例 #6
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            Dictionary <Vec3i, int> ores = new Dictionary <Vec3i, int>();

            for (int cY = 0; cY < chunks.Length; cY++)
            {
                IServerChunk chunk = chunks[cY];
                if (chunk.Blocks == null)
                {
                    continue;
                }
                for (int x = 0; x < chunksize; x++)
                {
                    for (int y = 0; y < chunksize; y++)
                    {
                        for (int z = 0; z < chunksize; z++)
                        {
                            int block = chunk.Blocks[(y * chunksize + z) * chunksize + x];
                            if (surfaceBlocks.ContainsKey(block) && !ores.ContainsKey(new Vec3i(x, y, z)))
                            {
                                ores.Add(new Vec3i(x, y, z), block);
                            }
                        }
                    }
                }
                foreach (var val in ores)
                {
                    Vec3i vec = val.Key;
                    int   ore = val.Value;
                    if (surfaceBlocks.TryGetValue(ore, out int surface))
                    {
                        for (int y = vec.Y; y < chunksize; y++)
                        {
                            rnd.InitPositionSeed(chunkX * vec.X, chunkZ * vec.Z);
                            if (y < 1 || rnd.NextDouble() > 0.1)
                            {
                                continue;
                            }
                            int dX = rnd.NextInt(chunksize), dZ = rnd.NextInt(chunksize);

                            int block  = chunk.Blocks[(y * chunksize + dZ) * chunksize + dX];
                            int dBlock = chunk.Blocks[((y - 1) * chunksize + dZ) * chunksize + dX];
                            if (bA.GetBlock(dBlock).Fertility > 4 && bA.GetBlock(block).IsReplacableBy(bA.GetBlock(ore)) && !bA.GetBlock(block).IsLiquid())
                            {
                                chunk.Blocks[(y * chunksize + dZ) * chunksize + dX] = surface;
                                bA.ScheduleBlockUpdate(new BlockPos(dX, y, dZ));
                            }
                        }
                    }
                }
            }
        }
コード例 #7
0
        internal bool TryGenerate(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos startPos, int climateUpLeft, int climateUpRight, int climateBotLeft, int climateBotRight)
        {
            this.climateUpLeft   = climateUpLeft;
            this.climateUpRight  = climateUpRight;
            this.climateBotLeft  = climateBotLeft;
            this.climateBotRight = climateBotRight;

            startPos.Y += OffsetY;

            rand.InitPositionSeed(startPos.X, startPos.Z);

            return(Generators[(int)Placement](blockAccessor, worldForCollectibleResolve, startPos));
        }
コード例 #8
0
        public void InitDummySim()
        {
            dummySim         = new WeatherSimulationRegion(this, 0, 0);
            dummySim.IsDummy = true;
            dummySim.Initialize();

            var rand = new LCGRandom(api.World.Seed);

            rand.InitPositionSeed(3, 3);

            rainOverlayPattern = new WeatherPattern(this, GeneralConfig.RainOverlayPattern, rand, 0, 0);
            rainOverlayPattern.Initialize(0, api.World.Seed);
            rainOverlayPattern.OnBeginUse();

            rainOverlaySnap = new WeatherDataSnapshot();
        }
コード例 #9
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ)
        {
            rnd.InitPositionSeed(chunkX, chunkZ);
            IMapChunk mapChunk = chunks[0].MapChunk;

            IntDataMap2D climateMap = mapChunk.MapRegion.ClimateMap;
            int          rlX        = chunkX % regionChunkSize;
            int          rlZ        = chunkZ % regionChunkSize;

            float facC = (float)climateMap.InnerSize / regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC + facC));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC + facC));

            heightmap = chunks[0].MapChunk.RainHeightMap;

            genPatches(chunkX, chunkZ);
        }
コード例 #10
0
        public override void GeneratePartial(IServerChunk[] chunks, int chunkX, int chunkZ, int cdx, int cdz)
        {
            int quantityCaves = chunkRand.NextInt(100) < TerraGenConfig.CavesPerChunkColumn * 100 ? 1 : 0;

            while (quantityCaves-- > 0)
            {
                int posX = cdx * chunksize + chunkRand.NextInt(chunksize);
                int posY = chunkRand.NextInt(worldheight - 20) + 8;
                int posZ = cdz * chunksize + chunkRand.NextInt(chunksize);

                float horAngle       = chunkRand.NextFloat() * GameMath.TWOPI;
                float vertAngle      = (chunkRand.NextFloat() - 0.5f) * 0.25f;
                float horizontalSize = chunkRand.NextFloat() * 2 + chunkRand.NextFloat();
                float verticalSize   = 0.75f + chunkRand.NextFloat() * 0.4f;

                if (chunkRand.NextFloat() < 0.04f)
                {
                    horizontalSize = chunkRand.NextFloat() * 2 + chunkRand.NextFloat() + chunkRand.NextFloat();
                    verticalSize   = 0.25f + chunkRand.NextFloat() * 0.2f;
                }
                else
                if (chunkRand.NextFloat() < 0.01f)
                {
                    horizontalSize = 0.75f + chunkRand.NextFloat();
                    verticalSize   = chunkRand.NextFloat() * 2 + chunkRand.NextFloat();
                }

                bool extraBranchy       = (posY < TerraGenConfig.seaLevel / 2) ? chunkRand.NextFloat() < 0.02f : false;
                bool largeNearLavaLayer = chunkRand.NextFloat() < 0.3f;

                float curviness = chunkRand.NextFloat() < 0.01f ? 0.035f : (chunkRand.NextFloat() < 0.03f ? 0.5f : 0.1f);

                int maxIterations = chunkRange * chunksize - chunksize / 2;
                maxIterations = maxIterations - chunkRand.NextInt(maxIterations / 4);

                caveRand.SetWorldSeed(chunkRand.NextInt(10000000));
                caveRand.InitPositionSeed(chunkX + cdx, chunkZ + cdz);
                CarveTunnel(chunks, chunkX, chunkZ, posX, posY, posZ, horAngle, vertAngle, horizontalSize, verticalSize, 0, maxIterations, 0, extraBranchy, curviness, largeNearLavaLayer);
            }
        }
コード例 #11
0
        public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
        {
            if (byEntity.World is IClientWorldAccessor)
            {
                ModelTransform tf = new ModelTransform();
                tf.EnsureDefaultValues();

                float nowx = 0, nowy = 0;

                if (secondsUsed > 0.3f)
                {
                    int cnt = (int)(secondsUsed * 10);
                    rnd.InitPositionSeed(cnt, 0);

                    float targetx = 3f * (rnd.NextFloat() - 0.5f);
                    float targety = 1.5f * (rnd.NextFloat() - 0.5f);

                    float dt = secondsUsed - prevSecUsed;

                    nowx = (curX - targetx) * dt * 2;
                    nowy = (curY - targety) * dt * 2;
                }

                tf.Translation.Set(nowx - Math.Min(1.5f, secondsUsed * 4), nowy, 0);
                byEntity.Controls.UsingHeldItemTransformBefore = tf;

                curX = nowx;
                curY = nowy;

                prevSecUsed = secondsUsed;
            }

            if (api.World.Side == EnumAppSide.Server)
            {
                return(true);
            }

            return(secondsUsed < 4.6f);
        }
コード例 #12
0
        public void GenPalmTree(IBlockAccessor blockAccessor, BlockPos pos, int fruit)
        {
            Block block = blockAccessor.GetBlock(pos.DownCopy());

            if (block.FirstCodePart() == "sand")
            {
                for (int i = 0; i < bottomOffsets.Length; i++)
                {
                    Block d = blockAccessor.GetBlock(pos.X + bottomOffsets[i].X, pos.Y + bottomOffsets[i].Y, pos.Z + bottomOffsets[i].Z);
                    if (d.LiquidCode == "water")
                    {
                        for (int k = 0; k < offsets.Length; k++)
                        {
                            Block c = blockAccessor.GetBlock(pos.X + offsets[i].X, pos.Y + offsets[i].Y, pos.Z + offsets[i].Z);
                            if (c.Class == Class)
                            {
                                return;
                            }
                        }
                        rand.InitPositionSeed(pos.X, pos.Y);
                        Block[] stretchedTrunk = trunk.Stretch((int)(rand.NextDouble() * (maxTreeSize)));

                        BlockPos top = new BlockPos(pos.X, pos.Y + stretchedTrunk.Length, pos.Z);
                        for (int j = 0; j < stretchedTrunk.Length; j++)
                        {
                            blockAccessor.SetBlock(stretchedTrunk[j].BlockId, new BlockPos(pos.X, pos.Y + j, pos.Z));
                        }
                        blockAccessor.SetBlock(tip.BlockId, top);
                        blockAccessor.SpawnBlockEntity("PalmTree", top);

                        GenFrondAndFruits(top, blockAccessor, stretchedTrunk.Length, fruit);
                        break;
                    }
                }
            }
            return;
        }
コード例 #13
0
        private void OnChunkColumnGeneration(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            int seaLevel = api.World.SeaLevel;
            int mapSizeY = api.WorldManager.MapSizeY;

            var veinMaps = chunks[0].MapChunk.MapRegion.GetModdata <Dictionary <string, IntDataMap2D> >("veinmaps");
            var oreMaps  = chunks[0].MapChunk.MapRegion.OreMaps;

            ushort[] heightMap = chunks[0].MapChunk.RainHeightMap;

            int chunksize = api.World.BlockAccessor.ChunkSize;

            int regionChunkSize = api.WorldManager.RegionSize / chunksize;

            int rdx = chunkX % regionChunkSize;
            int rdz = chunkZ % regionChunkSize;

            foreach (var vein in veinMaps)
            {
                if (!DepositByCode.ContainsKey(vein.Key))
                {
                    continue;
                }

                var deposit = DepositByCode[vein.Key];

                Dictionary <int, ResolvedDepositBlock> placeBlockByInBlockId   = deposit.GeneratorInst.GetField <Dictionary <int, ResolvedDepositBlock> >("placeBlockByInBlockId");
                Dictionary <int, ResolvedDepositBlock> surfaceBlockByInBlockId = deposit.GeneratorInst.GetField <Dictionary <int, ResolvedDepositBlock> >("surfaceBlockByInBlockId");

                var oreMap = oreMaps[vein.Key];

                var veinMap = vein.Value;

                float veinStep = (float)veinMap.InnerSize / regionChunkSize;
                float oreStep  = (float)oreMap.InnerSize / regionChunkSize;


                for (int x = 0; x < chunksize; x++)
                {
                    for (int z = 0; z < chunksize; z++)
                    {
                        rand.InitPositionSeed(chunkX + x, chunkZ + z);
                        int dCx = rand.NextInt(9) - 4;
                        int dCz = rand.NextInt(9) - 4;

                        int height = heightMap[z * chunksize + x];

                        veinAtPos.Value    = veinMap.GetInt((int)(rdx * veinStep + x), (int)(rdz * veinStep + z));
                        surfaceAtPos.Value = veinMap.GetInt((int)GameMath.Clamp(rdx * veinStep + (x + dCx), 0, veinMap.Size - 1), (int)GameMath.Clamp(rdz * veinStep + (z + dCz), 0, veinMap.Size - 1));

                        if (veinAtPos.Value == 0 && surfaceAtPos.Value == 0)
                        {
                            continue;
                        }

                        int  oreUpLeft   = oreMap.GetUnpaddedInt((int)(rdx * oreStep), (int)(rdz * oreStep));
                        int  oreUpRight  = oreMap.GetUnpaddedInt((int)(rdx * oreStep + oreStep), (int)(rdz * oreStep));
                        int  oreBotLeft  = oreMap.GetUnpaddedInt((int)(rdx * oreStep), (int)(rdz * oreStep + oreStep));
                        int  oreBotRight = oreMap.GetUnpaddedInt((int)(rdx * oreStep + oreStep), (int)(rdz * oreStep + oreStep));
                        uint oreMapInt   = (uint)GameMath.BiLerp(oreUpLeft, oreUpRight, oreBotLeft, oreBotRight, (float)x / chunksize, (float)z / chunksize);

                        float oreMapRel = ((oreMapInt & ~0xFF00FF) >> 8) / 15f;

                        if (veinAtPos.Rrel > 0.0)
                        {
                            int y = (int)((veinAtPos.Grel * mapSizeY) % height);

                            int depth = (int)(veinAtPos.Rrel * 10) + 1;

                            for (int dy = -depth; dy < depth; dy++)
                            {
                                if (y + dy > 0 && y + dy < mapSizeY)
                                {
                                    int chunkY = (y + dy) / chunksize;
                                    int lY     = (y + dy) % chunksize;

                                    int index3d = (chunksize * lY + z) * chunksize + x;
                                    int blockId = chunks[chunkY].Blocks[index3d];
                                    if (placeBlockByInBlockId?.ContainsKey(blockId) ?? false)
                                    {
                                        var blocks = placeBlockByInBlockId[blockId].Blocks;

                                        chunks[chunkY].Blocks[index3d] = blocks[(int)(oreMapRel * (blocks.Length - 1))].Id;

                                        if (deposit.ChildDeposits != null)
                                        {
                                            foreach (var child in deposit.ChildDeposits)
                                            {
                                                if (veinAtPos.Brel > 0.5)
                                                {
                                                    Dictionary <int, ResolvedDepositBlock> childPlaceBlockByInBlockId   = child.GeneratorInst.GetField <Dictionary <int, ResolvedDepositBlock> >("placeBlockByInBlockId");
                                                    Dictionary <int, ResolvedDepositBlock> childSurfaceBlockByInBlockId = child.GeneratorInst.GetField <Dictionary <int, ResolvedDepositBlock> >("surfaceBlockByInBlockId");

                                                    if (childPlaceBlockByInBlockId.ContainsKey(blockId))
                                                    {
                                                        blocks = childPlaceBlockByInBlockId[blockId].Blocks;
                                                        chunks[chunkY].Blocks[index3d] = blocks[(int)(oreMapRel * (blocks.Length - 1))].Id;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (surfaceAtPos.Rrel > 0.0)
                        {
                            //gen surface deposits
                            int y = (int)((surfaceAtPos.Grel * mapSizeY) % height);

                            int chunkY = y / chunksize;
                            int lY     = y % chunksize;

                            int index3d = (chunksize * lY + z) * chunksize + x;
                            int blockId = chunks[chunkY].Blocks[index3d];

                            if (surfaceBlockByInBlockId?.ContainsKey(blockId) ?? false)
                            {
                                if (height < mapSizeY && surfaceAtPos.Brel > 0.5f)
                                {
                                    Block belowBlock = api.World.Blocks[chunks[height / chunksize].Blocks[(height % chunksize * chunksize + z) * chunksize + x]];

                                    index3d = ((height + 1) % chunksize * chunksize + z) * chunksize + x;
                                    if (belowBlock.SideSolid[BlockFacing.UP.Index] && chunks[(height + 1) / chunksize].Blocks[index3d] == 0)
                                    {
                                        chunks[(height + 1) / chunksize].Blocks[index3d] = surfaceBlockByInBlockId[blockId].Blocks[0].BlockId;
#if DEBUG
                                        //so I can see it better when debugging
                                        index3d = (height % chunksize * chunksize + z) * chunksize + x;
                                        chunks[height / chunksize].Blocks[index3d] = 1;
#endif
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #14
0
        private void OnChunkColumnGeneration(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            rnd.InitPositionSeed(chunkX, chunkZ);

            IntDataMap2D forestMap  = chunks[0].MapChunk.MapRegion.ForestMap;
            IntDataMap2D climateMap = chunks[0].MapChunk.MapRegion.ClimateMap;
            IntDataMap2D beachMap   = chunks[0].MapChunk.MapRegion.BeachMap;

            ushort[] heightMap = chunks[0].MapChunk.RainHeightMap;

            int regionChunkSize = api.WorldManager.RegionSize / chunksize;
            int rdx             = chunkX % regionChunkSize;
            int rdz             = chunkZ % regionChunkSize;

            // Amount of data points per chunk
            float climateStep = (float)climateMap.InnerSize / regionChunkSize;
            float forestStep  = (float)forestMap.InnerSize / regionChunkSize;
            float beachStep   = (float)beachMap.InnerSize / regionChunkSize;

            // Retrieves the map data on the chunk edges
            int forestUpLeft   = forestMap.GetUnpaddedInt((int)(rdx * forestStep), (int)(rdz * forestStep));
            int forestUpRight  = forestMap.GetUnpaddedInt((int)(rdx * forestStep + forestStep), (int)(rdz * forestStep));
            int forestBotLeft  = forestMap.GetUnpaddedInt((int)(rdx * forestStep), (int)(rdz * forestStep + forestStep));
            int forestBotRight = forestMap.GetUnpaddedInt((int)(rdx * forestStep + forestStep), (int)(rdz * forestStep + forestStep));

            int beachUpLeft   = beachMap.GetUnpaddedInt((int)(rdx * beachStep), (int)(rdz * beachStep));
            int beachUpRight  = beachMap.GetUnpaddedInt((int)(rdx * beachStep + beachStep), (int)(rdz * beachStep));
            int beachBotLeft  = beachMap.GetUnpaddedInt((int)(rdx * beachStep), (int)(rdz * beachStep + beachStep));
            int beachBotRight = beachMap.GetUnpaddedInt((int)(rdx * beachStep + beachStep), (int)(rdz * beachStep + beachStep));


            // increasing x -> left to right
            // increasing z -> top to bottom

            float transitionSize = blockLayerConfig.blockLayerTransitionSize;


            for (int x = 0; x < chunksize; x++)
            {
                for (int z = 0; z < chunksize; z++)
                {
                    // Some weird randomnes stuff to hide fundamental bugs in the climate transition system :D T_T   (maybe not bugs but just fundamental shortcomings of using lerp on a very low resolution map)
                    float distx = (float)distort2dx.Noise(chunkX * chunksize + x, chunkZ * chunksize + z);
                    float distz = (float)distort2dz.Noise(chunkX * chunksize + x, chunkZ * chunksize + z);

                    double posRand        = (double)GameMath.MurmurHash3(x + chunkX * chunksize, 1, z + chunkZ * chunksize) / int.MaxValue;
                    double transitionRand = (posRand + 1) * transitionSize;

                    int posY = heightMap[z * chunksize + x];

                    int climate = climateMap.GetUnpaddedColorLerped(
                        rdx * climateStep + climateStep * (float)(x + distx) / chunksize,
                        rdz * climateStep + climateStep * (float)(z + distz) / chunksize
                        );

                    int   tempUnscaled = (climate >> 16) & 0xff;
                    int   rnd          = (int)(distx / 5);
                    float temp         = TerraGenConfig.GetScaledAdjustedTemperatureFloat(tempUnscaled, posY - TerraGenConfig.seaLevel + rnd);
                    float tempRel      = TerraGenConfig.GetAdjustedTemperature(tempUnscaled, posY - TerraGenConfig.seaLevel + rnd) / 255f;
                    float rainRel      = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, posY + rnd) / 255f;
                    float forestRel    = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, (float)x / chunksize, (float)z / chunksize) / 255f;
                    float beachRel     = GameMath.BiLerp(beachUpLeft, beachUpRight, beachBotLeft, beachBotRight, (float)x / chunksize, (float)z / chunksize) / 255f;

                    int prevY = posY;

                    posY = PutLayers(transitionRand, x, posY, z, chunks, rainRel, temp, tempUnscaled, heightMap);
                    int blockID = chunks[0].MapChunk.TopRockIdMap[z * chunksize + x];

                    GenBeach(x, prevY, z, chunks, rainRel, temp, beachRel, blockID);
                    PlaceTallGrass(x, prevY, z, chunks, rainRel, tempRel, temp, forestRel);


                    // Try again to put layers if above sealevel and we found over 10 air blocks
                    int foundAir = 0;
                    while (posY >= TerraGenConfig.seaLevel - 1)
                    {
                        int chunkY  = posY / chunksize;
                        int lY      = posY % chunksize;
                        int index3d = (chunksize * lY + z) * chunksize + x;
                        int blockId = chunks[chunkY].Blocks[index3d];

                        if (blockId == 0)
                        {
                            foundAir++;
                        }
                        else
                        {
                            if (foundAir >= 8)
                            {
                                //temp = TerraGenConfig.GetScaledAdjustedTemperatureFloat(tempUnscaled, posY - TerraGenConfig.seaLevel);
                                //rainRel = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, posY) / 255f;
                                //PutLayers(transitionRand, x, posY, z, chunks, rainRel, temp, tempUnscaled, null);
                                break;
                            }
                            else
                            {
                                foundAir = 0;
                            }
                        }

                        posY--;
                    }
                }
            }
        }
コード例 #15
0
        public void OnApply(WorldEdit worldEdit, int oldBlockId, BlockSelection blockSel, ItemStack withItemStack, bool isbreak = false)
        {
            if (Quantity == 0 || Radius == 0)
            {
                return;
            }

            float radSq = Radius * Radius;
            float q     = Quantity;

            Block block = blockAccessRev.GetBlock(blockSel.Position);

            if (isbreak)
            {
                block = blockAccessRev.GetBlock(0);
            }

            int quantityBlocks = (int)(GameMath.PI * radSq);

            if (!worldEdit.MayPlace(block, (int)q))
            {
                return;
            }

            if (oldBlockId >= 0)
            {
                worldEdit.sapi.World.BlockAccessor.SetBlock(oldBlockId, blockSel.Position);
            }
            lcgRand.SetWorldSeed(rand.Next());
            lcgRand.InitPositionSeed(blockSel.Position.X / blockAccessRev.ChunkSize, blockSel.Position.Z / blockAccessRev.ChunkSize);

            int xRadInt = (int)Math.Ceiling(Radius);
            int yRadInt = (int)Math.Ceiling(Radius);
            int zRadInt = (int)Math.Ceiling(Radius);

            HashSet <BlockPos> viablePositions = new HashSet <BlockPos>();
            BlockPos           dpos, ddpos;
            Block            testblock;
            EnumAirBrushMode mode = Mode;

            for (int dx = -xRadInt; dx <= xRadInt; dx++)
            {
                for (int dy = -yRadInt; dy <= yRadInt; dy++)
                {
                    for (int dz = -zRadInt; dz <= zRadInt; dz++)
                    {
                        if (dx * dx + dy * dy + dz * dz > radSq)
                        {
                            continue;
                        }

                        dpos      = blockSel.Position.AddCopy(dx, dy, dz);
                        testblock = blockAccessRev.GetBlock(dpos);
                        if (testblock.Replaceable >= 6000)
                        {
                            continue;
                        }

                        for (int i = 0; i < BlockFacing.NumberOfFaces; i++)
                        {
                            if (Apply == EnumAirBrushApply.SelectedFace && BlockFacing.ALLFACES[i] != blockSel.Face)
                            {
                                continue;
                            }

                            ddpos = dpos.AddCopy(BlockFacing.ALLFACES[i]);
                            Block dblock = blockAccessRev.GetBlock(ddpos);
                            if (dblock.Replaceable >= 6000 && (dblock.IsLiquid() == block.IsLiquid()))
                            {
                                // We found an air block beside a solid block -> let's remember that air block and keep looking
                                if (mode == EnumAirBrushMode.Add)
                                {
                                    viablePositions.Add(ddpos);
                                }
                                else
                                // We found an air block beside a solid block -> let's remember that solid block for removal and we can stop here
                                {
                                    viablePositions.Add(dpos);
                                }
                            }
                        }
                    }
                }
            }

            List <BlockPos> viablePositionsList = new List <BlockPos>(viablePositions);

            while (q-- > 0)
            {
                if (viablePositionsList.Count == 0)
                {
                    break;
                }

                if (q < 1 && rand.NextDouble() > q)
                {
                    break;
                }

                int index = rand.Next(viablePositionsList.Count);
                dpos = viablePositionsList[index];
                viablePositionsList.RemoveAt(index);

                if (mode == EnumAirBrushMode.Add)
                {
                    block.TryPlaceBlockForWorldGen(blockAccessRev, dpos, BlockFacing.UP, lcgRand);
                }
                else
                {
                    blockAccessRev.SetBlock(block.BlockId, dpos, withItemStack);
                }
            }

            if (oldBlockId >= 0)
            {
                blockAccessRev.SetHistoryStateBlock(blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z, oldBlockId, blockAccessRev.GetBlockId(blockSel.Position));
            }

            blockAccessRev.Commit();


            return;
        }
コード例 #16
0
        private void DoGenStructures(IMapRegion region, int chunkX, int chunkZ, bool postPass, ITreeAttribute chunkGenParams = null)
        {
            BlockPos pos = new BlockPos();

            ITreeAttribute chanceModTree      = null;
            ITreeAttribute maxQuantityModTree = null;

            if (chunkGenParams?["structureChanceModifier"] != null)
            {
                chanceModTree = chunkGenParams["structureChanceModifier"] as TreeAttribute;
            }
            if (chunkGenParams?["structureMaxCount"] != null)
            {
                maxQuantityModTree = chunkGenParams["structureMaxCount"] as TreeAttribute;
            }


            strucRand.InitPositionSeed(chunkX, chunkZ);

            scfg.Structures.Shuffle(strucRand);

            for (int i = 0; i < scfg.Structures.Length; i++)
            {
                WorldGenStructure struc = scfg.Structures[i];
                if (struc.PostPass != postPass)
                {
                    continue;
                }

                float chance     = struc.Chance * scfg.ChanceMultiplier;
                int   toGenerate = 9999;
                if (chanceModTree != null)
                {
                    chance *= chanceModTree.GetFloat(struc.Code, 0);
                }

                if (maxQuantityModTree != null)
                {
                    toGenerate = maxQuantityModTree.GetInt(struc.Code, 9999);
                }


                while (chance-- > strucRand.NextDouble() && toGenerate > 0)
                {
                    int dx       = strucRand.NextInt(chunksize);
                    int dz       = strucRand.NextInt(chunksize);
                    int ySurface = heightmap[dz * chunksize + dx];
                    if (ySurface <= 0 || ySurface >= worldheight - 15)
                    {
                        continue;
                    }

                    if (struc.Placement == EnumStructurePlacement.Underground)
                    {
                        if (struc.Depth != null)
                        {
                            pos.Set(chunkX * chunksize + dx, ySurface - (int)struc.Depth.nextFloat(1, strucRand), chunkZ * chunksize + dz);
                        }
                        else
                        {
                            pos.Set(chunkX * chunksize + dx, 8 + strucRand.NextInt(ySurface - 8 - 5), chunkZ * chunksize + dz);
                        }
                    }
                    else
                    {
                        pos.Set(chunkX * chunksize + dx, ySurface, chunkZ * chunksize + dz);
                    }

                    if (struc.TryGenerate(worldgenBlockAccessor, api.World, pos, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight))
                    {
                        Cuboidi loc = struc.LastPlacedSchematicLocation;

                        string code = struc.Code + (struc.LastPlacedSchematic == null ? "" : "/" + struc.LastPlacedSchematic.FromFileName);

                        region.GeneratedStructures.Add(new GeneratedStructure()
                        {
                            Code = code, Group = struc.Group, Location = loc.Clone()
                        });
                        region.DirtyForSaving = true;

                        if (struc.BuildProtected)
                        {
                            api.World.Claims.Add(new LandClaim()
                            {
                                Areas = new List <Cuboidi>()
                                {
                                    loc.Clone()
                                },
                                Description        = struc.BuildProtectionDesc,
                                ProtectionLevel    = 10,
                                LastKnownOwnerName = struc.BuildProtectionName,
                                AllowUse           = true
                            });
                        }

                        toGenerate--;
                    }
                }
            }
        }
コード例 #17
0
        public bool TryGenerate(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos pos, int climateUpLeft, int climateUpRight, int climateBotLeft, int climateBotRight, DidGenerate didGenerateStructure)
        {
            this.climateUpLeft   = climateUpLeft;
            this.climateUpRight  = climateUpRight;
            this.climateBotLeft  = climateBotLeft;
            this.climateBotRight = climateBotRight;

            float    cnt         = QuantityStructures.nextFloat();
            int      minQuantity = (int)cnt;
            BlockPos schemPos    = pos.Copy();
            Cuboidi  location    = new Cuboidi();

            rand.InitPositionSeed(pos.X, pos.Z);

            List <GeneratableStructure> generatables = new List <GeneratableStructure>();

            while (cnt-- > 0)
            {
                if (cnt < 1 && rand.NextDouble() > cnt)
                {
                    break;
                }

                int tries = 30;
                while (tries-- > 0)
                {
                    schemPos.Set(pos);
                    schemPos.Add(rand.NextInt(50) - 25, 0, rand.NextInt(50) - 25);
                    schemPos.Y = blockAccessor.GetTerrainMapheightAt(schemPos);

                    double           rndVal = rand.NextDouble() * totalWeight;
                    int              i      = 0;
                    VillageSchematic schem  = null;
                    while (rndVal > 0)
                    {
                        schem   = Schematics[i++];
                        rndVal -= schem.Weight;
                    }
                    BlockSchematicStructure struc = GetGeneratableStructure(schem, blockAccessor, worldForCollectibleResolve, schemPos);

                    if (struc != null)
                    {
                        location.Set(schemPos.X, schemPos.Y, schemPos.Z, schemPos.X + struc.SizeX, schemPos.Y + struc.SizeY, schemPos.Z + struc.SizeZ);
                        bool intersect = false;
                        for (int k = 0; k < generatables.Count; k++)
                        {
                            if (location.IntersectsOrTouches(generatables[k].location))
                            {
                                intersect = true;
                                break;
                            }
                        }

                        if (!intersect)
                        {
                            generatables.Add(new GeneratableStructure()
                            {
                                struc = struc, pos = schemPos.Copy(), location = location.Clone()
                            });
                        }
                        break;
                    }
                }
            }

            if (generatables.Count >= minQuantity)
            {
                foreach (var val in generatables)
                {
                    val.struc.PlaceRespectingBlockLayers(blockAccessor, worldForCollectibleResolve, val.pos, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight, replaceblockids);
                    didGenerateStructure(val.location, val.struc);
                }
            }

            return(true);
        }
コード例 #18
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            ushort[] heightMap = chunks[0].MapChunk.RainHeightMap;

            int regionChunkSize = Api.WorldManager.RegionSize / chunksize;
            int rdx             = chunkX % regionChunkSize;
            int rdz             = chunkZ % regionChunkSize;

            for (int x = 0; x < chunksize; x++)
            {
                for (int z = 0; z < chunksize; z++)
                {
                    double noise = sNoise.Noise(chunkX * chunksize + x, chunkZ * chunksize + z);

                    int y       = heightMap[z * chunksize + x];
                    int chunkY  = y / chunksize;
                    int lY      = y % chunksize;
                    int index3d = (chunksize * lY + z) * chunksize + x;
                    int bID     = chunks[chunkY].Blocks[index3d];
                    if (bID == 0 || bA.GetBlock(bID).LiquidCode != null)
                    {
                        continue;
                    }

                    int tY       = heightMap[z * chunksize + x] + 1;
                    int tChunkY  = tY / chunksize;
                    int tlY      = tY % chunksize;
                    int tIndex3d = (chunksize * tlY + z) * chunksize + x;

                    int    rockID = chunks[0].MapChunk.TopRockIdMap[z * chunksize + x];
                    string rock   = bA.GetBlock(rockID).Variant["rock"];

                    rand.InitPositionSeed(rdx + x, rdz + z);

                    var deposits = Deposits.Shuffle(rand);

                    for (int i = 0; i < Deposits.Length; i++)
                    {
                        double dnoise = sNoise.Noise(rdx + x + i + 4987, rdz + z + i + 15654);
                        if (dnoise > 0.9)
                        {
                            continue;
                        }

                        DepositVariant variant = Deposits[i];
                        if (!variant.WithOreMap)
                        {
                            continue;
                        }
                        float factor = variant.GetOreMapFactor(chunkX, chunkZ);
                        factor *= (float)genProperties.GlobalMult;

                        if (factor > 0 && factor > noise)
                        {
                            int?placed = bA.GetBlock(new AssetLocation(variant.Attributes.Token["placeblock"]["code"].ToString().Replace("{rock}", rock).Replace("*", "poor")))?.Id;
                            if (placed == null || !surfaceBlocks.ContainsKey((int)placed))
                            {
                                continue;
                            }

                            chunks[tChunkY].Blocks[tIndex3d] = surfaceBlocks[(int)placed];
                            chunks[tChunkY].MarkModified();
                            break;
                        }
                    }
                }
            }
        }
コード例 #19
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            rand.InitPositionSeed(chunkX, chunkZ);

            ushort[] heightmap = chunks[0].MapChunk.RainHeightMap;

            IntDataMap2D climateMap      = chunks[0].MapChunk.MapRegion.ClimateMap;
            int          regionChunkSize = api.WorldManager.RegionSize / chunksize;
            float        fac             = (float)climateMap.InnerSize / regionChunkSize;
            int          rlX             = chunkX % regionChunkSize;
            int          rlZ             = chunkZ % regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac + fac));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac + fac));

            int climateMid = GameMath.BiLerpRgbColor(0.5f, 0.5f, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

            // 16-23 bits = Red = temperature
            // 8-15 bits = Green = rain
            // 0-7 bits = Blue = humidity

            int rain     = (climateMid >> 8) & 0xff;
            int humidity = climateMid & 0xff;
            int temp     = (climateMid >> 16) & 0xff;

            // Lake density at chunk center
            float pondDensity = 4 * (rain + humidity) / 255f;

            float sealeveltemp = TerraGenConfig.GetScaledAdjustedTemperatureFloat(temp, 0);

            // Less lakes where its below -5 degrees
            pondDensity -= Math.Max(0, 5 - sealeveltemp);

            float maxTries = pondDensity * 10;

            int dx, dz;

            int baseX = chunkX * chunksize;
            int baseZ = chunkZ * chunksize;


            while (maxTries-- > 0)
            {
                if (maxTries < 1 && rand.NextDouble() > maxTries)
                {
                    break;
                }

                dx = rand.NextInt(chunksize);
                dz = rand.NextInt(chunksize);

                pondYPos = heightmap[dz * chunksize + dx] + 1;
                if (pondYPos <= 0 || pondYPos >= mapheight - 1)
                {
                    return;
                }

                TryPlacePondAt(dx, pondYPos, dz, chunkX, chunkZ);
            }

            maxTries = 600;
            while (maxTries-- > 0)
            {
                if (maxTries < 1 && rand.NextDouble() > maxTries)
                {
                    break;
                }

                dx = rand.NextInt(chunksize);
                dz = rand.NextInt(chunksize);

                pondYPos = (int)(rand.NextDouble() * heightmap[dz * chunksize + dx]);
                if (pondYPos <= 0 || pondYPos >= mapheight - 1)
                {
                    return;
                }

                int chunkY  = pondYPos / chunksize;
                int dy      = pondYPos % chunksize;
                int blockID = chunks[chunkY].Blocks[(dy * chunksize + dz) * chunksize + dx];

                while (blockID == 0 && pondYPos > 20)
                {
                    pondYPos--;

                    chunkY  = pondYPos / chunksize;
                    dy      = pondYPos % chunksize;
                    blockID = chunks[chunkY].Blocks[(dy * chunksize + dz) * chunksize + dx];

                    if (blockID != 0)
                    {
                        //blockAccessor.SetBlock(63, new BlockPos(dx + baseX, pondYPos, dz + baseZ));
                        TryPlacePondAt(dx, pondYPos, dz, chunkX, chunkZ);
                    }
                }
            }
        }