Example #1
0
        /// <summary>
        /// Cache index to the list of scaled shapeable typeface
        /// </summary>
        private void CacheScaledTypefaceMap(
            CharacterBufferRange unicodeString,
            CultureInfo culture,
            CultureInfo digitCulture,
            SpanVector scaledTypefaceSpans,
            ref SpanVector <int> cachedScaledTypefaceIndexSpans,
            int ichItem
            )
        {
            IntMap map;

            if (!_intMaps.TryGetValue(culture, out map))
            {
                map = new IntMap();
                _intMaps.Add(culture, map);
            }

            DigitMap digitMap = new DigitMap(digitCulture);

            SpanRider typefaceSpanRider = new SpanRider(scaledTypefaceSpans);

            int ich = 0;

            while (ich < unicodeString.Length)
            {
                typefaceSpanRider.At(ich);

                int cch = Math.Min(unicodeString.Length - ich, typefaceSpanRider.Length);

                int index = IndexOfScaledTypeface((ScaledShapeTypeface)typefaceSpanRider.CurrentElement);
                Debug.Assert(index >= 0, "Invalid scaled shapeable typeface index spans");

                cachedScaledTypefaceIndexSpans.Set(ichItem + ich, cch, index);

                // we keep index + 1 in the map, so that we leave map entry zero
                // to indicate uninitialized entry.
                index++;

                int sizeofChar;
                for (int c = 0; c < cch; c += sizeofChar)
                {
                    int ch = digitMap[
                        Classification.UnicodeScalar(
                            new CharacterBufferRange(unicodeString, ich + c, unicodeString.Length - ich - c),
                            out sizeofChar
                            )
                             ];

                    // only cache typeface map index for base characters
                    if (!Classification.IsCombining(ch) && !Classification.IsJoiner(ch))
                    {
                        // Dump values of local variables when the condition fails for better debuggability.
                        // We use "if" to avoid the expensive string.Format() in normal case.
                        if (map[ch] != 0 && map[ch] != index)
                        {
                            Invariant.Assert(
                                false,
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    "shapeable cache stores conflicting info, ch = {0}, map[ch] = {1}, index = {2}",
                                    ch, map[ch], index
                                    )
                                );
                        }

                        map[ch] = (ushort)index;
                    }
                }

                ich += cch;
            }
        }
Example #2
0
        public void genBlockColumn(IServerChunk[] chunks, int chunkX, int chunkZ, int lx, int lz)
        {
            int surfaceY = heightMap[lz * chunksize + lx];
            int ylower   = 1;
            int yupper   = surfaceY;

            strataThickness = 0;

            WeightedIndex[] indices = map[
                chunkInRegionX + lx * lerpMapInv,
                chunkInRegionZ + lz * lerpMapInv
                                      ];
            rockGroupMaxThickness[0]     = rockGroupMaxThickness[1] = rockGroupMaxThickness[2] = rockGroupMaxThickness[3] = 0;
            rockGroupCurrentThickness[0] = rockGroupCurrentThickness[1] = rockGroupCurrentThickness[2] = rockGroupCurrentThickness[3] = 0;

            for (int i = 0; i < indices.Length; i++)
            {
                float w = indices[i].Weight;

                GeologicProvinceVariant var = provinces.Variants[indices[i].Index];

                rockGroupMaxThickness[0] += var.RockStrataIndexed[0].MaxThickness * w;
                rockGroupMaxThickness[1] += var.RockStrataIndexed[1].MaxThickness * w;
                rockGroupMaxThickness[2] += var.RockStrataIndexed[2].MaxThickness * w;
                rockGroupMaxThickness[3] += var.RockStrataIndexed[3].MaxThickness * w;
            }



            float distx = (float)distort2dx.Noise(chunkX * chunksize + lx, chunkZ * chunksize + lz);
            float distz = (float)distort2dz.Noise(chunkX * chunksize + lx, chunkZ * chunksize + lz);


            rockStrataId = -1;

            while (ylower <= yupper)
            {
                if (--strataThickness <= 0)
                {
                    rockStrataId++;
                    if (rockStrataId >= strata.Variants.Length)
                    {
                        break;
                    }
                    stratum = strata.Variants[rockStrataId];
                    rockMap = mapChunk.MapRegion.RockStrata[rockStrataId];
                    step    = (float)rockMap.InnerSize / regionChunkSize;

                    grp = (int)stratum.RockGroup;

                    float thicknessDistort = GameMath.Clamp((distx + distz) / 30, 0.9f, 1.1f);

                    float allowedThickness = rockGroupMaxThickness[grp] * thicknessDistort - rockGroupCurrentThickness[grp];

                    strataThickness = Math.Min(allowedThickness, rockMap.GetIntLerpedCorrectly(rdx * step + step * (float)(lx + distx) / chunksize, rdz * step + step * (float)(lz + distz) / chunksize));

                    strataThickness -= (stratum.RockGroup == EnumRockGroup.Sedimentary) ? Math.Max(0, yupper - TerraGenConfig.seaLevel) * 0.5f : 0;

                    if (strataThickness < 2)
                    {
                        strataThickness = -1;
                        continue;
                    }
                }

                rockGroupCurrentThickness[grp]++;

                if (stratum.GenDir == EnumStratumGenDir.BottomUp)
                {
                    int chunkY       = ylower / chunksize;
                    int lY           = ylower - chunkY * chunksize;
                    int localIndex3D = (chunksize * lY + lz) * chunksize + lx;

                    if (chunks[chunkY].Blocks[localIndex3D] == rockBlockId)
                    {
                        chunks[chunkY].Blocks[localIndex3D] = stratum.BlockId;
                    }

                    ylower++;
                }
                else
                {
                    int chunkY       = yupper / chunksize;
                    int lY           = yupper - chunkY * chunksize;
                    int localIndex3D = (chunksize * lY + lz) * chunksize + lx;

                    if (chunks[chunkY].Blocks[localIndex3D] == rockBlockId)
                    {
                        chunks[chunkY].Blocks[localIndex3D] = stratum.BlockId;
                    }

                    yupper--;
                }
            }
        }
