internal bool TryGenerateRuinAtSurface(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos pos) { int num = rand.NextInt(schematicDatas.Length); int orient = rand.NextInt(4); BlockSchematicStructure schematic = schematicDatas[num][orient]; int wdthalf = (int)Math.Ceiling(schematic.SizeX / 2f); int lenhalf = (int)Math.Ceiling(schematic.SizeZ / 2f); int wdt = schematic.SizeX; int len = schematic.SizeZ; tmpPos.Set(pos.X + wdthalf, 0, pos.Z + lenhalf); int centerY = blockAccessor.GetTerrainMapheightAt(pos); // Probe all 4 corners + center if they either touch the surface or are sightly below ground tmpPos.Set(pos.X, 0, pos.Z); int topLeftY = blockAccessor.GetTerrainMapheightAt(tmpPos); tmpPos.Set(pos.X + wdt, 0, pos.Z); int topRightY = blockAccessor.GetTerrainMapheightAt(tmpPos); tmpPos.Set(pos.X, 0, pos.Z + len); int botLeftY = blockAccessor.GetTerrainMapheightAt(tmpPos); tmpPos.Set(pos.X + wdt, 0, pos.Z + len); int botRightY = blockAccessor.GetTerrainMapheightAt(tmpPos); int maxY = GameMath.Max(centerY, topLeftY, topRightY, botLeftY, botRightY); int minY = GameMath.Min(centerY, topLeftY, topRightY, botLeftY, botRightY); int diff = Math.Abs(maxY - minY); if (diff > 3) { return(false); } pos.Y = minY; // Ensure not deeply submerged in water tmpPos.Set(pos.X, pos.Y + 1 + OffsetY, pos.Z); if (blockAccessor.GetBlock(tmpPos).IsLiquid()) { return(false); } tmpPos.Set(pos.X + wdt, pos.Y + 1 + OffsetY, pos.Z); if (blockAccessor.GetBlock(tmpPos).IsLiquid()) { return(false); } tmpPos.Set(pos.X, pos.Y + 1 + OffsetY, pos.Z + len); if (blockAccessor.GetBlock(tmpPos).IsLiquid()) { return(false); } tmpPos.Set(pos.X + wdt, pos.Y + 1 + OffsetY, pos.Z + len); if (blockAccessor.GetBlock(tmpPos).IsLiquid()) { return(false); } pos.Y--; if (!satisfiesMinDistance(pos, worldForCollectibleResolve)) { return(false); } if (isStructureAt(pos, worldForCollectibleResolve)) { return(false); } LastPlacedSchematicLocation.Set(pos.X, pos.Y, pos.Z, pos.X + schematic.SizeX, pos.Y + schematic.SizeY, pos.Z + schematic.SizeZ); LastPlacedSchematic = schematic; schematic.PlaceRespectingBlockLayers(blockAccessor, worldForCollectibleResolve, pos, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight, replaceblockids); return(true); }
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); }