9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-29 20:09:13 +00:00

Merge pull request #388 from jhqwqmc/dev

feat(block): 添加瓜藤相关的方块行为并且修复判断方块问题
This commit is contained in:
XiaoMoMi
2025-09-23 17:29:38 +08:00
committed by GitHub
28 changed files with 813 additions and 158 deletions

View File

@@ -0,0 +1,110 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
import net.momirealms.craftengine.core.block.BlockBehavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.block.properties.IntegerProperty;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.util.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Callable;
public class AttachedStemBlockBehavior extends BushBlockBehavior {
public static final Factory FACTORY = new Factory();
private final Property<HorizontalDirection> facingProperty;
private final Key fruit;
private final Key stem;
public AttachedStemBlockBehavior(CustomBlock customBlock,
int delay,
boolean blacklist,
List<Object> tagsCanSurviveOn,
Set<Object> blockStatesCanSurviveOn,
Set<String> customBlocksCansSurviveOn,
Property<HorizontalDirection> facingProperty,
Key fruit,
Key stem) {
super(customBlock, delay, blacklist, false, tagsCanSurviveOn, blockStatesCanSurviveOn, customBlocksCansSurviveOn);
this.facingProperty = facingProperty;
this.fruit = fruit;
this.stem = stem;
}
@Override
public boolean propagatesSkylightDown(Object thisBlock, Object[] args, Callable<Object> superMethod) {
return FastNMS.INSTANCE.field$FluidState$isEmpty(FastNMS.INSTANCE.field$BlockBehaviour$BlockStateBase$fluidState(args[0]));
}
@Override
public boolean isPathFindable(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
return (VersionHelper.isOrAbove1_20_5() ? args[1] : args[3]).equals(CoreReflections.instance$PathComputationType$AIR)
&& !FastNMS.INSTANCE.field$BlockBehavior$hasCollision(thisBlock) || (boolean) superMethod.call();
}
@Override
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
Object state = args[0];
HorizontalDirection direction = DirectionUtils.fromNMSDirection(args[updateShape$direction]).toHorizontalDirection();
Object neighborState = args[updateShape$neighborState];
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(state);
if (optionalCustomState.isEmpty() || direction != optionalCustomState.get().get(this.facingProperty)) {
return super.updateShape(thisBlock, args, superMethod);
}
Optional<ImmutableBlockState> optionalCustomNeighborState = BlockStateUtils.getOptionalCustomBlockState(neighborState);
if (optionalCustomNeighborState.isPresent()) {
ImmutableBlockState customNeighborState = optionalCustomNeighborState.get();
if (!customNeighborState.owner().value().id().equals(this.fruit)) {
Object stemBlock = resetStemBlock();
if (stemBlock != null) return stemBlock;
}
} else {
if (this.stem.namespace().equals("minecraft")) {
Key neighborBlockId = BlockStateUtils.getBlockOwnerIdFromState(neighborState);
if (!neighborBlockId.equals(this.fruit)) {
Object stemBlock = resetStemBlock();
if (stemBlock != null) return stemBlock;
}
} else {
Object stemBlock = resetStemBlock();
if (stemBlock != null) return stemBlock;
}
}
return super.updateShape(thisBlock, args, superMethod);
}
private Object resetStemBlock() {
Optional<CustomBlock> optionalStemBlock = BukkitBlockManager.instance().blockById(this.stem);
if (optionalStemBlock.isPresent()) {
CustomBlock stemBlock = optionalStemBlock.get();
IntegerProperty ageProperty = (IntegerProperty) stemBlock.getProperty("age");
if (ageProperty == null) return stemBlock.defaultState().customBlockState().literalObject();
return stemBlock.defaultState().with(ageProperty, ageProperty.max).customBlockState().literalObject();
}
return null;
}
public static class Factory implements BlockBehaviorFactory {
@Override
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
Tuple<List<Object>, Set<Object>, Set<String>> tuple = readTagsAndState(arguments, false);
int delay = ResourceConfigUtils.getAsInt(arguments.getOrDefault("delay", 0), "delay");
boolean blacklistMode = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blacklist", false), "blacklist");
@SuppressWarnings("unchecked")
Property<HorizontalDirection> facingProperty = (Property<HorizontalDirection>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("facing"), "warning.config.block.behavior.attached_stem.missing_facing");
Key fruit = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("fruit"), "warning.config.block.behavior.attached_stem.missing_fruit"));
Key stem = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("stem"), "warning.config.block.behavior.attached_stem.missing_stem"));
return new AttachedStemBlockBehavior(block, delay, blacklistMode, tuple.left(), tuple.mid(), tuple.right(), facingProperty, fruit, stem);
}
}
}

