9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +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.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; 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.factory.BukkitItemFactory;
import net.momirealms.craftengine.bukkit.item.listener.ArmorEventListener; import net.momirealms.craftengine.bukkit.item.listener.ArmorEventListener;
import net.momirealms.craftengine.bukkit.item.listener.DebugStickListener; import net.momirealms.craftengine.bukkit.item.listener.DebugStickListener;
@@ -39,9 +40,6 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
static { static {
registerVanillaItemExtraBehavior(FlintAndSteelItemBehavior.INSTANCE, ItemKeys.FLINT_AND_STEEL); registerVanillaItemExtraBehavior(FlintAndSteelItemBehavior.INSTANCE, ItemKeys.FLINT_AND_STEEL);
registerVanillaItemExtraBehavior(AxeItemBehavior.INSTANCE, ItemKeys.AXES); 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; 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 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 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 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() { public static void init() {
register(EMPTY, EmptyItemBehavior.FACTORY); register(EMPTY, EmptyItemBehavior.FACTORY);
@@ -27,8 +24,5 @@ public class BukkitItemBehaviors extends ItemBehaviors {
register(AXE_ITEM, AxeItemBehavior.FACTORY); register(AXE_ITEM, AxeItemBehavior.FACTORY);
register(DOUBLE_HIGH_BLOCK_ITEM, DoubleHighBlockItemBehavior.FACTORY); register(DOUBLE_HIGH_BLOCK_ITEM, DoubleHighBlockItemBehavior.FACTORY);
register(WALL_BLOCK_ITEM, WallBlockItemBehavior.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 // custom item
else { else {
if (optionalCustomItem.get().settings().canPlaceRelatedVanillaBlock()) { if (optionalCustomItem.get().settings().disableVanillaBehavior()) {
// 如果用户设置了允许放置对应的原版方块,那么直接返回。 // 允许尝试放置方块
// 这种情况下最好是return以避免同时触发多个behavior发生冲突
// 当用户选择其作为原版方块放下时,自定义行为可能已经不重要了?
return;
} else {
// todo 实际上这里的处理并不正确,因为判断玩家是否能够放置那个方块需要更加细节的判断。比如玩家无法对着树叶放置火把,但是交互事件依然触发,此情况下不可丢弃自定义行为。
if (serverPlayer.isSecondaryUseActive() || !InteractUtils.isInteractable(player, blockData, hitResult, itemInHand)) { if (serverPlayer.isSecondaryUseActive() || !InteractUtils.isInteractable(player, blockData, hitResult, itemInHand)) {
// todo 检测不可以放置方块
event.setCancelled(true); event.setCancelled(true);
} }
} }

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.bukkit.util;
import io.papermc.paper.entity.Shearable; import io.papermc.paper.entity.Shearable;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.item.behavior.BlockItemBehavior; 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.behavior.FlintAndSteelItemBehavior;
import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager; import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock; 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.DRAGON_EGG, (player, item, blockState, result) -> true);
registerInteraction(BlockKeys.END_PORTAL_FRAME, (player, item, blockState, result) -> { registerInteraction(BlockKeys.END_PORTAL_FRAME, (player, item, blockState, result) -> {
Optional<List<ItemBehavior>> behaviors = item.getItemBehavior(); Key id = item.vanillaId();
if (behaviors.isPresent()) { return ItemKeys.ENDER_EYE.equals(id);
for (ItemBehavior behavior : behaviors.get()) {
if (behavior instanceof EnderEyeItemBehavior) return true;
}
}
return false;
}); });
registerInteraction(BlockKeys.VAULT, (player, item, blockState, result) -> blockState instanceof Vault vault && vault.getVaultState() == Vault.State.ACTIVE); registerInteraction(BlockKeys.VAULT, (player, item, blockState, result) -> blockState instanceof Vault vault && vault.getVaultState() == Vault.State.ACTIVE);
registerInteraction(BlockKeys.SPAWNER, (player, item, blockState, result) -> { 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 CRAFTER = Key.of("minecraft:crafter");
public static final Key HOPPER = Key.of("minecraft:hopper"); public static final Key HOPPER = Key.of("minecraft:hopper");
public static final Key OBSERVER = Key.of("minecraft:observer"); 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 DETECTOR_RAIL = Key.of("minecraft:detector_rail");
public static final Key TNT = Key.of("minecraft:tnt"); public static final Key TNT = Key.of("minecraft:tnt");
public static final Key REDSTONE_ORE = Key.of("minecraft:redstone_ore"); 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 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 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 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 BROWN_MUSHROOM_BLOCK = Key.of("minecraft:brown_mushroom_block");
public static final Key RED_MUSHROOM_BLOCK = Key.of("minecraft:red_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.BlockEntityElement;
import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfig; import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfig;
import net.momirealms.craftengine.core.util.Key;
import java.util.Optional; import java.util.Optional;

View File

@@ -569,11 +569,11 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
try { try {
settings = Optional.ofNullable(ResourceConfigUtils.get(section, "settings")) settings = Optional.ofNullable(ResourceConfigUtils.get(section, "settings"))
.map(map -> ItemSettings.fromMap(MiscUtils.castToMap(map, true))) .map(map -> ItemSettings.fromMap(MiscUtils.castToMap(map, true)))
.map(it -> isVanillaItem ? it.canPlaceRelatedVanillaBlock(true) : it) .map(it -> isVanillaItem ? it.disableVanillaBehavior(true) : it)
.orElse(ItemSettings.of().canPlaceRelatedVanillaBlock(isVanillaItem)); .orElse(ItemSettings.of().disableVanillaBehavior(isVanillaItem));
} catch (LocalizedResourceConfigException e) { } catch (LocalizedResourceConfigException e) {
collector.add(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; Repairable repairable = Repairable.UNDEFINED;
List<AnvilRepairItem> anvilRepairItems = List.of(); List<AnvilRepairItem> anvilRepairItems = List.of();
boolean renameable = true; boolean renameable = true;
boolean canPlaceRelatedVanillaBlock = false; boolean disableVanillaBehavior = true;
ProjectileMeta projectileMeta; ProjectileMeta projectileMeta;
Tristate dyeable = Tristate.UNDEFINED; Tristate dyeable = Tristate.UNDEFINED;
Helmet helmet = null; Helmet helmet = null;
@@ -92,7 +92,7 @@ public class ItemSettings {
newSettings.repairable = settings.repairable; newSettings.repairable = settings.repairable;
newSettings.anvilRepairItems = settings.anvilRepairItems; newSettings.anvilRepairItems = settings.anvilRepairItems;
newSettings.renameable = settings.renameable; newSettings.renameable = settings.renameable;
newSettings.canPlaceRelatedVanillaBlock = settings.canPlaceRelatedVanillaBlock; newSettings.disableVanillaBehavior = settings.disableVanillaBehavior;
newSettings.projectileMeta = settings.projectileMeta; newSettings.projectileMeta = settings.projectileMeta;
newSettings.dyeable = settings.dyeable; newSettings.dyeable = settings.dyeable;
newSettings.helmet = settings.helmet; newSettings.helmet = settings.helmet;
@@ -125,8 +125,8 @@ public class ItemSettings {
return projectileMeta; return projectileMeta;
} }
public boolean canPlaceRelatedVanillaBlock() { public boolean disableVanillaBehavior() {
return canPlaceRelatedVanillaBlock; return disableVanillaBehavior;
} }
public Repairable repairable() { public Repairable repairable() {
@@ -263,8 +263,8 @@ public class ItemSettings {
return this; return this;
} }
public ItemSettings canPlaceRelatedVanillaBlock(boolean canPlaceRelatedVanillaBlock) { public ItemSettings disableVanillaBehavior(boolean disableVanillaBehavior) {
this.canPlaceRelatedVanillaBlock = canPlaceRelatedVanillaBlock; this.disableVanillaBehavior = disableVanillaBehavior;
return this; return this;
} }
@@ -408,7 +408,11 @@ public class ItemSettings {
})); }));
registerFactory("can-place", (value -> { registerFactory("can-place", (value -> {
boolean bool = ResourceConfigUtils.getAsBoolean(value, "can-place"); 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 -> { registerFactory("projectile", (value -> {
Map<String, Object> args = MiscUtils.castToMap(value, false); Map<String, Object> args = MiscUtils.castToMap(value, false);