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

Implemented ServerLevel, ServerPlayer, Level, ClientLevel for phase 1 #16

Merged
Show file tree
Hide file tree
Changes from all commits
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,5 @@
package io.github.opencubicchunks.cubicchunks;

public interface CanBeCubic {
boolean cc_isCubic();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package io.github.opencubicchunks.cubicchunks;

public interface MarkableAsCubic {
public interface MarkableAsCubic extends CanBeCubic {
void cc_setCubic();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,28 @@

import io.github.opencubicchunks.cubicchunks.MarkableAsCubic;
import io.github.opencubicchunks.cubicchunks.client.multiplayer.CubicClientLevel;
import io.github.opencubicchunks.cubicchunks.mixin.core.common.world.level.MixinLevel;
import net.minecraft.client.multiplayer.ClientLevel;
import org.spongepowered.asm.mixin.Mixin;

@Mixin(ClientLevel.class)
public class MixinClientLevel implements CubicClientLevel, MarkableAsCubic {
public abstract class MixinClientLevel extends MixinLevel implements CubicClientLevel, MarkableAsCubic {
protected boolean cc_isCubic;

@Override
public void cc_setCubic() { cc_isCubic = true;}

// onCubeLoaded - new function
@Override public boolean cc_isCubic() {
return cc_isCubic;
}

// hasCube - new function
@Override public boolean cc_hasCube(int x, int y, int z) {
return true;
}

// unload
// TODO: Phase 2 - this interacts with the lighting engine and will need to change to support cubes

// onCubeLoaded
// TODO: Phase 3 - we will need to interact with entityStorage correctly at a per-cube level
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,106 @@
package io.github.opencubicchunks.cubicchunks.mixin.core.common.server;

import io.github.opencubicchunks.cubicchunks.MarkableAsCubic;
import com.llamalad7.mixinextras.injector.WrapWithCondition;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import io.github.opencubicchunks.cc_core.api.CubePos;
import io.github.opencubicchunks.cc_core.api.CubicConstants;
import io.github.opencubicchunks.cc_core.world.SpawnPlaceFinder;
import io.github.opencubicchunks.cubicchunks.CanBeCubic;
import net.minecraft.core.BlockPos;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.TicketType;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.storage.ServerLevelData;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(MinecraftServer.class)
public class MixinMinecraftServer implements MarkableAsCubic {
protected boolean cc_isCubic;
public abstract class MixinMinecraftServer {
@Shadow public abstract ServerLevel overworld();

@Override
public void cc_setCubic() { cc_isCubic = true;}
@Shadow public abstract boolean isRunning();

// setInitialSpawn - mixin
@Shadow protected long nextTickTimeNanos;

// prepareLevels - mixin
@Shadow protected abstract void waitUntilNextTick();

// setInitialSpawn
// We replace the ChunkPos spawn position with a CubePos spawn position and reuse it later to get the world position.
@Inject(method = "setInitialSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ChunkPos;<init>(Lnet/minecraft/core/BlockPos;)V"))
private static void cc_replaceChunkPosInSetInitialSpawn(ServerLevel serverLevel, ServerLevelData serverLevelData, boolean generateBonusChest, boolean debug, CallbackInfo ci, @Share(
"cubePos") LocalRef<CubePos> cubePosLocalRef) {
if (((CanBeCubic) serverLevel).cc_isCubic()) {
CubePos cubePos = new CubePos(serverLevel.getChunkSource().randomState().sampler().findSpawnPosition());
cubePosLocalRef.set(cubePos);
}
}

@WrapOperation(method = "setInitialSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ChunkPos;getWorldPosition()Lnet/minecraft/core/BlockPos;"))
private static BlockPos cc_replaceGetWorldPositionInSetInitialSpawn(ChunkPos chunkPos, Operation<BlockPos> original, ServerLevel serverLevel, @Share(
"cubePos") LocalRef<CubePos> cubePosLocalRef) {
if (((CanBeCubic) serverLevel).cc_isCubic()) {
return cubePosLocalRef.get().asChunkPos().getWorldPosition();
}
return original.call(chunkPos);
}

/**
* This mixin uses SpawnPlaceFinder (core CC2 code) in a similar fashion to the CC2 implementation.
*/
@WrapOperation(method = "setInitialSpawn",
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getHeight(Lnet/minecraft/world/level/levelgen/Heightmap$Types;II)I"))
private static int cc_replaceGetHeightWithSpawnPlaceFinder(ServerLevel serverLevel, Heightmap.Types heightmapType, int x, int z, Operation<Integer> original,
@Share("cubePos") LocalRef<CubePos> cubePosLocalRef) {
if (((CanBeCubic) serverLevel).cc_isCubic()) {
BlockPos topBlockBisect = SpawnPlaceFinder.getTopBlockBisect(serverLevel, cubePosLocalRef.get().asBlockPos(), false,
pos -> serverLevel.getBlockState(pos).is(BlockTags.VALID_SPAWN),
pos -> serverLevel.getBlockState(pos).getCollisionShape(serverLevel, pos).isEmpty());
if (topBlockBisect != null) {
return topBlockBisect.getY();
} else {
return serverLevel.getSeaLevel() + 1; // This is the default value in vanilla
}
}
return original.call(serverLevel, heightmapType, x, z);
}

// prepareLevels
// This mixin is copied from CC2. It fills in a spawnRadiusRef that is used to determine how many cubes we need to generate for spawn to be ready.
@WrapWithCondition(method = "prepareLevels", at = @At(value = "INVOKE",
target = "Lnet/minecraft/server/level/ServerChunkCache;addRegionTicket(Lnet/minecraft/server/level/TicketType;Lnet/minecraft/world/level/ChunkPos;ILjava/lang/Object;)V"))
private <T> boolean cc_replaceAddRegionTicketInPrepareLevels(ServerChunkCache serverChunkCache, TicketType<T> ticketType, ChunkPos chunkPos, int originalSpawnRadius, T unit,
@Share("spawnRadius") LocalRef<Integer> spawnRadiusRef) {
if (((CanBeCubic) serverChunkCache).cc_isCubic()) {
int spawnRadius = (int) Math.ceil(10 * (16 / (float) CubicConstants.DIAMETER_IN_BLOCKS)); //vanilla is 10, 32: 5, 64: 3
spawnRadiusRef.set(spawnRadius);
// TODO: Fix this when ServerChunkCache exists
//(CubicServerChunkCache)serverChunkCache.addRegionTicket(CubicTicketType.START, CloPos.cube(overworld().getSharedSpawnPos()), spawnRadius + 1, unit);
return false;
}
return true;
}

@Inject(method = "prepareLevels", at = @At(value = "FIELD", target = "Lnet/minecraft/server/MinecraftServer;nextTickTimeNanos:J"))
private void cc_waitUntilCubicGenerationComplete(CallbackInfo ci, @Share("spawnRadius") LocalRef<Integer> spawnRadiusRef) {
if (((CanBeCubic) overworld().getChunkSource()).cc_isCubic()) {
int d = spawnRadiusRef.get() * 2 + 1;
// TODO: Fix this when ServerChunkCache exists
//while (this.isRunning() && ((CubicServerChunkCache) overworld().getChunkSource()).getTickingGeneratedCubes() < d * d * d) {
// this.nextTickTimeNanos = Util.getMillis() + 10L;
// this.waitUntilNextTick();
//}
}
}

// TODO: forced cubes will need to be implemented for prepareLevels as well in the same way as above
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
public abstract class MixinChunkTaskPriorityQueue implements MarkableAsCubic {
protected boolean cc_isCubic;

@Override
public void cc_setCubic() {
@Override public void cc_setCubic() {
cc_isCubic = true;
}

@Override public boolean cc_isCubic() {
return cc_isCubic;
}

@Inject(method = "resortChunkTasks", at = @At("HEAD"))
private void cc_onResortChunkTasks(int queueLevel, ChunkPos chunkPos, int ticketLevel, CallbackInfo ci) {
assert !cc_isCubic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
public abstract class MixinChunkTaskPriorityQueueSorter implements CubicTaskPriorityQueueSorter, MarkableAsCubic {
protected boolean cc_isCubic;

@Override
public void cc_setCubic() {
@Override public void cc_setCubic() {
cc_isCubic = true;
}

@Override public boolean cc_isCubic() {
return cc_isCubic;
}

/**
* This is a method that is only used for debugging, so we don't currently test it.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public void cc_setCubic() {
cc_noChunkLevel = levelCount-1;
}

@Override public boolean cc_isCubic() {
return cc_isCubic;
}

@Redirect(method="*", at = @At(value = "FIELD", target = "Lnet/minecraft/world/level/ChunkPos;INVALID_CHUNK_POS:J"))
private long cc_sentinelValue() {
if (cc_isCubic)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ public void cc_setCubic() {
cc_isCubic = true;
}

@Override public boolean cc_isCubic() {
return cc_isCubic;
}

@Inject(method = {"addTicket(Lnet/minecraft/server/level/TicketType;Lnet/minecraft/world/level/ChunkPos;ILjava/lang/Object;)V",
"removeTicket(Lnet/minecraft/server/level/TicketType;Lnet/minecraft/world/level/ChunkPos;ILjava/lang/Object;)V",
"addRegionTicket(Lnet/minecraft/server/level/TicketType;Lnet/minecraft/world/level/ChunkPos;ILjava/lang/Object;)V",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.opencubicchunks.cubicchunks.mixin.core.common.server.level;

import io.github.opencubicchunks.cc_core.world.CubicLevelHeightAccessor;
import io.github.opencubicchunks.cc_core.world.SpawnPlaceFinder;
import io.github.opencubicchunks.cubicchunks.CanBeCubic;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.PlayerRespawnLogic;
import net.minecraft.server.level.ServerLevel;
Expand All @@ -15,13 +15,16 @@
@Mixin(value = PlayerRespawnLogic.class, priority = 999)
public class MixinPlayerRespawnLogic {

/**
* This mixin uses SpawnPlaceFinder (core CC2 code) in a similar fashion to the CC2 implementation.
*/
@Inject(method = "getOverworldRespawnPos", at = @At("HEAD"), cancellable = true)
private static void getOverworldRespawnPos(ServerLevel level, int posX, int posZ, CallbackInfoReturnable<BlockPos> cir) {
if (!((CubicLevelHeightAccessor) level).isCubic()) {
if (!((CanBeCubic) level).cc_isCubic()) {
return;
}
cir.setReturnValue(SpawnPlaceFinder.getTopBlockBisect(level, new BlockPos(posX, 0, posZ), false,
pos -> level.getBlockState((BlockPos) pos).is(BlockTags.VALID_SPAWN),
pos -> level.getBlockState((BlockPos) pos).getCollisionShape(level, (BlockPos) pos).isEmpty()));
pos -> level.getBlockState(pos).is(BlockTags.VALID_SPAWN),
pos -> level.getBlockState(pos).getCollisionShape(level, pos).isEmpty()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@ public void cc_setCubic() {
cc_isCubic = true;
}

// isNaturalSpawningAllowed - mixin? new function?
@Override
public boolean cc_isCubic() {
return cc_isCubic;
}

// TODO: phase 3 - isNaturalSpawningAllowed

// invalidateCapabilites - phase 3, neoforge api
// TODO: phase 3 - invalidateCapabilites, neoforge api

// tickCube - new function
// TODO: phase 2 - tickCube - new function

// setCubeForced - new function
// TODO: phase 4 - setCubeForced - new function

// saveDebugReport - mixins, debug only, low priority
// TODO: saveDebugReport - mixins, debug only, low priority, if we really really really really need it

// isPositionEntityTicking - mixin
// TODO: phase 2 - isPositionEntityTicking - mixin

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public void cc_setCubic() {
cc_isCubic = true;
}

@Override public boolean cc_isCubic() {
return cc_isCubic;
}

/**
* This mixin steals the x/y/z coordinates from a call to ChunkPos and replaces the ChunkPos in the addRegionTicketCall with a CloPos instead.
*/
Expand Down
Loading
Loading