View File

@@ -39,6 +39,8 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
public static final Key FENCE_BLOCK = Key.from("craftengine:fence_block");
public static final Key BUTTON_BLOCK = Key.from("craftengine:button_block");
public static final Key FACE_ATTACHED_HORIZONTAL_DIRECTIONAL_BLOCK = Key.from("craftengine:face_attached_horizontal_directional_block");
public static final Key STEM_BLOCK = Key.from("craftengine:stem_block");
public static final Key ATTACHED_STEM_BLOCK = Key.from("craftengine:attached_stem_block");
public static void init() {
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
@@ -76,5 +78,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
register(FENCE_BLOCK, FenceBlockBehavior.FACTORY);
register(BUTTON_BLOCK, ButtonBlockBehavior.FACTORY);
register(FACE_ATTACHED_HORIZONTAL_DIRECTIONAL_BLOCK, FaceAttachedHorizontalDirectionalBlockBehavior.FACTORY);
register(STEM_BLOCK, StemBlockBehavior.FACTORY);
register(ATTACHED_STEM_BLOCK, AttachedStemBlockBehavior.FACTORY);
}
}

View File

@@ -77,7 +77,7 @@ public class CropBlockBehavior extends BukkitBlockBehavior {
return minGrowLight;
}
private static int getRawBrightness(Object level, Object pos) throws InvocationTargetException, IllegalAccessException {
public static int getRawBrightness(Object level, Object pos) throws InvocationTargetException, IllegalAccessException {
return (int) CoreReflections.method$BlockAndTintGetter$getRawBrightness.invoke(level, pos, 0);
}

View File

@@ -0,0 +1,154 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.core.block.BlockBehavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.UpdateOption;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.block.properties.IntegerProperty;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.util.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Callable;
public class StemBlockBehavior extends BushBlockBehavior {
public static final Factory FACTORY = new Factory();
private final IntegerProperty ageProperty;
private final Key fruit;
private final Key attachedStem;
private final int minGrowLight;
private final Object tagMayPlaceFruit;
private final Object blockMayPlaceFruit;
public StemBlockBehavior(CustomBlock customBlock,
int delay,
boolean blacklist,
List<Object> tagsCanSurviveOn,
Set<Object> blockStatesCanSurviveOn,
Set<String> customBlocksCansSurviveOn,
IntegerProperty ageProperty,
Key fruit,
Key attachedStem,
int minGrowLight,
Object tagMayPlaceFruit,
Object blockMayPlaceFruit) {
super(customBlock, delay, blacklist, false, tagsCanSurviveOn, blockStatesCanSurviveOn, customBlocksCansSurviveOn);
this.ageProperty = ageProperty;
this.fruit = fruit;
this.attachedStem = attachedStem;
this.minGrowLight = minGrowLight;
this.tagMayPlaceFruit = tagMayPlaceFruit;
this.blockMayPlaceFruit = blockMayPlaceFruit;
}
@Override
public boolean propagatesSkylightDown(Object thisBlock, Object[] args, Callable<Object> superMethod) {
return FastNMS.INSTANCE.field$FluidState$isEmpty(FastNMS.INSTANCE.field$BlockBehaviour$BlockStateBase$fluidState(args[0]));
}
@Override
public boolean isPathFindable(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
return (VersionHelper.isOrAbove1_20_5() ? args[1] : args[3]).equals(CoreReflections.instance$PathComputationType$AIR)
&& !FastNMS.INSTANCE.field$BlockBehavior$hasCollision(thisBlock) || (boolean) superMethod.call();
}
@Override
public void randomTick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
Object state = args[0];
Object level = args[1];
Object pos = args[2];
if (CropBlockBehavior.getRawBrightness(level, pos) < this.minGrowLight) return;
ImmutableBlockState customState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null);
if (customState == null || customState.isEmpty()) return;
int age = customState.get(ageProperty);
if (age < ageProperty.max) {
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, customState.with(ageProperty, age + 1).customBlockState().literalObject(), 2);
return;
}
Object randomDirection = CoreReflections.instance$Direction$values[RandomUtils.generateRandomInt(2, 6)];
Object blockPos = FastNMS.INSTANCE.method$BlockPos$relative(pos, randomDirection);
if (!FastNMS.INSTANCE.method$BlockStateBase$isAir(FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, blockPos)))
return;
Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, FastNMS.INSTANCE.method$BlockPos$relative(blockPos, CoreReflections.instance$Direction$DOWN));
if (mayPlaceFruit(blockState)) {
Optional<CustomBlock> optionalFruit = BukkitBlockManager.instance().blockById(this.fruit);
Object fruitState = null;
if (optionalFruit.isPresent()) {
fruitState = optionalFruit.get().defaultState().customBlockState().literalObject();
} else if (fruit.namespace().equals("minecraft")) {
fruitState = FastNMS.INSTANCE.method$Block$defaultState(FastNMS.INSTANCE.method$Registry$getValue(
MBuiltInRegistries.BLOCK,
FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", fruit.value())
));
}
Optional<CustomBlock> optionalAttachedStem = BukkitBlockManager.instance().blockById(this.attachedStem);
if (fruitState == null || optionalAttachedStem.isEmpty()) return;
CustomBlock attachedStem = optionalAttachedStem.get();
@SuppressWarnings("unchecked")
Property<HorizontalDirection> facing = (Property<HorizontalDirection>) attachedStem.getProperty("facing");
if (facing == null) return;
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, fruitState, UpdateOption.UPDATE_ALL.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, attachedStem.defaultState().with(facing, DirectionUtils.fromNMSDirection(randomDirection).toHorizontalDirection()).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags());
}
}
@Override
public boolean isValidBoneMealTarget(Object thisBlock, Object[] args) {
ImmutableBlockState state = BlockStateUtils.getOptionalCustomBlockState(args[2]).orElse(null);
if (state == null || state.isEmpty()) return false;
return state.get(ageProperty) != ageProperty.max;
}
@Override
public boolean isBoneMealSuccess(Object thisBlock, Object[] args) {
return true;
}
@Override
public void performBoneMeal(Object thisBlock, Object[] args) {
ImmutableBlockState state = BlockStateUtils.getOptionalCustomBlockState(args[3]).orElse(null);
if (state == null || state.isEmpty()) return;
int min = Math.min(7, state.get(ageProperty) + RandomUtils.generateRandomInt(Math.min(ageProperty.min + 2, ageProperty.max), Math.min(ageProperty.max - 2, ageProperty.max)));
Object blockState = state.with(ageProperty, min).customBlockState().literalObject();
FastNMS.INSTANCE.method$LevelWriter$setBlock(args[0], args[2], blockState, 2);
if (min >= ageProperty.max) {
FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$randomTick(blockState, args[0], args[2]);
}
}
private boolean mayPlaceFruit(Object blockState) {
boolean flag1 = tagMayPlaceFruit != null && FastNMS.INSTANCE.method$BlockStateBase$is(blockState, tagMayPlaceFruit);
boolean flag2 = blockMayPlaceFruit != null && FastNMS.INSTANCE.method$BlockStateBase$isBlock(blockState, blockMayPlaceFruit);
if (tagMayPlaceFruit == null && blockMayPlaceFruit == null) return true;
return flag1 || flag2;
}
public static class Factory implements BlockBehaviorFactory {
@Override
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
Tuple<List<Object>, Set<Object>, Set<String>> tuple = readTagsAndState(arguments, false);
int delay = ResourceConfigUtils.getAsInt(arguments.getOrDefault("delay", 0), "delay");
boolean blacklistMode = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blacklist", false), "blacklist");
IntegerProperty ageProperty = (IntegerProperty) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("age"), "warning.config.block.behavior.stem.missing_age");
Key fruit = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("fruit"), "warning.config.block.behavior.stem.missing_fruit"));
Key attachedStem = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("attached-stem"), "warning.config.block.behavior.stem.missing_attached_stem"));
int minGrowLight = ResourceConfigUtils.getAsInt(arguments.getOrDefault("light-requirement", 9), "light-requirement");
Object tagMayPlaceFruit = FastNMS.INSTANCE.method$TagKey$create(MRegistries.BLOCK, KeyUtils.toResourceLocation(Key.of(arguments.getOrDefault("may-place-fruit", "minecraft:dirt").toString())));
Object blockMayPlaceFruit = FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.BLOCK, KeyUtils.toResourceLocation(Key.of(arguments.getOrDefault("may-place-fruit", "minecraft:farmland").toString())));
return new StemBlockBehavior(block, delay, blacklistMode, tuple.left(), tuple.mid(), tuple.right(), ageProperty, fruit, attachedStem, minGrowLight, tagMayPlaceFruit, blockMayPlaceFruit);
}
}
}