Example #3
0
        private void OnChunkColumnGeneration(IServerChunk[] chunks, int chunkX, int chunkZ)
        {
            IntMap forestMap  = chunks[0].MapChunk.MapRegion.ForestMap;
            IntMap climateMap = chunks[0].MapChunk.MapRegion.ClimateMap;

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

            int regionChunkSize = api.WorldManager.RegionSize / chunksize;
            int rlX             = chunkX % regionChunkSize;
            int rlZ             = chunkZ % regionChunkSize;

            // "Pixels per chunk"
            float facF = (float)forestMap.InnerSize / regionChunkSize;

            // Retrieves the map data on the chunk edges
            int forestUpLeft   = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF));
            int forestUpRight  = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF));
            int forestBotLeft  = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF + facF));
            int forestBotRight = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF + facF));

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



            for (int x = 0; x < chunksize; x++)
            {
                for (int z = 0; z < chunksize; z++)
                {
                    int posY = heightMap[z * chunksize + x];

                    int   climate      = GameMath.BiLerpRgbColor((float)x / chunksize, (float)z / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);
                    int   tempUnscaled = (climate >> 16) & 0xff;
                    float temp         = TerraGenConfig.GetScaledAdjustedTemperatureFloat(tempUnscaled, posY - TerraGenConfig.seaLevel);
                    float rainRel      = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, posY) / 255f;
                    float forestRel    = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, (float)x / chunksize, (float)z / chunksize) / 255f;

                    int prevY = posY;

                    posY = PutLayers(x, posY, z, chunks, rainRel, temp, tempUnscaled, heightMap);
                    PlaceTallGrass(x, prevY, z, chunks, rainRel, 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;
                        ushort 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(x, posY, z, chunks, rainRel, temp, tempUnscaled, null);
                                break;
                            }
                            else
                            {
                                foundAir = 0;
                            }
                        }

                        posY--;
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// forceInitialPosY is for subdeposits
        /// </summary>
        /// <param name="chunks"></param>
        /// <param name="chunkX"></param>
        /// <param name="chunkZ"></param>
        /// <param name="offsetX"></param>
        /// <param name="offsetZ"></param>
        /// <param name="variant"></param>
        /// <param name="forceInitialPosY"></param>
        /// <returns></returns>
        Dictionary <Vec3i, DepositVariant> GenDeposit(IServerChunk[] chunks, int chunkX, int chunkZ, int offsetX, int offsetZ, DepositVariant variant, int?forceInitialPosY = null)
        {
            Dictionary <Vec3i, DepositVariant> SubDepositsToPlace = new Dictionary <Vec3i, DepositVariant>();

            IMapChunk mapchunk = chunks[0].MapChunk;

            int radius = Math.Min(64, (int)variant.Radius.nextFloat(1, depositRand));

            if (radius <= 0)
            {
                return(SubDepositsToPlace);
            }

            // Let's deform that perfect circle a bit (+/- 25%)
            float deform  = GameMath.Clamp(depositRand.NextFloat() - 0.5f, -0.25f, 0.25f);
            int   radiusX = radius - (int)(radius * deform);
            int   radiusZ = radius + (int)(radius * deform);
            int   posY;

            // No need to caluclate further if this deposit won't be part of this chunk
            if (radiusX + offsetX < 0 || radiusZ + offsetZ < 0 || offsetX - radiusX >= chunksize || offsetZ - radiusZ >= chunksize)
            {
                return(SubDepositsToPlace);
            }


            IMapChunk originMapchunk = null;
            int       origPosY       = 0;

            int lx = GameMath.Mod(offsetX, chunksize);
            int lz = GameMath.Mod(offsetZ, chunksize);

            if (variant.MaxY < 1 || variant.CheckClimate)
            {
                originMapchunk = api.WorldManager.GetMapChunk((chunkX * chunksize + offsetX) / chunksize, (chunkZ * chunksize + offsetZ) / chunksize);
                if (originMapchunk == null)
                {
                    return(SubDepositsToPlace);                        // argh >.<
                }
                origPosY = originMapchunk.RainHeightMap[lz * chunksize + lx];
                if ((float)origPosY / api.World.BlockAccessor.MapSizeY > variant.MaxY)
                {
                    return(SubDepositsToPlace);
                }
            }



            // Check if suited for this area, climate wise
            if (variant.CheckClimate)
            {
                IntMap climateMap = api.World.BlockAccessor.GetMapRegion((chunkX * chunksize + offsetX) / regionSize, (chunkZ * chunksize + offsetZ) / regionSize).ClimateMap;

                float posXInRegionClimate = ((float)lx / regionSize - lx / regionSize) * noiseSizeClimate;
                float posZInRegionClimate = ((float)lz / regionSize - lz / regionSize) * noiseSizeClimate;

                int   climate = climateMap.GetUnpaddedColorLerped(posXInRegionClimate, posZInRegionClimate);
                float temp    = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, origPosY - TerraGenConfig.seaLevel);
                float rainRel = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, origPosY) / 255f;

                if (rainRel < variant.MinRain || rainRel > variant.MaxRain || temp < variant.MinTemp || temp > variant.MaxTemp)
                {
                    return(SubDepositsToPlace);
                }
            }


            // Ok generate
            float th        = variant.Thickness.nextFloat(1, depositRand);
            int   thickness = (int)th + (depositRand.NextFloat() < th - (int)th ? 1 : 0);

            float xRadSqInv = 1f / (radiusX * radiusX);
            float zRadSqInv = 1f / (radiusZ * radiusZ);

            int  blockIndex    = 0;
            bool parentBlockOk = false;

            float depthf;

            bool shouldGenSurfaceDeposit = depositRand.NextFloat() > 0.35f && variant.SurfaceBlockCode != null;

            if (forceInitialPosY != null)
            {
                depthf = (float)forceInitialPosY / mapchunk.WorldGenTerrainHeightMap[offsetX * chunksize + offsetZ];
            }
            else
            {
                depthf = variant.Depth.nextFloat(1, depositRand);
            }

            int depthi = (int)depthf;

            int topLeft  = 2 * depositRand.NextInt(radiusX + 1) - radiusX;
            int topRight = 2 * depositRand.NextInt(radiusZ + 1) - radiusZ;
            int botLeft  = 2 * depositRand.NextInt(radiusX + 1) - radiusX;
            int botRight = 2 * depositRand.NextInt(radiusZ + 1) - radiusZ;
            int yOff     = 0;

            // Only generate inside this current chunk column
            int minx = GameMath.Clamp(offsetX - radiusX, 0, chunksize);
            int maxx = GameMath.Clamp(offsetX + radiusX, 0, chunksize);
            int minz = GameMath.Clamp(offsetZ - radiusZ, 0, chunksize);
            int maxz = GameMath.Clamp(offsetZ + radiusZ, 0, chunksize);

            float invChunkAreaSize = 1f / (chunksize * chunksize);

            for (int x = minx; x < maxx; x++)
            {
                float xSq = (x - offsetX) * (x - offsetX) * xRadSqInv;
                for (int z = minz; z < maxz; z++)
                {
                    if (xSq + (z - offsetZ) * (z - offsetZ) * zRadSqInv > 1)
                    {
                        continue;
                    }

                    if (variant.Placement == EnumDepositPlacement.FollowSurfaceBelow)
                    {
                        posY = mapchunk.WorldGenTerrainHeightMap[z * chunksize + x] - depthi;
                    }
                    else if (variant.Placement == EnumDepositPlacement.FollowSurface)
                    {
                        yOff = (int)GameMath.BiLerp(topLeft, topRight, botLeft, botRight, (x - offsetX + radiusX) / (2f * radiusX), (z - offsetZ + radiusZ) / (2f * radiusZ));

                        posY = (int)(depthf * mapchunk.WorldGenTerrainHeightMap[z * chunksize + x]) + yOff / 2;
                    }
                    else if (variant.Placement == EnumDepositPlacement.Straight)
                    {
                        posY = (int)(depthf * mapchunk.WorldGenTerrainHeightMap[z * chunksize + x]);
                    }
                    else
                    {
                        yOff = (int)GameMath.BiLerp(topLeft, topRight, botLeft, botRight, (x - offsetX + radiusX) / (2f * radiusX), (z - offsetZ + radiusZ) / (2f * radiusZ));

                        posY = depthi + yOff;
                    }

                    // Some deposits may not appear all over cliffs
                    if (variant.CheckClimate && Math.Abs(origPosY - posY) > variant.MaxYRoughness)
                    {
                        continue;
                    }

                    for (int y = 0; y < thickness; y++)
                    {
                        if (posY <= 1 || posY >= worldheight)
                        {
                            continue;
                        }

                        long   index3d = ((posY % chunksize) * chunksize + z) * chunksize + x;
                        ushort blockId = chunks[posY / chunksize].Blocks[index3d];

                        // Check if we are in mother material, but only if it has changed since last iteration (should reduce amount of these checks by 50-100%)
                        parentBlockOk = false;
                        for (int i = 0; i < variant.ParentBlockIds.Length; i++)
                        {
                            if (variant.ParentBlockIds[i] == blockId)
                            {
                                parentBlockOk = true;
                                blockIndex    = i;
                                break;
                            }
                        }

                        if (parentBlockOk)
                        {
                            if (variant.WithBlockCallback)
                            {
                                tmpPos.Set(chunkX * chunksize + x, posY, chunkZ * chunksize + z);
                                blockTypes[variant.BlockIds[blockIndex]].TryPlaceBlockForWorldGen(blockAccessor, tmpPos, BlockFacing.UP);
                            }
                            else
                            {
                                chunks[posY / chunksize].Blocks[index3d] = variant.BlockIds[blockIndex];
                            }


                            for (int i = 0; i < variant.ChildDeposits.Length; i++)
                            {
                                float rndVal   = depositRand.NextFloat();
                                float quantity = variant.ChildDeposits[i].Quantity * invChunkAreaSize;

                                if (quantity > rndVal)
                                {
                                    Vec3i pos = new Vec3i(x, posY, z);

                                    if (ShouldPlaceAdjustedForOreMap(variant.ChildDeposits[i], chunkX * chunksize + x, chunkZ * chunksize + z, quantity, rndVal))
                                    {
                                        SubDepositsToPlace[pos] = variant.ChildDeposits[i];
                                    }
                                }
                            }

                            if (shouldGenSurfaceDeposit)
                            {
                                int   surfaceY = mapchunk.RainHeightMap[z * chunksize + x];
                                int   depth    = surfaceY - posY;
                                float chance   = variant.SurfaceBlockChance * Math.Max(0, 1 - depth / 8f);
                                if (depositRand.NextFloat() < chance)
                                {
                                    index3d = (((surfaceY + 1) % chunksize) * chunksize + z) * chunksize + x;

                                    Block belowBlock = api.World.Blocks[chunks[surfaceY / chunksize].Blocks[((surfaceY % chunksize) * chunksize + z) * chunksize + x]];

                                    if (belowBlock.SideSolid[BlockFacing.UP.Index] && chunks[(surfaceY + 1) / chunksize].Blocks[index3d] == 0)
                                    {
                                        chunks[(surfaceY + 1) / chunksize].Blocks[index3d] = variant.SurfaceBlockIds[blockIndex];
                                    }
                                }
                            }
                        }

                        posY--;
                    }
                }
            }

            return(SubDepositsToPlace);
        }
