Skip to content

Commit

Permalink
Merge pull request #5 from Minecraft-InCraftTime-Server/优化交互方式
Browse files Browse the repository at this point in the history
优化交互方式
  • Loading branch information
MineSunshineone authored Jan 19, 2025
2 parents 2742187 + 9616529 commit f7b1c7a
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 148 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>ict.minesunshineone</groupId>
<artifactId>LandmarkSystem</artifactId>
<version>1.6</version>
<version>1.7</version>

<properties>
<java.version>21</java.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import ict.minesunshineone.landmark.command.impl.ReloadCommand;
import ict.minesunshineone.landmark.command.impl.RenameCommand;
import ict.minesunshineone.landmark.command.impl.TeleportCommand;
import ict.minesunshineone.landmark.command.impl.UnlockAllCommand;

public class LandmarkCommand implements CommandExecutor, TabCompleter {

Expand All @@ -40,6 +41,7 @@ private void registerSubCommands() {
subCommands.put("rename", new RenameCommand(plugin));
subCommands.put("edit", new EditCommand(plugin));
subCommands.put("reload", new ReloadCommand(plugin));
subCommands.put("unlockall", new UnlockAllCommand(plugin));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ict.minesunshineone.landmark.command.impl;

import java.util.Collections;
import java.util.List;

import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import ict.minesunshineone.landmark.LandmarkPlugin;
import ict.minesunshineone.landmark.command.SubCommand;

public class UnlockAllCommand extends SubCommand {

public UnlockAllCommand(LandmarkPlugin plugin) {
super(plugin);
}

@Override
public void execute(CommandSender sender, String[] args) {
if (!(sender instanceof Player)) {
plugin.getConfigManager().sendMessage(sender, "command-player-only", "<red>该命令只能由玩家执行!</red>");
return;
}

Player player = (Player) sender;
plugin.getLandmarkManager().unlockAllLandmarks(player);
}

@Override
public String getPermission() {
return "landmark.unlock.all";
}

@Override
public List<String> onTabComplete(CommandSender sender, String[] args) {
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,13 @@
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Interaction;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
Expand Down Expand Up @@ -283,44 +279,27 @@ public void cleanup() {
lastCheckTimes.clear();
}

@EventHandler
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}

Block block = event.getClickedBlock();
if (block == null) {
return;
}
Action action = event.getAction();
Player player = event.getPlayer();

// 检查是否是锚点中心方块
for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) {
Location landmarkLoc = landmark.getLocation();
if (block.getLocation().equals(landmarkLoc)) {
event.setCancelled(true);
new LandmarkMenu(plugin, event.getPlayer()).open();
break;
// 检查是否是左键动作,并且点击的是空气(不要问为什么不右键,因为右键的事件好像有问题)
if (action == Action.LEFT_CLICK_AIR) {
// 检查权限
if (!player.hasPermission("landmark.menu")) {
return;
}
}
}

@EventHandler
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
Entity entity = event.getRightClicked();
if (!(entity instanceof Interaction)) {
return;
}

Player player = event.getPlayer();

// 检查是否是锚点交互实体
for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) {
if (landmark.getInteractionEntityId() != null
&& landmark.getInteractionEntityId().equals(entity.getUniqueId())) {
event.setCancelled(true);
new LandmarkMenu(plugin, player).open();
break;
// 检查玩家是否在任意锚点范围内
for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) {
if (plugin.getLandmarkManager().isPlayerNearLandmark(player, landmark.getLocation())) {
// 在锚点范围内,打开菜单
plugin.getServer().getRegionScheduler().execute(plugin, player.getLocation(), () -> {
new LandmarkMenu(plugin, player).open();
});
return;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,14 @@
import java.util.Set;
import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Interaction;
import org.bukkit.entity.Player;

import ict.minesunshineone.landmark.LandmarkPlugin;
import ict.minesunshineone.landmark.model.Landmark;
import net.kyori.adventure.text.Component;

public class LandmarkManager {

Expand Down Expand Up @@ -55,9 +52,6 @@ public void createLandmark(String name, Location location, String description) {
Landmark landmark = new Landmark(name, location, description, menuPosition[0], menuPosition[1]);
landmarks.put(name.toLowerCase(), landmark);

// 使用统一的方法创建实体
createLandmarkEntities(landmark);

plugin.getSLF4JLogger().info("成功创建锚点展示实体: {}", name);
saveData();
} catch (IllegalArgumentException | IllegalStateException e) {
Expand Down Expand Up @@ -107,25 +101,6 @@ public void deleteLandmark(String name) {
String lowerName = name.toLowerCase();
Landmark landmark = landmarks.get(lowerName);
if (landmark != null) {
// 移除交互实体
if (landmark.getInteractionEntityId() != null) {
Location loc = landmark.getLocation();
if (loc != null && loc.getWorld() != null) {
// 移除交互实体
Entity entity = Bukkit.getEntity(landmark.getInteractionEntityId());
if (entity != null) {
entity.remove();
}

// 移除同位置的所有具有相同名称的交互实体
loc.getWorld().getNearbyEntities(loc, 2, 2, 2).stream()
.filter(e -> e instanceof Interaction)
.filter(e -> e.customName() != null && e.customName().equals(Component.text("§e[点击打开]")))
.forEach(Entity::remove);
}
landmark.setInteractionEntityId(null);
}

// 移除锚点数据
landmarks.remove(lowerName);

Expand Down Expand Up @@ -156,6 +131,10 @@ public void unlockLandmark(Player player, String landmarkName) {
}

public boolean canTeleport(Player player) {
// 如果玩家有无视冷却权限,直接返回true
if (player.hasPermission("landmark.bypass.cooldown")) {
return true;
}
long lastTeleport = cooldowns.getOrDefault(player.getUniqueId(), 0L);
long cooldownTime = plugin.getConfigManager().getCooldownTime() * 1000L;
return System.currentTimeMillis() - lastTeleport >= cooldownTime;
Expand Down Expand Up @@ -254,19 +233,7 @@ public final void loadData() {
int menuColumn = landmarkSection.getInt("menu_column", 1);

Landmark landmark = new Landmark(key, location, description, menuRow, menuColumn);
String interactionId = landmarkSection.getString("interaction_entity_id");
if (interactionId != null) {
landmark.setInteractionEntityId(UUID.fromString(interactionId));
}

landmarks.put(key.toLowerCase(), landmark);

// 延迟创建实体,确保世界加载完成
plugin.getServer().getRegionScheduler().runDelayed(plugin, location, task -> {
if (location.getWorld() != null && location.getChunk().isLoaded()) {
createLandmarkEntities(landmark);
}
}, 100L);
}
} catch (IllegalArgumentException | IllegalStateException e) {
plugin.getSLF4JLogger().error("加载锚点 {} 时发生错误: {}", key, e.getMessage());
Expand Down Expand Up @@ -308,8 +275,6 @@ public void saveData() {
Landmark landmark = entry.getValue();
landmarkSection.set("location", landmark.getLocation());
landmarkSection.set("description", landmark.getDescription());
landmarkSection.set("interaction_entity_id", landmark.getInteractionEntityId() != null
? landmark.getInteractionEntityId().toString() : null);
landmarkSection.set("menu_row", landmark.getMenuRow());
landmarkSection.set("menu_column", landmark.getMenuColumn());
}
Expand Down Expand Up @@ -428,68 +393,13 @@ public boolean isPlayerNearLandmark(Player player, Location landmarkLoc) {
&& playerLoc.distance(landmarkLoc) <= plugin.getConfigManager().getUnlockRadius();
}

private void createLandmarkEntities(Landmark landmark) {
try {
Location location = landmark.getLocation();
if (location.getWorld() == null || !location.getChunk().isLoaded()) {
return;
}

// 确保位置是方块中心
Location centerLoc = location.clone();
centerLoc.setX(location.getBlockX() + 0.5);
centerLoc.setY(location.getBlockY());
centerLoc.setZ(location.getBlockZ() + 0.5);

// 创建交互实体
Location interactLoc = centerLoc.clone().add(0, 0, 0);
Interaction interaction = location.getWorld().spawn(interactLoc, Interaction.class, entity -> {
entity.setInteractionWidth(3.5f);
entity.setInteractionHeight(2.0f);
entity.setPersistent(true);
entity.setInvulnerable(true);
entity.setCustomNameVisible(true);
entity.customName(Component.text("§e[点击打开]"));
entity.setGravity(false);
});

landmark.setInteractionEntityId(interaction.getUniqueId());
saveData(); // 保存实体ID
} catch (IllegalArgumentException | IllegalStateException e) {
plugin.getSLF4JLogger().error("重建锚点实体时发生错误: {}", e.getMessage());
}
}

public void cleanup() {
// 清理所有实体
for (Landmark landmark : landmarks.values()) {
removeLandmarkEntities(landmark);
}

// 清理数据结构
landmarks.clear();
unlockedLandmarks.clear();
cooldowns.clear();
}

private void removeLandmarkEntities(Landmark landmark) {
if (landmark.getDisplayEntityId() != null) {
Entity entity = Bukkit.getEntity(landmark.getDisplayEntityId());
if (entity != null) {
entity.remove();
}
landmark.setDisplayEntityId(null);
}

if (landmark.getInteractionEntityId() != null) {
Entity entity = Bukkit.getEntity(landmark.getInteractionEntityId());
if (entity != null) {
entity.remove();
}
landmark.setInteractionEntityId(null);
}
}

public void updateMenuPosition(String landmarkName, int newRow, int newColumn) {
Landmark landmark = landmarks.get(landmarkName.toLowerCase());
if (landmark != null) {
Expand All @@ -501,4 +411,17 @@ public void updateMenuPosition(String landmarkName, int newRow, int newColumn) {
}
}
}

// 新增一键解锁所有锚点的方法
public void unlockAllLandmarks(Player player) {
if (!player.hasPermission("landmark.unlock.all")) {
return;
}
Set<String> playerUnlocked = unlockedLandmarks.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
for (String landmarkName : landmarks.keySet()) {
playerUnlocked.add(landmarkName.toLowerCase());
}
savePlayerData(player.getUniqueId());
plugin.getConfigManager().sendMessage(player, "unlock-all-success", "<gradient:green:aqua>✧ 魔法师解开了所有锚点的封印!</gradient>");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ public class Landmark {
private Location location;
private String description;
private UUID displayEntityId;
private UUID interactionEntityId;
private int menuRow; // 在菜单中的行位置
private int menuColumn; // 在菜单中的列位置

Expand Down Expand Up @@ -62,14 +61,6 @@ public void setDisplayEntityId(UUID displayEntityId) {
this.displayEntityId = displayEntityId;
}

public UUID getInteractionEntityId() {
return interactionEntityId;
}

public void setInteractionEntityId(UUID interactionEntityId) {
this.interactionEntityId = interactionEntityId;
}

public int getMenuRow() {
return menuRow;
}
Expand Down
7 changes: 1 addition & 6 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,7 @@ messages:
separator: '<gradient:gold:yellow>✧══════════ 魔法锚点咒语书 ══════════✧</gradient>'
command: '%prefix% <yellow>%command%</yellow>'
landmark-exists: '<gradient:red:dark_red>✧ 魔法师,这个锚点名称已被占用了!</gradient>'
create-title: '<gradient:gold:yellow>✧══════════ 魔法锚点 ══════════✧</gradient>'
create-subtitle: '<gradient:green:aqua>成功创造新的锚点!</gradient>'
delete-title: '<gradient:red:dark_red>✧══════════ 魔法锚点 ══════════✧</gradient>'
delete-subtitle: '<gradient:red:dark_red>锚点已被抹除!</gradient>'
rename-title: '<gradient:gold:yellow>✧══════════ 魔法锚点 ══════════✧</gradient>'
rename-subtitle: '<gradient:green:aqua>锚点重命名成功!</gradient>'
unlock-all-success: '<gradient:green:aqua>✧ 魔法师成功解开了所有锚点的封印!</gradient>'

# GUI设置
gui:
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,10 @@ permissions:
default: true
landmark.admin:
description: 管理员权限
default: op
landmark.unlock.all:
description: 允许一键解锁所有锚点
default: op
landmark.bypass.cooldown:
description: 允许无视传送冷却
default: op

0 comments on commit f7b1c7a

Please sign in to comment.