mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-30 20:39:10 +00:00
添加支撑形状
This commit is contained in:
@@ -2,12 +2,15 @@ package net.momirealms.craftengine.bukkit.block;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.shared.block.BlockShape;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BukkitBlockShape implements BlockShape {
|
||||
private final Object rawBlockState;
|
||||
private final Object supportBlockState;
|
||||
|
||||
public BukkitBlockShape(Object rawBlockState) {
|
||||
public BukkitBlockShape(Object rawBlockState, @Nullable Object supportBlockState) {
|
||||
this.rawBlockState = rawBlockState;
|
||||
this.supportBlockState = supportBlockState == null ? rawBlockState : supportBlockState;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -19,4 +22,9 @@ public class BukkitBlockShape implements BlockShape {
|
||||
public Object getCollisionShape(Object thisObj, Object[] args) {
|
||||
return FastNMS.INSTANCE.method$BlockState$getCollisionShape(this.rawBlockState, args[1], args[2], args[3]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSupportShape(Object thisObj, Object[] args) {
|
||||
return FastNMS.INSTANCE.method$BlockState$getBlockSupportShape(this.supportBlockState, args[1], args[2]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,15 +21,13 @@ import net.momirealms.craftengine.core.util.Tristate;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.shared.ObjectHolder;
|
||||
import net.momirealms.craftengine.shared.block.BlockBehavior;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class BukkitCustomBlock extends AbstractCustomBlock {
|
||||
|
||||
@@ -103,7 +101,16 @@ public class BukkitCustomBlock extends AbstractCustomBlock {
|
||||
Field shapeField = mcBlock.getClass().getField("shapeHolder");
|
||||
@SuppressWarnings("unchecked")
|
||||
ObjectHolder<BukkitBlockShape> shapeHolder = (ObjectHolder<BukkitBlockShape>) shapeField.get(mcBlock);
|
||||
shapeHolder.bindValue(new BukkitBlockShape(state.vanillaBlockState().handle()));
|
||||
shapeHolder.bindValue(new BukkitBlockShape(state.vanillaBlockState().handle(), Optional.ofNullable(state.settings().supportShapeBlockState()).map(it -> {
|
||||
try {
|
||||
Object blockState = BlockStateUtils.blockDataToBlockState(Bukkit.createBlockData(it));
|
||||
if (!BlockStateUtils.isVanillaBlock(blockState)) return null;
|
||||
return blockState;
|
||||
} catch (IllegalArgumentException e) {
|
||||
CraftEngine.instance().logger().warn("Illegal shape block state: " + it, e);
|
||||
return null;
|
||||
}
|
||||
}).orElse(null)));
|
||||
// bind behavior
|
||||
Field behaviorField = mcBlock.getClass().getField("behaviorHolder");
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -73,7 +73,7 @@ import java.util.function.Consumer;
|
||||
|
||||
public class BukkitInjector {
|
||||
private static final ByteBuddy byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V17);
|
||||
private static final BukkitBlockShape STONE_SHAPE = new BukkitBlockShape(Reflections.instance$Blocks$STONE$defaultState);
|
||||
private static final BukkitBlockShape STONE_SHAPE = new BukkitBlockShape(Reflections.instance$Blocks$STONE$defaultState, Reflections.instance$Blocks$STONE$defaultState);
|
||||
|
||||
private static Class<?> clazz$InjectedPalettedContainer;
|
||||
private static Class<?> clazz$InjectedLevelChunkSection;
|
||||
@@ -251,6 +251,9 @@ public class BukkitInjector {
|
||||
// getCollisionShape
|
||||
.method(ElementMatchers.is(Reflections.method$BlockBehaviour$getCollisionShape))
|
||||
.intercept(MethodDelegation.to(GetCollisionShapeInterceptor.INSTANCE))
|
||||
// getSupportShape
|
||||
.method(ElementMatchers.is(Reflections.method$BlockBehaviour$getBlockSupportShape))
|
||||
.intercept(MethodDelegation.to(GetSupportShapeInterceptor.INSTANCE))
|
||||
// mirror
|
||||
.method(ElementMatchers.is(Reflections.method$BlockBehaviour$mirror))
|
||||
.intercept(MethodDelegation.to(MirrorInterceptor.INSTANCE))
|
||||
@@ -941,6 +944,21 @@ public class BukkitInjector {
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetSupportShapeInterceptor {
|
||||
public static final GetSupportShapeInterceptor INSTANCE = new GetSupportShapeInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) throws Exception {
|
||||
ObjectHolder<BlockShape> holder = ((ShapeHolder) thisObj).getShapeHolder();
|
||||
try {
|
||||
return holder.value().getSupportShape(thisObj, args);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to run getSupportShape", e);
|
||||
return superMethod.call();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MirrorInterceptor {
|
||||
public static final MirrorInterceptor INSTANCE = new MirrorInterceptor();
|
||||
|
||||
|
||||
@@ -2548,6 +2548,12 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$BlockBehaviour$getBlockSupportShape = requireNonNull(
|
||||
ReflectionUtils.getDeclaredMethod(
|
||||
clazz$BlockBehaviour, clazz$VoxelShape, new String[]{"getBlockSupportShape", "b_"}, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$BlockBehaviour$tick = requireNonNull(
|
||||
ReflectionUtils.getDeclaredMethod(
|
||||
clazz$BlockBehaviour, void.class, new String[]{"tick", "a"}, clazz$BlockState, clazz$ServerLevel, clazz$BlockPos, clazz$RandomSource
|
||||
|
||||
Reference in New Issue
Block a user