Example #5
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            landforms = NoiseLandforms.landforms;
            IMapChunk mapchunk = chunks[0].MapChunk;

            IntMap regionMap = mapchunk.MapRegion.LandformMap;
            // Amount of pixels for each chunk (probably 1, 2, or 4)
            float chunkPixelSize = regionMap.InnerSize / regionChunkSize;
            // Adjusted lerp for the noiseWidth
            float chunkPixelStep = chunkPixelSize / noiseWidth;
            // Start coordinates for the chunk in the region map
            float baseX = (chunkX % regionChunkSize) * chunkPixelSize;
            float baseZ = (chunkZ % regionChunkSize) * chunkPixelSize;


            LerpedWeightedIndex2DMap landLerpMap = GetOrLoadLerpedLandformMap(chunks[0].MapChunk, chunkX / regionChunkSize, chunkZ / regionChunkSize);

            // Terrain octaves
            double[] octNoiseX0, octNoiseX1, octNoiseX2, octNoiseX3;
            double[] octThX0, octThX1, octThX2, octThX3;

            GetInterpolatedOctaves(landLerpMap[baseX, baseZ], out octNoiseX0, out octThX0);
            GetInterpolatedOctaves(landLerpMap[baseX + chunkPixelSize, baseZ], out octNoiseX1, out octThX1);
            GetInterpolatedOctaves(landLerpMap[baseX, baseZ + chunkPixelSize], out octNoiseX2, out octThX2);
            GetInterpolatedOctaves(landLerpMap[baseX + chunkPixelSize, baseZ + chunkPixelSize], out octNoiseX3, out octThX3);


            double[] terrainNoise3d = GetTerrainNoise3D(octNoiseX0, octNoiseX1, octNoiseX2, octNoiseX3, octThX0, octThX1, octThX2, octThX3, chunkX * noiseWidth, 0, chunkZ * noiseWidth);

            // Store heightmap in the map chunk
            ushort[] rainheightmap    = chunks[0].MapChunk.RainHeightMap;
            ushort[] terrainheightmap = chunks[0].MapChunk.WorldGenTerrainHeightMap;


            // Terrain thresholds
            double tnoiseY0;
            double tnoiseY1;
            double tnoiseY2;
            double tnoiseY3;
            double tnoiseGainY0;
            double tnoiseGainY1;
            double tnoiseGainY2;
            double tnoiseGainY3;


            double thNoiseX0;
            double thNoiseX1;
            double thNoiseGainX0;
            double thNoiseGainX1;
            double thNoiseGainZ0;
            double thNoiseZ0;

            float[] terrainThresholdsX0 = new float[api.WorldManager.MapSizeY];
            float[] terrainThresholdsX1 = new float[api.WorldManager.MapSizeY];
            float[] terrainThresholdsX2 = new float[api.WorldManager.MapSizeY];
            float[] terrainThresholdsX3 = new float[api.WorldManager.MapSizeY];



            for (int xN = 0; xN < noiseWidth; xN++)
            {
                for (int zN = 0; zN < noiseWidth; zN++)
                {
                    // Landform thresholds
                    LoadInterpolatedThresholds(landLerpMap[baseX + xN * chunkPixelStep, baseZ + zN * chunkPixelStep], terrainThresholdsX0);
                    LoadInterpolatedThresholds(landLerpMap[baseX + (xN + 1) * chunkPixelStep, baseZ + zN * chunkPixelStep], terrainThresholdsX1);
                    LoadInterpolatedThresholds(landLerpMap[baseX + xN * chunkPixelStep, baseZ + (zN + 1) * chunkPixelStep], terrainThresholdsX2);
                    LoadInterpolatedThresholds(landLerpMap[baseX + (xN + 1) * chunkPixelStep, baseZ + (zN + 1) * chunkPixelStep], terrainThresholdsX3);

                    for (int yN = 0; yN < noiseHeight; yN++)
                    {
                        // Terrain noise
                        tnoiseY0 = terrainNoise3d[NoiseIndex3d(xN, yN, zN)];
                        tnoiseY1 = terrainNoise3d[NoiseIndex3d(xN, yN, zN + 1)];
                        tnoiseY2 = terrainNoise3d[NoiseIndex3d(xN + 1, yN, zN)];
                        tnoiseY3 = terrainNoise3d[NoiseIndex3d(xN + 1, yN, zN + 1)];

                        tnoiseGainY0 = (terrainNoise3d[NoiseIndex3d(xN, yN + 1, zN)] - tnoiseY0) * lerpDeltaVert;
                        tnoiseGainY1 = (terrainNoise3d[NoiseIndex3d(xN, yN + 1, zN + 1)] - tnoiseY1) * lerpDeltaVert;
                        tnoiseGainY2 = (terrainNoise3d[NoiseIndex3d(xN + 1, yN + 1, zN)] - tnoiseY2) * lerpDeltaVert;
                        tnoiseGainY3 = (terrainNoise3d[NoiseIndex3d(xN + 1, yN + 1, zN + 1)] - tnoiseY3) * lerpDeltaVert;



                        for (int y = 0; y < lerpVer; y++)
                        {
                            int posY   = yN * lerpVer + y;
                            int chunkY = posY / chunksize;
                            int localY = posY % chunksize;

                            // For Terrain noise
                            double tnoiseX0 = tnoiseY0;
                            double tnoiseX1 = tnoiseY1;

                            double tnoiseGainX0 = (tnoiseY2 - tnoiseY0) * lerpDeltaHor;
                            double tnoiseGainX1 = (tnoiseY3 - tnoiseY1) * lerpDeltaHor;

                            // Landform thresholds lerp
                            thNoiseX0 = terrainThresholdsX0[posY];
                            thNoiseX1 = terrainThresholdsX2[posY];

                            thNoiseGainX0 = (terrainThresholdsX1[posY] - thNoiseX0) * lerpDeltaHor;
                            thNoiseGainX1 = (terrainThresholdsX3[posY] - thNoiseX1) * lerpDeltaHor;


                            for (int x = 0; x < lerpHor; x++)
                            {
                                // For terrain noise
                                double tnoiseZ0     = tnoiseX0;
                                double tnoiseGainZ0 = (tnoiseX1 - tnoiseX0) * lerpDeltaHor;

                                // Landform
                                thNoiseZ0     = thNoiseX0;
                                thNoiseGainZ0 = (thNoiseX1 - thNoiseX0) * lerpDeltaHor;

                                for (int z = 0; z < lerpHor; z++)
                                {
                                    int lX = xN * lerpHor + x;
                                    int lZ = zN * lerpHor + z;

                                    int mapIndex   = ChunkIndex2d(lX, lZ);
                                    int chunkIndex = ChunkIndex3d(lX, localY, lZ);

                                    chunks[chunkY].Blocks[chunkIndex] = 0;

                                    if (posY == 0)
                                    {
                                        chunks[chunkY].Blocks[chunkIndex] = GlobalConfig.mantleBlockId;
                                        continue;
                                    }


                                    if (tnoiseZ0 > thNoiseZ0)
                                    {
                                        terrainheightmap[mapIndex] = rainheightmap[mapIndex] = (ushort)Math.Max(rainheightmap[mapIndex], posY);

                                        chunks[chunkY].Blocks[chunkIndex] = GlobalConfig.defaultRockId;
                                    }
                                    else
                                    {
                                        if (posY < TerraGenConfig.seaLevel)
                                        {
                                            terrainheightmap[mapIndex] = rainheightmap[mapIndex] = (ushort)Math.Max(rainheightmap[mapIndex], posY);

                                            chunks[chunkY].Blocks[chunkIndex] = GlobalConfig.waterBlockId;
                                        }
                                        else
                                        {
                                            chunks[chunkY].Blocks[chunkIndex] = 0;
                                        }
                                    }

                                    tnoiseZ0  += tnoiseGainZ0;
                                    thNoiseZ0 += thNoiseGainZ0;
                                }

                                tnoiseX0 += tnoiseGainX0;
                                tnoiseX1 += tnoiseGainX1;

                                thNoiseX0 += thNoiseGainX0;
                                thNoiseX1 += thNoiseGainX1;
                            }

                            tnoiseY0 += tnoiseGainY0;
                            tnoiseY1 += tnoiseGainY1;
                            tnoiseY2 += tnoiseGainY2;
                            tnoiseY3 += tnoiseGainY3;
                        }
                    }
                }
            }

            int ymax = 0;

            for (int i = 0; i < rainheightmap.Length; i++)
            {
                ymax = Math.Max(ymax, rainheightmap[i]);
            }
            chunks[0].MapChunk.YMax = (ushort)ymax;
        }
