Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ProtoCube and ImposterProtoCube #22

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.github.opencubicchunks.cubicchunks.mixin.core.common.world.level.cube;

import io.github.opencubicchunks.cubicchunks.world.level.chunklike.ImposterProtoClo;
import io.github.opencubicchunks.cubicchunks.world.level.chunklike.LevelClo;
import io.github.opencubicchunks.cubicchunks.world.level.cube.ImposterProtoCube;
import io.github.opencubicchunks.cubicchunks.world.level.cube.LevelCube;
import org.spongepowered.asm.mixin.Dynamic;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

// Needed for DASM to apply
@Mixin(ImposterProtoCube.class)
public abstract class MixinImposterProtoCube extends MixinProtoCube implements ImposterProtoClo {
// Field generated by DASM
@Dynamic @Shadow @Final private LevelCube wrapped;

@Override public LevelClo cc_getWrappedClo() {
return this.wrapped;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.opencubicchunks.cubicchunks.mixin.core.common.world.level.cube;

import io.github.opencubicchunks.cc_core.utils.Coords;
import io.github.opencubicchunks.cubicchunks.world.level.cube.ProtoCube;
import net.minecraft.core.BlockPos;
import org.spongepowered.asm.mixin.Dynamic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

// Needed for DASM to apply
@Mixin(ProtoCube.class)
public abstract class MixinProtoCube extends MixinCubeAccess {
/**
* Redirect to use cube section indexing instead of chunk section indexing
*/
@Dynamic @Redirect(method = {"markPosForPostprocessing", "cc_dasm$getBlockState", "cc_dasm$getFluidState"}, at = @At(value = "INVOKE", target = "Lio/github/opencubicchunks/cubicchunks"
+ "/world/level/cube/ProtoCube;getSectionIndex(I)I"))
private int cc_onGetBlockState_SectionIndex(ProtoCube instance, int i, BlockPos pos) {
return Coords.blockToIndex(pos);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.UpgradeData;
import net.minecraft.world.level.gameevent.GameEventListenerRegistry;
import net.minecraft.world.level.levelgen.BelowZeroRetrogen;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.NoiseChunk;
Expand Down Expand Up @@ -112,6 +113,9 @@ private static void replaceMissingSections(Registry<Biome> biomeRegistry, LevelC
}
}

@TransformFrom(copyFrom = @CopyFrom(clazz = ChunkAccess.class), value = "getListenerRegistry(I)Lnet/minecraft/world/level/gameevent/GameEventListenerRegistry;")
@Override public native GameEventListenerRegistry getListenerRegistry(int sectionY);

@Override @Nullable public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving);

@Override public abstract void setBlockEntity(BlockEntity blockEntity);
Expand Down Expand Up @@ -287,6 +291,9 @@ private static void replaceMissingSections(Registry<Biome> biomeRegistry, LevelC
@TransformFrom(copyFrom = @CopyFrom(clazz = ChunkAccess.class), value = "setInhabitedTime(J)V")
@Override public native void setInhabitedTime(long inhabitedTime);

@TransformFrom(copyFrom = @CopyFrom(clazz = ChunkAccess.class), value = "getOrCreateOffsetList([Lit/unimi/dsi/fastutil/shorts/ShortList;I)Lit/unimi/dsi/fastutil/shorts/ShortList;")
public static native ShortList getOrCreateOffsetList(ShortList[] packedPositions, int index);

@TransformFrom(copyFrom = @CopyFrom(clazz = ChunkAccess.class), value = "isLightCorrect()Z")
@Override public native boolean isLightCorrect();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
package io.github.opencubicchunks.cubicchunks.world.level.cube;

import io.github.opencubicchunks.cubicchunks.mixin.CopyFrom;
import io.github.opencubicchunks.cubicchunks.mixin.DasmRedirect;
import io.github.opencubicchunks.cubicchunks.mixin.TransformFromClass;
import io.github.opencubicchunks.cubicchunks.world.level.chunklike.ImposterProtoClo;
import io.github.opencubicchunks.cubicchunks.world.level.chunklike.LevelClo;
import net.minecraft.world.level.chunk.ImposterProtoChunk;

// not yet implemented - stub class
public abstract class ImposterProtoCube extends ProtoCube implements ImposterProtoClo {
// Whole class redirect
@DasmRedirect({ "cubeAccessAndDescendants" })
@TransformFromClass(@CopyFrom(clazz = ImposterProtoChunk.class))
public class ImposterProtoCube extends ProtoCube implements ImposterProtoClo {
// Field cleared and re-generated by DASM; we just need it here because otherwise mixin does not detect that the field exists.
private LevelCube wrapped;

public ImposterProtoCube(LevelCube wrapped, boolean allowWrites) {
super(null, null, null, null, null);
throw new IllegalStateException("DASM failed to apply");
}

// Method is implemented in MixinImposterProtoCube instead, since DASM clears everything in this class.
@Override public LevelClo cc_getWrappedClo() {
throw new IllegalStateException("DASM failed to apply");
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,191 @@
package io.github.opencubicchunks.cubicchunks.world.level.cube;

import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

import com.google.common.collect.Lists;
import io.github.opencubicchunks.cc_core.utils.Coords;
import io.github.opencubicchunks.cubicchunks.mixin.CopyFrom;
import io.github.opencubicchunks.cubicchunks.mixin.DasmRedirect;
import io.github.opencubicchunks.cubicchunks.mixin.TransformFrom;
import io.github.opencubicchunks.cubicchunks.world.level.chunklike.CloPos;
import io.github.opencubicchunks.cubicchunks.world.level.chunklike.ProtoClo;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.CarvingMask;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.UpgradeData;
import net.minecraft.world.level.levelgen.BelowZeroRetrogen;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.blending.BlendingData;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.ticks.LevelChunkTicks;
import net.minecraft.world.ticks.ProtoChunkTicks;
import net.minecraft.world.ticks.TickContainerAccess;

@DasmRedirect({ "cubeAccessAndDescendants" })
public class ProtoCube extends CubeAccess implements ProtoClo {
// Fields matching ProtoChunk
@Nullable
private volatile LevelLightEngine lightEngine;
private volatile ChunkStatus status;
private final List<CompoundTag> entities;
private final Map<GenerationStep.Carving, CarvingMask> carvingMasks;
@Nullable
private BelowZeroRetrogen belowZeroRetrogen;
private final ProtoChunkTicks<Block> blockTicks;
private final ProtoChunkTicks<Fluid> fluidTicks;

// Constructors mirroring vanilla signatures
public ProtoCube(CloPos cloPos, UpgradeData upgradeData, LevelHeightAccessor levelHeightAccessor, Registry<Biome> biomeRegistry, @Nullable BlendingData blendingData) {
this(cloPos, upgradeData, null, new ProtoChunkTicks(), new ProtoChunkTicks(), levelHeightAccessor, biomeRegistry, blendingData);
}

public ProtoCube(CloPos cloPos, UpgradeData upgradeData, @Nullable LevelChunkSection[] sections, ProtoChunkTicks<Block> blockTicks, ProtoChunkTicks<Fluid> liquidTicks,
LevelHeightAccessor levelHeightAccessor, Registry<Biome> biomeRegistry, @Nullable BlendingData blendingData) {
super(cloPos, upgradeData, levelHeightAccessor, biomeRegistry, 0L, sections, blendingData);
this.status = ChunkStatus.EMPTY;
this.entities = Lists.newArrayList();
this.carvingMasks = new Object2ObjectArrayMap();
this.blockTicks = blockTicks;
this.fluidTicks = liquidTicks;
}

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getBlockTicks()Lnet/minecraft/world/ticks/TickContainerAccess;")
@Override public native TickContainerAccess<Block> getBlockTicks();

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getFluidTicks()Lnet/minecraft/world/ticks/TickContainerAccess;")
@Override public native TickContainerAccess<Fluid> getFluidTicks();

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getTicksForSerialization()Lnet/minecraft/world/level/chunk/ChunkAccess$TicksToSave;")
@Override public native ChunkAccess.TicksToSave getTicksForSerialization();

// dasm + mixin
@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;")
@Override public native BlockState getBlockState(BlockPos pos);

// dasm + mixin
@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getFluidState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/material/FluidState;")
@Override public native FluidState getFluidState(BlockPos pos);

@Nullable
@Override public BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving) {
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
LevelChunkSection section = this.getSection(Coords.blockToIndex(pos));
boolean emptySection = section.hasOnlyAir();
if (emptySection && state.is(Blocks.AIR)) {
return state;
} else {
int sectionLocalX = SectionPos.sectionRelative(x);
int sectionLocalY = SectionPos.sectionRelative(y);
int sectionLocalZ = SectionPos.sectionRelative(z);
BlockState blockstate = section.setBlockState(sectionLocalX, sectionLocalY, sectionLocalZ, state);
// TODO (P2) lighting and heightmaps - see vanilla method - might be dasm-able once we do?

return blockstate;
}
}

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "setBlockEntity(Lnet/minecraft/world/level/block/entity/BlockEntity;)V")
@Override public native void setBlockEntity(BlockEntity pBlockEntity);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getBlockEntity(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/entity/BlockEntity;")
@Override @Nullable public native BlockEntity getBlockEntity(BlockPos pPos);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getBlockEntities()Ljava/util/Map;")
@Override public native Map<BlockPos, BlockEntity> getBlockEntities();

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "addEntity(Lnet/minecraft/nbt/CompoundTag;)V")
@Override public native void addEntity(CompoundTag pTag);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "addEntity(Lnet/minecraft/world/entity/Entity;)V")
@Override public native void addEntity(Entity pEntity);

// setStartForStructure: ProtoChunk logic handles below-zero retrogen then calls super, so we don't need to override

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getEntities()Ljava/util/List;")
@Override public native List<CompoundTag> getEntities();

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getStatus()Lnet/minecraft/world/level/chunk/ChunkStatus;")
@Override public native ChunkStatus getStatus();

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "setStatus(Lnet/minecraft/world/level/chunk/ChunkStatus;)V")
@Override public native void setStatus(ChunkStatus pStatus);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getNoiseBiome(III)Lnet/minecraft/core/Holder;")
@Override public native Holder<Biome> getNoiseBiome(int pX, int pY, int pZ);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "packOffsetCoordinates(Lnet/minecraft/core/BlockPos;)S")
public native static short packOffsetCoordinates(BlockPos pPos);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "unpackOffsetCoordinates(SILnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/core/BlockPos;")
public native static BlockPos unpackOffsetCoordinates(short pPackedPos, int pYOffset, ChunkPos pChunkPos);

// dasm + mixin
@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "markPosForPostprocessing(Lnet/minecraft/core/BlockPos;)V")
@Override public native void markPosForPostprocessing(BlockPos pPos);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "addPackedPostProcess(SI)V")
@Override public native void addPackedPostProcess(short pPackedPosition, int pIndex);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getBlockEntityNbts()Ljava/util/Map;")
@Override public native Map<BlockPos, CompoundTag> getBlockEntityNbts();

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getBlockEntityNbtForSaving(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/nbt/CompoundTag;")
@Override @Nullable public native CompoundTag getBlockEntityNbtForSaving(BlockPos pPos);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "removeBlockEntity(Lnet/minecraft/core/BlockPos;)V")
@Override public native void removeBlockEntity(BlockPos pPos);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getCarvingMask(Lnet/minecraft/world/level/levelgen/GenerationStep$Carving;)Lnet/minecraft/world/level/chunk/CarvingMask;")
@Override @Nullable public native CarvingMask getCarvingMask(GenerationStep.Carving pStep);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "getOrCreateCarvingMask(Lnet/minecraft/world/level/levelgen/GenerationStep$Carving;)Lnet/minecraft/world/level/chunk/CarvingMask;")
@Override public native CarvingMask getOrCreateCarvingMask(GenerationStep.Carving pStep);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "setCarvingMask(Lnet/minecraft/world/level/levelgen/GenerationStep$Carving;Lnet/minecraft/world/level/chunk/CarvingMask;)V")
@Override public native void setCarvingMask(GenerationStep.Carving pStep, CarvingMask pCarvingMask);

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "setLightEngine(Lnet/minecraft/world/level/lighting/LevelLightEngine;)V")
@Override public native void setLightEngine(LevelLightEngine pLightEngine);

