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

准备大改交互判断

This commit is contained in:
XiaoMoMi
2025-10-10 19:28:43 +08:00
parent 9a45fa5ecc
commit faedac3957
11 changed files with 21 additions and 210 deletions

View File

@@ -4,7 +4,8 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import net.momirealms.craftengine.bukkit.item.behavior.*;
import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior;
import net.momirealms.craftengine.bukkit.item.behavior.FlintAndSteelItemBehavior;
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
import net.momirealms.craftengine.bukkit.item.listener.ArmorEventListener;
import net.momirealms.craftengine.bukkit.item.listener.DebugStickListener;
@@ -39,9 +40,6 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
static {
registerVanillaItemExtraBehavior(FlintAndSteelItemBehavior.INSTANCE, ItemKeys.FLINT_AND_STEEL);
registerVanillaItemExtraBehavior(AxeItemBehavior.INSTANCE, ItemKeys.AXES);
registerVanillaItemExtraBehavior(CompassItemBehavior.INSTANCE, ItemKeys.COMPASS);
registerVanillaItemExtraBehavior(EnderEyeItemBehavior.INSTANCE, ItemKeys.ENDER_EYE);
registerVanillaItemExtraBehavior(EndCrystalItemBehavior.INSTANCE, ItemKeys.END_CRYSTAL);
}
private static BukkitItemManager instance;

View File

@@ -13,9 +13,6 @@ public class BukkitItemBehaviors extends ItemBehaviors {
public static final Key AXE_ITEM = Key.from("craftengine:axe_item");
public static final Key DOUBLE_HIGH_BLOCK_ITEM = Key.from("craftengine:double_high_block_item");
public static final Key WALL_BLOCK_ITEM = Key.from("craftengine:wall_block_item");
public static final Key COMPASS_ITEM = Key.from("craftengine:compass_item");
public static final Key ENDER_EYE_ITEM = Key.from("craftengine:ender_eye_item");
public static final Key END_CRYSTAL_ITEM = Key.from("craftengine:end_crystal_item");
public static void init() {
register(EMPTY, EmptyItemBehavior.FACTORY);
@@ -27,8 +24,5 @@ public class BukkitItemBehaviors extends ItemBehaviors {
register(AXE_ITEM, AxeItemBehavior.FACTORY);
register(DOUBLE_HIGH_BLOCK_ITEM, DoubleHighBlockItemBehavior.FACTORY);
register(WALL_BLOCK_ITEM, WallBlockItemBehavior.FACTORY);
register(COMPASS_ITEM, CompassItemBehavior.FACTORY);
register(ENDER_EYE_ITEM, EnderEyeItemBehavior.FACTORY);
register(END_CRYSTAL_ITEM, EndCrystalItemBehavior.FACTORY);
}
}

View File

@@ -1,40 +0,0 @@
package net.momirealms.craftengine.bukkit.item.behavior;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
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 org.bukkit.block.data.BlockData;
import java.nio.file.Path;
import java.util.Map;
public class CompassItemBehavior extends ItemBehavior {
public static final CompassItemBehavior INSTANCE = new CompassItemBehavior();
public static final CompassItemBehavior.Factory FACTORY = new CompassItemBehavior.Factory();
@Override
public InteractionResult useOnBlock(UseOnContext context) {
BukkitExistingBlock block = (BukkitExistingBlock) context.getLevel().getBlockAt(context.getClickedPos());
BlockData blockData = block.block().getBlockData();
Object blockOwner = BlockStateUtils.getBlockOwner(BlockStateUtils.blockDataToBlockState(blockData));
if (blockOwner != MBlocks.LODESTONE) {
return InteractionResult.PASS;
} else {
return InteractionResult.SUCCESS;
}
}
public static class Factory implements ItemBehaviorFactory {
@Override
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
return INSTANCE;
}
}
}

View File