Example #6
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            IntMap 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;

            int climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac));
            int climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac));
            int climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac + fac));
            int 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;


            int quantityRivulets = (int)(80 * (rain + humidity) / 255f) * (api.WorldManager.MapSizeY / chunksize) - Math.Max(0, 100 - temp);
            int fx, fy, fz;

            while (quantityRivulets-- > 0)
            {
                int dx = 1 + rnd.Next(chunksize - 2);
                int y  = 1 + rnd.Next(api.WorldManager.MapSizeY - 2);
                int dz = 1 + rnd.Next(chunksize - 2);

                int quantitySolid = 0;
                int quantityAir   = 0;
                for (int i = 0; i < BlockFacing.ALLFACES.Length; i++)
                {
                    BlockFacing facing = BlockFacing.ALLFACES[i];
                    fx = dx + facing.Normali.X;
                    fy = y + facing.Normali.Y;
                    fz = dz + facing.Normali.Z;

                    Block block = api.World.Blocks[
                        chunks[fy / chunksize].Blocks[(chunksize * (fy % chunksize) + fz) * chunksize + fx]
                                  ];

                    bool solid = block.BlockMaterial == EnumBlockMaterial.Stone;
                    quantitySolid += solid ? 1 : 0;
                    quantityAir   += (block.BlockMaterial == EnumBlockMaterial.Air) ? 1 : 0;

                    if (!solid && facing == BlockFacing.UP)
                    {
                        quantitySolid = 0;
                    }
                }

                if (quantitySolid != 5 || quantityAir != 1)
                {
                    continue;
                }

                chunks[y / chunksize].Blocks[(chunksize * (y % chunksize) + dz) * chunksize + dx] = y < 24 ? GlobalConfig.lavaBlockId : GlobalConfig.waterBlockId;

                BlockPos pos = new BlockPos(chunkX * chunksize + dx, y, chunkZ * chunksize + dz);
                blockAccessor.ScheduleBlockUpdate(pos);
            }
        }
 public LazySymbolMap(IntMap intMap, Value [] values)
 {
     _intMap = intMap;
     _values = values;
 }
