Merge branch 'master' into 1.16
# Conflicts: # src/main/java/carpet/helpers/FeatureGenerator.java # src/main/java/carpet/script/CarpetExpression.java
This commit is contained in:
commit
6299e72e38
4 files changed
+133
-15
No files matched your search
@@ -2060,6 +2060,25 @@ if the chunk is not in memory unless called with optional `true`.
|
||||
|
||||
Returns inhabited time for a chunk.
|
||||
|
||||
### `spawn_potential(pos)`
|
||||
|
||||
Returns spawn potential at a location (1.16+ only)
|
||||
|
||||
### `structure_eligibility(pos, ?structure, ?size_needed)`
|
||||
|
||||
Checks wordgen eligibility for a structure in a given chunk. If no structure is given, or `null`, then it will check
|
||||
for all structures. If bounding box of the structures is also requested, it will compute size of potential
|
||||
structures. This function, unlike other in the `structure*` category is not using world data nor accesses chunks
|
||||
making it preferred for scoping ungenerated terrain.
|
||||
|
||||
If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or
|
||||
a pair of coordinates indicating bounding box of the structure.
|
||||
|
||||
If structure is not specified, it will return a set of structure names that are eligible, or a map with structures
|
||||
as keys, and pair of bounding box coordinates as values. An empty set or an empty map would indicate that nothing
|
||||
should be generated there.
|
||||
|
||||
|
||||
### `structures(pos), structures(pos, structure_name)`
|
||||
|
||||
Returns structure information for a given block position. Note that structure information is the same for all the
|
||||
|
||||
@@ -523,6 +523,25 @@ if the chunk is not in memory unless called with optional `true`.
|
||||
|
||||
Returns inhabited time for a chunk.
|
||||
|
||||
### `spawn_potential(pos)`
|
||||
|
||||
Returns spawn potential at a location (1.16+ only)
|
||||
|
||||
### `structure_eligibility(pos, ?structure, ?size_needed)`
|
||||
|
||||
Checks wordgen eligibility for a structure in a given chunk. If no structure is given, or `null`, then it will check
|
||||
for all structures. If bounding box of the structures is also requested, it will compute size of potential
|
||||
structures. This function, unlike other in the `structure*` category is not using world data nor accesses chunks
|
||||
making it preferred for scoping ungenerated terrain.
|
||||
|
||||
If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or
|
||||
a pair of coordinates indicating bounding box of the structure.
|
||||
|
||||
If structure is not specified, it will return a set of structure names that are eligible, or a map with structures
|
||||
as keys, and pair of bounding box coordinates as values. An empty set or an empty map would indicate that nothing
|
||||
should be generated there.
|
||||
|
||||
|
||||
### `structures(pos), structures(pos, structure_name)`
|
||||
|
||||
Returns structure information for a given block position. Note that structure information is the same for all the
|
||||
|
||||
@@ -7,14 +7,20 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.structure.StructureManager;
|
||||
import net.minecraft.structure.StructureStart;
|
||||
import net.minecraft.util.math.BlockBox;
|
||||
import net.minecraft.structure.BastionRemnantGenerator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biomes;
|
||||
import net.minecraft.world.biome.DefaultBiomeFeatures;
|
||||
import net.minecraft.world.biome.source.BiomeAccess;
|
||||
import net.minecraft.world.biome.source.BiomeSource;
|
||||
import net.minecraft.world.biome.source.VanillaLayeredBiomeSource;
|
||||
import net.minecraft.world.biome.source.VanillaLayeredBiomeSourceConfig;
|
||||
import net.minecraft.world.gen.ChunkRandom;
|
||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.gen.chunk.OverworldChunkGenerator;
|
||||
import net.minecraft.world.gen.chunk.OverworldChunkGeneratorConfig;
|
||||
@@ -148,26 +154,48 @@ public class FeatureGenerator
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BlockBox DEFAULT_BOX = new BlockBox(0,0,0,1,1,1);
|
||||
public static BlockBox shouldStructureStartAt(ServerWorld world, BlockPos pos, StructureFeature<?> structure, boolean computeBox)
|
||||
{
|
||||
ChunkGenerator generator = world.getChunkManager().getChunkGenerator();
|
||||
if (!generator.getBiomeSource().hasStructureFeature(structure))
|
||||
return null;
|
||||
BiomeAccess biomeAccess = world.getBiomeAccess().withSource(generator.getBiomeSource());
|
||||
ChunkRandom chunkRandom = new ChunkRandom();
|
||||
ChunkPos chunkPos = new ChunkPos(pos);
|
||||
Biome biome = biomeAccess.getBiome(new BlockPos(chunkPos.getStartX() + 9, 0, chunkPos.getStartZ() + 9));
|
||||
if (structure.shouldStartAt(biomeAccess, generator, chunkRandom, chunkPos.x, chunkPos.z, biome))
|
||||
{
|
||||
if (!computeBox) return DEFAULT_BOX;
|
||||
StructureManager manager = world.getSaveHandler().getStructureManager();
|
||||
StructureStart structureStart3 = structure.getStructureStartFactory().create(structure, chunkPos.x, chunkPos.z, BlockBox.empty(), 0, generator.getSeed());
|
||||
structureStart3.initialize(generator, manager, chunkPos.x, chunkPos.z, biome);
|
||||
if (!structureStart3.hasChildren()) return null;
|
||||
return structureStart3.getBoundingBox();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static final Map<String, List<String>> structureToFeature = new HashMap<>();
|
||||
public static final Map<String, String> featureToStructure = new HashMap<>();
|
||||
static
|
||||
{
|
||||
structureToFeature.put("Monument", Collections.singletonList("monument"));
|
||||
structureToFeature.put("EndCity", Collections.singletonList("end_city"));
|
||||
structureToFeature.put("Ocean_Ruin", Arrays.asList("ocean_ruin", "ocean_ruin_warm", "ocean_ruin_small", "ocean_ruin_warm_small", "ocean_ruin_tall", "ocean_ruin_warm_tall"));
|
||||
structureToFeature.put("Village", Arrays.asList("village", "village_desert", "village_savanna", "village_taiga", "village_snowy"));
|
||||
structureToFeature.put("Mansion", Collections.singletonList("mansion"));
|
||||
structureToFeature.put("Buried_Treasure", Collections.singletonList("treasure"));
|
||||
structureToFeature.put("Swamp_Hut", Collections.singletonList("witch_hut"));
|
||||
structureToFeature.put("Stronghold", Collections.singletonList("stronghold"));
|
||||
structureToFeature.put("Desert_Pyramid", Collections.singletonList("desert_temple"));
|
||||
structureToFeature.put("Jungle_Pyramid", Collections.singletonList("jungle_temple"));
|
||||
structureToFeature.put("Shipwreck", Arrays.asList("shipwreck", "shipwreck2"));
|
||||
structureToFeature.put("Pillager_Outpost", Collections.singletonList("pillager_outpost"));
|
||||
structureToFeature.put("Mineshaft", Arrays.asList("mineshaft", "mineshaft_mesa"));
|
||||
structureToFeature.put("Igloo", Collections.singletonList("igloo"));
|
||||
structureToFeature.put("Fortress", Collections.singletonList("fortress"));
|
||||
structureToFeature.put(Feature.OCEAN_MONUMENT.getName(), Collections.singletonList("monument"));
|
||||
structureToFeature.put(Feature.END_CITY.getName(), Collections.singletonList("end_city"));
|
||||
structureToFeature.put(Feature.OCEAN_RUIN.getName(), Arrays.asList("ocean_ruin", "ocean_ruin_warm", "ocean_ruin_small", "ocean_ruin_warm_small", "ocean_ruin_tall", "ocean_ruin_warm_tall"));
|
||||
structureToFeature.put(Feature.VILLAGE.getName(), Arrays.asList("village", "village_desert", "village_savanna", "village_taiga", "village_snowy"));
|
||||
structureToFeature.put(Feature.WOODLAND_MANSION.getName(), Collections.singletonList("mansion"));
|
||||
structureToFeature.put(Feature.BURIED_TREASURE.getName(), Collections.singletonList("treasure"));
|
||||
structureToFeature.put(Feature.SWAMP_HUT.getName(), Collections.singletonList("witch_hut"));
|
||||
structureToFeature.put(Feature.STRONGHOLD.getName(), Collections.singletonList("stronghold"));
|
||||
structureToFeature.put(Feature.DESERT_PYRAMID.getName(), Collections.singletonList("desert_temple"));
|
||||
structureToFeature.put(Feature.JUNGLE_TEMPLE.getName(), Collections.singletonList("jungle_temple"));
|
||||
structureToFeature.put(Feature.SHIPWRECK.getName(), Arrays.asList("shipwreck", "shipwreck2"));
|
||||
structureToFeature.put(Feature.PILLAGER_OUTPOST.getName(), Collections.singletonList("pillager_outpost"));
|
||||
structureToFeature.put(Feature.MINESHAFT.getName(), Arrays.asList("mineshaft", "mineshaft_mesa"));
|
||||
structureToFeature.put(Feature.IGLOO.getName(), Collections.singletonList("igloo"));
|
||||
structureToFeature.put(Feature.NETHER_BRIDGE.getName(), Collections.singletonList("fortress"));
|
||||
structureToFeature.put("Nether_Fossil", Collections.singletonList("nether_fossil"));
|
||||
structureToFeature.put("Bastion_Remnant", Arrays.asList("bastion_remnant", "bastion_remnant_housing", "bastion_remnant_stable", "bastion_remnant_treasure", "bastion_remnant_bridge"));
|
||||
structureToFeature.put("Ruined_Portal", Collections.singletonList("ruined_portal"));
|
||||
|
||||
@@ -111,6 +111,8 @@ import net.minecraft.util.math.BlockBox;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
import net.minecraft.world.SpawnHelper;
|
||||
import net.minecraft.world.poi.PointOfInterest;
|
||||
import net.minecraft.world.poi.PointOfInterestStorage;
|
||||
@@ -1120,6 +1122,56 @@ public class CarpetExpression
|
||||
return (_c, _t) -> ret;
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("structure_eligibility", -1, (c, t, lv) ->
|
||||
{
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
|
||||
|
||||
ServerWorld world = cc.s.getWorld();
|
||||
BlockPos pos = locator.block.getPos();
|
||||
StructureFeature<?> structure = null;
|
||||
boolean needSize = false;
|
||||
if (lv.size() > locator.offset)
|
||||
{
|
||||
Value requested = lv.get(locator.offset+0).evalValue(c);
|
||||
if (!(requested instanceof NullValue))
|
||||
{
|
||||
String reqString = requested.getString();
|
||||
String structureName = FeatureGenerator.featureToStructure.get(reqString);
|
||||
if (structureName == null) throw new InternalExpressionException("Unknown structure: " + reqString);
|
||||
structure = Feature.STRUCTURES.get(structureName);
|
||||
}
|
||||
if (lv.size() > locator.offset+1)
|
||||
{
|
||||
needSize = lv.get(locator.offset+1).evalValue(c).getBoolean();
|
||||
}
|
||||
}
|
||||
if (structure != null)
|
||||
{
|
||||
BlockBox box = FeatureGenerator.shouldStructureStartAt(world, pos, structure, needSize);
|
||||
if (box == null) return LazyValue.NULL;
|
||||
if (!needSize) return LazyValue.TRUE;
|
||||
Value ret = ListValue.of(
|
||||
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)),
|
||||
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ))
|
||||
);
|
||||
return (_c, _t) -> ret;
|
||||
}
|
||||
Map<Value, Value> ret = new HashMap<>();
|
||||
for(StructureFeature<?> str : Feature.STRUCTURES.values())
|
||||
{
|
||||
BlockBox box = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize);
|
||||
if (box == null) continue;
|
||||
Value key = new StringValue(FeatureGenerator.structureToFeature.get(str.getName()).get(0));
|
||||
ret.put(key, (!needSize)?Value.NULL:ListValue.of(
|
||||
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)),
|
||||
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ))
|
||||
));
|
||||
}
|
||||
Value retMap = MapValue.wrap(ret);
|
||||
return (_c, _t) -> retMap;
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("structures", -1, (c, t, lv) -> {
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
|
||||
|
||||
Reference in new issue
Block a user