@Override public void setBelowZeroRetrogen(@Nullable BelowZeroRetrogen pBelowZeroRetrogen) {
// Unused
}

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "unpackTicks(Lnet/minecraft/world/ticks/ProtoChunkTicks;)Lnet/minecraft/world/ticks/LevelChunkTicks;")
private static <T> LevelChunkTicks<T> unpackTicks(ProtoChunkTicks<T> pTicks) {
return new LevelChunkTicks(pTicks.scheduledTicks());
}

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "unpackBlockTicks()Lnet/minecraft/world/ticks/LevelChunkTicks;")
@Override public native LevelChunkTicks<Block> unpackBlockTicks();

@TransformFrom(copyFrom = @CopyFrom(clazz = ProtoChunk.class), value = "unpackFluidTicks()Lnet/minecraft/world/ticks/LevelChunkTicks;")
@Override public native LevelChunkTicks<Fluid> unpackFluidTicks();

// not yet implemented - stub class
public abstract class ProtoCube extends CubeAccess implements ProtoClo {
public ProtoCube() {
super(null, null, null, null, 0L, null, null);
@Override public LevelHeightAccessor getHeightAccessorForGeneration() {
return this; // Vanilla has logic for below-zero retrogen here
}
}
2 changes: 2 additions & 0 deletions src/main/resources/cubicchunks.mixins.core.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
"common.world.level.chunk.MixinImposterProtoChunk",
"common.world.level.chunk.MixinLevelChunk",
"common.world.level.cube.MixinCubeAccess",
"common.world.level.cube.MixinImposterProtoCube",
"common.world.level.cube.MixinLevelCube",
"common.world.level.cube.MixinLevelCube$BoundTickingBlockEntity",
"common.world.level.cube.MixinLevelCube$RebindableTickingBlockEntityWrapper",
"common.world.level.cube.MixinProtoCube",
"common.world.level.MixinLevel"
],
"client": [],
Expand Down
10 changes: 8 additions & 2 deletions src/main/resources/dasm/sets/sets.dasm
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@
"net.minecraft.world.level.chunk.LevelChunk$PostLoadProcessor",
"net.minecraft.world.level.chunk.LevelChunk$RebindableTickingBlockEntityWrapper",
"net.minecraft.world.level.chunk.ChunkAccess",
"net.minecraft.world.level.chunk.ProtoChunk",
"net.minecraft.world.level.chunk.ImposterProtoChunk",
"io.github.opencubicchunks.cubicchunks.world.level.chunklike.CloAccess",
"io.github.opencubicchunks.cubicchunks.world.level.chunklike.LevelClo",
"io.github.opencubicchunks.cubicchunks.world.level.cube.CubeAccess",
"io.github.opencubicchunks.cubicchunks.world.level.cube.LevelCube",
"io.github.opencubicchunks.cubicchunks.world.level.cube.LevelCube$BoundTickingBlockEntity",
"io.github.opencubicchunks.cubicchunks.world.level.cube.LevelCube$PostLoadProcessor",
"io.github.opencubicchunks.cubicchunks.world.level.cube.LevelCube$RebindableTickingBlockEntityWrapper"
"io.github.opencubicchunks.cubicchunks.world.level.cube.LevelCube$RebindableTickingBlockEntityWrapper",
"io.github.opencubicchunks.cubicchunks.world.level.cube.ProtoCube",
"io.github.opencubicchunks.cubicchunks.world.level.cube.ImposterProtoCube"
],
"sets": {
"general": {
Expand All @@ -36,7 +40,9 @@
"LevelChunk": "LevelCube",
"LevelChunk$BoundTickingBlockEntity": "LevelCube$BoundTickingBlockEntity",
"LevelChunk$PostLoadProcessor": "LevelCube$PostLoadProcessor",
"LevelChunk$RebindableTickingBlockEntityWrapper": "LevelCube$RebindableTickingBlockEntityWrapper"
"LevelChunk$RebindableTickingBlockEntityWrapper": "LevelCube$RebindableTickingBlockEntityWrapper",
"ProtoChunk": "ProtoCube",
"ImposterProtoChunk": "ImposterProtoCube"
},
"fieldRedirects": {
"ChunkAccess | ChunkPos chunkPos": "cloPos"
Expand Down
Loading
Loading