View File

@@ -381,4 +381,14 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior
}
FallOnBlockBehavior.super.updateEntityMovementAfterFallOn(thisBlock, args, superMethod);
}
}
@Override
public boolean propagatesSkylightDown(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
for (AbstractBlockBehavior behavior : this.behaviors) {
if (!behavior.propagatesSkylightDown(thisBlock, args, superMethod)) {
return false;
}
}
return (boolean) superMethod.call();
}
}

View File

@@ -170,6 +170,9 @@ public final class BlockGenerator {
// stepOn
.method(ElementMatchers.is(CoreReflections.method$Block$stepOn))
.intercept(MethodDelegation.to(StepOnInterceptor.INSTANCE))
// propagatesSkylightDown
.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$propagatesSkylightDown))
.intercept(MethodDelegation.to(PropagatesSkylightDownInterceptor.INSTANCE))
;
// 1.21.5+
if (CoreReflections.method$BlockBehaviour$affectNeighborsAfterRemoval != null) {
@@ -760,4 +763,19 @@ public final class BlockGenerator {
}
}
}
public static class PropagatesSkylightDownInterceptor {
public static final PropagatesSkylightDownInterceptor INSTANCE = new PropagatesSkylightDownInterceptor();
@RuntimeType
public boolean intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
ObjectHolder<BlockBehavior> holder = ((DelegatingBlock) thisObj).behaviorDelegate();
try {
return holder.value().propagatesSkylightDown(thisObj, args, superMethod);
} catch (Exception e) {
CraftEngine.instance().logger().severe("Failed to run propagatesSkylightDown", e);
return false;
}
}
}
}