Example #8
0
 internal void CreatePage(int i, IntMap intMap) 
 {
     if(this[i] == Plane.EmptyPage) 
     {
         Page page = new Page();
         this[i] = page;
     } 
 }
Example #9
0
 public HierarchyView(UIView[] views, TreeViewState state) : base(state)
 {
     this.views  = views;
     m_ViewState = new IntMap <ViewState>();
     needsReload = true;
 }
Example #10
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ)
        {
            if (!TerraGenConfig.GenerateStructures)
            {
                return;
            }

            IMapRegion region = chunks[0].MapChunk.MapRegion;

            IntMap forestMap  = region.ForestMap;
            IntMap climateMap = region.ClimateMap;
            int    rlX        = chunkX % regionChunkSize;
            int    rlZ        = chunkZ % regionChunkSize;


            // 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.WorldGenTerrainHeightMap;

            BlockPos pos = new BlockPos();

            for (int i = 0; i < scfg.Structures.Length; i++)
            {
                WorldGenStructure struc  = scfg.Structures[i];
                float             chance = struc.Chance * scfg.ChanceMultiplier;

                while (chance-- > rnd.NextDouble())
                {
                    int dx       = rnd.Next(chunksize);
                    int dz       = rnd.Next(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(), chunkZ * chunksize + dz);
                        }
                        else
                        {
                            pos.Set(chunkX * chunksize + dx, 8 + rnd.Next(ySurface - 8 - 5), chunkZ * chunksize + dz);
                        }
                    }
                    else
                    {
                        pos.Set(chunkX * chunksize + dx, ySurface, chunkZ * chunksize + dz);
                    }

                    struc.TryGenerate(worldgenBlockAccessor, api.World, pos, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);
                }
            }
        }