@@ -1,90 +0,0 @@
package net.momirealms.craftengine.bukkit.item.behavior;
import net.momirealms.craftengine.bukkit.entity.BukkitEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.core.entity.Entity;
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 net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.collision.AABB;
import org.bukkit.GameMode;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.util.BoundingBox;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class EndCrystalItemBehavior extends ItemBehavior {
public static final EndCrystalItemBehavior INSTANCE = new EndCrystalItemBehavior();
public static final EndCrystalItemBehavior.Factory FACTORY = new EndCrystalItemBehavior.Factory();
@Override
public InteractionResult useOnBlock(UseOnContext context) {
World world = context.getLevel();
BlockPos blockPos = context.getClickedPos();
BukkitExistingBlock block = (BukkitExistingBlock) world.getBlockAt(blockPos);
BlockData blockData = block.block().getBlockData();
Object blockOwner = BlockStateUtils.getBlockOwner(BlockStateUtils.blockDataToBlockState(blockData));
if (blockOwner != MBlocks.OBSIDIAN && blockOwner != MBlocks.BEDROCK) {
return InteractionResult.PASS;
} else {
BlockPos abovePos = blockPos.above();
BukkitExistingBlock aboveBlock = (BukkitExistingBlock) world.getBlockAt(abovePos);
BlockData aboveBlockData = aboveBlock.block().getBlockData();
Object aboveBlockOwner = BlockStateUtils.getBlockOwner(BlockStateUtils.blockDataToBlockState(aboveBlockData));
if (aboveBlockOwner != MBlocks.AIR) {
return InteractionResult.PASS;
} else {
double x = abovePos.x();
double y = abovePos.y();
double z = abovePos.z();
Object level = world.serverWorld();
org.bukkit.World bukkitWorld = (org.bukkit.World) world.platformWorld();
AABB aabb = new AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0);
BoundingBox bukkitAABB = new BoundingBox(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ);
// 忽略旁观者
List<Entity> entities = new ArrayList<>();
for (org.bukkit.entity.Entity bukkitEntity : bukkitWorld.getNearbyEntities(bukkitAABB)) {
if (bukkitEntity instanceof Player player && player.getGameMode().equals(GameMode.SPECTATOR)) {
continue;
}
Entity entity = new BukkitEntity(bukkitEntity);
entities.add(entity);
}
// 检测家具实体
List<AABB> detectionAABBs = List.of(aabb);
List<Object> nmsAABBs = detectionAABBs.stream()
.map(aabbs -> FastNMS.INSTANCE.constructor$AABB(aabbs.minX, aabbs.minY, aabbs.minZ, aabbs.maxX, aabbs.maxY, aabbs.maxZ))
.toList();
boolean hasEntities = FastNMS.INSTANCE.checkEntityCollision(level, nmsAABBs, x + 0.5, y, z + 0.5);
if (!entities.isEmpty() || !hasEntities) {
return InteractionResult.PASS;
} else {
return InteractionResult.SUCCESS;
}
}
}
}
public static class Factory implements ItemBehaviorFactory {
@Override
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
return INSTANCE;
}
}
}

View File

@@ -1,41 +0,0 @@
package net.momirealms.craftengine.bukkit.item.behavior;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
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 org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.EndPortalFrame;
import java.nio.file.Path;
import java.util.Map;
public class EnderEyeItemBehavior extends ItemBehavior {
public static final EnderEyeItemBehavior INSTANCE = new EnderEyeItemBehavior();
public static final EnderEyeItemBehavior.Factory FACTORY = new EnderEyeItemBehavior.Factory();
@Override
public InteractionResult useOnBlock(UseOnContext context) {
BukkitExistingBlock block = (BukkitExistingBlock) context.getLevel().getBlockAt(context.getClickedPos());
BlockData blockData = block.block().getBlockData();
Object blockOwner = BlockStateUtils.getBlockOwner(BlockStateUtils.blockDataToBlockState(blockData));
if (blockOwner != MBlocks.END_PORTAL_FRAME || (blockData instanceof EndPortalFrame endPortalFrame && endPortalFrame.hasEye())) {
return InteractionResult.PASS;
} else {
return InteractionResult.SUCCESS;
}
}
public static class Factory implements ItemBehaviorFactory {
@Override
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
return INSTANCE;
}
}
}

View File