View File

@@ -12,7 +12,6 @@ import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.implementation.bind.annotation.This;
import net.bytebuddy.matcher.ElementMatchers;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
@@ -20,18 +19,16 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlockStateProperties;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MLootContextParams;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.*;
import net.momirealms.craftengine.core.block.BlockSettings;
import net.momirealms.craftengine.core.block.DelegatingBlockState;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
import net.momirealms.craftengine.core.util.ObjectHolder;
import net.momirealms.craftengine.core.util.ReflectionUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.world.World;
@@ -42,8 +39,6 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
public final class BlockStateGenerator {
private static MethodHandle constructor$CraftEngineBlockState;
@@ -71,27 +66,15 @@ public final class BlockStateGenerator {
.method(ElementMatchers.is(CoreReflections.method$StateHolder$setValue))
.intercept(MethodDelegation.to(SetPropertyValueInterceptor.INSTANCE))
.method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isBlock))
.intercept(MethodDelegation.to(IsBlockInterceptor.INSTANCE))
.method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isHolderSetBlock))
.intercept(MethodDelegation.to(IsHolderSetBlockInterceptor.INSTANCE));
if (CoreReflections.method$BlockStateBase$isHolderBlock != null) {
stateBuilder = stateBuilder
.method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isHolderBlock))
.intercept(MethodDelegation.to(IsHolderBlockInterceptor.INSTANCE));
}
if (CoreReflections.method$BlockStateBase$isResourceKeyBlock != null) {
stateBuilder = stateBuilder
.method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isResourceKeyBlock))
.intercept(MethodDelegation.to(IsResourceKeyBlockInterceptor.INSTANCE));
}
.intercept(MethodDelegation.to(IsBlockInterceptor.INSTANCE));
Class<?> clazz$CraftEngineBlock = stateBuilder.make().load(BlockStateGenerator.class.getClassLoader()).getLoaded();
constructor$CraftEngineBlockState = VersionHelper.isOrAbove1_20_5() ?
MethodHandles.publicLookup().in(clazz$CraftEngineBlock)
.findConstructor(clazz$CraftEngineBlock, MethodType.methodType(void.class, CoreReflections.clazz$Block, Reference2ObjectArrayMap.class, MapCodec.class))
.asType(MethodType.methodType(CoreReflections.clazz$BlockState, CoreReflections.clazz$Block, Reference2ObjectArrayMap.class, MapCodec.class)) :
.findConstructor(clazz$CraftEngineBlock, MethodType.methodType(void.class, CoreReflections.clazz$Block, Reference2ObjectArrayMap.class, MapCodec.class))
.asType(MethodType.methodType(CoreReflections.clazz$BlockState, CoreReflections.clazz$Block, Reference2ObjectArrayMap.class, MapCodec.class)) :
MethodHandles.publicLookup().in(clazz$CraftEngineBlock)
.findConstructor(clazz$CraftEngineBlock, MethodType.methodType(void.class, CoreReflections.clazz$Block, ImmutableMap.class, MapCodec.class))
.asType(MethodType.methodType(CoreReflections.clazz$BlockState, CoreReflections.clazz$Block, ImmutableMap.class, MapCodec.class));
.findConstructor(clazz$CraftEngineBlock, MethodType.methodType(void.class, CoreReflections.clazz$Block, ImmutableMap.class, MapCodec.class))
.asType(MethodType.methodType(CoreReflections.clazz$BlockState, CoreReflections.clazz$Block, ImmutableMap.class, MapCodec.class));
String generatedFactoryClassName = packageWithName.substring(0, packageWithName.lastIndexOf('.')) + ".CraftEngineStateFactory";
DynamicType.Builder<?> factoryBuilder = byteBuddy
@@ -210,70 +193,15 @@ public final class BlockStateGenerator {
DelegatingBlockState customState = (DelegatingBlockState) thisObj;
ImmutableBlockState thisState = customState.blockState();
if (thisState == null) return false;
if (!(args[0] instanceof DelegatingBlock delegatingBlock)) return false;
BlockBehavior behavior = delegatingBlock.behaviorDelegate().value();
if (behavior == null) return false;
return behavior.block().equals(thisState.owner().value());
}
}
public static class IsHolderSetBlockInterceptor {
public static final IsHolderSetBlockInterceptor INSTANCE = new IsHolderSetBlockInterceptor();
@SuppressWarnings("unchecked")
@RuntimeType
public boolean intercept(@This Object thisObj, @AllArguments Object[] args) {
DelegatingBlockState customState = (DelegatingBlockState) thisObj;
ImmutableBlockState thisState = customState.blockState();
if (thisState == null) return false;
CustomBlock thisBlock = thisState.owner().value();
for (Object holder : (Iterable<Object>) args[0]) {
Object block = FastNMS.INSTANCE.method$Holder$value(holder);
if (!(block instanceof DelegatingBlock delegatingBlock)) continue;
BlockBehavior behavior = delegatingBlock.behaviorDelegate().value();
if (behavior == null) continue;
if (behavior.block().equals(thisBlock)) return true;
if (FastNMS.INSTANCE.method$Block$defaultState(args[0]) instanceof DelegatingBlockState holder) {
ImmutableBlockState holderState = holder.blockState();
if (holderState == null) return false;
return holderState.owner().equals(thisState.owner());
}
return false;
}
}
public static class IsHolderBlockInterceptor {
public static final IsHolderBlockInterceptor INSTANCE = new IsHolderBlockInterceptor();
@RuntimeType
public boolean intercept(@This Object thisObj, @AllArguments Object[] args) {
Object block = FastNMS.INSTANCE.method$Holder$value(args[0]);
if (!(block instanceof DelegatingBlock delegatingBlock)) return false;
BlockBehavior behavior = delegatingBlock.behaviorDelegate().value();
if (behavior == null) return false;
DelegatingBlockState customState = (DelegatingBlockState) thisObj;
ImmutableBlockState thisState = customState.blockState();
if (thisState == null) return false;
CustomBlock thisBlock = thisState.owner().value();
return behavior.block().equals(thisBlock);
}
}
public static class IsResourceKeyBlockInterceptor {
public static final IsResourceKeyBlockInterceptor INSTANCE = new IsResourceKeyBlockInterceptor();
@RuntimeType
public boolean intercept(@This Object thisObj, @AllArguments Object[] args) {
Object block = FastNMS.INSTANCE.method$HolderGetter$getResourceKey(MBuiltInRegistries.BLOCK, args[0])
.map(FastNMS.INSTANCE::method$Holder$value)
.orElse(null);
if (!(block instanceof DelegatingBlock delegatingBlock)) return false;
BlockBehavior behavior = delegatingBlock.behaviorDelegate().value();
if (behavior == null) return false;
DelegatingBlockState customState = (DelegatingBlockState) thisObj;
ImmutableBlockState thisState = customState.blockState();
if (thisState == null) return false;
CustomBlock thisBlock = thisState.owner().value();
return behavior.block().equals(thisBlock);
}
}
public static class CreateStateInterceptor {
public static final CreateStateInterceptor INSTANCE = new CreateStateInterceptor();

View File

@@ -4419,19 +4419,13 @@ public final class CoreReflections {
ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$Block)
);
public static final Method method$BlockStateBase$isHolderSetBlock = requireNonNull(
ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$HolderSet)
);
// 1.20.2+
public static final Method method$BlockStateBase$isHolderBlock = MiscUtils.requireNonNullIf(
ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$Holder),
VersionHelper.isOrAbove1_20_2()
);
// 1.20.3+
public static final Method method$BlockStateBase$isResourceKeyBlock = MiscUtils.requireNonNullIf(
ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$ResourceKey),
VersionHelper.isOrAbove1_20_3()
public static final Method method$BlockBehaviour$propagatesSkylightDown = requireNonNull(
VersionHelper.isOrAbove1_21_2()
? ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, boolean.class, new String[]{"propagatesSkylightDown", "e_"}, clazz$BlockState)
: VersionHelper.isOrAbove1_20_5()
? ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, boolean.class, new String[]{"propagatesSkylightDown", "a_"}, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos)
: VersionHelper.isOrAbove1_20_4()
? ReflectionUtils.getDeclaredMethod(clazz$Block, boolean.class, new String[]{"propagatesSkylightDown", "a_"}, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos)
: ReflectionUtils.getDeclaredMethod(clazz$Block, boolean.class, new String[]{"propagatesSkylightDown", "c"}, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos)
);
}

