mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
improve waterlogged
This commit is contained in:
@@ -813,36 +813,42 @@ templates#block_states:
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=2,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=3,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=4,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=5,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=6,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=7,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
@@ -850,48 +856,56 @@ templates#block_states:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
is-randomly-ticking: true
|
||||
fluid-state: water
|
||||
distance=1,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=2,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=3,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=4,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=5,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=6,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=7,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
|
||||
# recipes
|
||||
templates#recipes:
|
||||
|
||||
@@ -332,41 +332,4 @@ public class BlockEventListener implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Is there a way to deceive the server?
|
||||
// @SuppressWarnings("unchecked")
|
||||
// @EventHandler(ignoreCancelled = true)
|
||||
// public void onDispenserWork(BlockDispenseEvent event) {
|
||||
// ItemStack itemStack = event.getItem();
|
||||
// Material type = itemStack.getType();
|
||||
// Block block = event.getBlock();
|
||||
// if (type == Material.BUCKET) {
|
||||
// if (block.getBlockData() instanceof Dispenser dispenser) {
|
||||
// Block against = block.getRelative(dispenser.getFacing());
|
||||
// ImmutableBlockState state = this.manager.getImmutableBlockState(BlockStateUtils.blockDataToId(against.getBlockData()));
|
||||
// if (state != null && !state.isEmpty()) {
|
||||
// Location location = against.getLocation();
|
||||
// CustomBlock customBlock = state.owner().value();
|
||||
// Property<Boolean> waterlogged = (Property<Boolean>) customBlock.getProperty("waterlogged");
|
||||
// if (waterlogged == null) return;
|
||||
// if (!state.get(waterlogged)) return;
|
||||
// ImmutableBlockState nextState = state.with(waterlogged, false);
|
||||
// CraftEngineBlocks.place(location, nextState, UpdateOption.UPDATE_ALL);
|
||||
// }
|
||||
// }
|
||||
// } else if (WATER_BUCKETS.contains(type)) {
|
||||
// if (block.getBlockData() instanceof Dispenser dispenser) {
|
||||
// Block against = block.getRelative(dispenser.getFacing());
|
||||
// ImmutableBlockState state = this.manager.getImmutableBlockState(BlockStateUtils.blockDataToId(against.getBlockData()));
|
||||
// if (state != null && !state.isEmpty()) {
|
||||
// Location location = against.getLocation();
|
||||
// CustomBlock customBlock = state.owner().value();
|
||||
// Property<Boolean> waterlogged = (Property<Boolean>) customBlock.getProperty("waterlogged");
|
||||
// if (waterlogged == null) return;
|
||||
// ImmutableBlockState nextState = state.with(waterlogged, true);
|
||||
// CraftEngineBlocks.place(location, nextState, UpdateOption.UPDATE_ALL);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -103,6 +103,12 @@ public class BukkitCustomBlock extends CustomBlock {
|
||||
Reflections.field$BlockBehaviour$soundType.set(mcBlock, SoundUtils.toSoundType(settings.sounds()));
|
||||
// init cache
|
||||
Reflections.method$BlockStateBase$initCache.invoke(mcBlockState);
|
||||
// set fluid later
|
||||
if (settings.fluidState()) {
|
||||
Reflections.field$BlockStateBase$fluidState.set(mcBlockState, Reflections.method$FlowingFluid$getSource.invoke(Reflections.instance$Fluids$WATER, false));
|
||||
} else {
|
||||
Reflections.field$BlockStateBase$fluidState.set(mcBlockState, Reflections.instance$Fluid$EMPTY$defaultState);
|
||||
}
|
||||
// set random tick later
|
||||
BlockStateUtils.setIsRandomlyTicking(mcBlockState, settings.isRandomlyTicking());
|
||||
// bind tags
|
||||
|
||||
@@ -11,6 +11,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
||||
public static final Key STRIPPABLE_BLOCK = Key.from("craftengine:strippable_block");
|
||||
public static final Key SAPLING_BLOCK = Key.from("craftengine:sapling_block");
|
||||
public static final Key ON_LIQUID_BLOCK = Key.from("craftengine:on_liquid_block");
|
||||
public static final Key WATERLOGGED_BLOCK = Key.from("craftengine:waterlogged_block");
|
||||
public static final Key CONCRETE_POWDER_BLOCK = Key.from("craftengine:concrete_powder_block");
|
||||
|
||||
public static void init() {
|
||||
@@ -21,5 +22,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
||||
register(STRIPPABLE_BLOCK, StrippableBlockBehavior.FACTORY);
|
||||
register(SAPLING_BLOCK, SaplingBlockBehavior.FACTORY);
|
||||
register(ON_LIQUID_BLOCK, OnLiquidBlockBehavior.FACTORY);
|
||||
register(WATERLOGGED_BLOCK, WaterLoggedBlockBehavior.FACTORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,4 +5,9 @@ public class ConcretePowderBlockBehavior extends FallingBlockBehavior {
|
||||
public ConcretePowderBlockBehavior(float hurtAmount, int maxHurt) {
|
||||
super(hurtAmount, maxHurt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLand(Object thisBlock, Object[] args) throws Exception {
|
||||
super.onLand(thisBlock, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class LeavesBlockBehavior extends BlockBehavior {
|
||||
public class LeavesBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private static final Object LOG_TAG = BlockTags.getOrCreate(Key.of("minecraft", "logs"));
|
||||
private final int maxDistance;
|
||||
@@ -39,6 +39,7 @@ public class LeavesBlockBehavior extends BlockBehavior {
|
||||
private final Property<Boolean> waterloggedProperty;
|
||||
|
||||
public LeavesBlockBehavior(int maxDistance, Property<Integer> distanceProperty, Property<Boolean> persistentProperty, @Nullable Property<Boolean> waterloggedProperty) {
|
||||
super(waterloggedProperty);
|
||||
this.maxDistance = maxDistance;
|
||||
this.distanceProperty = distanceProperty;
|
||||
this.persistentProperty = persistentProperty;
|
||||
@@ -183,13 +184,4 @@ public class LeavesBlockBehavior extends BlockBehavior {
|
||||
return new LeavesBlockBehavior(actual, distance, persistent, waterlogged);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFluidState(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
Object blockState = args[0];
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (state == null || state.isEmpty() || waterloggedProperty == null) return super.getFluidState(thisBlock, args, superMethod);
|
||||
boolean waterlogged = state.get(waterloggedProperty);
|
||||
return waterlogged ? Reflections.method$FlowingFluid$getSource.invoke(Reflections.instance$Fluids$WATER, false) : super.getFluidState(thisBlock, args, superMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.shared.block.BlockBehavior;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class WaterLoggedBlockBehavior extends BlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
@Nullable
|
||||
private final Property<Boolean> waterloggedProperty;
|
||||
|
||||
public WaterLoggedBlockBehavior(@Nullable Property<Boolean> waterloggedProperty) {
|
||||
this.waterloggedProperty = waterloggedProperty;
|
||||
}
|
||||
|
||||
// TODO create real waterlogged blocks
|
||||
// @Override
|
||||
// public Object pickupBlock(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// if (this.waterloggedProperty == null) return Reflections.instance$ItemStack$EMPTY;
|
||||
// Object blockState;
|
||||
// Object world;
|
||||
// Object pos;
|
||||
// if (VersionHelper.isVersionNewerThan1_20_2()) {
|
||||
// world = args[1];
|
||||
// pos = args[2];
|
||||
// blockState = args[3];
|
||||
// } else {
|
||||
// world = args[0];
|
||||
// pos = args[1];
|
||||
// blockState = args[2];
|
||||
// }
|
||||
// ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
// if (immutableBlockState != null) {
|
||||
// if (immutableBlockState.get(this.waterloggedProperty)) {
|
||||
// Reflections.method$LevelWriter$setBlock.invoke(world, pos, immutableBlockState.with(this.waterloggedProperty, false).customBlockState().handle(), 3);
|
||||
// // TODO check can survive
|
||||
// Object itemStack = Reflections.constructor$ItemStack.newInstance(Reflections.instance$Items$WATER_BUCKET);
|
||||
// System.out.println(itemStack);
|
||||
// return itemStack;
|
||||
// }
|
||||
// }
|
||||
// return Reflections.instance$ItemStack$EMPTY;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// if (this.waterloggedProperty == null) return false;
|
||||
// Object blockState = args[2];
|
||||
// ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
// if (immutableBlockState != null) {
|
||||
// Object fluidType = Reflections.method$FluidState$getType.invoke(args[3]);
|
||||
// if (!immutableBlockState.get(this.waterloggedProperty) && fluidType == Reflections.instance$Fluids$WATER) {
|
||||
// Reflections.method$LevelWriter$setBlock.invoke(args[0], args[1], immutableBlockState.with(this.waterloggedProperty, true).customBlockState().handle(), 3);
|
||||
// Reflections.method$LevelAccessor$scheduleTick.invoke(args[0], fluidType, Reflections.method$Fluid$getTickDelay.invoke(fluidType, args[0]));
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // use water
|
||||
// @Override
|
||||
// public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// return super.canPlaceLiquid(thisBlock, args, superMethod);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Object getFluidState(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// Object blockState = args[0];
|
||||
// ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
// if (state == null || state.isEmpty() || this.waterloggedProperty == null) return super.getFluidState(thisBlock, args, superMethod);
|
||||
// boolean waterlogged = state.get(this.waterloggedProperty);
|
||||
// return waterlogged ? Reflections.method$FlowingFluid$getSource.invoke(Reflections.instance$Fluids$WATER, false) : super.getFluidState(thisBlock, args, superMethod);
|
||||
// }
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
@Override
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
Property<Boolean> waterlogged = (Property<Boolean>) block.getProperty("waterlogged");
|
||||
return new WaterLoggedBlockBehavior(waterlogged);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -863,7 +863,7 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
|
||||
List<Object> itemStacks = new ArrayList<>();
|
||||
for (Holder<Key> holder : holders) {
|
||||
ItemStack itemStack = BukkitItemManager.instance().getBuildableItem(holder.value()).get().buildItemStack(ItemBuildContext.EMPTY, 1);
|
||||
Object nmsStack = Reflections.method$CraftItemStack$asNMSMirror.invoke(null, itemStack);
|
||||
Object nmsStack = Reflections.method$CraftItemStack$asNMSCopy.invoke(null, itemStack);
|
||||
itemStacks.add(nmsStack);
|
||||
}
|
||||
return itemStacks;
|
||||
@@ -994,14 +994,14 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
|
||||
toOptionalMinecraftIngredient(ceRecipe.template()),
|
||||
toOptionalMinecraftIngredient(ceRecipe.base()),
|
||||
toOptionalMinecraftIngredient(ceRecipe.addition()),
|
||||
Reflections.method$CraftItemStack$asNMSMirror.invoke(null, ceRecipe.result(ItemBuildContext.EMPTY))
|
||||
Reflections.method$CraftItemStack$asNMSCopy.invoke(null, ceRecipe.result(ItemBuildContext.EMPTY))
|
||||
);
|
||||
} else if (VersionHelper.isVersionNewerThan1_20_2()) {
|
||||
return Reflections.constructor$SmithingTransformRecipe.newInstance(
|
||||
toMinecraftIngredient(ceRecipe.template()),
|
||||
toMinecraftIngredient(ceRecipe.base()),
|
||||
toMinecraftIngredient(ceRecipe.addition()),
|
||||
Reflections.method$CraftItemStack$asNMSMirror.invoke(null, ceRecipe.result(ItemBuildContext.EMPTY))
|
||||
Reflections.method$CraftItemStack$asNMSCopy.invoke(null, ceRecipe.result(ItemBuildContext.EMPTY))
|
||||
);
|
||||
} else {
|
||||
return Reflections.constructor$SmithingTransformRecipe.newInstance(
|
||||
@@ -1009,7 +1009,7 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
|
||||
toMinecraftIngredient(ceRecipe.template()),
|
||||
toMinecraftIngredient(ceRecipe.base()),
|
||||
toMinecraftIngredient(ceRecipe.addition()),
|
||||
Reflections.method$CraftItemStack$asNMSMirror.invoke(null, ceRecipe.result(ItemBuildContext.EMPTY))
|
||||
Reflections.method$CraftItemStack$asNMSCopy.invoke(null, ceRecipe.result(ItemBuildContext.EMPTY))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ public class RecipeEventListener implements Listener {
|
||||
Optional<Object> optionalMCRecipe = (Optional<Object>) Reflections.method$RecipeManager$getRecipeFor1.invoke(
|
||||
BukkitRecipeManager.minecraftRecipeManager(),
|
||||
Reflections.instance$RecipeType$CAMPFIRE_COOKING,
|
||||
Reflections.constructor$SingleRecipeInput.newInstance(Reflections.method$CraftItemStack$asNMSMirror.invoke(null, itemStack)),
|
||||
Reflections.constructor$SingleRecipeInput.newInstance(Reflections.method$CraftItemStack$asNMSCopy.invoke(null, itemStack)),
|
||||
Reflections.field$CraftWorld$ServerLevel.get(event.getPlayer().getWorld()),
|
||||
null
|
||||
);
|
||||
|
||||
@@ -50,7 +50,6 @@ import java.lang.reflect.Field;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class BukkitCraftEngine extends CraftEngine {
|
||||
|
||||
@@ -183,6 +183,7 @@ public class BukkitInjector {
|
||||
// should always implement this interface
|
||||
.implement(Reflections.clazz$Fallable)
|
||||
.implement(Reflections.clazz$BonemealableBlock)
|
||||
// TODO .implement(Reflections.clazz$SimpleWaterloggedBlock)
|
||||
// internal interfaces
|
||||
.implement(BehaviorHolder.class)
|
||||
.implement(ShapeHolder.class)
|
||||
@@ -208,6 +209,15 @@ public class BukkitInjector {
|
||||
// performBoneMeal
|
||||
.method(ElementMatchers.is(Reflections.method$BonemealableBlock$performBonemeal))
|
||||
.intercept(MethodDelegation.to(PerformBoneMealInterceptor.INSTANCE))
|
||||
// // pickupBlock
|
||||
// .method(ElementMatchers.is(Reflections.method$SimpleWaterloggedBlock$pickupBlock))
|
||||
// .intercept(MethodDelegation.to(PickUpBlockInterceptor.INSTANCE))
|
||||
// // placeLiquid
|
||||
// .method(ElementMatchers.is(Reflections.method$SimpleWaterloggedBlock$placeLiquid))
|
||||
// .intercept(MethodDelegation.to(PlaceLiquidInterceptor.INSTANCE))
|
||||
// // canPlaceLiquid
|
||||
// .method(ElementMatchers.is(Reflections.method$SimpleWaterloggedBlock$canPlaceLiquid))
|
||||
// .intercept(MethodDelegation.to(CanPlaceLiquidInterceptor.INSTANCE))
|
||||
// random tick
|
||||
.method(ElementMatchers.is(Reflections.method$BlockBehaviour$randomTick))
|
||||
.intercept(MethodDelegation.to(RandomTickInterceptor.INSTANCE))
|
||||
@@ -251,10 +261,11 @@ public class BukkitInjector {
|
||||
.and(ElementMatchers.takesArgument(1, Reflections.clazz$LevelReader).or(ElementMatchers.takesArgument(1, Reflections.clazz$Direction)))
|
||||
.and(ElementMatchers.named("updateShape").or(ElementMatchers.named("a"))))
|
||||
.intercept(MethodDelegation.to(UpdateShapeInterceptor.INSTANCE))
|
||||
// getFluidState
|
||||
.method(ElementMatchers.returns(Reflections.clazz$FluidState)
|
||||
.and(ElementMatchers.takesArgument(0, Reflections.clazz$BlockState)))
|
||||
.intercept(MethodDelegation.to(FluidStateInterceptor.INSTANCE));
|
||||
// // getFluidState
|
||||
// .method(ElementMatchers.returns(Reflections.clazz$FluidState)
|
||||
// .and(ElementMatchers.takesArgument(0, Reflections.clazz$BlockState)))
|
||||
// .intercept(MethodDelegation.to(FluidStateInterceptor.INSTANCE))
|
||||
;
|
||||
clazz$CraftEngineBlock = builder.make().load(BukkitInjector.class.getClassLoader()).getLoaded();
|
||||
|
||||
constructor$CraftEngineBlock = MethodHandles.publicLookup().in(clazz$CraftEngineBlock)
|
||||
@@ -647,20 +658,21 @@ public class BukkitInjector {
|
||||
return newBlockInstance;
|
||||
}
|
||||
|
||||
public static class FluidStateInterceptor {
|
||||
public static final FluidStateInterceptor INSTANCE = new FluidStateInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
|
||||
ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
|
||||
try {
|
||||
return holder.value().getFluidState(thisObj, args, superMethod);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to run getFluidState", e);
|
||||
return args[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// public static class FluidStateInterceptor {
|
||||
// public static final FluidStateInterceptor INSTANCE = new FluidStateInterceptor();
|
||||
//
|
||||
// @RuntimeType
|
||||
// public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
|
||||
// ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
|
||||
// try {
|
||||
// return holder.value().getFluidState(thisObj, args, superMethod);
|
||||
// } catch (Exception e) {
|
||||
// CraftEngine.instance().logger().severe("Failed to run getFluidState", e);
|
||||
// return args[0];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public static class UpdateShapeInterceptor {
|
||||
public static final UpdateShapeInterceptor INSTANCE = new UpdateShapeInterceptor();
|
||||
@@ -849,4 +861,46 @@ public class BukkitInjector {
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// public static class PickUpBlockInterceptor {
|
||||
// public static final PickUpBlockInterceptor INSTANCE = new PickUpBlockInterceptor();
|
||||
//
|
||||
// @RuntimeType
|
||||
// public void intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
|
||||
// ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
|
||||
// try {
|
||||
// holder.value().pickupBlock(thisObj, args, superMethod);
|
||||
// } catch (Exception e) {
|
||||
// CraftEngine.instance().logger().severe("Failed to run pickupBlock", e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static class PlaceLiquidInterceptor {
|
||||
// public static final PlaceLiquidInterceptor INSTANCE = new PlaceLiquidInterceptor();
|
||||
//
|
||||
// @RuntimeType
|
||||
// public void intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
|
||||
// ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
|
||||
// try {
|
||||
// holder.value().placeLiquid(thisObj, args, superMethod);
|
||||
// } catch (Exception e) {
|
||||
// CraftEngine.instance().logger().severe("Failed to run placeLiquid", e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static class CanPlaceLiquidInterceptor {
|
||||
// public static final CanPlaceLiquidInterceptor INSTANCE = new CanPlaceLiquidInterceptor();
|
||||
//
|
||||
// @RuntimeType
|
||||
// public void intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) {
|
||||
// ObjectHolder<BlockBehavior> holder = ((BehaviorHolder) thisObj).getBehaviorHolder();
|
||||
// try {
|
||||
// holder.value().canPlaceLiquid(thisObj, args, superMethod);
|
||||
// } catch (Exception e) {
|
||||
// CraftEngine.instance().logger().severe("Failed to run canPlaceLiquid", e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ import org.bukkit.util.RayTraceResult;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -516,7 +514,7 @@ public class PacketConsumers {
|
||||
}
|
||||
assert Reflections.method$ServerGamePacketListenerImpl$tryPickItem != null;
|
||||
Reflections.method$ServerGamePacketListenerImpl$tryPickItem.invoke(
|
||||
Reflections.field$ServerPlayer$connection.get(Reflections.method$CraftPlayer$getHandle.invoke(player)), Reflections.method$CraftItemStack$asNMSMirror.invoke(null, itemStack));
|
||||
Reflections.field$ServerPlayer$connection.get(Reflections.method$CraftPlayer$getHandle.invoke(player)), Reflections.method$CraftItemStack$asNMSCopy.invoke(null, itemStack));
|
||||
}
|
||||
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> ADD_ENTITY = (user, event, packet) -> {
|
||||
|
||||
@@ -1537,13 +1537,13 @@ public class Reflections {
|
||||
|
||||
public static final Method method$CraftBlockData$createData = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$CraftBlockData, new String[]{"createData"}, clazz$CraftBlockData, clazz$BlockState
|
||||
clazz$CraftBlockData, clazz$CraftBlockData, new String[]{"createData"}, clazz$BlockState
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$CraftBlockData$fromData = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$CraftBlockData, new String[]{"fromData"}, clazz$CraftBlockData, clazz$BlockState
|
||||
clazz$CraftBlockData, clazz$CraftBlockData, new String[]{"fromData"}, clazz$BlockState
|
||||
)
|
||||
);
|
||||
|
||||
@@ -2230,6 +2230,12 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$BlockStateBase$fluidState = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$BlockStateBase, clazz$FluidState, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$BlockStateBase$pushReaction = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$BlockStateBase, clazz$PushReaction, 0
|
||||
@@ -3162,6 +3168,20 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Object instance$ItemStack$EMPTY;
|
||||
|
||||
static {
|
||||
try {
|
||||
instance$ItemStack$EMPTY = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ItemStack, clazz$ItemStack, 0
|
||||
).get(null)
|
||||
);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Field field$ServerboundSetCreativeModeSlotPacket$itemStack = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ServerboundSetCreativeModeSlotPacket, clazz$ItemStack, 0
|
||||
@@ -3176,13 +3196,13 @@ public class Reflections {
|
||||
|
||||
public static final Method method$CraftItemStack$asCraftMirror = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$CraftItemStack, new String[]{"asCraftMirror"}, clazz$CraftItemStack, clazz$ItemStack
|
||||
clazz$CraftItemStack, clazz$CraftItemStack, new String[]{"asCraftMirror"}, clazz$ItemStack
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$CraftItemStack$asNMSMirror = requireNonNull(
|
||||
public static final Method method$CraftItemStack$asNMSCopy = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$CraftItemStack, new String[]{"asNMSCopy"}, clazz$ItemStack, ItemStack.class
|
||||
clazz$CraftItemStack, clazz$ItemStack, new String[]{"asNMSCopy"}, ItemStack.class
|
||||
)
|
||||
);
|
||||
|
||||
@@ -3652,6 +3672,7 @@ public class Reflections {
|
||||
);
|
||||
|
||||
public static final Object instance$Items$AIR;
|
||||
public static final Object instance$Items$WATER_BUCKET;
|
||||
public static final Object instance$ItemStack$Air;
|
||||
|
||||
static {
|
||||
@@ -3659,6 +3680,8 @@ public class Reflections {
|
||||
Object air = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "air");
|
||||
instance$Items$AIR = method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ITEM, air);
|
||||
instance$ItemStack$Air = constructor$ItemStack.newInstance(instance$Items$AIR);
|
||||
Object waterBucket = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "water_bucket");
|
||||
instance$Items$WATER_BUCKET = method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ITEM, waterBucket);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -5293,4 +5316,59 @@ public class Reflections {
|
||||
clazz$ServerboundEditBookPacket, int.class, List.class, Optional.class
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$SimpleWaterloggedBlock = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("world.level.block.SimpleWaterloggedBlock"),
|
||||
BukkitReflectionUtils.assembleMCClass("world.level.block.IBlockWaterlogged")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$SimpleWaterloggedBlock$canPlaceLiquid = requireNonNull(
|
||||
VersionHelper.isVersionNewerThan1_20_2() ?
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$SimpleWaterloggedBlock, boolean.class, clazz$Player, clazz$BlockGetter, clazz$BlockPos, clazz$BlockState, clazz$Fluid
|
||||
) :
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$SimpleWaterloggedBlock, boolean.class, clazz$BlockGetter, clazz$BlockPos, clazz$BlockState, clazz$Fluid
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$SimpleWaterloggedBlock$placeLiquid = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$SimpleWaterloggedBlock, boolean.class, clazz$LevelAccessor, clazz$BlockPos, clazz$BlockState, clazz$FluidState
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$SimpleWaterloggedBlock$pickupBlock = requireNonNull(
|
||||
VersionHelper.isVersionNewerThan1_20_2() ?
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$SimpleWaterloggedBlock, clazz$ItemStack, clazz$Player, clazz$LevelAccessor, clazz$BlockPos, clazz$BlockState
|
||||
) :
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$SimpleWaterloggedBlock, clazz$ItemStack, clazz$LevelAccessor, clazz$BlockPos, clazz$BlockState
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$Fluid$getTickDelay = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$Fluid, int.class, clazz$LevelReader
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$Fluid$defaultFluidState = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$Fluid, clazz$FluidState, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Object instance$Fluid$EMPTY$defaultState;
|
||||
|
||||
static {
|
||||
try {
|
||||
instance$Fluid$EMPTY$defaultState = method$Fluid$defaultFluidState.invoke(instance$Fluids$EMPTY);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
package net.momirealms.craftengine.core.block;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.AbstractModelGenerator;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractBlockManager extends AbstractModelGenerator implements BlockManager {
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ public class BlockSettings {
|
||||
float hardness = 2f;
|
||||
float resistance = 2f;
|
||||
boolean canOcclude;
|
||||
boolean fluidState;
|
||||
Tristate isRedstoneConductor = Tristate.UNDEFINED;
|
||||
Tristate isSuffocating = Tristate.UNDEFINED;
|
||||
Tristate isViewBlocking = Tristate.UNDEFINED;
|
||||
@@ -75,6 +76,7 @@ public class BlockSettings {
|
||||
newSettings.isSuffocating = settings.isSuffocating;
|
||||
newSettings.isViewBlocking = settings.isViewBlocking;
|
||||
newSettings.correctTools = settings.correctTools;
|
||||
newSettings.fluidState = settings.fluidState;
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
@@ -94,6 +96,10 @@ public class BlockSettings {
|
||||
return resistance;
|
||||
}
|
||||
|
||||
public boolean fluidState() {
|
||||
return fluidState;
|
||||
}
|
||||
|
||||
public boolean isRandomlyTicking() {
|
||||
return isRandomlyTicking;
|
||||
}
|
||||
@@ -250,6 +256,11 @@ public class BlockSettings {
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockSettings fluidState(boolean state) {
|
||||
this.fluidState = state;
|
||||
return this;
|
||||
}
|
||||
|
||||
public interface Modifier {
|
||||
|
||||
void apply(BlockSettings settings);
|
||||
@@ -332,6 +343,10 @@ public class BlockSettings {
|
||||
Map<String, Object> soundMap = MiscUtils.castToMap(value, false);
|
||||
return settings -> settings.sounds(BlockSounds.fromMap(soundMap));
|
||||
}));
|
||||
registerFactory("fluid-state", (value -> {
|
||||
String state = (String) value;
|
||||
return settings -> settings.fluidState(state.equals("water"));
|
||||
}));
|
||||
registerFactory("can-occlude", (value -> {
|
||||
boolean booleanValue = (boolean) value;
|
||||
return settings -> settings.canOcclude(booleanValue);
|
||||
|
||||
@@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.plugin;
|
||||
import net.momirealms.craftengine.core.block.BlockManager;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureManager;
|
||||
import net.momirealms.craftengine.core.font.ImageManager;
|
||||
import net.momirealms.craftengine.core.font.AbstractImageManager;
|
||||
import net.momirealms.craftengine.core.item.ItemManager;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeManager;
|
||||
import net.momirealms.craftengine.core.loot.VanillaLootManager;
|
||||
|
||||
@@ -249,7 +249,7 @@ public class ConfigManager implements Reloadable {
|
||||
|
||||
Class<?> modClazz = ReflectionUtils.getClazz(CraftEngine.MOD_CLASS);
|
||||
if (modClazz != null) {
|
||||
Method setMaxChainMethod = ReflectionUtils.getStaticMethod(modClazz, new String[] {"setMaxChainUpdate"}, void.class, int.class);
|
||||
Method setMaxChainMethod = ReflectionUtils.getStaticMethod(modClazz, void.class, new String[] {"setMaxChainUpdate"}, int.class);
|
||||
try {
|
||||
assert setMaxChainMethod != null;
|
||||
setMaxChainMethod.invoke(null, performance$max_block_chain_update_limit);
|
||||
|
||||
@@ -321,7 +321,7 @@ public class ReflectionUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Method getStaticMethod(final Class<?> clazz, String[] possibleNames, Class<?> returnType, final Class<?>... parameterTypes) {
|
||||
public static Method getStaticMethod(final Class<?> clazz, Class<?> returnType, String[] possibleNames, final Class<?>... parameterTypes) {
|
||||
outer:
|
||||
for (Method method : clazz.getMethods()) {
|
||||
if (method.getParameterCount() != parameterTypes.length) {
|
||||
|
||||
@@ -15,7 +15,6 @@ import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.Fallable;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.momirealms.craftengine.mod.util.NoteBlockUtils;
|
||||
@@ -23,7 +22,11 @@ import net.momirealms.craftengine.shared.ObjectHolder;
|
||||
import net.momirealms.craftengine.shared.block.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CraftEngineBlock extends Block implements BehaviorHolder, ShapeHolder, NoteBlockIndicator, Fallable, BonemealableBlock {
|
||||
public class CraftEngineBlock
|
||||
extends Block
|
||||
implements BehaviorHolder, ShapeHolder, NoteBlockIndicator, Fallable, BonemealableBlock
|
||||
//TODO , SimpleWaterloggedBlock
|
||||
{
|
||||
private static final StoneBlockShape STONE = new StoneBlockShape(Blocks.STONE.defaultBlockState());
|
||||
private boolean isNoteBlock;
|
||||
public ObjectHolder<BlockBehavior> behaviorHolder;
|
||||
@@ -168,15 +171,15 @@ public class CraftEngineBlock extends Block implements BehaviorHolder, ShapeHold
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull FluidState getFluidState(@NotNull BlockState state) {
|
||||
try {
|
||||
return (FluidState) behaviorHolder.value().getFluidState(this, new Object[]{state}, () -> super.getFluidState(state));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return super.getFluidState(state);
|
||||
}
|
||||
}
|
||||
// @Override
|
||||
// protected @NotNull FluidState getFluidState(@NotNull BlockState state) {
|
||||
// try {
|
||||
// return (FluidState) behaviorHolder.value().getFluidState(this, new Object[]{state}, () -> super.getFluidState(state));
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return super.getFluidState(state);
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean isValidBonemealTarget(@NotNull LevelReader levelReader, @NotNull BlockPos blockPos, @NotNull BlockState blockState) {
|
||||
@@ -215,4 +218,35 @@ public class CraftEngineBlock extends Block implements BehaviorHolder, ShapeHold
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean canPlaceLiquid(@Nullable Player player, @NotNull BlockGetter level, @NotNull BlockPos pos, @NotNull BlockState state, @NotNull Fluid fluid) {
|
||||
// try {
|
||||
// return behaviorHolder.value().canPlaceLiquid(this, new Object[]{player, level, pos, state, fluid}, () -> SimpleWaterloggedBlock.super.canPlaceLiquid(player, level, pos, state, fluid));
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return SimpleWaterloggedBlock.super.canPlaceLiquid(player, level, pos, state, fluid);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean placeLiquid(@NotNull LevelAccessor level, @NotNull BlockPos pos, @NotNull BlockState state, @NotNull FluidState fluidState) {
|
||||
// try {
|
||||
// return behaviorHolder.value().placeLiquid(this, new Object[]{level, pos, state, fluidState}, () -> SimpleWaterloggedBlock.super.placeLiquid(level, pos, state, fluidState));
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return SimpleWaterloggedBlock.super.placeLiquid(level, pos, state, fluidState);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @NotNull
|
||||
// @Override
|
||||
// public ItemStack pickupBlock(@Nullable Player player, @NotNull LevelAccessor level, @NotNull BlockPos pos, @NotNull BlockState state) {
|
||||
// try {
|
||||
// return (ItemStack) behaviorHolder.value().pickupBlock(this, new Object[]{player, level, pos, state}, () -> SimpleWaterloggedBlock.super.pickupBlock(player, level, pos, state));
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return SimpleWaterloggedBlock.super.pickupBlock(player, level, pos, state);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -8,10 +8,6 @@ public abstract class BlockBehavior {
|
||||
return superMethod.call();
|
||||
}
|
||||
|
||||
public Object getFluidState(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
return superMethod.call();
|
||||
}
|
||||
|
||||
public void tick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
superMethod.call();
|
||||
}
|
||||
@@ -48,4 +44,20 @@ public abstract class BlockBehavior {
|
||||
public Object updateStateForPlacement(Object context, Object state) {
|
||||
return state;
|
||||
}
|
||||
|
||||
//
|
||||
// public Object getFluidState(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// return superMethod.call();
|
||||
// }
|
||||
// public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// return (boolean) superMethod.call();
|
||||
// }
|
||||
//
|
||||
// public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// return (boolean) superMethod.call();
|
||||
// }
|
||||
//
|
||||
// public Object pickupBlock(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
// return superMethod.call();
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user