mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-31 12:56:28 +00:00
让全部自定义方块均支持waterlogged
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.bukkit.block;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.behavior.UnsafeCompositeBlockBehavior;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
@@ -10,6 +11,8 @@ import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.SoundUtils;
|
||||
import net.momirealms.craftengine.core.block.*;
|
||||
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
|
||||
import net.momirealms.craftengine.core.block.behavior.BlockBehaviors;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
@@ -46,6 +49,21 @@ public class BukkitCustomBlock extends AbstractCustomBlock {
|
||||
super(id, holder, properties, appearances, variantMapper, settings, events, behavior, lootTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockBehavior setupBehavior(List<Map<String, Object>> behaviorConfig) {
|
||||
if (behaviorConfig.isEmpty()) {
|
||||
return new EmptyBlockBehavior();
|
||||
} else if (behaviorConfig.size() == 1) {
|
||||
return BlockBehaviors.fromMap(this, behaviorConfig.get(0));
|
||||
} else {
|
||||
List<AbstractBlockBehavior> behaviors = new ArrayList<>();
|
||||
for (Map<String, Object> config : behaviorConfig) {
|
||||
behaviors.add((AbstractBlockBehavior) BlockBehaviors.fromMap(this, config));
|
||||
}
|
||||
return new UnsafeCompositeBlockBehavior(this, behaviors);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
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.MFluids;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MItems;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.MirrorUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.RotationUtils;
|
||||
@@ -8,10 +12,8 @@ import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.HorizontalDirection;
|
||||
import net.momirealms.craftengine.core.util.Mirror;
|
||||
import net.momirealms.craftengine.core.util.Rotation;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -75,16 +77,20 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private MirrorFunction mirrorFunction;
|
||||
@Nullable
|
||||
private RotateFunction rotateFunction;
|
||||
@Nullable
|
||||
protected final Property<Boolean> waterloggedProperty;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public BukkitBlockBehavior(CustomBlock customBlock) {
|
||||
super(customBlock);
|
||||
for (Property<?> property : customBlock.properties()) {
|
||||
Optional.ofNullable(HARD_CODED_PROPERTY_DATA.get(property.name())).ifPresent(
|
||||
c -> c.accept(this, property)
|
||||
);
|
||||
Optional.ofNullable(HARD_CODED_PROPERTY_DATA.get(property.name())).ifPresent(c -> c.accept(this, property));
|
||||
}
|
||||
this.waterloggedProperty = (Property<Boolean>) customBlock.getProperty("waterlogged");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -118,4 +124,48 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
|
||||
|
||||
Object rotate(Object thisBlock, ImmutableBlockState state, Rotation rotation) throws Exception;
|
||||
}
|
||||
|
||||
private static final int pickupBlock$world = VersionHelper.isOrAbove1_20_2() ? 1 : 0;
|
||||
private static final int pickupBlock$pos = VersionHelper.isOrAbove1_20_2() ? 2 : 1;
|
||||
private static final int pickupBlock$blockState = VersionHelper.isOrAbove1_20_2() ? 3 : 2;
|
||||
|
||||
@Override
|
||||
public Object pickupBlock(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return CoreReflections.instance$ItemStack$EMPTY;
|
||||
Object blockState = args[pickupBlock$blockState];
|
||||
Object world = args[pickupBlock$world];
|
||||
Object pos = args[pickupBlock$pos];
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (immutableBlockState != null) {
|
||||
if (immutableBlockState.get(this.waterloggedProperty)) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, pos, immutableBlockState.with(this.waterloggedProperty, false).customBlockState().handle(), 3);
|
||||
return FastNMS.INSTANCE.constructor$ItemStack(MItems.WATER_BUCKET, 1);
|
||||
}
|
||||
}
|
||||
return CoreReflections.instance$ItemStack$EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return false;
|
||||
Object blockState = args[2];
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (immutableBlockState != null) {
|
||||
Object fluidType = FastNMS.INSTANCE.method$FluidState$getType(args[3]);
|
||||
if (!immutableBlockState.get(this.waterloggedProperty) && fluidType == MFluids.WATER) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(args[0], args[1], immutableBlockState.with(this.waterloggedProperty, true).customBlockState().handle(), 3);
|
||||
FastNMS.INSTANCE.method$LevelAccessor$scheduleFluidTick(args[0], args[1], fluidType, 5);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final int canPlaceLiquid$liquid = VersionHelper.isOrAbove1_20_2() ? 4 : 3;
|
||||
|
||||
@Override
|
||||
public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return false;
|
||||
return args[canPlaceLiquid$liquid] == MFluids.WATER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
||||
register(SAPLING_BLOCK, SaplingBlockBehavior.FACTORY);
|
||||
register(ON_LIQUID_BLOCK, OnLiquidBlockBehavior.FACTORY);
|
||||
register(NEAR_LIQUID_BLOCK, NearLiquidBlockBehavior.FACTORY);
|
||||
register(WATERLOGGED_BLOCK, WaterLoggedBlockBehavior.FACTORY);
|
||||
register(CONCRETE_POWDER_BLOCK, ConcretePowderBlockBehavior.FACTORY);
|
||||
register(VERTICAL_CROP_BLOCK, VerticalCropBlockBehavior.FACTORY);
|
||||
register(CROP_BLOCK, CropBlockBehavior.FACTORY);
|
||||
|
||||
@@ -27,27 +27,26 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.block.LeavesDecayEvent;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class LeavesBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
public class LeavesBlockBehavior extends BukkitBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private static final Object LOG_TAG = BlockTags.getOrCreate(Key.of("minecraft", "logs"));
|
||||
private final int maxDistance;
|
||||
private final Property<Integer> distanceProperty;
|
||||
private final Property<Boolean> persistentProperty;
|
||||
@Nullable
|
||||
private final Property<Boolean> waterloggedProperty;
|
||||
|
||||
public LeavesBlockBehavior(CustomBlock block, int maxDistance, Property<Integer> distanceProperty, Property<Boolean> persistentProperty, @Nullable Property<Boolean> waterloggedProperty) {
|
||||
super(block, waterloggedProperty);
|
||||
public LeavesBlockBehavior(CustomBlock block,
|
||||
int maxDistance,
|
||||
Property<Integer> distanceProperty,
|
||||
Property<Boolean> persistentProperty) {
|
||||
super(block);
|
||||
this.maxDistance = maxDistance;
|
||||
this.distanceProperty = distanceProperty;
|
||||
this.persistentProperty = persistentProperty;
|
||||
this.waterloggedProperty = waterloggedProperty;
|
||||
}
|
||||
|
||||
public int getDistance(ImmutableBlockState state) {
|
||||
@@ -115,7 +114,7 @@ public class LeavesBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
public void randomTick(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object level = args[1];
|
||||
Object blockPos = args[2];
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(args[0]));
|
||||
@@ -190,9 +189,8 @@ public class LeavesBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
Property<Boolean> persistent = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("persistent"), "warning.config.block.behavior.leaves.missing_persistent");
|
||||
Property<Integer> distance = (Property<Integer>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("distance"), "warning.config.block.behavior.leaves.missing_distance");
|
||||
Property<Boolean> waterlogged = (Property<Boolean>) block.getProperty("waterlogged");
|
||||
int actual = distance.possibleValues().get(distance.possibleValues().size() - 1);
|
||||
return new LeavesBlockBehavior(block, actual, distance, persistent, waterlogged);
|
||||
return new LeavesBlockBehavior(block, actual, distance, persistent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
public class TrapDoorBlockBehavior extends BukkitBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final Property<SingleBlockHalf> halfProperty;
|
||||
private final Property<HorizontalDirection> facingProperty;
|
||||
@@ -55,7 +55,6 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
private final SoundData closeSound;
|
||||
|
||||
public TrapDoorBlockBehavior(CustomBlock block,
|
||||
@Nullable Property<Boolean> waterloggedProperty,
|
||||
Property<SingleBlockHalf> halfProperty,
|
||||
Property<HorizontalDirection> facingProperty,
|
||||
Property<Boolean> poweredProperty,
|
||||
@@ -64,7 +63,7 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
boolean canOpenByWindCharge,
|
||||
SoundData openSound,
|
||||
SoundData closeSound) {
|
||||
super(block, waterloggedProperty);
|
||||
super(block);
|
||||
this.halfProperty = halfProperty;
|
||||
this.facingProperty = facingProperty;
|
||||
this.poweredProperty = poweredProperty;
|
||||
@@ -78,9 +77,9 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
@Override
|
||||
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object blockState = args[0];
|
||||
if (this.waterloggedProperty != null) {
|
||||
if (super.waterloggedProperty != null) {
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (state != null && !state.isEmpty() && state.get(this.waterloggedProperty)) {
|
||||
if (state != null && !state.isEmpty() && state.get(super.waterloggedProperty)) {
|
||||
FastNMS.INSTANCE.method$LevelAccessor$scheduleFluidTick(VersionHelper.isOrAbove1_21_2() ? args[2] : args[3], VersionHelper.isOrAbove1_21_2() ? args[3] : args[4], MFluids.WATER, 5);
|
||||
}
|
||||
}
|
||||
@@ -238,7 +237,6 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
@Override
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
Property<Boolean> waterlogged = (Property<Boolean>) block.getProperty("waterlogged");
|
||||
Property<SingleBlockHalf> half = (Property<SingleBlockHalf>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("half"), "warning.config.block.behavior.trapdoor.missing_half");
|
||||
Property<HorizontalDirection> facing = (Property<HorizontalDirection>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("facing"), "warning.config.block.behavior.trapdoor.missing_facing");
|
||||
Property<Boolean> open = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("open"), "warning.config.block.behavior.trapdoor.missing_open");
|
||||
@@ -252,7 +250,7 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
openSound = Optional.ofNullable(sounds.get("open")).map(obj -> SoundData.create(obj, 1, 1)).orElse(null);
|
||||
closeSound = Optional.ofNullable(sounds.get("close")).map(obj -> SoundData.create(obj, 1, 1)).orElse(null);
|
||||
}
|
||||
return new TrapDoorBlockBehavior(block, waterlogged, half, facing, powered, open, canOpenWithHand, canOpenByWindCharge, openSound, closeSound);
|
||||
return new TrapDoorBlockBehavior(block, half, facing, powered, open, canOpenWithHand, canOpenByWindCharge, openSound, closeSound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||
|
||||
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.AbstractBlockBehavior;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior {
|
||||
private final AbstractBlockBehavior[] behaviors;
|
||||
|
||||
public UnsafeCompositeBlockBehavior(CustomBlock customBlock, List<AbstractBlockBehavior> behaviors) {
|
||||
super(customBlock);
|
||||
this.behaviors = behaviors.toArray(new AbstractBlockBehavior[0]);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends BlockBehavior> Optional<T> getAs(Class<T> tClass) {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
if (tClass.isInstance(behavior)) {
|
||||
return Optional.of((T) behavior);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context, ImmutableBlockState state) {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
InteractionResult result = behavior.useOnBlock(context, state);
|
||||
if (result != InteractionResult.PASS) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return super.useOnBlock(context, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
state = behavior.updateStateForPlacement(context, state);
|
||||
if (state == null) return null;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
Object previous = args[0];
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
Object processed = behavior.updateShape(thisBlock, args, superMethod);
|
||||
if (processed != previous) {
|
||||
return processed;
|
||||
}
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
behavior.tick(thisBlock, args, superMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
behavior.randomTick(thisBlock, args, superMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object rotate(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
Object previous = args[0];
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
Object processed = behavior.rotate(thisBlock, args, superMethod);
|
||||
if (processed != previous) {
|
||||
return processed;
|
||||
}
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object mirror(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
Object previous = args[0];
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
Object processed = behavior.mirror(thisBlock, args, superMethod);
|
||||
if (processed != previous) {
|
||||
return processed;
|
||||
}
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performBoneMeal(Object thisBlock, Object[] args) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
behavior.performBoneMeal(thisBlock, args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlace(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
behavior.onPlace(thisBlock, args, superMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLand(Object thisBlock, Object[] args) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
behavior.onLand(thisBlock, args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBrokenAfterFall(Object thisBlock, Object[] args) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
behavior.onBrokenAfterFall(thisBlock, args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
behavior.neighborChanged(thisBlock, args, superMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidBoneMealTarget(Object thisBlock, Object[] args) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
if (behavior.isValidBoneMealTarget(thisBlock, args)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoneMealSuccess(Object thisBlock, Object[] args) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
if (behavior.isBoneMealSuccess(thisBlock, args)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSurvive(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
if (!behavior.canSurvive(thisBlock, args, superMethod)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPathFindable(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
if (!behavior.isPathFindable(thisBlock, args, superMethod)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (boolean) superMethod.call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExplosionHit(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
behavior.onExplosionHit(thisBlock, args, superMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
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.MFluids;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MItems;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
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.Property;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class WaterLoggedBlockBehavior extends BukkitBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
@Nullable
|
||||
protected final Property<Boolean> waterloggedProperty;
|
||||
|
||||
public WaterLoggedBlockBehavior(CustomBlock block, @Nullable Property<Boolean> waterloggedProperty) {
|
||||
super(block);
|
||||
this.waterloggedProperty = waterloggedProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object pickupBlock(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return CoreReflections.instance$ItemStack$EMPTY;
|
||||
Object blockState;
|
||||
Object world;
|
||||
Object pos;
|
||||
if (VersionHelper.isOrAbove1_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)) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, pos, immutableBlockState.with(this.waterloggedProperty, false).customBlockState().handle(), 3);
|
||||
return FastNMS.INSTANCE.constructor$ItemStack(MItems.WATER_BUCKET, 1);
|
||||
}
|
||||
}
|
||||
return CoreReflections.instance$ItemStack$EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean placeLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return false;
|
||||
Object blockState = args[2];
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (immutableBlockState != null) {
|
||||
Object fluidType = FastNMS.INSTANCE.method$FluidState$getType(args[3]);
|
||||
if (!immutableBlockState.get(this.waterloggedProperty) && fluidType == MFluids.WATER) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(args[0], args[1], immutableBlockState.with(this.waterloggedProperty, true).customBlockState().handle(), 3);
|
||||
FastNMS.INSTANCE.method$LevelAccessor$scheduleFluidTick(args[0], args[1], fluidType, 5);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceLiquid(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.waterloggedProperty == null) return false;
|
||||
return (VersionHelper.isOrAbove1_20_2() ? args[4] : args[3]) == MFluids.WATER;
|
||||
}
|
||||
|
||||
@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(block, waterlogged);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user