View File

@@ -6,54 +6,31 @@ import net.momirealms.craftengine.core.util.VersionHelper;
public final class MBlocks {
private MBlocks() {}
public static final Object AIR;
public static final Object AIR$defaultState;
public static final Object STONE;
public static final Object STONE$defaultState;
public static final Object FIRE;
public static final Object SOUL_FIRE;
public static final Object ICE;
public static final Object SHORT_GRASS;
public static final Object SHORT_GRASS$defaultState;
public static final Object SHULKER_BOX;
public static final Object COMPOSTER;
public static final Object SNOW;
public static final Object WATER;
public static final Object WATER$defaultState;
public static final Object TNT;
public static final Object TNT$defaultState;
public static final Object BARRIER;
public static final Object CARVED_PUMPKIN;
public static final Object JACK_O_LANTERN;
public static final Object MELON;
public static final Object PUMPKIN;
public static final Object AIR = getById("air");
public static final Object AIR$defaultState = FastNMS.INSTANCE.method$Block$defaultState(AIR);
public static final Object STONE = getById("stone");
public static final Object STONE$defaultState = FastNMS.INSTANCE.method$Block$defaultState(STONE);
public static final Object FIRE = getById("fire");
public static final Object SOUL_FIRE = getById("soul_fire");
public static final Object ICE = getById("ice");
public static final Object SHORT_GRASS = getById(VersionHelper.isOrAbove1_20_3() ? "short_grass" : "grass");
public static final Object SHORT_GRASS$defaultState = FastNMS.INSTANCE.method$Block$defaultState(SHORT_GRASS);
public static final Object SHULKER_BOX = getById("shulker_box");
public static final Object COMPOSTER = getById("composter");
public static final Object SNOW = getById("snow");
public static final Object WATER = getById("water");
public static final Object WATER$defaultState = FastNMS.INSTANCE.method$Block$defaultState(WATER);
public static final Object TNT = getById("tnt");
public static final Object TNT$defaultState = FastNMS.INSTANCE.method$Block$defaultState(TNT);
public static final Object BARRIER = getById("barrier");
public static final Object CARVED_PUMPKIN = getById("carved_pumpkin");
public static final Object JACK_O_LANTERN = getById("jack_o_lantern");
public static final Object MELON = getById("melon");
public static final Object PUMPKIN = getById("pumpkin");
public static final Object FARMLAND = getById("farmland");
private static Object getById(String id) {
Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id);
return FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.BLOCK, rl);
}
static {
AIR = getById("air");
AIR$defaultState = FastNMS.INSTANCE.method$Block$defaultState(AIR);
FIRE = getById("fire");
SOUL_FIRE = getById("soul_fire");
STONE = getById("stone");
STONE$defaultState = FastNMS.INSTANCE.method$Block$defaultState(STONE);
ICE = getById("ice");
SHORT_GRASS = getById(VersionHelper.isOrAbove1_20_3() ? "short_grass" : "grass");
SHORT_GRASS$defaultState = FastNMS.INSTANCE.method$Block$defaultState(SHORT_GRASS);
SHULKER_BOX = getById("shulker_box");
COMPOSTER = getById("composter");
SNOW = getById("snow");
WATER = getById("water");
WATER$defaultState = FastNMS.INSTANCE.method$Block$defaultState(WATER);
TNT = getById("tnt");
TNT$defaultState = FastNMS.INSTANCE.method$Block$defaultState(TNT);
BARRIER = getById("barrier");
CARVED_PUMPKIN = getById("carved_pumpkin");
JACK_O_LANTERN = getById("jack_o_lantern");
MELON = getById("melon");
PUMPKIN = getById("pumpkin");
}
}

View File

@@ -12,6 +12,7 @@ public final class MTagKeys {
public static final Object Block$SHULKER_BOXES = create(MRegistries.BLOCK, "shulker_boxes");
public static final Object Block$FENCES = create(MRegistries.BLOCK, "fences");
public static final Object Block$WOODEN_FENCES = create(MRegistries.BLOCK, "wooden_fences");
public static final Object Block$DIRT = create(MRegistries.BLOCK, "dirt");
private static Object create(Object registry, String location) {
Object resourceLocation = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", location);