Example #11
0
        public void TryPlaceLakeAt(int dx, int dz, int chunkX, int chunkZ, ushort[] heightmap, int depth = 0)
        {
            searchPositionsDeltas.Clear();
            lakePositions.Clear();

            // Clear Array
            for (int i = 0; i < didCheckPosition.Length; i++)
            {
                didCheckPosition[i] = false;
            }

            lakeYPos = heightmap[dz * chunksize + dx] + 1;

            if (lakeYPos <= 0 || lakeYPos >= mapheight - 1)
            {
                return;
            }

            int   basePosX = chunkX * chunksize;
            int   basePosZ = chunkZ * chunksize;
            Vec2i tmp      = new Vec2i();



            searchPositionsDeltas.Enqueue(new Vec2i(dx, dz));
            lakePositions.Enqueue(new Vec2i(basePosX + dx, basePosZ + dz));
            didCheckPosition[(dz + mapOffset) * searchSize + dx + mapOffset] = true;



            while (searchPositionsDeltas.Count > 0)
            {
                Vec2i p = searchPositionsDeltas.Dequeue();

                foreach (BlockFacing facing in BlockFacing.HORIZONTALS)
                {
                    ndx = p.X + facing.Normali.X;
                    ndz = p.Y + facing.Normali.Z;

                    tmp.Set(chunkX * chunksize + ndx, chunkZ * chunksize + ndz);

                    Block belowBlock = blockAccessor.GetBlock(tmp.X, lakeYPos - 1, tmp.Y);

                    bool inBoundary = ndx > minBoundary && ndz > minBoundary && ndx < maxBoundary && ndz < maxBoundary;

                    // Only continue when within our 3x3 chunk search area and having a more or less solid block below (or water)
                    if (inBoundary && (belowBlock.Replaceable < 6000 || belowBlock.BlockId == GlobalConfig.waterBlockId))
                    {
                        int arrayIndex = (ndz + mapOffset) * searchSize + ndx + mapOffset;

                        // Already checked or did we reach a lake border?
                        if (!didCheckPosition[arrayIndex] && blockAccessor.GetBlock(tmp.X, lakeYPos, tmp.Y).Replaceable >= 6000)
                        {
                            searchPositionsDeltas.Enqueue(new Vec2i(ndx, ndz));
                            lakePositions.Enqueue(tmp.Copy());

                            didCheckPosition[arrayIndex] = true;
                        }
                    }
                    else
                    {
                        lakePositions.Clear();
                        searchPositionsDeltas.Clear();
                        return;
                    }
                }
            }

            if (lakePositions.Count == 0)
            {
                return;
            }


            int          curChunkX, curChunkZ;
            int          prevChunkX = -1, prevChunkZ = -1;
            int          regionChunkSize    = api.WorldManager.RegionSize / chunksize;
            IMapChunk    mapchunk           = null;
            IServerChunk chunk              = null;
            IServerChunk chunkOneBlockBelow = null;

            int ly = GameMath.Mod(lakeYPos, chunksize);

            bool extraLakeDepth = rand.NextDouble() > 0.5;
            bool withSeabed     = extraLakeDepth || lakePositions.Count > 16;

            foreach (Vec2i p in lakePositions)
            {
                curChunkX = p.X / chunksize;
                curChunkZ = p.Y / chunksize;

                int lx = GameMath.Mod(p.X, chunksize);
                int lz = GameMath.Mod(p.Y, chunksize);

                // Get correct chunk and correct climate data if we don't have it already
                if (curChunkX != prevChunkX || curChunkZ != prevChunkZ)
                {
                    chunk = ((IServerChunk)blockAccessor.GetChunk(curChunkX, lakeYPos / chunksize, curChunkZ));
                    chunk.Unpack();

                    if (ly == 0)
                    {
                        chunkOneBlockBelow = ((IServerChunk)blockAccessor.GetChunk(curChunkX, (lakeYPos - 1) / chunksize, curChunkZ));
                        chunkOneBlockBelow.Unpack();
                    }
                    else
                    {
                        chunkOneBlockBelow = chunk;
                    }

                    mapchunk = chunk.MapChunk;
                    IntMap climateMap = mapchunk.MapRegion.ClimateMap;

                    float fac = (float)climateMap.InnerSize / regionChunkSize;
                    int   rlX = curChunkX % regionChunkSize;
                    int   rlZ = curChunkZ % 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));

                    prevChunkX = curChunkX;
                    prevChunkZ = curChunkZ;
                }


                // Raise heightmap by 1
                mapchunk.RainHeightMap[lz * chunksize + lx] = (ushort)lakeYPos;

                // Identify correct climate at this position
                int   climate = GameMath.BiLerpRgbColor((float)lx / chunksize, (float)lz / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);
                float temp    = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, lakeYPos - TerraGenConfig.seaLevel);


                // 1. Place water or ice block
                chunk.Blocks[(ly * chunksize + lz) * chunksize + lx] = temp < -5 ? GlobalConfig.lakeIceBlockId : GlobalConfig.waterBlockId;


                // 2. Let's make a nice muddy gravely sea bed
                if (!withSeabed)
                {
                    continue;
                }

                // Need to check the block below first
                int index = ly == 0 ?
                            ((31 * chunksize + lz) * chunksize + lx) :
                            (((ly - 1) * chunksize + lz) * chunksize + lx)
                ;

                Block belowBlock = api.World.Blocks[chunkOneBlockBelow.Blocks[index]];

                // Water below? Seabed already placed
                if (belowBlock.IsLiquid())
                {
                    continue;
                }

                float  rainRel     = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, lakeYPos) / 255f;
                ushort rockBlockId = mapchunk.TopRockIdMap[lz * chunksize + lx];
                if (rockBlockId == 0)
                {
                    continue;
                }

                for (int i = 0; i < lakebedLayerConfig.BlockCodeByMin.Length; i++)
                {
                    if (lakebedLayerConfig.BlockCodeByMin[i].Suitable(temp, rainRel, (float)lakeYPos / mapheight, rand))
                    {
                        chunkOneBlockBelow.Blocks[index] = lakebedLayerConfig.BlockCodeByMin[i].GetBlockForMotherRock(rockBlockId);
                        break;
                    }
                }
            }


            if (lakePositions.Count > 0 && extraLakeDepth)
            {
                TryPlaceLakeAt(dx, dz, chunkX, chunkZ, heightmap, depth + 1);
            }
        }