@@ -285,14 +285,10 @@ public class ItemEventListener implements Listener {
}
// custom item
else {
if (optionalCustomItem.get().settings().canPlaceRelatedVanillaBlock()) {
// 如果用户设置了允许放置对应的原版方块,那么直接返回。
// 这种情况下最好是return以避免同时触发多个behavior发生冲突
// 当用户选择其作为原版方块放下时,自定义行为可能已经不重要了?
return;
} else {
// todo 实际上这里的处理并不正确,因为判断玩家是否能够放置那个方块需要更加细节的判断。比如玩家无法对着树叶放置火把,但是交互事件依然触发,此情况下不可丢弃自定义行为。
if (optionalCustomItem.get().settings().disableVanillaBehavior()) {
// 允许尝试放置方块
if (serverPlayer.isSecondaryUseActive() || !InteractUtils.isInteractable(player, blockData, hitResult, itemInHand)) {
// todo 检测不可以放置方块
event.setCancelled(true);
}
}

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.bukkit.util;
import io.papermc.paper.entity.Shearable;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.item.behavior.BlockItemBehavior;
import net.momirealms.craftengine.bukkit.item.behavior.EnderEyeItemBehavior;
import net.momirealms.craftengine.bukkit.item.behavior.FlintAndSteelItemBehavior;
import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
@@ -168,13 +167,8 @@ public final class InteractUtils {
});
registerInteraction(BlockKeys.DRAGON_EGG, (player, item, blockState, result) -> true);
registerInteraction(BlockKeys.END_PORTAL_FRAME, (player, item, blockState, result) -> {
Optional<List<ItemBehavior>> behaviors = item.getItemBehavior();
if (behaviors.isPresent()) {
for (ItemBehavior behavior : behaviors.get()) {
if (behavior instanceof EnderEyeItemBehavior) return true;
}
}
return false;
Key id = item.vanillaId();
return ItemKeys.ENDER_EYE.equals(id);
});
registerInteraction(BlockKeys.VAULT, (player, item, blockState, result) -> blockState instanceof Vault vault && vault.getVaultState() == Vault.State.ACTIVE);
registerInteraction(BlockKeys.SPAWNER, (player, item, blockState, result) -> {

View File

@@ -75,7 +75,6 @@ public final class BlockKeys {
public static final Key CRAFTER = Key.of("minecraft:crafter");
public static final Key HOPPER = Key.of("minecraft:hopper");
public static final Key OBSERVER = Key.of("minecraft:observer");
public static final Key NOTE_BLOCK = Key.of("minecraft:note_block");
public static final Key DETECTOR_RAIL = Key.of("minecraft:detector_rail");
public static final Key TNT = Key.of("minecraft:tnt");
public static final Key REDSTONE_ORE = Key.of("minecraft:redstone_ore");
@@ -304,8 +303,6 @@ public final class BlockKeys {
public static final Key BAMBOO_WALL_HANGING_SIGN = Key.of("minecraft:bamboo_wall_hanging_sign");
public static final Key CRIMSON_WALL_HANGING_SIGN = Key.of("minecraft:crimson_wall_hanging_sign");
public static final Key WARPED_WALL_HANGING_SIGN = Key.of("minecraft:warped_wall_hanging_sign");
public static final Key CACTUS = Key.of("minecraft:cactus");
public static final Key BROWN_MUSHROOM_BLOCK = Key.of("minecraft:brown_mushroom_block");
public static final Key RED_MUSHROOM_BLOCK = Key.of("minecraft:red_mushroom_block");

View File

@@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.block;
import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElement;
import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfig;
import net.momirealms.craftengine.core.util.Key;
import java.util.Optional;

View File

@@ -569,11 +569,11 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
try {
settings = Optional.ofNullable(ResourceConfigUtils.get(section, "settings"))
.map(map -> ItemSettings.fromMap(MiscUtils.castToMap(map, true)))
.map(it -> isVanillaItem ? it.canPlaceRelatedVanillaBlock(true) : it)
.orElse(ItemSettings.of().canPlaceRelatedVanillaBlock(isVanillaItem));
.map(it -> isVanillaItem ? it.disableVanillaBehavior(true) : it)
.orElse(ItemSettings.of().disableVanillaBehavior(isVanillaItem));
} catch (LocalizedResourceConfigException e) {
collector.add(e);
settings = ItemSettings.of().canPlaceRelatedVanillaBlock(isVanillaItem);
settings = ItemSettings.of().disableVanillaBehavior(isVanillaItem);
}
// 行为

View File

@@ -27,7 +27,7 @@ public class ItemSettings {
Repairable repairable = Repairable.UNDEFINED;
List<AnvilRepairItem> anvilRepairItems = List.of();
boolean renameable = true;
boolean canPlaceRelatedVanillaBlock = false;
boolean disableVanillaBehavior = true;
ProjectileMeta projectileMeta;
Tristate dyeable = Tristate.UNDEFINED;
Helmet helmet = null;
@@ -92,7 +92,7 @@ public class ItemSettings {
newSettings.repairable = settings.repairable;
newSettings.anvilRepairItems = settings.anvilRepairItems;
newSettings.renameable = settings.renameable;
newSettings.canPlaceRelatedVanillaBlock = settings.canPlaceRelatedVanillaBlock;
newSettings.disableVanillaBehavior = settings.disableVanillaBehavior;
newSettings.projectileMeta = settings.projectileMeta;
newSettings.dyeable = settings.dyeable;
newSettings.helmet = settings.helmet;
@@ -125,8 +125,8 @@ public class ItemSettings {
return projectileMeta;
}
public boolean canPlaceRelatedVanillaBlock() {
return canPlaceRelatedVanillaBlock;
public boolean disableVanillaBehavior() {
return disableVanillaBehavior;
}
public Repairable repairable() {
@@ -263,8 +263,8 @@ public class ItemSettings {
return this;
}
public ItemSettings canPlaceRelatedVanillaBlock(boolean canPlaceRelatedVanillaBlock) {
this.canPlaceRelatedVanillaBlock = canPlaceRelatedVanillaBlock;
public ItemSettings disableVanillaBehavior(boolean disableVanillaBehavior) {
this.disableVanillaBehavior = disableVanillaBehavior;
return this;
}
@@ -408,7 +408,11 @@ public class ItemSettings {
}));
registerFactory("can-place", (value -> {
boolean bool = ResourceConfigUtils.getAsBoolean(value, "can-place");
return settings -> settings.canPlaceRelatedVanillaBlock(bool);
return settings -> settings.disableVanillaBehavior(!bool);
}));
registerFactory("disable-vanilla-behavior", (value -> {
boolean bool = ResourceConfigUtils.getAsBoolean(value, "disable-vanilla-behavior");
return settings -> settings.disableVanillaBehavior(bool);
}));
registerFactory("projectile", (value -> {
Map<String, Object> args = MiscUtils.castToMap(value, false);