mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-28 19:39:11 +00:00
add on liquid blocks
This commit is contained in:
@@ -5,12 +5,12 @@ import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.shared.block.EmptyBlockBehavior;
|
||||
|
||||
public class BukkitBlockBehaviors extends BlockBehaviors {
|
||||
public static final Key EMPTY = Key.from("craftengine:empty");
|
||||
public static final Key BUSH_BLOCK = Key.from("craftengine:bush_block");
|
||||
public static final Key FALLING_BLOCK = Key.from("craftengine:falling_block");
|
||||
public static final Key LEAVES_BLOCK = Key.from("craftengine:leaves_block");
|
||||
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 void init() {
|
||||
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
|
||||
@@ -19,5 +19,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
||||
register(LEAVES_BLOCK, LeavesBlockBehavior.FACTORY);
|
||||
register(STRIPPABLE_BLOCK, StrippableBlockBehavior.FACTORY);
|
||||
register(SAPLING_BLOCK, SaplingBlockBehavior.FACTORY);
|
||||
register(ON_LIQUID_BLOCK, OnLiquidBlockBehavior.FACTORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,9 @@ public class BushBlockBehavior extends BlockBehavior {
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
@Override
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
if (arguments.containsKey("tags")) {
|
||||
if (arguments.containsKey("bottom-block-tags")) {
|
||||
return new BushBlockBehavior(MiscUtils.getAsStringList(arguments.get("bottom-block-tags")).stream().map(it -> BlockTags.getOrCreate(Key.of(it))).toList());
|
||||
} else if (arguments.containsKey("tags")) {
|
||||
return new BushBlockBehavior(MiscUtils.getAsStringList(arguments.get("tags")).stream().map(it -> BlockTags.getOrCreate(Key.of(it))).toList());
|
||||
} else {
|
||||
return INSTANCE;
|
||||
@@ -100,7 +102,7 @@ public class BushBlockBehavior extends BlockBehavior {
|
||||
return mayPlaceOn(belowState, world, belowPos);
|
||||
}
|
||||
|
||||
private boolean mayPlaceOn(Object belowState, Object world, Object blockPos) throws ReflectiveOperationException {
|
||||
protected boolean mayPlaceOn(Object belowState, Object world, Object belowPos) throws ReflectiveOperationException {
|
||||
for (Object tag : this.tagsCanSurviveOn) {
|
||||
if ((boolean) Reflections.method$BlockStateBase$hasTag.invoke(belowState, tag)) {
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.shared.block.BlockBehavior;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OnLiquidBlockBehavior extends BushBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final boolean onWater;
|
||||
private final boolean onLava;
|
||||
|
||||
public OnLiquidBlockBehavior(List<Object> tagsCanSurviveOn, boolean onWater, boolean onLava) {
|
||||
super(tagsCanSurviveOn);
|
||||
this.onWater = onWater;
|
||||
this.onLava = onLava;
|
||||
}
|
||||
|
||||
public boolean onWater() {
|
||||
return this.onWater;
|
||||
}
|
||||
|
||||
public boolean onLava() {
|
||||
return this.onLava;
|
||||
}
|
||||
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
@Override
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
List<String> liquidTypes = MiscUtils.getAsStringList(arguments.getOrDefault("liquid-type", List.of("water")));
|
||||
return new OnLiquidBlockBehavior(List.of(), liquidTypes.contains("water"), liquidTypes.contains("lava"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mayPlaceOn(Object belowState, Object world, Object belowPos) throws ReflectiveOperationException {
|
||||
Object fluidState = Reflections.method$Level$getFluidState.invoke(world, belowPos);
|
||||
Object fluidStateAbove = Reflections.method$Level$getFluidState.invoke(world, LocationUtils.above(belowPos));
|
||||
if (Reflections.method$FluidState$getType.invoke(fluidStateAbove) != Reflections.instance$Fluids$EMPTY) {
|
||||
return false;
|
||||
}
|
||||
if (this.onWater && (Reflections.method$FluidState$getType.invoke(fluidState) == Reflections.instance$Fluids$WATER || Reflections.field$StateHolder$owner.get(belowState) == Reflections.instance$Blocks$ICE)) {
|
||||
return true;
|
||||
}
|
||||
if (this.onLava && Reflections.method$FluidState$getType.invoke(fluidState) == Reflections.instance$Fluids$LAVA) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.momirealms.craftengine.bukkit.item;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BoneMealBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.WaterBucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
|
||||
@@ -50,7 +49,6 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
registerVanillaItemExtraBehavior(AxeItemBehavior.INSTANCE, ItemKeys.AXES);
|
||||
registerVanillaItemExtraBehavior(WaterBucketItemBehavior.INSTANCE, ItemKeys.WATER_BUCKETS);
|
||||
registerVanillaItemExtraBehavior(BucketItemBehavior.INSTANCE, ItemKeys.BUCKET);
|
||||
registerVanillaItemExtraBehavior(BoneMealBehavior.INSTANCE, ItemKeys.BONE_MEAL);
|
||||
}
|
||||
|
||||
private static BukkitItemManager instance;
|
||||
|
||||
@@ -157,6 +157,8 @@ public class ItemEventListener implements Listener {
|
||||
}
|
||||
|
||||
for (ItemBehavior itemBehavior : optionalItemBehaviors.get()) {
|
||||
|
||||
|
||||
InteractionResult result = itemBehavior.useOnBlock(new UseOnContext(player, hand, hitResult));
|
||||
if (result == InteractionResult.SUCCESS_AND_CANCEL) {
|
||||
event.setCancelled(true);
|
||||
|
||||
@@ -79,7 +79,7 @@ public class BlockItemBehavior extends ItemBehavior {
|
||||
|
||||
BlockPos pos = placeContext.getClickedPos();
|
||||
BlockPos againstPos = placeContext.getAgainstPos();
|
||||
World world = (World) placeContext.getLevel().getHandle();
|
||||
World world = (World) placeContext.getLevel().platformWorld();
|
||||
Location placeLocation = new Location(world, pos.x(), pos.y(), pos.z());
|
||||
|
||||
Block bukkitBlock = world.getBlockAt(placeLocation);
|
||||
@@ -151,7 +151,7 @@ public class BlockItemBehavior extends ItemBehavior {
|
||||
Object blockState = state.customBlockState().handle();
|
||||
Object blockPos = LocationUtils.toBlockPos(context.getClickedPos());
|
||||
Object voxelShape = Reflections.method$CollisionContext$of.invoke(null, player);
|
||||
Object world = Reflections.field$CraftWorld$ServerLevel.get(context.getLevel().getHandle());
|
||||
Object world = Reflections.field$CraftWorld$ServerLevel.get(context.getLevel().platformWorld());
|
||||
boolean defaultReturn = ((!this.checkStatePlacement() || (boolean) Reflections.method$BlockStateBase$canSurvive.invoke(blockState, world, blockPos))
|
||||
&& (boolean) Reflections.method$ServerLevel$checkEntityCollision.invoke(world, blockState, player, voxelShape, blockPos, true));
|
||||
Block block = (Block) Reflections.method$CraftBlock$at.invoke(null, world, blockPos);
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public class BoneMealBehavior extends ItemBehavior {
|
||||
public static final BoneMealBehavior INSTANCE = new BoneMealBehavior();
|
||||
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context) {
|
||||
return super.useOnBlock(context);
|
||||
}
|
||||
|
||||
public static class Factory implements ItemBehaviorFactory {
|
||||
@Override
|
||||
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,17 @@ import net.momirealms.craftengine.core.item.behavior.ItemBehaviors;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
public static final Key EMPTY = Key.from("craftengine:empty");
|
||||
public static final Key BLOCK_ITEM = Key.from("craftengine:block_item");
|
||||
public static final Key ON_LIQUID_BLOCK_ITEM = Key.from("craftengine:liquid_collision_block_item");
|
||||
public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item");
|
||||
public static final Key AXE_ITEM = Key.from("craftengine:axe_item");
|
||||
public static final Key WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item");
|
||||
public static final Key BUCKET_ITEM = Key.from("craftengine:bucket_item");
|
||||
|
||||
public static void init() {
|
||||
register(EMPTY, (pack, path, args, id) -> EmptyItemBehavior.INSTANCE);
|
||||
register(EMPTY, EmptyItemBehavior.FACTORY);
|
||||
register(BLOCK_ITEM, BlockItemBehavior.FACTORY);
|
||||
register(ON_LIQUID_BLOCK_ITEM, LiquidCollisionBlockItemBehavior.FACTORY);
|
||||
register(FURNITURE_ITEM, FurnitureItemBehavior.FACTORY);
|
||||
register(AXE_ITEM, AxeItemBehavior.FACTORY);
|
||||
register(WATER_BUCKET_ITEM, WaterBucketItemBehavior.FACTORY);
|
||||
|
||||
@@ -77,7 +77,7 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
|
||||
// trigger event
|
||||
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.platformPlayer();
|
||||
World world = (World) context.getLevel().getHandle();
|
||||
World world = (World) context.getLevel().platformWorld();
|
||||
|
||||
// get position and rotation for placement
|
||||
Vec3d finalPlacePosition;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.world.BlockHitResult;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public class LiquidCollisionBlockItemBehavior extends BlockItemBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final int offsetY;
|
||||
|
||||
public LiquidCollisionBlockItemBehavior(Key blockId, int offsetY) {
|
||||
super(blockId);
|
||||
this.offsetY = offsetY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context) {
|
||||
return use(context.getLevel(), context.getPlayer(), context.getHand());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(World world, Player player, InteractionHand hand) {
|
||||
try {
|
||||
Object blockHitResult = Reflections.method$Item$getPlayerPOVHitResult.invoke(null, world.serverWorld(), player.serverPlayer(), Reflections.instance$ClipContext$Fluid$SOURCE_ONLY);
|
||||
Object blockPos = Reflections.field$BlockHitResul$blockPos.get(blockHitResult);
|
||||
BlockPos above = new BlockPos(Reflections.field$Vec3i$x.getInt(blockPos), Reflections.field$Vec3i$y.getInt(blockPos) + offsetY, Reflections.field$Vec3i$z.getInt(blockPos));
|
||||
Direction direction = Direction.values()[(int) Reflections.method$Direction$ordinal.invoke(Reflections.field$BlockHitResul$direction.get(blockHitResult))];
|
||||
boolean miss = Reflections.field$BlockHitResul$miss.getBoolean(blockHitResult);
|
||||
Vec3d hitPos = LocationUtils.fromVec(Reflections.field$HitResult$location.get(blockHitResult));
|
||||
if (miss) {
|
||||
return super.useOnBlock(new UseOnContext(player, hand, BlockHitResult.miss(hitPos, direction, above)));
|
||||
} else {
|
||||
boolean inside = Reflections.field$BlockHitResul$inside.getBoolean(blockHitResult);
|
||||
return super.useOnBlock(new UseOnContext(player, hand, new BlockHitResult(hitPos, direction, above, inside)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Error handling use", e);
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory implements ItemBehaviorFactory {
|
||||
@Override
|
||||
public ItemBehavior create(Pack pack, Path path, Key key, Map<String, Object> arguments) {
|
||||
Object id = arguments.get("block");
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("Missing required parameter 'block' for on_liquid_block_item behavior");
|
||||
}
|
||||
int offset = MiscUtils.getAsInt(arguments.getOrDefault("y-offset", 1));
|
||||
if (id instanceof Map<?, ?> map) {
|
||||
BukkitBlockManager.instance().parseSection(pack, path, key, MiscUtils.castToMap(map, false));
|
||||
return new LiquidCollisionBlockItemBehavior(key, offset);
|
||||
} else {
|
||||
return new LiquidCollisionBlockItemBehavior(Key.of(id.toString()), offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,7 +344,7 @@ public class PacketConsumers {
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundSetCreativeModeSlotPacket", e);
|
||||
}
|
||||
}, (World) player.level().getHandle(), (MCUtils.fastFloor(player.x())) >> 4, (MCUtils.fastFloor(player.z())) >> 4);
|
||||
}, (World) player.level().platformWorld(), (MCUtils.fastFloor(player.x())) >> 4, (MCUtils.fastFloor(player.z())) >> 4);
|
||||
} else {
|
||||
handleSetCreativeSlotPacketOnMainThread(player, packet);
|
||||
}
|
||||
|
||||
@@ -16,15 +16,15 @@ import net.momirealms.craftengine.core.plugin.network.ConnectionState;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import net.momirealms.craftengine.core.world.*;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.util.RayTraceResult;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
@@ -201,6 +201,31 @@ public class BukkitServerPlayer extends Player {
|
||||
platformPlayer().closeInventory();
|
||||
}
|
||||
|
||||
// TODO DO NOT USE BUKKIT API
|
||||
@Override
|
||||
public BlockHitResult rayTrace(double distance, FluidCollisionRule collisionRule) {
|
||||
RayTraceResult result = platformPlayer().rayTraceBlocks(distance, FluidUtils.toCollisionRule(collisionRule));
|
||||
if (result == null) {
|
||||
Location eyeLocation = platformPlayer().getEyeLocation();
|
||||
Location targetLocation = eyeLocation.clone();
|
||||
targetLocation.add(eyeLocation.getDirection().multiply(distance));
|
||||
return BlockHitResult.miss(new Vec3d(eyeLocation.getX(), eyeLocation.getY(), eyeLocation.getZ()),
|
||||
Direction.getApproximateNearest(eyeLocation.getX() - targetLocation.getX(), eyeLocation.getY() - targetLocation.getY(), eyeLocation.getZ() - targetLocation.getZ()),
|
||||
new BlockPos(targetLocation.getBlockX(), targetLocation.getBlockY(), targetLocation.getBlockZ())
|
||||
);
|
||||
} else {
|
||||
Vector hitPos = result.getHitPosition();
|
||||
Block hitBlock = result.getHitBlock();
|
||||
Location hitBlockLocation = hitBlock.getLocation();
|
||||
return new BlockHitResult(
|
||||
new Vec3d(hitPos.getX(), hitPos.getY(), hitPos.getZ()),
|
||||
DirectionUtils.toDirection(result.getHitBlockFace()),
|
||||
new BlockPos(hitBlockLocation.getBlockX(), hitBlockLocation.getBlockY(), hitBlockLocation.getBlockZ()),
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Object packet, boolean immediately) {
|
||||
this.plugin.networkManager().sendPacket(this, packet, immediately);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.momirealms.craftengine.bukkit.util;
|
||||
|
||||
import net.momirealms.craftengine.core.world.FluidCollisionRule;
|
||||
import org.bukkit.FluidCollisionMode;
|
||||
|
||||
public class FluidUtils {
|
||||
|
||||
private FluidUtils() {}
|
||||
|
||||
public static FluidCollisionMode toCollisionRule(FluidCollisionRule rule) {
|
||||
switch (rule) {
|
||||
case NONE -> {
|
||||
return FluidCollisionMode.NEVER;
|
||||
}
|
||||
case ALWAYS -> {
|
||||
return FluidCollisionMode.ALWAYS;
|
||||
}
|
||||
case SOURCE_ONLY -> {
|
||||
return FluidCollisionMode.SOURCE_ONLY;
|
||||
}
|
||||
}
|
||||
return FluidCollisionMode.NEVER;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,14 @@ public class LocationUtils {
|
||||
return new Vec3d(loc.getX(), loc.getY(), loc.getZ());
|
||||
}
|
||||
|
||||
public static Vec3d fromVec(Object vec) throws ReflectiveOperationException {
|
||||
return new Vec3d(
|
||||
Reflections.field$Vec3$x.getDouble(vec),
|
||||
Reflections.field$Vec3$y.getDouble(vec),
|
||||
Reflections.field$Vec3$z.getDouble(vec)
|
||||
);
|
||||
}
|
||||
|
||||
public static Object toBlockPos(BlockPos pos) {
|
||||
try {
|
||||
return Reflections.constructor$BlockPos.newInstance(pos.x(), pos.y(), pos.z());
|
||||
@@ -21,6 +29,14 @@ public class LocationUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Object above(Object blockPos) throws ReflectiveOperationException {
|
||||
return toBlockPos(
|
||||
Reflections.field$Vec3i$x.getInt(blockPos),
|
||||
Reflections.field$Vec3i$y.getInt(blockPos) + 1,
|
||||
Reflections.field$Vec3i$z.getInt(blockPos)
|
||||
);
|
||||
}
|
||||
|
||||
public static Object toBlockPos(int x, int y, int z) {
|
||||
try {
|
||||
return Reflections.constructor$BlockPos.newInstance(x, y, z);
|
||||
|
||||
@@ -1455,6 +1455,12 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$Direction$ordinal = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$Direction, new String[]{"ordinal"}
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$Direction$values = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$Direction, clazz$Direction.arrayType()
|
||||
@@ -3326,6 +3332,7 @@ public class Reflections {
|
||||
public static final Object instance$Blocks$STONE;
|
||||
public static final Object instance$Blocks$STONE$defaultState;
|
||||
public static final Object instance$Blocks$FIRE;
|
||||
public static final Object instance$Blocks$ICE;
|
||||
|
||||
static {
|
||||
try {
|
||||
@@ -3337,6 +3344,8 @@ public class Reflections {
|
||||
Object stone = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "stone");
|
||||
instance$Blocks$STONE = method$Registry$get.invoke(instance$BuiltInRegistries$BLOCK, stone);
|
||||
instance$Blocks$STONE$defaultState = method$Block$defaultBlockState.invoke(instance$Blocks$STONE);
|
||||
Object ice = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "ice");
|
||||
instance$Blocks$ICE = method$Registry$get.invoke(instance$BuiltInRegistries$BLOCK, ice);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -3862,11 +3871,17 @@ public class Reflections {
|
||||
);
|
||||
|
||||
public static final Object instance$Fluids$WATER;
|
||||
public static final Object instance$Fluids$LAVA;
|
||||
public static final Object instance$Fluids$EMPTY;
|
||||
|
||||
static {
|
||||
try {
|
||||
Object waterId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "water");
|
||||
instance$Fluids$WATER = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, waterId);
|
||||
Object lavaId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "lava");
|
||||
instance$Fluids$LAVA = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, lavaId);
|
||||
Object emptyId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "empty");
|
||||
instance$Fluids$EMPTY = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, emptyId);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -5015,4 +5030,85 @@ public class Reflections {
|
||||
clazz$ItemStack, clazz$Item
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$BlockHitResult = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("world.phys.BlockHitResult")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$ClipContext$Fluid = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("world.level.ClipContext$Fluid")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$ClipContext$Fluid$values = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$ClipContext$Fluid, clazz$ClipContext$Fluid.arrayType()
|
||||
)
|
||||
);
|
||||
|
||||
public static final Object instance$ClipContext$Fluid$NONE;
|
||||
public static final Object instance$ClipContext$Fluid$SOURCE_ONLY;
|
||||
public static final Object instance$ClipContext$Fluid$ANY;
|
||||
|
||||
static {
|
||||
try {
|
||||
Object[] values = (Object[]) method$ClipContext$Fluid$values.invoke(null);
|
||||
instance$ClipContext$Fluid$NONE = values[0];
|
||||
instance$ClipContext$Fluid$SOURCE_ONLY = values[1];
|
||||
instance$ClipContext$Fluid$ANY = values[2];
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Method method$Item$getPlayerPOVHitResult = requireNonNull(
|
||||
ReflectionUtils.getDeclaredMethod(
|
||||
clazz$Item, clazz$BlockHitResult, clazz$Level, clazz$Player, clazz$ClipContext$Fluid
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$BlockHitResult$withPosition = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$BlockHitResult, clazz$BlockHitResult, clazz$BlockPos
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$BlockHitResul$blockPos = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$BlockHitResult, clazz$BlockPos, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$BlockHitResul$direction = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$BlockHitResult, clazz$Direction, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$BlockHitResul$miss = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$BlockHitResult, boolean.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$BlockHitResul$inside = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$BlockHitResult, boolean.class, 1
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$HitResult = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("world.phys.HitResult")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$HitResult$location = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$HitResult, clazz$Vec3, 0
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public class BukkitCEWorld extends CEWorld {
|
||||
@Override
|
||||
public void tick() {
|
||||
if (ConfigManager.enableLightSystem()) {
|
||||
LightUtils.updateChunkLight((org.bukkit.World) world.getHandle(), SectionPosUtils.toMap(super.updatedSectionPositions, world.worldHeight().getMinSection() - 1, world.worldHeight().getMaxSection() + 1));
|
||||
LightUtils.updateChunkLight((org.bukkit.World) world.platformWorld(), SectionPosUtils.toMap(super.updatedSectionPositions, world.worldHeight().getMinSection() - 1, world.worldHeight().getMaxSection() + 1));
|
||||
super.updatedSectionPositions.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.world;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.util.EntityUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.ItemUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
@@ -28,36 +29,45 @@ public class BukkitWorld implements World {
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.World getHandle() {
|
||||
public org.bukkit.World platformWorld() {
|
||||
return world.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object serverWorld() {
|
||||
try {
|
||||
return Reflections.field$CraftWorld$ServerLevel.get(platformWorld());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get server world", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldHeight worldHeight() {
|
||||
if (this.worldHeight == null) {
|
||||
this.worldHeight = WorldHeight.create(getHandle().getMinHeight(), getHandle().getMaxHeight() - getHandle().getMinHeight());
|
||||
this.worldHeight = WorldHeight.create(platformWorld().getMinHeight(), platformWorld().getMaxHeight() - platformWorld().getMinHeight());
|
||||
}
|
||||
return this.worldHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldBlock getBlockAt(int x, int y, int z) {
|
||||
return new BukkitWorldBlock(getHandle().getBlockAt(x, y, z));
|
||||
return new BukkitWorldBlock(platformWorld().getBlockAt(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return getHandle().getName();
|
||||
return platformWorld().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path directory() {
|
||||
return getHandle().getWorldFolder().toPath();
|
||||
return platformWorld().getWorldFolder().toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID uuid() {
|
||||
return getHandle().getUID();
|
||||
return platformWorld().getUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,16 +75,16 @@ public class BukkitWorld implements World {
|
||||
ItemStack itemStack = (ItemStack) item.load();
|
||||
if (ItemUtils.isEmpty(itemStack)) return;
|
||||
if (VersionHelper.isVersionNewerThan1_21_2()) {
|
||||
getHandle().dropItemNaturally(new Location(null, location.x(), location.y(), location.z()), (ItemStack) item.getItem());
|
||||
platformWorld().dropItemNaturally(new Location(null, location.x(), location.y(), location.z()), (ItemStack) item.getItem());
|
||||
} else {
|
||||
getHandle().dropItemNaturally(new Location(null, location.x() - 0.5, location.y() - 0.5, location.z() - 0.5), (ItemStack) item.getItem());
|
||||
platformWorld().dropItemNaturally(new Location(null, location.x() - 0.5, location.y() - 0.5, location.z() - 0.5), (ItemStack) item.getItem());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropExp(Vec3d location, int amount) {
|
||||
if (amount <= 0) return;
|
||||
EntityUtils.spawnEntity(getHandle(), new Location(getHandle(), location.x(), location.y(), location.z()), EntityType.EXPERIENCE_ORB, (e) -> {
|
||||
EntityUtils.spawnEntity(platformWorld(), new Location(platformWorld(), location.x(), location.y(), location.z()), EntityType.EXPERIENCE_ORB, (e) -> {
|
||||
ExperienceOrb orb = (ExperienceOrb) e;
|
||||
orb.setExperience(amount);
|
||||
});
|
||||
@@ -82,6 +92,6 @@ public class BukkitWorld implements World {
|
||||
|
||||
@Override
|
||||
public void playBlockSound(Vec3d location, Key sound, float volume, float pitch) {
|
||||
getHandle().playSound(new Location(null, location.x(), location.y(), location.z()), sound.toString(), SoundCategory.BLOCKS, volume, pitch);
|
||||
platformWorld().playSound(new Location(null, location.x(), location.y(), location.z()), sound.toString(), SoundCategory.BLOCKS, volume, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user