mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
f
This commit is contained in:
1 parent
0193f75daa
commit
ad41b6795c
48 files changed
+1193
-141
No files matched your search
@@ -163,7 +163,6 @@ final class DecoratorCore {
|
||||
}
|
||||
data.set(x, height, z, fixFacesForHunk(
|
||||
decorator.getForceBlock().getBlockData(irisData), data, x, z, realX, height, realZ, mantle));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!decorator.isForcePlace()) {
|
||||
|
||||
+17
-9
@@ -135,36 +135,42 @@ public class IrisStructureComponent extends IrisMantleComponent {
|
||||
|
||||
ObjectPlaceMode mode = structure.getPlaceMode();
|
||||
int failedPieces = 0;
|
||||
Long2IntOpenHashMap foundationColumns = placement.getStilt() == null
|
||||
IrisStructureStiltSettings stilt = placement.getStilt();
|
||||
Long2IntOpenHashMap foundationColumns = stilt == null
|
||||
? null : new Long2IntOpenHashMap();
|
||||
boolean supportNonOccluding = stilt != null && stilt.isSupportNonOccluding();
|
||||
if (placement.isUnderground()) {
|
||||
ObjectPlaceMode undergroundMode = (mode == ObjectPlaceMode.ORGANIC_STILT || mode == ObjectPlaceMode.CEILING_HANG)
|
||||
? mode : ObjectPlaceMode.STRUCTURE_PIECE;
|
||||
for (PlacedStructurePiece p : pieces) {
|
||||
if (placeObject(writer, structure, p, undergroundMode, p.getY(), rng, foundationColumns) == -1) {
|
||||
if (placeObject(writer, structure, p, undergroundMode, p.getY(), rng,
|
||||
foundationColumns, supportNonOccluding) == -1) {
|
||||
failedPieces++;
|
||||
}
|
||||
}
|
||||
} else if (mode == ObjectPlaceMode.STRUCTURE_PIECE || mode == ObjectPlaceMode.FLOATING) {
|
||||
for (PlacedStructurePiece p : pieces) {
|
||||
if (placeObject(writer, structure, p, ObjectPlaceMode.STRUCTURE_PIECE, p.getY(), rng, foundationColumns) == -1) {
|
||||
if (placeObject(writer, structure, p, ObjectPlaceMode.STRUCTURE_PIECE, p.getY(), rng,
|
||||
foundationColumns, supportNonOccluding) == -1) {
|
||||
failedPieces++;
|
||||
}
|
||||
}
|
||||
} else if (pieces.size() == 1) {
|
||||
if (placeObject(writer, structure, pieces.getFirst(), mode, -1, rng, foundationColumns) == -1) {
|
||||
if (placeObject(writer, structure, pieces.getFirst(), mode, -1, rng,
|
||||
foundationColumns, supportNonOccluding) == -1) {
|
||||
failedPieces++;
|
||||
}
|
||||
} else {
|
||||
for (PlacedStructurePiece p : pieces) {
|
||||
if (placeObject(writer, structure, p, ObjectPlaceMode.STRUCTURE_PIECE, p.getY(), rng, foundationColumns) == -1) {
|
||||
if (placeObject(writer, structure, p, ObjectPlaceMode.STRUCTURE_PIECE, p.getY(), rng,
|
||||
foundationColumns, supportNonOccluding) == -1) {
|
||||
failedPieces++;
|
||||
}
|
||||
}
|
||||
}
|
||||
requireAppliedPieces(resolved, cx, cz, failedPieces);
|
||||
if (failedPieces == 0 && placement.getStilt() != null) {
|
||||
placeFoundation(writer, foundationColumns, placement.getStilt(), rng, !placement.isUnderground());
|
||||
if (failedPieces == 0 && stilt != null) {
|
||||
placeFoundation(writer, foundationColumns, stilt, rng, !placement.isUnderground());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,7 +539,8 @@ public class IrisStructureComponent extends IrisMantleComponent {
|
||||
}
|
||||
|
||||
private int placeObject(MantleWriter writer, IrisStructure structure, PlacedStructurePiece p,
|
||||
ObjectPlaceMode mode, int y, RNG rng, Long2IntOpenHashMap foundationColumns) {
|
||||
ObjectPlaceMode mode, int y, RNG rng, Long2IntOpenHashMap foundationColumns,
|
||||
boolean supportNonOccluding) {
|
||||
IrisObject object = p.getObject();
|
||||
String objectKey = object.getLoadKey();
|
||||
IrisObjectPlacement config = structure.createLootPlacement(objectKey);
|
||||
@@ -549,7 +556,8 @@ public class IrisStructureComponent extends IrisMantleComponent {
|
||||
String marker = structurePlacementMarker(structure, p, objectKey);
|
||||
return object.place(p.getX(), placeY, p.getZ(), writer, config, rng, (position, state) -> {
|
||||
StructureFoundationPlanner.recordBaseCell(
|
||||
foundationColumns, position.getX(), position.getY(), position.getZ(), state);
|
||||
foundationColumns, position.getX(), position.getY(), position.getZ(), state,
|
||||
supportNonOccluding);
|
||||
if (marker != null && shouldWriteStructureMarker(state)) {
|
||||
writer.setData(position.getX(), position.getY(), position.getZ(), marker);
|
||||
}
|
||||
|
||||
+3
-2
@@ -13,8 +13,9 @@ final class StructureFoundationPlanner {
|
||||
}
|
||||
|
||||
static void recordBaseCell(Long2IntOpenHashMap columns, int x, int y, int z,
|
||||
PlatformBlockState state) {
|
||||
if (columns == null || state == null || !state.isOccluding()) {
|
||||
PlatformBlockState state, boolean supportNonOccluding) {
|
||||
if (columns == null || state == null
|
||||
|| !(supportNonOccluding ? state.isSolid() : state.isOccluding())) {
|
||||
return;
|
||||
}
|
||||
long columnKey = pack(x, z);
|
||||
|
||||
@@ -24,6 +24,7 @@ import art.arcane.iris.engine.object.IrisBiome;
|
||||
import art.arcane.iris.engine.object.IrisDepositGenerator;
|
||||
import art.arcane.iris.engine.object.IrisDepositVariant;
|
||||
import art.arcane.iris.engine.object.IrisDimension;
|
||||
import art.arcane.iris.engine.object.IrisDimensionCarvingResolver;
|
||||
import art.arcane.iris.engine.object.IrisObject;
|
||||
import art.arcane.iris.engine.object.IrisProceduralBlocks;
|
||||
import art.arcane.iris.engine.object.IrisRegion;
|
||||
@@ -87,6 +88,7 @@ public class IrisDepositModifier extends EngineAssignedModifier<PlatformBlockSta
|
||||
}
|
||||
|
||||
public void generate(IrisDepositGenerator k, MantleChunk chunk, Hunk<PlatformBlockState> data, RNG rng, int cx, int cz, boolean safe, HeightMap he, ChunkContext context) {
|
||||
IrisDimensionCarvingResolver.State carvingState = new IrisDimensionCarvingResolver.State();
|
||||
if (k.getSpawnChance() < rng.d())
|
||||
return;
|
||||
|
||||
@@ -123,6 +125,29 @@ public class IrisDepositModifier extends EngineAssignedModifier<PlatformBlockSta
|
||||
if (y > k.getMaxHeight() || y < k.getMinHeight() || y > height - 2)
|
||||
continue;
|
||||
|
||||
if (k.isOre(getData())) {
|
||||
IrisBiome depositBiome = getEngine().getCaveBiome(
|
||||
(cx << 4) + x, y, (cz << 4) + z, carvingState);
|
||||
|
||||
if (depositBiome != null) {
|
||||
double frequencyMultiplier = depositBiome.getOreDepositFrequencyMultiplier();
|
||||
if (frequencyMultiplier < 1D
|
||||
&& !passesOreFrequency(frequencyMultiplier, rng.d())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double sizeMultiplier = depositBiome.getOreDepositSizeMultiplier();
|
||||
if (sizeMultiplier != 1D) {
|
||||
IrisObject scaledClump = k.getClump(getEngine(), rng, getData(), sizeMultiplier);
|
||||
int scaledDimension = scaledClump.getW();
|
||||
x = clampDepositCenter(x, scaledDimension, 16);
|
||||
y = clampDepositCenter(y, scaledDimension, getEngine().getHeight());
|
||||
z = clampDepositCenter(z, scaledDimension, 16);
|
||||
clump = scaledClump;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IrisDimension dimension = getDimension();
|
||||
|
||||
for (art.arcane.iris.util.common.math.IrisBlockVector j : clump.getBlocks().keys()) {
|
||||
@@ -148,7 +173,8 @@ public class IrisDepositModifier extends EngineAssignedModifier<PlatformBlockSta
|
||||
|
||||
if (chunk.get(nx, ny, nz, MatterCavern.class) == null) {
|
||||
PlatformBlockState ore = clump.getBlocks().get(j);
|
||||
PlatformBlockState remapped = resolveDepositVariant(cx, cz, nx, ny, nz, ore, dimension, context);
|
||||
PlatformBlockState remapped = resolveDepositVariant(
|
||||
cx, cz, nx, ny, nz, ore, dimension, context, carvingState);
|
||||
PlatformBlockState finalBlock = remapped != null
|
||||
? remapped
|
||||
: B.toDeepSlateOre(current, ore);
|
||||
@@ -177,12 +203,22 @@ public class IrisDepositModifier extends EngineAssignedModifier<PlatformBlockSta
|
||||
return state != null && !state.isAir() && !state.isFluid();
|
||||
}
|
||||
|
||||
private PlatformBlockState resolveDepositVariant(int cx, int cz, int nx, int localY, int nz, PlatformBlockState ore, IrisDimension dimension, ChunkContext context) {
|
||||
static boolean passesOreFrequency(double multiplier, double sample) {
|
||||
return multiplier >= 1D || sample < Math.max(0D, multiplier);
|
||||
}
|
||||
|
||||
static int clampDepositCenter(int center, int dimension, int limit) {
|
||||
int minimum = dimension / 2;
|
||||
int maximum = (int) (limit - dimension / 2D);
|
||||
return Math.max(minimum, Math.min(center, maximum));
|
||||
}
|
||||
|
||||
private PlatformBlockState resolveDepositVariant(int cx, int cz, int nx, int localY, int nz, PlatformBlockState ore, IrisDimension dimension, ChunkContext context, IrisDimensionCarvingResolver.State carvingState) {
|
||||
int worldX = (cx << 4) + nx;
|
||||
int worldZ = (cz << 4) + nz;
|
||||
int worldY = absoluteWorldY(getEngine().getMinHeight(), localY);
|
||||
|
||||
IrisBiome biome = getEngine().getBiome(worldX, localY, worldZ);
|
||||
IrisBiome biome = getEngine().getCaveBiome(worldX, localY, worldZ, carvingState);
|
||||
if (biome != null) {
|
||||
PlatformBlockState match = matchDepositVariant(biome.getDepositVariants(), ore, worldY);
|
||||
if (match != null) {
|
||||
|
||||
@@ -205,6 +205,14 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
||||
@ArrayType(min = 1, type = IrisDepositGenerator.class)
|
||||
@Desc("Define biome deposit generators that add onto the existing regional and global deposit generators")
|
||||
private KList<IrisDepositGenerator> deposits = new KList<>();
|
||||
@MinNumber(0)
|
||||
@MaxNumber(1)
|
||||
@Desc("Multiplier applied to the frequency of every ore deposit whose center is inside this biome. A value of 0.4 keeps 40% of ore veins while leaving non-ore deposits unchanged.")
|
||||
private double oreDepositFrequencyMultiplier = 1D;
|
||||
@MinNumber(0.01)
|
||||
@MaxNumber(16)
|
||||
@Desc("Multiplier applied to the block count of every ore deposit whose center is inside this biome. Non-ore deposits are unchanged.")
|
||||
private double oreDepositSizeMultiplier = 1D;
|
||||
@ArrayType(min = 1, type = IrisDepositVariant.class)
|
||||
@Desc("Deposit ore remap rules scoped to this biome. Each entry declares a vertical band and a source->replacement block id map. Applied before regional and dimension rules; first matching biome rule wins.")
|
||||
private KList<IrisDepositVariant> depositVariants = new KList<>();
|
||||
|
||||
@@ -27,16 +27,18 @@ import art.arcane.iris.engine.object.annotations.MaxNumber;
|
||||
import art.arcane.iris.engine.object.annotations.MinNumber;
|
||||
import art.arcane.iris.engine.object.annotations.Required;
|
||||
import art.arcane.iris.engine.object.annotations.Snippet;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.math.IrisBlockVector;
|
||||
import art.arcane.iris.util.common.math.Vector3i;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import art.arcane.volmlib.util.collection.KSet;
|
||||
import art.arcane.volmlib.util.math.BlockPosition;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Snippet("deposit")
|
||||
@@ -46,8 +48,10 @@ import lombok.experimental.Accessors;
|
||||
@Desc("Creates ore & other block deposits underground")
|
||||
@Data
|
||||
public class IrisDepositGenerator {
|
||||
private final transient AtomicCache<KList<IrisObject>> objects = new AtomicCache<>();
|
||||
private final transient ConcurrentMap<ClumpCacheKey, KList<IrisObject>> objects = new ConcurrentHashMap<>();
|
||||
private final transient AtomicCache<KList<PlatformBlockState>> blockData = new AtomicCache<>();
|
||||
private final transient AtomicCache<Boolean> ore = new AtomicCache<>();
|
||||
private final transient ConcurrentMap<ClumpCacheKey, KList<IrisObject>> scaledObjects = new ConcurrentHashMap<>();
|
||||
@Required
|
||||
@MinNumber(0)
|
||||
@MaxNumber(8192) // TODO: WARNING HEIGHT
|
||||
@@ -98,13 +102,14 @@ public class IrisDepositGenerator {
|
||||
private boolean replaceBedrock = false;
|
||||
|
||||
public IrisObject getClump(Engine engine, RNG rng, IrisData rdata) {
|
||||
KList<IrisObject> objects = this.objects.aquire(() ->
|
||||
{
|
||||
RNG rngv = new RNG(engine.getSeedManager().getDeposit() + hashCode());
|
||||
ClumpCacheKey cacheKey = new ClumpCacheKey(engine.getSeedManager().getDeposit(), minSize, maxSize);
|
||||
KList<IrisObject> objects = this.objects.computeIfAbsent(cacheKey, key -> {
|
||||
RNG rngv = new RNG(key.depositSeed() + hashCode());
|
||||
KList<IrisObject> objectsf = new KList<>();
|
||||
|
||||
for (int i = 0; i < varience; i++) {
|
||||
objectsf.add(generateClumpObject(rngv.nextParallelRNG(2349 * i + 3598), rdata));
|
||||
objectsf.add(generateClumpObject(
|
||||
rngv.nextParallelRNG(2349 * i + 3598), rdata, key.minSize(), key.maxSize()));
|
||||
}
|
||||
|
||||
return objectsf;
|
||||
@@ -112,12 +117,40 @@ public class IrisDepositGenerator {
|
||||
return objects.get(rng.i(0, objects.size()));
|
||||
}
|
||||
|
||||
public IrisObject getClump(Engine engine, RNG rng, IrisData rdata, double sizeMultiplier) {
|
||||
if (sizeMultiplier == 1D) {
|
||||
return getClump(engine, rng, rdata);
|
||||
}
|
||||
|
||||
int scaledMinSize = scaledDepositSize(minSize, sizeMultiplier);
|
||||
int scaledMaxSize = scaledDepositSize(maxSize, sizeMultiplier);
|
||||
ClumpCacheKey cacheKey = new ClumpCacheKey(
|
||||
engine.getSeedManager().getDeposit(), scaledMinSize, scaledMaxSize);
|
||||
KList<IrisObject> objects = scaledObjects.computeIfAbsent(cacheKey, key -> {
|
||||
long sizeSeed = ((long) key.minSize() << 32) ^ (key.maxSize() & 0xffffffffL);
|
||||
RNG rngv = new RNG(key.depositSeed() + hashCode() + sizeSeed);
|
||||
KList<IrisObject> generated = new KList<>();
|
||||
|
||||
for (int i = 0; i < varience; i++) {
|
||||
generated.add(generateClumpObject(
|
||||
rngv.nextParallelRNG(2349 * i + 3598), rdata, key.minSize(), key.maxSize()));
|
||||
}
|
||||
|
||||
return generated;
|
||||
});
|
||||
return objects.get(rng.i(0, objects.size()));
|
||||
}
|
||||
|
||||
public int getMaxDimension() {
|
||||
return Math.min(11, (int) Math.ceil(Math.cbrt(maxSize)));
|
||||
}
|
||||
|
||||
private IrisObject generateClumpObject(RNG rngv, IrisData rdata) {
|
||||
int s = rngv.i(minSize, maxSize + 1);
|
||||
static int scaledDepositSize(int size, double multiplier) {
|
||||
return Math.max(0, Math.min(8192, (int) Math.round(size * multiplier)));
|
||||
}
|
||||
|
||||
private IrisObject generateClumpObject(RNG rngv, IrisData rdata, int clumpMinSize, int clumpMaxSize) {
|
||||
int s = rngv.i(clumpMinSize, clumpMaxSize + 1);
|
||||
if (s == 1) {
|
||||
IrisObject o = new IrisObject(1, 1, 1);
|
||||
Vector3i center = o.getCenter();
|
||||
@@ -184,4 +217,19 @@ public class IrisDepositGenerator {
|
||||
return blockData;
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isOre(IrisData rdata) {
|
||||
return ore.aquire(() -> {
|
||||
for (PlatformBlockState block : getBlockData(rdata)) {
|
||||
if (block.isOre()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
record ClumpCacheKey(long depositSeed, int minSize, int maxSize) {
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@@ -100,7 +101,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
protected transient volatile boolean smartBored = false;
|
||||
@Setter
|
||||
protected transient AtomicCache<AxisAlignedBB> aabb = new AtomicCache<>();
|
||||
private transient final AtomicCache<Boolean> treeBlockPresence = new AtomicCache<>();
|
||||
private transient final AtomicCache<KList<IrisBlockVector>> surfaceSupportOffsets = new AtomicCache<>();
|
||||
@Getter
|
||||
private VectorMap<PlatformBlockState> blocks;
|
||||
@Getter
|
||||
@@ -326,7 +327,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
public void readLegacy(InputStream in) throws IOException {
|
||||
treeBlockPresence.reset();
|
||||
surfaceSupportOffsets.reset();
|
||||
DataInputStream din = new DataInputStream(in);
|
||||
this.w = din.readInt();
|
||||
this.h = din.readInt();
|
||||
@@ -358,7 +359,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
public void read(InputStream in) throws Throwable {
|
||||
treeBlockPresence.reset();
|
||||
surfaceSupportOffsets.reset();
|
||||
DataInputStream din = new DataInputStream(in);
|
||||
this.w = din.readInt();
|
||||
this.h = din.readInt();
|
||||
@@ -602,6 +603,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
shrinkOffset = offset;
|
||||
blocks = b;
|
||||
states = s;
|
||||
surfaceSupportOffsets.reset();
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
@@ -613,6 +615,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
|
||||
blocks = d;
|
||||
states = dx;
|
||||
surfaceSupportOffsets.reset();
|
||||
}
|
||||
|
||||
public IrisBlockVector getSigned(int x, int y, int z) {
|
||||
@@ -624,7 +627,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
public void setUnsigned(int x, int y, int z, PlatformBlockState block) {
|
||||
treeBlockPresence.reset();
|
||||
surfaceSupportOffsets.reset();
|
||||
IrisBlockVector v = getSigned(x, y, z);
|
||||
|
||||
if (block == null) {
|
||||
@@ -646,7 +649,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
public void setUnsigned(int x, int y, int z, Block block, boolean legacy) {
|
||||
treeBlockPresence.reset();
|
||||
surfaceSupportOffsets.reset();
|
||||
IrisBlockVector v = getSigned(x, y, z);
|
||||
|
||||
if (block == null) {
|
||||
@@ -932,9 +935,8 @@ public class IrisObject extends IrisRegistrant {
|
||||
&& !config.isUnderwater()
|
||||
&& !config.isOnwater()
|
||||
&& config.getCarvingSupport().supportsSurface()
|
||||
&& hasTreeBlocks()
|
||||
&& IrisSurfaceOpening.isOpen(oplacer, getLoader(), x, z, config.getTranslate(),
|
||||
config.getRotation(), spinx, spiny, spinz)) {
|
||||
config.getRotation(), spinx, spiny, spinz, getSurfaceSupportOffsets())) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1511,16 +1513,32 @@ public class IrisObject extends IrisRegistrant {
|
||||
};
|
||||
}
|
||||
|
||||
boolean hasTreeBlocks() {
|
||||
Boolean present = treeBlockPresence.aquire(() -> {
|
||||
KList<IrisBlockVector> getSurfaceSupportOffsets() {
|
||||
return surfaceSupportOffsets.aquire(() -> {
|
||||
readLock.lock();
|
||||
try {
|
||||
return IrisSurfaceOpening.containsTreeBlocks(blocks.values());
|
||||
int lowestY = Integer.MAX_VALUE;
|
||||
KList<IrisBlockVector> offsets = new KList<>();
|
||||
for (Map.Entry<IrisBlockVector, PlatformBlockState> entry : blocks) {
|
||||
PlatformBlockState state = entry.getValue();
|
||||
if (state == null || !state.isSolid() || state.isFoliage()) {
|
||||
continue;
|
||||
}
|
||||
IrisBlockVector position = entry.getKey();
|
||||
int blockY = position.getBlockY();
|
||||
if (blockY < lowestY) {
|
||||
lowestY = blockY;
|
||||
offsets.clear();
|
||||
}
|
||||
if (blockY == lowestY) {
|
||||
offsets.add(position.clone());
|
||||
}
|
||||
}
|
||||
return offsets;
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
});
|
||||
return Boolean.TRUE.equals(present);
|
||||
}
|
||||
|
||||
private boolean isCarvedCaveAnchor(IObjectPlacer placer, int x, int y, int z) {
|
||||
@@ -1584,6 +1602,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
|
||||
blocks = d;
|
||||
states = dx;
|
||||
surfaceSupportOffsets.reset();
|
||||
shrinkwrap();
|
||||
writeLock.unlock();
|
||||
}
|
||||
@@ -1713,6 +1732,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
blocks = b;
|
||||
surfaceSupportOffsets.reset();
|
||||
writeLock.unlock();
|
||||
}
|
||||
|
||||
@@ -1744,6 +1764,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
blocks = b;
|
||||
surfaceSupportOffsets.reset();
|
||||
writeLock.unlock();
|
||||
}
|
||||
|
||||
@@ -1779,6 +1800,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
blocks = b;
|
||||
surfaceSupportOffsets.reset();
|
||||
writeLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,4 +21,7 @@ public class IrisStructureStiltSettings {
|
||||
|
||||
@Desc("Block palette used for foundation columns.")
|
||||
private IrisMaterialPalette palette = new IrisMaterialPalette().qclear().qadd("minecraft:cobblestone");
|
||||
|
||||
@Desc("For Iris-authored structures, whether solid partial blocks such as slabs, stairs, and walls may seed foundation columns instead of requiring a fully occluding base block.")
|
||||
private boolean supportNonOccluding = false;
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package art.arcane.iris.engine.object;
|
||||
|
||||
import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.math.IrisBlockVector;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
final class IrisSurfaceOpening {
|
||||
private static final int SUPPORT_RADIUS = 1;
|
||||
|
||||
@@ -11,15 +12,37 @@ final class IrisSurfaceOpening {
|
||||
}
|
||||
|
||||
static boolean isOpen(IObjectPlacer placer, IrisData data, int x, int z, IrisObjectTranslate translate,
|
||||
IrisObjectRotation rotation, int spinX, int spinY, int spinZ) {
|
||||
IrisBlockVector offset = new IrisBlockVector(0, 0, 0);
|
||||
if (translate != null) {
|
||||
offset = rotation == null
|
||||
? translate.translate(offset)
|
||||
: translate.translate(offset, rotation, spinX, spinY, spinZ);
|
||||
IrisObjectRotation rotation, int spinX, int spinY, int spinZ,
|
||||
List<IrisBlockVector> supportOffsets) {
|
||||
if (supportOffsets.isEmpty()) {
|
||||
IrisBlockVector origin = transform(new IrisBlockVector(0, 0, 0), translate, rotation, spinX, spinY, spinZ);
|
||||
return isOpenAround(placer, data, x + origin.getBlockX(), z + origin.getBlockZ());
|
||||
}
|
||||
int centerX = x + offset.getBlockX();
|
||||
int centerZ = z + offset.getBlockZ();
|
||||
|
||||
for (IrisBlockVector supportOffset : supportOffsets) {
|
||||
IrisBlockVector transformed = transform(supportOffset, translate, rotation, spinX, spinY, spinZ);
|
||||
if (isOpenAround(placer, data, x + transformed.getBlockX(), z + transformed.getBlockZ())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static IrisBlockVector transform(IrisBlockVector offset, IrisObjectTranslate translate,
|
||||
IrisObjectRotation rotation, int spinX, int spinY, int spinZ) {
|
||||
IrisBlockVector transformed = offset.clone();
|
||||
if (rotation != null) {
|
||||
transformed = rotation.rotate(transformed, spinX, spinY, spinZ);
|
||||
}
|
||||
if (translate == null) {
|
||||
return transformed;
|
||||
}
|
||||
return rotation == null
|
||||
? translate.translate(transformed)
|
||||
: translate.translate(transformed, rotation, spinX, spinY, spinZ);
|
||||
}
|
||||
|
||||
private static boolean isOpenAround(IObjectPlacer placer, IrisData data, int centerX, int centerZ) {
|
||||
for (int dx = -SUPPORT_RADIUS; dx <= SUPPORT_RADIUS; dx++) {
|
||||
for (int dz = -SUPPORT_RADIUS; dz <= SUPPORT_RADIUS; dz++) {
|
||||
int sampleX = centerX + dx;
|
||||
@@ -32,13 +55,4 @@ final class IrisSurfaceOpening {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean containsTreeBlocks(Iterable<PlatformBlockState> states) {
|
||||
for (PlatformBlockState state : states) {
|
||||
if (state != null && state.isTreeBlock()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user