Example #12
0
        void ReadPos(IServerPlayer player, CmdArgs arguments)
        {
            if (arguments.Length < 2)
            {
                player.SendMessage(groupId, "/wgen pos [gprov|landform|climate|height]", EnumChatType.CommandError);
                return;
            }


            int          chunkSize   = api.WorldManager.ChunkSize;
            BlockPos     pos         = player.Entity.Pos.AsBlockPos;
            IServerChunk serverchunk = api.WorldManager.GetChunk(pos);

            if (serverchunk == null)
            {
                player.SendMessage(groupId, "Can check here, beyond chunk boundaries!", EnumChatType.CommandError);
                return;
            }

            IMapRegion mapRegion = serverchunk.MapChunk.MapRegion;


            int regionChunkSize = api.WorldManager.RegionSize / chunkSize;


            int lx      = pos.X % chunkSize;
            int lz      = pos.Z % chunkSize;
            int chunkX  = pos.X / chunkSize;
            int chunkZ  = pos.Z / chunkSize;
            int regionX = pos.X / regionSize;
            int regionZ = pos.Z / regionSize;

            switch (arguments[1])
            {
            case "height":
            {
                string str = string.Format("Rain y={0}, Worldgen terrain y={1}", serverchunk.MapChunk.RainHeightMap[lz * chunkSize + lx], serverchunk.MapChunk.WorldGenTerrainHeightMap[lz * chunkSize + lx]);
                player.SendMessage(groupId, str, EnumChatType.CommandSuccess);
            }
            break;

            case "gprov":
            {
                int noiseSizeGeoProv = mapRegion.GeologicProvinceMap.InnerSize;

                float posXInRegion = ((float)pos.X / regionSize - pos.X / regionSize) * noiseSizeGeoProv;
                float posZInRegion = ((float)pos.Z / regionSize - pos.Z / regionSize) * noiseSizeGeoProv;


                GeologicProvinceVariant[] provincesByIndex = NoiseGeoProvince.provinces.Variants;

                IntMap intmap = mapRegion.GeologicProvinceMap;

                LerpedWeightedIndex2DMap map = new LerpedWeightedIndex2DMap(intmap.Data, mapRegion.GeologicProvinceMap.Size, TerraGenConfig.geoProvSmoothingRadius);

                WeightedIndex[] indices = map[intmap.TopLeftPadding + posXInRegion, intmap.TopLeftPadding + posZInRegion];

                string text = "";
                foreach (WeightedIndex windex in indices)
                {
                    if (text.Length > 0)
                    {
                        text += ", ";
                    }

                    text += (100 * windex.weight).ToString("#.#") + "% " + provincesByIndex[windex.index].Code;
                }

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);

                break;
            }


            case "landform":
            {
                int noiseSizeLandform = mapRegion.LandformMap.InnerSize;

                float posXInRegion = ((float)pos.X / regionSize - pos.X / regionSize) * noiseSizeLandform;
                float posZInRegion = ((float)pos.Z / regionSize - pos.Z / regionSize) * noiseSizeLandform;


                LandformVariant[] landforms = NoiseLandforms.landforms.LandFormsByIndex;

                IntMap intmap = mapRegion.LandformMap;

                LerpedWeightedIndex2DMap map = new LerpedWeightedIndex2DMap(intmap.Data, mapRegion.LandformMap.Size, TerraGenConfig.landFormSmothingRadius);

                WeightedIndex[] indices = map[intmap.TopLeftPadding + posXInRegion, intmap.TopLeftPadding + posZInRegion];

                string text = "";
                foreach (WeightedIndex windex in indices)
                {
                    if (text.Length > 0)
                    {
                        text += ", ";
                    }

                    text += (100 * windex.weight).ToString("#.#") + "% " + landforms[windex.index].Code;
                }

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);

                break;
            }

            case "climate":
            {
                ClimateCondition climate = api.World.BlockAccessor.GetClimateAt(pos);

                string text = string.Format("Temperature: {0}°, Rainfall: {1}%, Fertility: {2}%, Forest: {3}%, Shrub: {4}%, Sealevel dist: {5}%", climate.Temperature.ToString("0.#"), (int)(climate.Rainfall * 100f), (int)(climate.Fertility * 100f), (int)(climate.ForestDensity * 100f), (int)(climate.ShrubDensity * 100f), (int)(100f * pos.Y / 255f));

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);


                break;
            }
            }
        }
