9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 04:19:27 +00:00

完善上一个commit

This commit is contained in:
XiaoMoMi
2025-07-14 23:44:46 +08:00
parent 7d2e8f1a54
commit 5b00f695f1
10 changed files with 63 additions and 68 deletions

View File

@@ -67,7 +67,7 @@ public class AxeItemBehavior extends ItemBehavior {
Optional<StrippableBlockBehavior> behaviorOptional = customState.behavior().getAs(StrippableBlockBehavior.class);
if (behaviorOptional.isEmpty()) return InteractionResult.PASS;
Key stripped = behaviorOptional.get().stripped();
Item<ItemStack> offHandItem = player != null ? (Item<ItemStack>) player.getItemInHand(InteractionHand.OFF_HAND) : BukkitItemManager.instance().wrap(new ItemStack(Material.AIR));
Item<ItemStack> offHandItem = player != null ? (Item<ItemStack>) player.getItemInHand(InteractionHand.OFF_HAND) : BukkitItemManager.instance().uniqueEmptyItem().item();
// is using a shield
if (context.getHand() == InteractionHand.MAIN_HAND && !ItemUtils.isEmpty(offHandItem) && canBlockAttack(offHandItem) && player != null && !player.isSecondaryUseActive()) {
return InteractionResult.PASS;

View File

@@ -63,6 +63,7 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
return this.place(new BlockPlaceContext(context));
}
@SuppressWarnings("UnstableApiUsage")
public InteractionResult place(BlockPlaceContext context) {
Optional<CustomBlock> optionalBlock = BukkitBlockManager.instance().blockById(this.blockId);
if (optionalBlock.isEmpty()) {
@@ -77,8 +78,10 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
CustomBlock block = optionalBlock.get();
BlockPos pos = context.getClickedPos();
int maxY = context.getLevel().worldHeight().getMaxBuildHeight() - 1;
if (player != null && context.getClickedFace() == Direction.UP && pos.y() >= maxY) {
player.sendActionBar(Component.translatable("build.tooHigh").arguments(Component.text(maxY)).color(NamedTextColor.RED));
if (context.getClickedFace() == Direction.UP && pos.y() >= maxY) {
if (player != null) {
player.sendActionBar(Component.translatable("build.tooHigh").arguments(Component.text(maxY)).color(NamedTextColor.RED));
}
return InteractionResult.FAIL;
}
@@ -94,23 +97,24 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
Block againstBlock = world.getBlockAt(againstPos.x(), againstPos.y(), againstPos.z());
org.bukkit.entity.Player bukkitPlayer = player != null ? (org.bukkit.entity.Player) player.platformPlayer() : null;
if (player != null && player.isAdventureMode()) {
Object againstBlockState = BlockStateUtils.blockDataToBlockState(againstBlock.getBlockData());
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(againstBlockState);
if (optionalCustomState.isEmpty()) {
if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, againstBlockState)) {
return InteractionResult.FAIL;
}
} else {
ImmutableBlockState customState = optionalCustomState.get();
// custom block
if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, Config.simplifyAdventurePlaceCheck() ? customState.vanillaBlockState().handle() : againstBlockState)) {
return InteractionResult.FAIL;
if (player != null) {
if (player.isAdventureMode()) {
Object againstBlockState = BlockStateUtils.blockDataToBlockState(againstBlock.getBlockData());
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(againstBlockState);
if (optionalCustomState.isEmpty()) {
if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, againstBlockState)) {
return InteractionResult.FAIL;
}
} else {
ImmutableBlockState customState = optionalCustomState.get();
// custom block
if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, Config.simplifyAdventurePlaceCheck() ? customState.vanillaBlockState().handle() : againstBlockState)) {
return InteractionResult.FAIL;
}
}
}
}
if (player != null) {
// trigger event
CustomBlockAttemptPlaceEvent attemptPlaceEvent = new CustomBlockAttemptPlaceEvent(bukkitPlayer, placeLocation.clone(), blockStateToPlace,
DirectionUtils.toBlockFace(context.getClickedFace()), bukkitBlock, context.getHand());
@@ -123,6 +127,7 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
BlockState previousState = bukkitBlock.getState();
// place custom block
CraftEngineBlocks.place(placeLocation, blockStateToPlace, UpdateOption.UPDATE_ALL_IMMEDIATE, false);
if (player != null) {
// call bukkit event
BlockPlaceEvent bukkitPlaceEvent = new BlockPlaceEvent(bukkitBlock, previousState, againstBlock, (ItemStack) context.getItem().getItem(), bukkitPlayer, true, context.getHand() == InteractionHand.MAIN_HAND ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND);
@@ -155,16 +160,15 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
return InteractionResult.SUCCESS_AND_CANCEL;
}
if (player != null && !player.isCreativeMode()) {
Item<?> item = context.getItem();
item.count(item.count() - 1);
if (player != null) {
if (!player.isCreativeMode()) {
Item<?> item = context.getItem();
item.count(item.count() - 1);
}
player.swingHand(context.getHand());
}
block.setPlacedBy(context, blockStateToPlace);
if (player != null) {
player.swingHand(context.getHand());
}
context.getLevel().playBlockSound(position, blockStateToPlace.settings().sounds().placeSound());
world.sendGameEvent(bukkitPlayer, GameEvent.BLOCK_PLACE, new Vector(pos.x(), pos.y(), pos.z()));
return InteractionResult.SUCCESS;
@@ -179,6 +183,7 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
return true;
}
@SuppressWarnings("UnstableApiUsage")
protected boolean canPlace(BlockPlaceContext context, ImmutableBlockState state) {
try {
Player cePlayer = context.getPlayer();
@@ -194,8 +199,8 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
voxelShape = CoreReflections.instance$CollisionContext$empty;
}
Object world = FastNMS.INSTANCE.field$CraftWorld$ServerLevel((World) context.getLevel().platformWorld());
boolean defaultReturn = ((!this.checkStatePlacement() || (boolean) CoreReflections.method$BlockStateBase$canSurvive.invoke(blockState, world, blockPos))
&& (boolean) CoreReflections.method$ServerLevel$checkEntityCollision.invoke(world, blockState, player, voxelShape, blockPos, true));
boolean defaultReturn = ((!this.checkStatePlacement() || FastNMS.INSTANCE.method$BlockStateBase$canSurvive(blockState, world, blockPos))
&& (boolean) CoreReflections.method$ServerLevel$checkEntityCollision.invoke(world, blockState, player, voxelShape, blockPos, true)); // paper only
Block block = FastNMS.INSTANCE.method$CraftBlock$at(world, blockPos);
BlockData blockData = FastNMS.INSTANCE.method$CraftBlockData$fromData(blockState);
BlockCanBuildEvent canBuildEvent = new BlockCanBuildEvent(

View File

@@ -7,6 +7,7 @@ import net.momirealms.craftengine.bukkit.util.EventUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
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;
@@ -44,15 +45,17 @@ public class CompostableItemBehavior extends ItemBehavior {
if (!(blockData instanceof Levelled levelled)) {
return InteractionResult.PASS;
}
int maxLevel = levelled.getMaximumLevel();
int currentLevel = levelled.getLevel();
if (currentLevel >= maxLevel) return InteractionResult.PASS;
boolean willRaise = (currentLevel == 0) && (this.chance > 0) || (RandomUtils.generateRandomDouble(0, 1) < this.chance);
Player player = context.getPlayer();
if (willRaise) {
levelled.setLevel(currentLevel + 1);
if (context.getPlayer() != null) {
EntityChangeBlockEvent event = new EntityChangeBlockEvent((Entity) context.getPlayer().platformPlayer(), block.block(), levelled);
if (player != null) {
EntityChangeBlockEvent event = new EntityChangeBlockEvent((Entity) player.platformPlayer(), block.block(), levelled);
if (EventUtils.fireAndCheckCancel(event)) {
return InteractionResult.FAIL;
}
@@ -61,14 +64,16 @@ public class CompostableItemBehavior extends ItemBehavior {
}
context.getLevel().levelEvent(WorldEvents.COMPOSTER_COMPOSTS, context.getClickedPos(), willRaise ? 1 : 0);
((World) context.getLevel().platformWorld()).sendGameEvent(context.getPlayer() != null ? (Entity) context.getPlayer().platformPlayer() : null, GameEvent.BLOCK_CHANGE, new Vector(block.x() + 0.5, block.y() + 0.5, block.z() + 0.5));
((World) context.getLevel().platformWorld()).sendGameEvent(player != null ? (Entity) player.platformPlayer() : null, GameEvent.BLOCK_CHANGE, new Vector(block.x() + 0.5, block.y() + 0.5, block.z() + 0.5));
if (currentLevel + 1 == 7) {
FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), blockOwner, 20);
}
if (!context.getPlayer().canInstabuild()) {
context.getItem().shrink(1);
if (player != null) {
if (!player.canInstabuild()) {
context.getItem().shrink(1);
}
player.swingHand(context.getHand());
}
context.getPlayer().swingHand(context.getHand());
return InteractionResult.SUCCESS;
}

View File

@@ -36,6 +36,9 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
@SuppressWarnings("unchecked")
@Override
public InteractionResult useOnBlock(UseOnContext context) {
net.momirealms.craftengine.core.entity.player.Player player = context.getPlayer();
if (player == null) return InteractionResult.PASS;
BlockPos clickedPos = context.getClickedPos();
BukkitBlockInWorld clicked = (BukkitBlockInWorld) context.getLevel().getBlockAt(clickedPos);
Block block = clicked.block();
@@ -65,7 +68,6 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
return InteractionResult.PASS;
}
net.momirealms.craftengine.core.entity.player.Player player = context.getPlayer();
// 点击对象直接可燃,则忽略
if (isClickedBlockBurnable) {
int stateId = BlockStateUtils.blockStateToId(clickedBlockState);
@@ -80,7 +82,7 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
}
BlockData vanillaBlockState = BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().handle());
// 点击的是方块上面则只需要判断shift和可交互
if (player != null && direction == Direction.UP) {
if (direction == Direction.UP) {
// 客户端层面必须可交互
if (!InteractUtils.isInteractable((Player) player.platformPlayer(), vanillaBlockState,
context.getHitResult(), (Item<ItemStack>) context.getItem())) {
@@ -106,7 +108,7 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
}
// 客户端觉得这玩意可交互,就会忽略声音
if (player != null && InteractUtils.isInteractable((Player) player.platformPlayer(), vanillaBlockState, context.getHitResult(), (Item<ItemStack>) context.getItem())) {
if (InteractUtils.isInteractable((Player) player.platformPlayer(), vanillaBlockState, context.getHitResult(), (Item<ItemStack>) context.getItem())) {
// 如果按住了shift则代表尝试对侧面方块点火
if (player.isSecondaryUseActive()) {
// 如果底部不能燃烧,则燃烧点位为侧面,需要补发
@@ -119,7 +121,7 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
}
} else {
// 如果底部方块不可燃烧才补发
if (player != null && !belowCanBurn) {
if (!belowCanBurn) {
player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
player.swingHand(context.getHand());
}
@@ -151,10 +153,8 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
}
}
}
if (player != null) {
player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
player.swingHand(context.getHand());
}
player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
player.swingHand(context.getHand());
}
return InteractionResult.PASS;
}

View File

@@ -163,14 +163,14 @@ public class FurnitureItemBehavior extends ItemBehavior {
return InteractionResult.SUCCESS_AND_CANCEL;
}
if (player != null && !player.isCreativeMode()) {
item.count(item.count() - 1);
if (player != null) {
if (!player.canInstabuild()) {
item.count(item.count() - 1);
}
player.swingHand(context.getHand());
}
context.getLevel().playBlockSound(finalPlacePosition, customFurniture.settings().sounds().placeSound());
if (player != null) {
player.swingHand(context.getHand());
}
return InteractionResult.SUCCESS;
}

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.bukkit.item.behavior;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.entity.player.InteractionResult;
@@ -38,26 +37,14 @@ public class LiquidCollisionBlockItemBehavior extends BlockItemBehavior {
@Override
public InteractionResult useOnBlock(UseOnContext context) {
return use(context.getLevel(), context.getPlayer(), context.getHand(), context);
return use(context.getLevel(), context.getPlayer(), context.getHand());
}
@Override
public InteractionResult use(World world, @Nullable Player player, InteractionHand hand, @Nullable UseOnContext context) {
public InteractionResult use(World world, @Nullable Player player, InteractionHand hand) {
try {
Object blockHitResult;
if (player != null) {
blockHitResult = CoreReflections.method$Item$getPlayerPOVHitResult.invoke(null, world.serverWorld(), player.serverPlayer(), CoreReflections.instance$ClipContext$Fluid$SOURCE_ONLY);
} else if (context != null) {
BlockPos clickedPos = context.getClickedPos();
blockHitResult = CoreReflections.constructor$BlockHitResult.newInstance(
CoreReflections.constructor$Vec3.newInstance(clickedPos.x() + 0.5, clickedPos.y() + 0.5, clickedPos.z() + 0.5),
DirectionUtils.toNMSDirection(context.getHorizontalDirection()),
LocationUtils.toBlockPos(clickedPos),
false
);
} else {
return InteractionResult.FAIL;
}
if (player == null) return InteractionResult.FAIL;
Object blockHitResult = CoreReflections.method$Item$getPlayerPOVHitResult.invoke(null, world.serverWorld(), player.serverPlayer(), CoreReflections.instance$ClipContext$Fluid$SOURCE_ONLY);
Object blockPos = CoreReflections.field$BlockHitResul$blockPos.get(blockHitResult);
BlockPos above = new BlockPos(FastNMS.INSTANCE.field$Vec3i$x(blockPos), FastNMS.INSTANCE.field$Vec3i$y(blockPos) + offsetY, FastNMS.INSTANCE.field$Vec3i$z(blockPos));
Direction direction = Direction.values()[(int) CoreReflections.method$Direction$ordinal.invoke(CoreReflections.field$BlockHitResul$direction.get(blockHitResult))];

View File

@@ -365,7 +365,7 @@ public class ItemEventListener implements Listener {
Optional<List<ItemBehavior>> optionalItemBehaviors = itemInHand.getItemBehavior();
if (optionalItemBehaviors.isPresent()) {
for (ItemBehavior itemBehavior : optionalItemBehaviors.get()) {
InteractionResult result = itemBehavior.use(serverPlayer.world(), serverPlayer, hand, null);
InteractionResult result = itemBehavior.use(serverPlayer.world(), serverPlayer, hand);
if (result.success()) {
serverPlayer.updateLastSuccessfulInteractionTick(serverPlayer.gameTicks());
}

View File

@@ -3841,9 +3841,9 @@ public final class CoreReflections {
}
// 1.21.6+
public static final Method method$CollisionContext$placementContext = ReflectionUtils.getStaticMethod(
public static final Method method$CollisionContext$placementContext = MiscUtils.requireNonNullIf(ReflectionUtils.getStaticMethod(
clazz$CollisionContext, clazz$CollisionContext, clazz$Player
);
), VersionHelper.isOrAbove1_21_6());
public static final Constructor<?> constructor$BlockHitResult = requireNonNull(
ReflectionUtils.getConstructor(