diff --git a/README.md b/README.md index ea3c73de8..d766c3f46 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ The code you contribute will be open-sourced under the GPLv3 license. If you pre ### 🌍 Translations 1. Clone this repository. -2. Create a new language file in: `/bukkit-loader/src/main/resources/translations` +2. Create a new language file in: `/bukkit/loader/src/main/resources/translations` 3. Once done, submit a **pull request** for review. We appreciate your contributions! ### 💖 Support the Developer @@ -135,7 +135,7 @@ repositories { ``` ```kotlin dependencies { - compileOnly("net.momirealms:craft-engine-core:0.0.34") - compileOnly("net.momirealms:craft-engine-bukkit:0.0.34") + compileOnly("net.momirealms:craft-engine-core:0.0.38") + compileOnly("net.momirealms:craft-engine-bukkit:0.0.38") } ``` diff --git a/bukkit/loader/src/main/resources/commands.yml b/bukkit/loader/src/main/resources/commands.yml index 58f61982f..1e4acc716 100644 --- a/bukkit/loader/src/main/resources/commands.yml +++ b/bukkit/loader/src/main/resources/commands.yml @@ -77,6 +77,13 @@ debug_set_block: - /craftengine debug setblock - /ce debug setblock +debug_spawn_furniture: + enable: true + permission: ce.command.debug.spawn_furniture + usage: + - /craftengine debug spawn-furniture + - /ce debug spawn-furniture + debug_get_block_state_registry_id: enable: true permission: ce.command.debug.get_block_state_registry_id diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/blocks.yml b/bukkit/loader/src/main/resources/resources/default/configuration/blocks.yml index e0c42419d..83a7c0c52 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/blocks.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/blocks.yml @@ -114,6 +114,86 @@ items#misc: facing_clockwise=south: appearance: axisZ id: 3 + default:gunpowder_block: + material: paper + custom-model-data: 3002 + data: + item-name: "" + model: + type: "minecraft:model" + path: "minecraft:item/custom/gunpowder_block" + generation: + parent: "minecraft:block/custom/gunpowder_block" + behavior: + type: block_item + block: + behavior: + type: concrete_powder_block + solid-block: default:solid_gunpowder_block + loot: + template: "default:loot_table/basic" + arguments: + item: default:gunpowder_block + settings: + template: + - default:sound/sand + overrides: + hardness: 0.5 + resistance: 0.5 + replaceable: false + is-redstone-conductor: true + is-suffocating: true + instrument: SNARE + map-color: 45 + item: default:gunpowder_block + state: + id: 16 + state: note_block:16 + model: + path: "minecraft:block/custom/gunpowder_block" + generation: + parent: "minecraft:block/cube_all" + textures: + "all": "minecraft:block/custom/gunpowder_block" + default:solid_gunpowder_block: + material: paper + custom-model-data: 3003 + data: + item-name: "" + model: + type: "minecraft:model" + path: "minecraft:item/custom/solid_gunpowder_block" + generation: + parent: "minecraft:block/custom/solid_gunpowder_block" + behavior: + type: block_item + block: + loot: + template: "default:loot_table/basic" + arguments: + item: default:solid_gunpowder_block + settings: + template: + - default:sound/sand + - default:pickaxe_power/level_1 + overrides: + hardness: 1.8 + resistance: 1.8 + replaceable: false + is-redstone-conductor: true + is-suffocating: true + instrument: BASEDRUM + map-color: 45 + item: default:solid_gunpowder_block + state: + id: 17 + state: note_block:17 + model: + path: "minecraft:block/custom/solid_gunpowder_block" + generation: + parent: "minecraft:block/cube_all" + textures: + "all": "minecraft:block/custom/solid_gunpowder_block" recipes#misc: default:chinese_lantern: type: shaped @@ -148,4 +228,22 @@ recipes#misc: B: "minecraft:netherite_ingot" result: id: default:netherite_anvil + count: 1 + default:gunpowder_from_block: + type: shapeless + ingredients: + A: "default:gunpowder_block" + result: + id: minecraft:gunpowder + count: 9 + default:gunpowder_block: + type: shaped + pattern: + - "AAA" + - "AAA" + - "AAA" + ingredients: + A: "minecraft:gunpowder" + result: + id: default:gunpowder_block count: 1 \ No newline at end of file diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/categories.yml b/bukkit/loader/src/main/resources/resources/default/configuration/categories.yml index da8c4c458..7df2d92c5 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/categories.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/categories.yml @@ -58,4 +58,6 @@ categories: - default:chinese_lantern - default:netherite_anvil - default:fairy_flower - - default:reed \ No newline at end of file + - default:reed + - default:gunpowder_block + - default:solid_gunpowder_block \ No newline at end of file diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/i18n.yml b/bukkit/loader/src/main/resources/resources/default/configuration/i18n.yml index a4f86bb33..c3ad09c0a 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/i18n.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/i18n.yml @@ -29,6 +29,8 @@ i18n: item.palm_sapling: "Palm Sapling" item.palm_leaves: "Palm Leaves" item.netherite_anvil: "Netherite Anvil" + item.gunpowder_block: "GunPowder Block" + item.solid_gunpowder_block: "Solid GunPowder Block" category.default.name: "Default Assets" category.default.lore: "Contains the default configuration of CraftEngine" category.palm_tree: "Palm Tree" @@ -65,6 +67,8 @@ i18n: item.palm_sapling: "棕榈树苗" item.palm_leaves: "棕榈树叶" item.netherite_anvil: "下界合金砧" + item.gunpowder_block: "火药粉末" + item.solid_gunpowder_block: "凝固火药块" category.default.name: "默认资产" category.default.lore: "包含了CraftEngine的默认配置" category.palm_tree: "棕榈树" diff --git a/bukkit/loader/src/main/resources/resources/default/resourcepack/assets/minecraft/textures/block/custom/gunpowder_block.png b/bukkit/loader/src/main/resources/resources/default/resourcepack/assets/minecraft/textures/block/custom/gunpowder_block.png new file mode 100644 index 000000000..a6705caa5 Binary files /dev/null and b/bukkit/loader/src/main/resources/resources/default/resourcepack/assets/minecraft/textures/block/custom/gunpowder_block.png differ diff --git a/bukkit/loader/src/main/resources/resources/default/resourcepack/assets/minecraft/textures/block/custom/solid_gunpowder_block.png b/bukkit/loader/src/main/resources/resources/default/resourcepack/assets/minecraft/textures/block/custom/solid_gunpowder_block.png new file mode 100644 index 000000000..0531b07a4 Binary files /dev/null and b/bukkit/loader/src/main/resources/resources/default/resourcepack/assets/minecraft/textures/block/custom/solid_gunpowder_block.png differ diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java index ddef57af8..10c928c92 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java @@ -37,6 +37,20 @@ public class CraftEngineFurniture { return BukkitFurnitureManager.instance().getFurniture(id).orElse(null); } + /** + * Places furniture at the certain location + * + * @param location location + * @param furnitureId furniture to place + * @return the loaded furniture + */ + @Nullable + public static LoadedFurniture place(Location location, Key furnitureId) { + CustomFurniture furniture = byId(furnitureId); + if (furniture == null) return null; + return place(location, furnitureId, furniture.getAnyPlacement()); + } + /** * Places furniture at the certain location * diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index f935288c9..c88b70609 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -308,10 +308,10 @@ public class BlockEventListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onBlockPhysics(BlockPhysicsEvent event) { if (!this.enableNoteBlockCheck) return; - Block block = event.getBlock(); // for vanilla blocks - if (block.getBlockData() instanceof NoteBlock) { + if (event.getChangedType() == Material.NOTE_BLOCK) { try { + Block block = event.getBlock(); World world = block.getWorld(); Location location = block.getLocation(); Block sourceBlock = event.getSourceBlock(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java index c4ca15763..fc6fd3488 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java @@ -23,5 +23,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors { register(SAPLING_BLOCK, SaplingBlockBehavior.FACTORY); register(ON_LIQUID_BLOCK, OnLiquidBlockBehavior.FACTORY); register(WATERLOGGED_BLOCK, WaterLoggedBlockBehavior.FACTORY); + register(CONCRETE_POWDER_BLOCK, ConcretePowderBlockBehavior.FACTORY); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java index d3013442a..6de0a63b8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java @@ -8,6 +8,7 @@ import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.bukkit.world.BukkitWorld; 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.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.loot.parameter.LootParameters; @@ -24,7 +25,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Callable; -public class BushBlockBehavior extends BlockBehavior { +public class BushBlockBehavior extends AbstractBlockBehavior { public static final Factory FACTORY = new Factory(); protected static final Object DIRT_TAG = BlockTags.getOrCreate(Key.of("minecraft", "dirt")); protected static final Object FARMLAND = BlockTags.getOrCreate(Key.of("minecraft", "farmland")); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java index 563eac99d..5ebdc11dc 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java @@ -1,13 +1,157 @@ package net.momirealms.craftengine.bukkit.block.behavior; -public class ConcretePowderBlockBehavior extends FallingBlockBehavior { +import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.bukkit.util.EventUtils; +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.EmptyBlock; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.UpdateOption; +import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; +import net.momirealms.craftengine.core.item.context.BlockPlaceContext; +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.shared.block.BlockBehavior; +import org.bukkit.block.BlockState; +import org.bukkit.event.block.BlockFormEvent; - public ConcretePowderBlockBehavior(float hurtAmount, int maxHurt) { +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.Callable; + +public class ConcretePowderBlockBehavior extends FallingBlockBehavior { + public static final Factory FACTORY = new Factory(); + private final Key targetBlock; + private Object defaultBlockState; + private ImmutableBlockState defaultImmutableBlockState; + + public ConcretePowderBlockBehavior(float hurtAmount, int maxHurt, Key block) { super(hurtAmount, maxHurt); + this.targetBlock = block; + } + + public ImmutableBlockState defaultImmutableBlockState() { + if (this.defaultImmutableBlockState == null) { + this.getDefaultBlockState(); + } + return this.defaultImmutableBlockState; + } + + public Object getDefaultBlockState() { + if (this.defaultBlockState != null) { + return this.defaultBlockState; + } + Optional optionalCustomBlock = BukkitBlockManager.instance().getBlock(this.targetBlock); + if (optionalCustomBlock.isPresent()) { + CustomBlock customBlock = optionalCustomBlock.get(); + this.defaultBlockState = customBlock.defaultState().customBlockState().handle(); + this.defaultImmutableBlockState = customBlock.defaultState(); + } else { + CraftEngine.instance().logger().warn("Failed to create solid block " + this.targetBlock + " in ConcretePowderBlockBehavior"); + this.defaultBlockState = Reflections.instance$Blocks$STONE$defaultState; + this.defaultImmutableBlockState = EmptyBlock.INSTANCE.defaultState(); + } + return this.defaultBlockState; + } + + @Override + public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { + Object level = context.getLevel().serverWorld(); + Object blockPos = LocationUtils.toBlockPos(context.getClickedPos()); + try { + Object previousState = Reflections.method$BlockGetter$getBlockState.invoke(level, blockPos); + if (!shouldSolidify(level, blockPos, previousState)) { + return super.updateStateForPlacement(context, state); + } else { + BlockState craftBlockState = (BlockState) Reflections.method$CraftBlockStates$getBlockState.invoke(null, level, blockPos); + craftBlockState.setBlockData(BlockStateUtils.fromBlockData(getDefaultBlockState())); + BlockFormEvent event = new BlockFormEvent(craftBlockState.getBlock(), craftBlockState); + if (!EventUtils.fireAndCheckCancel(event)) { + return defaultImmutableBlockState(); + } else { + return super.updateStateForPlacement(context, state); + } + } + } catch (ReflectiveOperationException e) { + CraftEngine.instance().logger().warn("Failed to update state for placement " + context.getClickedPos(), e); + } + return super.updateStateForPlacement(context, state); } @Override public void onLand(Object thisBlock, Object[] args) throws Exception { - super.onLand(thisBlock, args); + Object world = args[0]; + Object blockPos = args[1]; + Object replaceableState = args[3]; + if (shouldSolidify(world, blockPos, replaceableState)) { + Reflections.method$CraftEventFactory$handleBlockFormEvent.invoke(null, world, blockPos, getDefaultBlockState(), UpdateOption.UPDATE_ALL.flags()); + } + } + + @Override + public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + Object level = args[1]; + Object pos = args[3]; + if (touchesLiquid(level, pos)) { + if (!Reflections.clazz$Level.isInstance(level)) { + return getDefaultBlockState(); + } else { + BlockState craftBlockState = (BlockState) Reflections.method$CraftBlockStates$getBlockState.invoke(null, level, pos); + craftBlockState.setBlockData(BlockStateUtils.fromBlockData(getDefaultBlockState())); + BlockFormEvent event = new BlockFormEvent(craftBlockState.getBlock(), craftBlockState); + if (!EventUtils.fireAndCheckCancel(event)) { + return Reflections.method$CraftBlockState$getHandle.invoke(craftBlockState); + } + } + } + return super.updateShape(thisBlock, args, superMethod); + } + + private static boolean shouldSolidify(Object level, Object blockPos, Object blockState) throws ReflectiveOperationException { + return canSolidify(blockState) || touchesLiquid(level, blockPos); + } + + private static boolean canSolidify(Object state) throws ReflectiveOperationException { + Object fluidState = Reflections.field$BlockStateBase$fluidState.get(state); + if (fluidState == null) return false; + Object fluidType = Reflections.method$FluidState$getType.invoke(fluidState); + return fluidType == Reflections.instance$Fluids$WATER || fluidType == Reflections.instance$Fluids$FLOWING_WATER; + } + + private static boolean touchesLiquid(Object level, Object pos) throws ReflectiveOperationException { + boolean flag = false; + Object mutablePos = Reflections.method$BlockPos$mutable.invoke(pos); + int j = Direction.values().length; + for (int k = 0; k < j; k++) { + Object direction = Reflections.instance$Directions[k]; + Object blockState = Reflections.method$BlockGetter$getBlockState.invoke(level, mutablePos); + if (direction != Reflections.instance$Direction$DOWN || canSolidify(blockState)) { + Reflections.method$MutableBlockPos$setWithOffset.invoke(mutablePos, pos, direction); + blockState = Reflections.method$BlockGetter$getBlockState.invoke(level, mutablePos); + if (canSolidify(blockState) && !(boolean) Reflections.method$BlockStateBase$isFaceSturdy.invoke(blockState, level, pos, Reflections.getOppositeDirection(direction), Reflections.instance$SupportType$FULL)) { + flag = true; + break; + } + } + } + return flag; + } + + public static class Factory implements BlockBehaviorFactory { + + @Override + public BlockBehavior create(CustomBlock block, Map arguments) { + float hurtAmount = MiscUtils.getAsFloat(arguments.getOrDefault("hurt-amount", -1f)); + int hurtMax = MiscUtils.getAsInt(arguments.getOrDefault("max-hurt", -1)); + String solidBlock = (String) arguments.get("solid-block"); + if (solidBlock == null) { + throw new IllegalArgumentException("No `solid-block` specified for concrete powder block behavior"); + } + return new ConcretePowderBlockBehavior(hurtAmount, hurtMax, Key.of(solidBlock)); + } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java index 30d7c08f2..9517544c6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java @@ -7,6 +7,7 @@ import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.bukkit.world.BukkitWorld; 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.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.loot.parameter.LootParameters; @@ -20,7 +21,7 @@ import org.bukkit.World; import java.util.Map; import java.util.concurrent.Callable; -public class FallingBlockBehavior extends BlockBehavior { +public class FallingBlockBehavior extends AbstractBlockBehavior { public static final Factory FACTORY = new Factory(); private final float hurtAmount; private final int maxHurt; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StrippableBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StrippableBlockBehavior.java index fae1a2f5f..6d0429c37 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StrippableBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StrippableBlockBehavior.java @@ -1,13 +1,14 @@ package net.momirealms.craftengine.bukkit.block.behavior; import net.momirealms.craftengine.core.block.CustomBlock; +import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.shared.block.BlockBehavior; import java.util.Map; -public class StrippableBlockBehavior extends BlockBehavior { +public class StrippableBlockBehavior extends AbstractBlockBehavior { public static final Factory FACTORY = new Factory(); private final Key stripped; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java index 1f77a5a10..2cdc56660 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.bukkit.block.behavior; import net.momirealms.craftengine.core.block.CustomBlock; +import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.shared.block.BlockBehavior; @@ -8,7 +9,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; -public class WaterLoggedBlockBehavior extends BlockBehavior { +public class WaterLoggedBlockBehavior extends AbstractBlockBehavior { public static final Factory FACTORY = new Factory(); @Nullable private final Property waterloggedProperty; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditCommandHelper.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditCommandHelper.java index 31d3f331d..cdd32e55d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditCommandHelper.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditCommandHelper.java @@ -12,7 +12,9 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; // TODO A better command suggestion system public class WorldEditCommandHelper implements Listener { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index 7614ca1f9..96129b367 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -16,6 +16,7 @@ import org.bukkit.entity.*; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.persistence.PersistentDataType; +import org.incendo.cloud.suggestion.Suggestion; import org.jetbrains.annotations.NotNull; import org.joml.Vector3f; @@ -41,6 +42,8 @@ public class BukkitFurnitureManager implements FurnitureManager { private final FurnitureEventListener furnitureEventListener; // tick task private SchedulerTask tickTask; + // Cached command suggestions + private final List cachedSuggestions = new ArrayList<>(); public static BukkitFurnitureManager instance() { return instance; @@ -54,10 +57,14 @@ public class BukkitFurnitureManager implements FurnitureManager { } public LoadedFurniture place(CustomFurniture furniture, Location location, AnchorType anchorType, boolean playSound) { + if (furniture.isAllowedPlacement(anchorType)) { + anchorType = furniture.getAnyPlacement(); + } + AnchorType finalAnchorType = anchorType; Entity furnitureEntity = EntityUtils.spawnEntity(location.getWorld(), location, EntityType.ITEM_DISPLAY, entity -> { ItemDisplay display = (ItemDisplay) entity; display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_KEY, PersistentDataType.STRING, furniture.id().toString()); - display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_ANCHOR_KEY, PersistentDataType.STRING, anchorType.name()); + display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_ANCHOR_KEY, PersistentDataType.STRING, finalAnchorType.name()); handleEntityLoadEarly(display); }); if (playSound) { @@ -67,6 +74,24 @@ public class BukkitFurnitureManager implements FurnitureManager { return getLoadedFurnitureByBaseEntityId(furnitureEntity.getEntityId()); } + @Override + public void delayedLoad() { + this.initSuggestions(); + } + + @Override + public void initSuggestions() { + this.cachedSuggestions.clear(); + for (Key key : this.byId.keySet()) { + this.cachedSuggestions.add(Suggestion.suggestion(key.toString())); + } + } + + @Override + public Collection cachedSuggestions() { + return Collections.unmodifiableCollection(this.cachedSuggestions); + } + @SuppressWarnings("unchecked") @Override public void parseSection(Pack pack, Path path, Key id, Map section) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java index e7dfd93e0..f0dec7311 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java @@ -23,7 +23,6 @@ import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.Pair; import net.momirealms.craftengine.core.world.Vec3d; import org.bukkit.Location; -import org.bukkit.SoundCategory; import org.bukkit.World; import java.nio.file.Path; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java index fc5b6b2a5..da00efaa4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java @@ -4,7 +4,6 @@ import net.momirealms.antigrieflib.AntiGriefLib; import net.momirealms.craftengine.bukkit.api.event.CraftEngineReloadEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.block.behavior.BukkitBlockBehaviors; -import net.momirealms.craftengine.bukkit.block.worldedit.WorldEditCommandHelper; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.font.BukkitImageManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java index 1c859475f..ec38a6f81 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java @@ -44,6 +44,7 @@ public class BukkitCommandManager extends AbstractCommandManager new DebugRealStateUsageCommand(this, plugin), new DebugItemDataCommand(this, plugin), new DebugSetBlockCommand(this, plugin), + new DebugSpawnFurnitureCommand(this, plugin), new DebugTargetBlockCommand(this, plugin) )); final LegacyPaperCommandManager manager = (LegacyPaperCommandManager) getCommandManager(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DebugSpawnFurnitureCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DebugSpawnFurnitureCommand.java new file mode 100644 index 000000000..f5bbb5a8f --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DebugSpawnFurnitureCommand.java @@ -0,0 +1,66 @@ +package net.momirealms.craftengine.bukkit.plugin.command.feature; + +import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; +import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.bukkit.util.KeyUtils; +import net.momirealms.craftengine.core.entity.furniture.AnchorType; +import net.momirealms.craftengine.core.entity.furniture.CustomFurniture; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; +import net.momirealms.craftengine.core.plugin.command.FlagKeys; +import net.momirealms.craftengine.core.util.Key; +import org.bukkit.Location; +import org.bukkit.NamespacedKey; +import org.bukkit.command.CommandSender; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.parser.NamespacedKeyParser; +import org.incendo.cloud.bukkit.parser.location.LocationParser; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.parser.standard.EnumParser; +import org.incendo.cloud.suggestion.Suggestion; +import org.incendo.cloud.suggestion.SuggestionProvider; + +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +public class DebugSpawnFurnitureCommand extends BukkitCommandFeature { + + public DebugSpawnFurnitureCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { + super(commandManager, plugin); + } + + @Override + public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { + return builder + .required("location", LocationParser.locationParser()) + .required("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() { + @Override + public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { + return CompletableFuture.completedFuture(plugin().furnitureManager().cachedSuggestions()); + } + })) + .optional("anchor-type", EnumParser.enumParser(AnchorType.class)) + .flag(FlagKeys.SILENT_FLAG) + .handler(context -> { + NamespacedKey namespacedKey = context.get("id"); + Key id = KeyUtils.namespacedKey2Key(namespacedKey); + BukkitFurnitureManager furnitureManager = BukkitFurnitureManager.instance(); + Optional optionalCustomFurniture = furnitureManager.getFurniture(id); + if (optionalCustomFurniture.isEmpty()) { + return; + } + Location location = context.get("location"); + CustomFurniture customFurniture = optionalCustomFurniture.get(); + AnchorType anchorType = (AnchorType) context.optional("anchor-type").orElse(customFurniture.getAnyPlacement()); + boolean playSound = context.flags().hasFlag("silent"); + furnitureManager.place(customFurniture, location, anchorType, !playSound); + }); + } + + @Override + public String getFeatureID() { + return "debug_spawn_furniture"; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java index d30c22073..69cd69ccf 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java @@ -49,7 +49,6 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -589,16 +588,6 @@ public class BukkitInjector { } } - public static class PalettedContainerMethodInterceptor { - public static final PalettedContainerMethodInterceptor INSTANCE = new PalettedContainerMethodInterceptor(); - - @RuntimeType - public Object intercept(@This Object thisObj, @AllArguments Object[] args, @Origin Method method) throws Throwable { - InjectedPalettedContainerHolder holder = (InjectedPalettedContainerHolder) thisObj; - return method.invoke(holder.target(), args); - } - } - public static class GetAndSetInterceptor { public static final GetAndSetInterceptor INSTANCE = new GetAndSetInterceptor(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/OptimizedReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/OptimizedReflections.java new file mode 100644 index 000000000..211da4037 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/OptimizedReflections.java @@ -0,0 +1,6 @@ +package net.momirealms.craftengine.bukkit.util; + +public class OptimizedReflections { + + +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 82b91b1db..707181184 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -1488,18 +1488,37 @@ public class Reflections { public static final Object instance$Direction$DOWN; public static final Object instance$Direction$UP; + public static final Object instance$Direction$NORTH; + public static final Object instance$Direction$SOUTH; + public static final Object instance$Direction$WEST; + public static final Object instance$Direction$EAST; public static final Object[] instance$Directions; + private static final Map oppositeDirections = new HashMap<>(); static { try { instance$Directions = (Object[]) method$Direction$values.invoke(null); instance$Direction$DOWN = instance$Directions[0]; instance$Direction$UP = instance$Directions[1]; + instance$Direction$NORTH = instance$Directions[2]; + instance$Direction$SOUTH = instance$Directions[3]; + instance$Direction$WEST = instance$Directions[4]; + instance$Direction$EAST = instance$Directions[5]; + oppositeDirections.put(instance$Direction$DOWN, instance$Direction$UP); + oppositeDirections.put(instance$Direction$UP, instance$Direction$DOWN); + oppositeDirections.put(instance$Direction$NORTH, instance$Direction$SOUTH); + oppositeDirections.put(instance$Direction$SOUTH, instance$Direction$NORTH); + oppositeDirections.put(instance$Direction$WEST, instance$Direction$EAST); + oppositeDirections.put(instance$Direction$EAST, instance$Direction$WEST); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } } + public static Object getOppositeDirection(Object direction) { + return oppositeDirections.get(direction); + } + public static final Class clazz$CraftBlock = requireNonNull( ReflectionUtils.getClazz( BukkitReflectionUtils.assembleCBClass("block.CraftBlock") @@ -1536,6 +1555,12 @@ public class Reflections { ) ); + public static final Method method$CraftBlockState$getHandle = requireNonNull( + ReflectionUtils.getMethod( + clazz$CraftBlockState, clazz$BlockState + ) + ); + public static final Class clazz$CraftBlockData = requireNonNull( ReflectionUtils.getClazz( BukkitReflectionUtils.assembleCBClass("block.data.CraftBlockData") @@ -3452,6 +3477,12 @@ public class Reflections { ) ); + public static final Method method$BlockPos$mutable = requireNonNull( + ReflectionUtils.getMethod( + clazz$BlockPos, clazz$MutableBlockPos + ) + ); + public static final Class clazz$LeavesBlock = requireNonNull( ReflectionUtils.getClazz( BukkitReflectionUtils.assembleMCClass("world.level.block.LeavesBlock"), @@ -3944,15 +3975,21 @@ public class Reflections { ); public static final Object instance$Fluids$WATER; + public static final Object instance$Fluids$FLOWING_WATER; public static final Object instance$Fluids$LAVA; + public static final Object instance$Fluids$FLOWING_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 flowingWaterId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "flowing_water"); + instance$Fluids$FLOWING_WATER = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, flowingWaterId); Object lavaId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "lava"); instance$Fluids$LAVA = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, lavaId); + Object flowingLavaId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "flowing_lava"); + instance$Fluids$FLOWING_LAVA = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, flowingLavaId); Object emptyId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "empty"); instance$Fluids$EMPTY = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, emptyId); } catch (ReflectiveOperationException e) { @@ -5497,6 +5534,45 @@ public class Reflections { ) ); + public static final Class clazz$SupportType = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("world.level.block.SupportType") + ) + ); + + public static final Method method$SupportType$values = requireNonNull( + ReflectionUtils.getStaticMethod( + clazz$SupportType, clazz$SupportType.arrayType() + ) + ); + + public static final Object instance$SupportType$FULL; + public static final Object instance$SupportType$CENTER; + public static final Object instance$SupportType$RIGID; + + static { + try { + Object[] values = (Object[]) method$SupportType$values.invoke(null); + instance$SupportType$FULL = values[0]; + instance$SupportType$CENTER = values[1]; + instance$SupportType$RIGID = values[2]; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public static final Method method$BlockStateBase$isFaceSturdy = requireNonNull( + ReflectionUtils.getMethod( + clazz$BlockStateBase, boolean.class, clazz$BlockGetter, clazz$BlockPos, clazz$Direction, clazz$SupportType + ) + ); + + public static final Method method$CraftEventFactory$handleBlockFormEvent = requireNonNull( + ReflectionUtils.getStaticMethod( + clazz$CraftEventFactory, boolean.class, new String[] { "handleBlockFormEvent" }, clazz$Level, clazz$BlockPos, clazz$BlockState, int.class + ) + ); + public static final Constructor constructor$ClientboundLevelChunkWithLightPacket = requireNonNull( ReflectionUtils.getConstructor( clazz$ClientboundLevelChunkWithLightPacket, clazz$LevelChunk, clazz$LevelLightEngine, BitSet.class, BitSet.class diff --git a/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java b/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java index 00572f0ba..1eb473f1a 100644 --- a/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java +++ b/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java @@ -5,8 +5,6 @@ import net.fabricmc.loader.api.FabricLoader; import net.minecraft.block.BlockState; import net.minecraft.block.piston.PistonBehavior; import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.shape.VoxelShape; import net.momirealms.craftengine.fabric.client.config.ModConfig; import net.momirealms.craftengine.fabric.util.BlockUtils; import net.momirealms.craftengine.fabric.util.LoggerFilter; diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/CustomBlock.java b/core/src/main/java/net/momirealms/craftengine/core/block/CustomBlock.java index 95c79dfad..89c09e11c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/CustomBlock.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/CustomBlock.java @@ -1,5 +1,6 @@ package 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.item.context.BlockPlaceContext; @@ -153,7 +154,9 @@ public abstract class CustomBlock { for (BiFunction placement : this.placements) { state = placement.apply(context, state); } - state = (ImmutableBlockState) this.behavior.updateStateForPlacement(context, state); + if (this.behavior instanceof AbstractBlockBehavior blockBehavior) { + state = blockBehavior.updateStateForPlacement(context, state); + } return state; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/behavior/AbstractBlockBehavior.java b/core/src/main/java/net/momirealms/craftengine/core/block/behavior/AbstractBlockBehavior.java new file mode 100644 index 000000000..948700454 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/block/behavior/AbstractBlockBehavior.java @@ -0,0 +1,12 @@ +package net.momirealms.craftengine.core.block.behavior; + +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.item.context.BlockPlaceContext; +import net.momirealms.craftengine.shared.block.BlockBehavior; + +public abstract class AbstractBlockBehavior extends BlockBehavior { + + public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { + return state; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java index ada46b3c4..5cb3f595d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java @@ -4,12 +4,20 @@ import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.plugin.Reloadable; import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; import net.momirealms.craftengine.core.util.Key; +import org.incendo.cloud.suggestion.Suggestion; +import java.util.Collection; import java.util.Optional; public interface FurnitureManager extends Reloadable, ConfigSectionParser { String CONFIG_SECTION_NAME = "furniture"; + void delayedLoad(); + + void initSuggestions(); + + Collection cachedSuggestions(); + void delayedInit(); @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index b40ec0909..6add299f1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -284,6 +284,8 @@ public abstract class AbstractPackManager implements PackManager { plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/chinese_lantern_top.png.mcmeta"); plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/netherite_anvil.png"); plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/netherite_anvil_top.png"); + plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/solid_gunpowder_block.png"); + plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/gunpowder_block.png"); // items plugin.saveResource("resources/default/configuration/items.yml"); plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/topaz_rod.png"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index 46da0bb76..5e3792702 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -105,6 +105,7 @@ public abstract class CraftEngine implements Plugin { // load at last this.guiManager.reload(); this.blockManager.delayedLoad(); + this.furnitureManager.delayedLoad(); this.itemBrowserManager.delayedLoad(); this.soundManager.delayedLoad(); this.imageManager.delayedLoad(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java index 77b5c2d1e..28f2b5822 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java @@ -3,12 +3,15 @@ package net.momirealms.craftengine.core.util; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ReflectionUtils { + private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); private ReflectionUtils() {} @@ -446,4 +449,22 @@ public class ReflectionUtils { } return constructors[0]; } + + public static MethodHandle unreflectGetter(Field field) throws IllegalAccessException { + try { + return LOOKUP.unreflectGetter(field); + } catch (IllegalAccessException e) { + field.setAccessible(true); + return LOOKUP.unreflectGetter(field); + } + } + + public static MethodHandle unreflectMethod(Method method) throws IllegalAccessException { + try { + return LOOKUP.unreflect(method); + } catch (IllegalAccessException e) { + method.setAccessible(true); + return LOOKUP.unreflect(method); + } + } } diff --git a/readme/README_zh-CN.md b/readme/README_zh-CN.md index 30e371948..e5a08026c 100644 --- a/readme/README_zh-CN.md +++ b/readme/README_zh-CN.md @@ -105,7 +105,7 @@ CraftEngine 的实现依赖于以下基础库: ### 🌍 翻译 1. 克隆此仓库。 -2. 在 `/bukkit-loader/src/main/resources/translations` 中创建一个新的语言文件。 +2. 在 `/bukkit/loader/src/main/resources/translations` 中创建一个新的语言文件。 3. 完成后,提交 **pull request** 以供审核。我们感谢您的贡献! ### 💖 支持开发者 @@ -126,7 +126,7 @@ repositories { ``` ```kotlin dependencies { - compileOnly("net.momirealms:craft-engine-core:0.0.29") - compileOnly("net.momirealms:craft-engine-bukkit:0.0.29") + compileOnly("net.momirealms:craft-engine-core:0.0.38") + compileOnly("net.momirealms:craft-engine-bukkit:0.0.38") } ``` diff --git a/readme/README_zh-TW.md b/readme/README_zh-TW.md index 0ed3cbe95..9191c8b3b 100644 --- a/readme/README_zh-TW.md +++ b/readme/README_zh-TW.md @@ -105,7 +105,7 @@ CraftEngine 的實現依賴於以下基礎庫: ### 🌍 翻譯 1. 克隆此倉庫。 -2. 在 '/bukkit-loader/src/main/resources/translations' 中創建一個新的語言檔。 +2. 在 '/bukkit/loader/src/main/resources/translations' 中創建一個新的語言檔。 3. 完成後,提交 **pull request** 以供審核。我們感謝您的貢獻! ### 💖 支持開發者 @@ -126,7 +126,7 @@ repositories { ``` ```kotlin dependencies { - compileOnly("net.momirealms:craft-engine-core:0.0.29") - compileOnly("net.momirealms:craft-engine-bukkit:0.0.29") + compileOnly("net.momirealms:craft-engine-core:0.0.38") + compileOnly("net.momirealms:craft-engine-bukkit:0.0.38") } ``` diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java index 54effc4b0..134ce71e2 100644 --- a/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java @@ -10,16 +10,15 @@ import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.ScheduledTickAccess; -import net.minecraft.world.level.block.Block; -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.*; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import net.momirealms.craftengine.mod.util.NoteBlockUtils; import net.momirealms.craftengine.shared.ObjectHolder; import net.momirealms.craftengine.shared.block.*; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.event.block.BlockPhysicsEvent; import org.jetbrains.annotations.NotNull; public class CraftEngineBlock diff --git a/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockBehavior.java b/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockBehavior.java index c96ae499e..957e207d2 100644 --- a/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockBehavior.java +++ b/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockBehavior.java @@ -41,10 +41,6 @@ public abstract class BlockBehavior { public void performBoneMeal(Object thisBlock, Object[] args) throws Exception { } - public Object updateStateForPlacement(Object context, Object state) { - return state; - } - // // public Object getFluidState(Object thisBlock, Object[] args, Callable superMethod) throws Exception { // return superMethod.call();