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); }
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); }
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); } }
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); } }
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); } } }
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)); } } } } } }
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)); }
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(); }
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); }
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); } }
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); }
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; }
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 } } } } } } } }
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--; } } } }
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; }
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--; } } } }
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); }
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; } } } } }
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); } } } }