Files
fabric-carpet/src/main/java/carpet/mixins/StructureFeatureMixin.java
T
2020-05-21 02:59:17 -03:00

156 lines
6.5 KiB
Java

package carpet.mixins;
import carpet.CarpetSettings;
import carpet.fakes.StructureFeatureInterface;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.structure.StructureStart;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.BlockBox;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.BiomeSource;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.gen.ChunkRandom;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Random;
@Mixin(StructureFeature.class)
public abstract class StructureFeatureMixin<C extends FeatureConfig> implements StructureFeatureInterface<C>
{
//problem is that is seems that now chunks deal with its portion of the strucuture
//on its own.
//@Shadow public abstract int getRadius();
@Shadow public abstract String getName();
@Shadow public abstract StructureFeature.StructureStartFactory getStructureStartFactory();
@Shadow protected abstract boolean shouldStartAt(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long l, ChunkRandom chunkRandom, int i, int j, Biome biome, ChunkPos chunkPos, C featureConfig);
@Override
public boolean plopAnywhere(ServerWorld world, BlockPos pos)
{
return plopAnywhere(world, pos, world.getChunkManager().getChunkGenerator(), false, null, null);
}
@Override
public boolean gridAnywhere(ServerWorld world, BlockPos pos)
{
return plopAnywhere(world, pos, world.getChunkManager().getChunkGenerator(), true, null, null);
}
@Override
public boolean plopAnywhere(ServerWorld world, BlockPos pos, ChunkGenerator generator, boolean wireOnly, Biome biome, FeatureConfig config)
{
if (world.isClient())
return false;
CarpetSettings.skipGenerationChecks = true;
try
{
Random rand = new Random(world.getRandom().nextInt());
int j = pos.getX() >> 4;
int k = pos.getZ() >> 4;
long chId = ChunkPos.toLong(j, k);
StructureStart structurestart = forceStructureStart(world, generator, rand, chId, biome, config);
if (structurestart == StructureStart.DEFAULT)
{
return false;
}
//generator.ge getStructurePositionToReferenceMap(this).computeIfAbsent(chId,
// (x) -> new LongOpenHashSet()).add(chId);
world.getChunk(j, k).addStructureReference(this.getName(), chId); //, ChunkStatus.STRUCTURE_STARTS
BlockBox box = structurestart.getBoundingBox();
if (!wireOnly)
{
structurestart.generateStructure(world, world.getStructureAccessor(), generator, rand,box,
/*new BlockBox(
pos.getX() - this.getRadius() * 16,
pos.getZ() - this.getRadius() * 16,
pos.getX() + (this.getRadius() + 1) * 16,
pos.getZ() + (1 + this.getRadius()) * 16),*/
new ChunkPos(j, k)
);
}
//structurestart.notifyPostProcessAt(new ChunkPos(j, k));
int i = Math.max(box.getBlockCountX(),box.getBlockCountZ())/16+1; //size
//int i = getRadius();
for (int k1 = j - i; k1 <= j + i; ++k1)
{
for (int l1 = k - i; l1 <= k + i; ++l1)
{
if (k1 == j && l1 == k) continue;
long nbchkid = ChunkPos.toLong(k1, l1);
if (box.intersectsXZ(k1<<4, l1<<4, (k1<<4) + 15, (l1<<4) + 15))
{
//generator.getStructurePositionToReferenceMap(this).computeIfAbsent(nbchkid, (__) -> new LongOpenHashSet()).add(chId);
world.getChunk(k1, l1).addStructureReference(this.getName(), chId); //, ChunkStatus.STRUCTURE_STARTS
//structurestart. notifyPostProcessAt(new ChunkPos(k1, l1));
}
}
}
}
catch (Exception booboo)
{
CarpetSettings.LOG.error("Unknown Exception while plopping structure: "+booboo);
booboo.printStackTrace();
return false;
}
finally
{
CarpetSettings.skipGenerationChecks = false;
}
return true;
}
private StructureStart forceStructureStart(ServerWorld worldIn, ChunkGenerator generator, Random rand, long packedChunkPos, Biome biome, FeatureConfig config)
{
ChunkPos chunkpos = new ChunkPos(packedChunkPos);
StructureStart structurestart;
Chunk ichunk = worldIn.getChunk(chunkpos.x, chunkpos.z, ChunkStatus.STRUCTURE_STARTS, false);
if (ichunk != null)
{
structurestart = ichunk.getStructureStart(this.getName());
if (structurestart != null && structurestart != StructureStart.DEFAULT)
{
return structurestart;
}
}
Biome biome_1 = biome;
if (biome == null)
biome_1 = generator.getBiomeSource().getBiomeForNoiseGen((chunkpos.getStartX() + 9) >> 2, 0, (chunkpos.getStartZ() + 9) >> 2 );
StructureStart structurestart1 = getStructureStartFactory().create((StructureFeature)(Object)this, chunkpos.x, chunkpos.z, BlockBox.empty(),0,worldIn.getSeed());
if (config == null)
config = new DefaultFeatureConfig();
structurestart1.init(generator, worldIn.getStructureManager() , chunkpos.x, chunkpos.z, biome_1, config);
structurestart = structurestart1.hasChildren() ? structurestart1 : StructureStart.DEFAULT;
if (structurestart.hasChildren())
{
worldIn.getChunk(chunkpos.x, chunkpos.z).setStructureStart(this.getName(), structurestart);
}
//long2objectmap.put(packedChunkPos, structurestart);
return structurestart;
}
@Override
public boolean shouldStartPublicAt(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long l, ChunkRandom chunkRandom, int i, int j, Biome biome, ChunkPos chunkPos, C featureConfig)
{
return shouldStartAt(chunkGenerator, biomeSource, l, chunkRandom, i, j, biome, chunkPos, featureConfig);
}
}