diff --git a/src/main/java/com/simpletombstone/SimpleTombstone.java b/src/main/java/com/simpletombstone/SimpleTombstone.java index a41518c..6cee055 100644 --- a/src/main/java/com/simpletombstone/SimpleTombstone.java +++ b/src/main/java/com/simpletombstone/SimpleTombstone.java @@ -4,72 +4,133 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.api.EnvType; import net.minecraft.block.*; -import net.minecraft.block.entity.BlockEntityType; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; -import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import net.minecraft.block.entity.ChestBlockEntity; import net.minecraft.item.ItemStack; - -// 新增导入语句 +import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; +import java.util.*; public class SimpleTombstone implements ModInitializer { public static final String MOD_ID = "simple-tombstone"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - - // 自定义墓碑方块 - public static final Block LOOT_CHEST = Blocks.CHEST; // 修改为原版箱子 + private static final Map TOMBSTONE_CHESTS = new HashMap<>(); + private static final Set DEAD_PLAYERS = new HashSet<>(); + private static final Set RESURRECTED_PLAYERS = new HashSet<>(); @Override public void onInitialize() { - // 将事件注册移到服务端环境判断块内 if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) { - ServerPlayerEvents.ALLOW_DEATH.register((player, damageSource, damageAmount) -> { - createTombstoneForMixin(player); - player.getInventory().clear(); // 需要手动清空背包 - return false; // 阻止物品掉落 + LOGGER.info("[SimpleTombstone] 服务器端初始化中..."); + ServerLivingEntityEvents.ALLOW_DEATH.register((entity, damageSource, damageAmount) -> { + if (entity instanceof ServerPlayerEntity player) { + LOGGER.info("[SimpleTombstone] 检测到玩家 {} 死亡,创建墓碑...", player.getName().getString()); + createTombstoneForMixin(player); + DEAD_PLAYERS.add(player.getUuid()); + return false; + } + return true; }); - LOGGER.info("服务端初始化完成"); - } else { - LOGGER.info("客户端初始化完成"); + + ServerPlayerEvents.AFTER_RESPAWN.register((oldPlayer, newPlayer, alive) -> { + UUID playerId = newPlayer.getUuid(); + if (DEAD_PLAYERS.contains(playerId)) { + LOGGER.info("[SimpleTombstone] 玩家 {} 已重生,物品归还功能已启用。", newPlayer.getName().getString()); + DEAD_PLAYERS.remove(playerId); + RESURRECTED_PLAYERS.add(playerId); + } + }); + + LOGGER.info("[SimpleTombstone] 服务器端初始化完成"); } + + ServerTickEvents.END_SERVER_TICK.register(server -> { + for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) { + if (RESURRECTED_PLAYERS.contains(player.getUuid())) { + checkPlayerNearTombstone(player); + } + } + }); } - /** - * 供 Mixin 调用,在玩家死亡时创建物品箱 - */ public static void createTombstoneForMixin(ServerPlayerEntity player) { BlockPos deathPos = player.getBlockPos(); World world = player.getWorld(); - // 检查位置是否为空 - if (!world.isAir(deathPos)) { - return; + while (world.isAir(deathPos.down())) { + deathPos = deathPos.down(); } - // 放置箱子方块 - world.setBlockState(deathPos, LOOT_CHEST.getDefaultState()); + if (!world.getBlockState(deathPos).isSolid()) { + LOGGER.warn("[SimpleTombstone] 位置 {} 处为液体,替换为玻璃。", deathPos.toShortString()); + world.setBlockState(deathPos, Blocks.GLASS.getDefaultState()); + } - // 存储物品到箱子 - if (world.getBlockEntity(deathPos) instanceof ChestBlockEntity chestEntity) { - for (int i = 0; i < player.getInventory().size(); i++) { - ItemStack stack = player.getInventory().removeStack(i, Integer.MAX_VALUE); - if (!stack.isEmpty()) { - chestEntity.setStack(i,stack); + BlockPos tombstonePos = deathPos.up(); + List items = new ArrayList<>(); + for (int i = 0; i < player.getInventory().size(); i++) { + ItemStack stack = player.getInventory().removeStack(i, Integer.MAX_VALUE); + if (!stack.isEmpty()) { + items.add(stack); + } + } + TOMBSTONE_CHESTS.put(tombstonePos, new PlayerTombstoneData(player.getUuid(), items)); + + Random random = new Random(); + List flowerPots = Arrays.asList( + Blocks.POTTED_OAK_SAPLING, + Blocks.POTTED_DANDELION, + Blocks.POTTED_POPPY, + Blocks.POTTED_BLUE_ORCHID + ); + Block chosenFlowerPot = flowerPots.get(random.nextInt(flowerPots.size())); + world.setBlockState(tombstonePos, chosenFlowerPot.getDefaultState()); + + player.sendMessage(Text.of("A loot chest has been placed at " + deathPos.toShortString()), false); + LOGGER.info("[SimpleTombstone] 为玩家 {} 在 {} 创建了墓碑。", player.getName().getString(), deathPos.toShortString()); + } + + private void checkPlayerNearTombstone(ServerPlayerEntity player) { + World world = player.getWorld(); + BlockPos playerPos = player.getBlockPos(); + + for (BlockPos pos : BlockPos.iterate( + playerPos.getX() - 4, playerPos.getY() - 4, playerPos.getZ() - 4, + playerPos.getX() + 4, playerPos.getY() + 4, playerPos.getZ() + 4 + )) { + PlayerTombstoneData data = TOMBSTONE_CHESTS.get(pos); + if (data != null && data.getPlayerId().equals(player.getUuid())) { + Block block = world.getBlockState(pos).getBlock(); + if (block instanceof FlowerPotBlock) { + LOGGER.info("[SimpleTombstone] 玩家 {} 靠近墓碑,恢复物品。", player.getName().getString()); + for (ItemStack stack : data.getItems()) { + player.getInventory().offerOrDrop(stack); + } + world.removeBlock(pos, false); + TOMBSTONE_CHESTS.remove(pos); + RESURRECTED_PLAYERS.remove(player.getUuid()); + LOGGER.info("[SimpleTombstone] 移除墓碑 {} 并归还物品。", pos.toShortString()); + break; } } } - - // 发送消息和日志 - player.sendMessage(Text.of("A loot chest has been placed at " + deathPos.toShortString()), false); - LOGGER.info("为玩家 {} 在 {} 创建了物品箱。", player.getName().getString(), deathPos.toShortString()); } -} \ No newline at end of file + + private static class PlayerTombstoneData { + private final UUID playerId; + private final List items; + + public PlayerTombstoneData(UUID playerId, List items) { + this.playerId = playerId; + this.items = items; + } + + public UUID getPlayerId() { return playerId; } + public List getItems() { return items; } + } +}