mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-26 10:29:20 +00:00
Merge pull request #352 from ArubikU/preparing-block-entity
Added container and analog
This commit is contained in:
@@ -92,6 +92,18 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior {
|
||||
return previous;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getContainer(Object thisBlock, Object[] args) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
Object container = behavior.getContainer(thisBlock, args);
|
||||
if (container != null) {
|
||||
return container;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
@@ -282,6 +294,30 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
if (behavior.hasAnalogOutputSignal(thisBlock, args)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception {
|
||||
int signal = 0;
|
||||
int count = 0;
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
int s = behavior.getAnalogOutputSignal(thisBlock, args);
|
||||
if (s != 0) {
|
||||
signal += s;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count == 0 ? 0 : signal / count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object playerWillDestroy(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
Object previous = args[0];
|
||||
@@ -300,4 +336,4 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior {
|
||||
behavior.spawnAfterBreak(thisBlock, args, superMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import net.bytebuddy.implementation.bind.annotation.This;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockShape;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.injector.BlockGenerator.*;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
|
||||
import net.momirealms.craftengine.bukkit.util.NoteBlockChainUpdateUtils;
|
||||
@@ -62,6 +63,7 @@ public final class BlockGenerator {
|
||||
.implement(CoreReflections.clazz$Fallable)
|
||||
.implement(CoreReflections.clazz$BonemealableBlock)
|
||||
.implement(CoreReflections.clazz$SimpleWaterloggedBlock)
|
||||
.implement(CoreReflections.clazz$WorldlyContainerHolder)
|
||||
// internal interfaces
|
||||
.method(ElementMatchers.named("behaviorDelegate"))
|
||||
.intercept(FieldAccessor.ofField("behaviorHolder"))
|
||||
@@ -89,12 +91,21 @@ public final class BlockGenerator {
|
||||
// rotate
|
||||
.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$rotate))
|
||||
.intercept(MethodDelegation.to(RotateInterceptor.INSTANCE))
|
||||
// hasAnalogOutputSignal
|
||||
.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$hasAnalogOutputSignal))
|
||||
.intercept(MethodDelegation.to(HasAnalogOutputSignalInterceptor.INSTANCE))
|
||||
// getAnalogOutputSignal
|
||||
.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$getAnalogOutputSignal))
|
||||
.intercept(MethodDelegation.to(GetAnalogOutputSignalInterceptor.INSTANCE))
|
||||
// tick
|
||||
.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$tick))
|
||||
.intercept(MethodDelegation.to(TickInterceptor.INSTANCE))
|
||||
// isValidBoneMealTarget
|
||||
.method(ElementMatchers.is(CoreReflections.method$BonemealableBlock$isValidBonemealTarget))
|
||||
.intercept(MethodDelegation.to(IsValidBoneMealTargetInterceptor.INSTANCE))
|
||||
// getContainer
|
||||
.method(ElementMatchers.is(CoreReflections.method$WorldlyContainerHolder$getContainer))
|
||||
.intercept(MethodDelegation.to(GetContainerInterceptor.INSTANCE))
|
||||
// isBoneMealSuccess
|
||||
.method(ElementMatchers.is(CoreReflections.method$BonemealableBlock$isBonemealSuccess))
|
||||
.intercept(MethodDelegation.to(IsBoneMealSuccessInterceptor.INSTANCE))
|
||||
@@ -441,6 +452,50 @@ public final class BlockGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetContainerInterceptor {
|
||||
public static final GetContainerInterceptor INSTANCE = new GetContainerInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||
ObjectHolder<BlockBehavior> holder = ((DelegatingBlock) thisObj).behaviorDelegate();
|
||||
try {
|
||||
return holder.value().getContainer(thisObj, args);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to run getContainer", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class HasAnalogOutputSignalInterceptor {
|
||||
public static final HasAnalogOutputSignalInterceptor INSTANCE = new HasAnalogOutputSignalInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public boolean intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||
ObjectHolder<BlockBehavior> holder = ((DelegatingBlock) thisObj).behaviorDelegate();
|
||||
try {
|
||||
return holder.value().hasAnalogOutputSignal(thisObj, args);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to run hasAnalogOutputSignal", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetAnalogOutputSignalInterceptor {
|
||||
public static final GetAnalogOutputSignalInterceptor INSTANCE = new GetAnalogOutputSignalInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public int intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||
ObjectHolder<BlockBehavior> holder = ((DelegatingBlock) thisObj).behaviorDelegate();
|
||||
try {
|
||||
return holder.value().getAnalogOutputSignal(thisObj, args);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to run getAnalogOutputSignal", e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static class PerformBoneMealInterceptor {
|
||||
public static final PerformBoneMealInterceptor INSTANCE = new PerformBoneMealInterceptor();
|
||||
|
||||
@@ -644,4 +699,4 @@ public final class BlockGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1570,6 +1570,14 @@ public final class CoreReflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$BlockBehaviour$hasAnalogOutputSignal = requireNonNull(
|
||||
ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, boolean.class, new String[]{"hasAnalogOutputSignal", "c"}, clazz$BlockState)
|
||||
);
|
||||
|
||||
public static final Method method$BlockBehaviour$getAnalogOutputSignal = requireNonNull(
|
||||
ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, int.class, new String[]{"getAnalogOutputSignal", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos)
|
||||
);
|
||||
|
||||
public static final Method method$Entity$level = requireNonNull(
|
||||
ReflectionUtils.getMethod(clazz$Entity, clazz$Level)
|
||||
);
|
||||
@@ -2314,12 +2322,30 @@ public final class CoreReflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$WorldlyContainerHolder = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.IInventoryHolder",
|
||||
"world.WorldlyContainerHolder"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$BonemealableBlock$isValidBonemealTarget = requireNonNull(
|
||||
VersionHelper.isOrAbove1_20_2() ?
|
||||
ReflectionUtils.getInstanceMethod(clazz$BonemealableBlock, boolean.class, clazz$LevelReader, clazz$BlockPos, clazz$BlockState) :
|
||||
ReflectionUtils.getInstanceMethod(clazz$BonemealableBlock, boolean.class, clazz$LevelReader, clazz$BlockPos, clazz$BlockState, boolean.class)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$WorldlyContainer = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.IWorldInventory",
|
||||
"world.WorldlyContainer"
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
public static final Method method$WorldlyContainerHolder$getContainer = requireNonNull(
|
||||
ReflectionUtils.getMethod(clazz$WorldlyContainerHolder, clazz$WorldlyContainer, clazz$BlockState, clazz$LevelAccessor, clazz$BlockPos)
|
||||
);
|
||||
public static final Method method$BonemealableBlock$isBonemealSuccess = requireNonNull(
|
||||
ReflectionUtils.getMethod(clazz$BonemealableBlock, boolean.class, clazz$Level, clazz$RandomSource, clazz$BlockPos, clazz$BlockState)
|
||||
);
|
||||
|
||||
@@ -95,6 +95,21 @@ public abstract class BlockBehavior {
|
||||
return false;
|
||||
}
|
||||
|
||||
//BlockState state
|
||||
public boolean hasAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception {
|
||||
return false;
|
||||
}
|
||||
|
||||
//BlockState state Level level BlockPos pos
|
||||
public int getAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// BlockState state, LevelReader world, BlockPos pos
|
||||
public Object getContainer(Object thisBlock, Object[] args) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Level level, RandomSource random, BlockPos pos, BlockState state
|
||||
public boolean isBoneMealSuccess(Object thisBlock, Object[] args) throws Exception {
|
||||
return false;
|
||||
@@ -196,4 +211,4 @@ public abstract class BlockBehavior {
|
||||
}
|
||||
|
||||
public abstract CustomBlock block();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user