Example #13
0
        void TestMap(IServerPlayer player, CmdArgs arguments)
        {
            if (arguments.Length < 2)
            {
                player.SendMessage(groupId, "/wgen testmap [climate|forest|wind|gprov|landform|ore]", EnumChatType.CommandError);
                return;
            }

            Random rnd  = new Random();
            long   seed = rnd.Next();

            switch (arguments[1])
            {
            case "climate":
            {
                NoiseBase.Debug = true;
                NoiseClimate noiseClimate = new NoiseClimate(seed);
                MapLayerBase climate      = GenMaps.GetClimateMap(seed, noiseClimate);
                player.SendMessage(groupId, "Climate map generated", EnumChatType.CommandSuccess);
            }
            break;

            case "forest":
            {
                NoiseBase.Debug = false;
                NoiseClimate noiseClimate = new NoiseClimate(seed);
                MapLayerBase climate      = GenMaps.GetClimateMap(seed, noiseClimate);
                MapLayerBase forest       = GenMaps.GetForestMap(seed + 1, TerraGenConfig.forestMapScale);

                IntMap climateMap = new IntMap()
                {
                    Data = climate.GenLayer(0, 0, 512, 512), Size = 512
                };

                forest.SetInputMap(climateMap, new IntMap()
                    {
                        Size = 512
                    });

                NoiseBase.Debug = true;
                forest.DebugDrawBitmap(1, 0, 0, "Forest 1 - Forest");
                player.SendMessage(groupId, "Forest map generated", EnumChatType.CommandSuccess);
            }
            break;


            case "ore":
            {
                NoiseBase.Debug = false;
                NoiseOre     noiseOre = new NoiseOre(seed);
                MapLayerBase climate  = GenMaps.GetOreMap(seed, noiseOre);
                NoiseBase.Debug = true;
                climate.DebugDrawBitmap(0, 0, 0, 1024, "Ore 1 - Ore");
                player.SendMessage(groupId, "ore map generated", EnumChatType.CommandSuccess);
            }
            break;

            case "wind":
                NoiseBase.Debug = true;
                NoiseBase wind = GenMaps.GetDebugWindMap(seed);
                player.SendMessage(groupId, "Wind map generated", EnumChatType.CommandSuccess);
                break;

            case "gprov":
                NoiseBase.Debug = true;
                MapLayerBase provinces = GenMaps.GetGeologicProvinceMap(seed, api);

                player.SendMessage(groupId, "Province map generated", EnumChatType.CommandSuccess);
                break;

            case "landform":
            {
                NoiseBase.Debug = true;
                NoiseClimate noiseClimate = new NoiseClimate(seed);
                MapLayerBase landforms    = GenMaps.GetLandformMap(seed + 1, noiseClimate, api);

                player.SendMessage(groupId, "Landforms map generated", EnumChatType.CommandSuccess);
            }
            break;


            default:
                player.SendMessage(groupId, "/wgen testmap [climate|forest|wind|gprov]", EnumChatType.CommandError);
                break;
            }

            NoiseBase.Debug = false;
        }
Example #14
0
        LerpedWeightedIndex2DMap CreateLerpedProvinceMap(IntMap geoMap, int regionX, int regionZ)
        {
            int index2d = regionZ * regionMapSize + regionX;

            return(ProvinceMapByRegion[index2d] = new LerpedWeightedIndex2DMap(geoMap.Data, geoMap.Size, TerraGenConfig.geoProvSmoothingRadius, geoMap.TopLeftPadding, geoMap.BottomRightPadding));
        }
 public void SetInputMap(IntMap inputMap, IntMap outputMap)
 {
     this.inputMap  = inputMap;
     this.outputMap = outputMap;
 }
Example #16
0
 public StyleSystem()
 {
     this.m_ChangeSets = new IntMap <ChangeSet>();
 }
Example #17
0
        private void OnChunkColumnGeneration(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            rnd.InitPositionSeed(chunkX, chunkZ);

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

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

            int regionChunkSize = api.WorldManager.RegionSize / chunksize;

            //fetch the region coordinates
            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(
                        Math.Abs(rdx * climateStep + climateStep * (float)(x + distx) / chunksize),
                        Math.Abs(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 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;

                    //api.World.Logger.Notification(x.ToString() + " " + z.ToString() + " temp: " + tempUnscaled.ToString() + " distx" + distx.ToString() + " distz" + distz.ToString());

                    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, 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--;
                    }
                }
            }
        }
Example #18
0
        /// <summary> 
        /// Cache index to the list of scaled shapeable typeface 
        /// </summary>
        private void CacheScaledTypefaceMap( 
            CharacterBufferRange        unicodeString,
            CultureInfo                 culture,
            CultureInfo                 digitCulture,
            SpanVector                  scaledTypefaceSpans, 
            ref SpanVector<int>         cachedScaledTypefaceIndexSpans,
            int                         ichItem 
            ) 
        {
 
            IntMap map;
            if (!_intMaps.TryGetValue(culture, out map))
            {
                map = new IntMap(); 
                _intMaps.Add(culture, map);
            } 
 
            DigitMap digitMap = new DigitMap(digitCulture);
 
            SpanRider typefaceSpanRider = new SpanRider(scaledTypefaceSpans);

            int ich = 0;
            while(ich < unicodeString.Length) 
            {
                typefaceSpanRider.At(ich); 
 
                int cch = Math.Min(unicodeString.Length - ich, typefaceSpanRider.Length);
 
                int index = IndexOfScaledTypeface((ScaledShapeTypeface)typefaceSpanRider.CurrentElement);
                Debug.Assert(index >= 0, "Invalid scaled shapeable typeface index spans");

                cachedScaledTypefaceIndexSpans.Set(ichItem + ich, cch, index); 

                // we keep index + 1 in the map, so that we leave map entry zero 
                // to indicate uninitialized entry. 
                index++;
 
                int sizeofChar;
                for (int c = 0; c < cch; c += sizeofChar)
                {
                    int ch = digitMap[ 
                        Classification.UnicodeScalar(
                            new CharacterBufferRange(unicodeString, ich + c, unicodeString.Length - ich - c), 
                            out sizeofChar 
                        )
                    ]; 

                    // only cache typeface map index for base characters
                    if(!Classification.IsCombining(ch) && !Classification.IsJoiner(ch))
                    { 
                        // Dump values of local variables when the condition fails for better debuggability.
                        // We use "if" to avoid the expensive string.Format() in normal case. 
                        if (map[ch] != 0 && map[ch] != index) 
                        {
                            Invariant.Assert( 
                                false,
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    "shapeable cache stores conflicting info, ch = {0}, map[ch] = {1}, index = {2}", 
                                    ch, map[ch], index
                                ) 
                            ); 
                        }
 
                        map[ch] = (ushort)index;
                    }
                }
 
                ich += cch;
            } 
        } 
 private static int ApplyIntMap(IntMap f, int x)
 {
     return(f(x));
 }