Skip to content

Commit f7b1c7a

Browse files
Merge pull request #5 from Minecraft-InCraftTime-Server/优化交互方式
优化交互方式
2 parents 2742187 + 9616529 commit f7b1c7a

8 files changed

Lines changed: 82 additions & 148 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>ict.minesunshineone</groupId>
88
<artifactId>LandmarkSystem</artifactId>
9-
<version>1.6</version>
9+
<version>1.7</version>
1010

1111
<properties>
1212
<java.version>21</java.version>

src/main/java/ict/minesunshineone/landmark/command/LandmarkCommand.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import ict.minesunshineone.landmark.command.impl.ReloadCommand;
2121
import ict.minesunshineone.landmark.command.impl.RenameCommand;
2222
import ict.minesunshineone.landmark.command.impl.TeleportCommand;
23+
import ict.minesunshineone.landmark.command.impl.UnlockAllCommand;
2324

2425
public class LandmarkCommand implements CommandExecutor, TabCompleter {
2526

@@ -40,6 +41,7 @@ private void registerSubCommands() {
4041
subCommands.put("rename", new RenameCommand(plugin));
4142
subCommands.put("edit", new EditCommand(plugin));
4243
subCommands.put("reload", new ReloadCommand(plugin));
44+
subCommands.put("unlockall", new UnlockAllCommand(plugin));
4345
}
4446

4547
@Override
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package ict.minesunshineone.landmark.command.impl;
2+
3+
import java.util.Collections;
4+
import java.util.List;
5+
6+
import org.bukkit.command.CommandSender;
7+
import org.bukkit.entity.Player;
8+
9+
import ict.minesunshineone.landmark.LandmarkPlugin;
10+
import ict.minesunshineone.landmark.command.SubCommand;
11+
12+
public class UnlockAllCommand extends SubCommand {
13+
14+
public UnlockAllCommand(LandmarkPlugin plugin) {
15+
super(plugin);
16+
}
17+
18+
@Override
19+
public void execute(CommandSender sender, String[] args) {
20+
if (!(sender instanceof Player)) {
21+
plugin.getConfigManager().sendMessage(sender, "command-player-only", "<red>该命令只能由玩家执行!</red>");
22+
return;
23+
}
24+
25+
Player player = (Player) sender;
26+
plugin.getLandmarkManager().unlockAllLandmarks(player);
27+
}
28+
29+
@Override
30+
public String getPermission() {
31+
return "landmark.unlock.all";
32+
}
33+
34+
@Override
35+
public List<String> onTabComplete(CommandSender sender, String[] args) {
36+
return Collections.emptyList();
37+
}
38+
}

src/main/java/ict/minesunshineone/landmark/listener/PlayerListener.java

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,13 @@
88
import org.bukkit.Location;
99
import org.bukkit.Particle;
1010
import org.bukkit.Sound;
11-
import org.bukkit.block.Block;
1211
import org.bukkit.configuration.file.FileConfiguration;
13-
import org.bukkit.entity.Entity;
14-
import org.bukkit.entity.Interaction;
1512
import org.bukkit.entity.Player;
1613
import org.bukkit.event.EventHandler;
1714
import org.bukkit.event.EventPriority;
1815
import org.bukkit.event.Listener;
1916
import org.bukkit.event.block.Action;
2017
import org.bukkit.event.inventory.InventoryClickEvent;
21-
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
2218
import org.bukkit.event.player.PlayerInteractEvent;
2319
import org.bukkit.event.player.PlayerMoveEvent;
2420
import org.bukkit.event.player.PlayerQuitEvent;
@@ -283,44 +279,27 @@ public void cleanup() {
283279
lastCheckTimes.clear();
284280
}
285281

286-
@EventHandler
282+
@EventHandler(priority = EventPriority.LOWEST)
287283
public void onPlayerInteract(PlayerInteractEvent event) {
288-
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
289-
return;
290-
}
291-
292-
Block block = event.getClickedBlock();
293-
if (block == null) {
294-
return;
295-
}
284+
Action action = event.getAction();
285+
Player player = event.getPlayer();
296286

297-
// 检查是否是锚点中心方块
298-
for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) {
299-
Location landmarkLoc = landmark.getLocation();
300-
if (block.getLocation().equals(landmarkLoc)) {
301-
event.setCancelled(true);
302-
new LandmarkMenu(plugin, event.getPlayer()).open();
303-
break;
287+
// 检查是否是左键动作,并且点击的是空气(不要问为什么不右键,因为右键的事件好像有问题)
288+
if (action == Action.LEFT_CLICK_AIR) {
289+
// 检查权限
290+
if (!player.hasPermission("landmark.menu")) {
291+
return;
304292
}
305-
}
306-
}
307-
308-
@EventHandler
309-
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
310-
Entity entity = event.getRightClicked();
311-
if (!(entity instanceof Interaction)) {
312-
return;
313-
}
314-
315-
Player player = event.getPlayer();
316293

317-
// 检查是否是锚点交互实体
318-
for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) {
319-
if (landmark.getInteractionEntityId() != null
320-
&& landmark.getInteractionEntityId().equals(entity.getUniqueId())) {
321-
event.setCancelled(true);
322-
new LandmarkMenu(plugin, player).open();
323-
break;
294+
// 检查玩家是否在任意锚点范围内
295+
for (Landmark landmark : plugin.getLandmarkManager().getLandmarks().values()) {
296+
if (plugin.getLandmarkManager().isPlayerNearLandmark(player, landmark.getLocation())) {
297+
// 在锚点范围内,打开菜单
298+
plugin.getServer().getRegionScheduler().execute(plugin, player.getLocation(), () -> {
299+
new LandmarkMenu(plugin, player).open();
300+
});
301+
return;
302+
}
324303
}
325304
}
326305
}

src/main/java/ict/minesunshineone/landmark/manager/LandmarkManager.java

Lines changed: 17 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,14 @@
1010
import java.util.Set;
1111
import java.util.UUID;
1212

13-
import org.bukkit.Bukkit;
1413
import org.bukkit.Location;
1514
import org.bukkit.configuration.ConfigurationSection;
1615
import org.bukkit.configuration.file.YamlConfiguration;
1716
import org.bukkit.entity.Entity;
18-
import org.bukkit.entity.Interaction;
1917
import org.bukkit.entity.Player;
2018

2119
import ict.minesunshineone.landmark.LandmarkPlugin;
2220
import ict.minesunshineone.landmark.model.Landmark;
23-
import net.kyori.adventure.text.Component;
2421

2522
public class LandmarkManager {
2623

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

58-
// 使用统一的方法创建实体
59-
createLandmarkEntities(landmark);
60-
6155
plugin.getSLF4JLogger().info("成功创建锚点展示实体: {}", name);
6256
saveData();
6357
} catch (IllegalArgumentException | IllegalStateException e) {
@@ -107,25 +101,6 @@ public void deleteLandmark(String name) {
107101
String lowerName = name.toLowerCase();
108102
Landmark landmark = landmarks.get(lowerName);
109103
if (landmark != null) {
110-
// 移除交互实体
111-
if (landmark.getInteractionEntityId() != null) {
112-
Location loc = landmark.getLocation();
113-
if (loc != null && loc.getWorld() != null) {
114-
// 移除交互实体
115-
Entity entity = Bukkit.getEntity(landmark.getInteractionEntityId());
116-
if (entity != null) {
117-
entity.remove();
118-
}
119-
120-
// 移除同位置的所有具有相同名称的交互实体
121-
loc.getWorld().getNearbyEntities(loc, 2, 2, 2).stream()
122-
.filter(e -> e instanceof Interaction)
123-
.filter(e -> e.customName() != null && e.customName().equals(Component.text("§e[点击打开]")))
124-
.forEach(Entity::remove);
125-
}
126-
landmark.setInteractionEntityId(null);
127-
}
128-
129104
// 移除锚点数据
130105
landmarks.remove(lowerName);
131106

@@ -156,6 +131,10 @@ public void unlockLandmark(Player player, String landmarkName) {
156131
}
157132

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

256235
Landmark landmark = new Landmark(key, location, description, menuRow, menuColumn);
257-
String interactionId = landmarkSection.getString("interaction_entity_id");
258-
if (interactionId != null) {
259-
landmark.setInteractionEntityId(UUID.fromString(interactionId));
260-
}
261-
262236
landmarks.put(key.toLowerCase(), landmark);
263-
264-
// 延迟创建实体,确保世界加载完成
265-
plugin.getServer().getRegionScheduler().runDelayed(plugin, location, task -> {
266-
if (location.getWorld() != null && location.getChunk().isLoaded()) {
267-
createLandmarkEntities(landmark);
268-
}
269-
}, 100L);
270237
}
271238
} catch (IllegalArgumentException | IllegalStateException e) {
272239
plugin.getSLF4JLogger().error("加载锚点 {} 时发生错误: {}", key, e.getMessage());
@@ -308,8 +275,6 @@ public void saveData() {
308275
Landmark landmark = entry.getValue();
309276
landmarkSection.set("location", landmark.getLocation());
310277
landmarkSection.set("description", landmark.getDescription());
311-
landmarkSection.set("interaction_entity_id", landmark.getInteractionEntityId() != null
312-
? landmark.getInteractionEntityId().toString() : null);
313278
landmarkSection.set("menu_row", landmark.getMenuRow());
314279
landmarkSection.set("menu_column", landmark.getMenuColumn());
315280
}
@@ -428,68 +393,13 @@ public boolean isPlayerNearLandmark(Player player, Location landmarkLoc) {
428393
&& playerLoc.distance(landmarkLoc) <= plugin.getConfigManager().getUnlockRadius();
429394
}
430395

431-
private void createLandmarkEntities(Landmark landmark) {
432-
try {
433-
Location location = landmark.getLocation();
434-
if (location.getWorld() == null || !location.getChunk().isLoaded()) {
435-
return;
436-
}
437-
438-
// 确保位置是方块中心
439-
Location centerLoc = location.clone();
440-
centerLoc.setX(location.getBlockX() + 0.5);
441-
centerLoc.setY(location.getBlockY());
442-
centerLoc.setZ(location.getBlockZ() + 0.5);
443-
444-
// 创建交互实体
445-
Location interactLoc = centerLoc.clone().add(0, 0, 0);
446-
Interaction interaction = location.getWorld().spawn(interactLoc, Interaction.class, entity -> {
447-
entity.setInteractionWidth(3.5f);
448-
entity.setInteractionHeight(2.0f);
449-
entity.setPersistent(true);
450-
entity.setInvulnerable(true);
451-
entity.setCustomNameVisible(true);
452-
entity.customName(Component.text("§e[点击打开]"));
453-
entity.setGravity(false);
454-
});
455-
456-
landmark.setInteractionEntityId(interaction.getUniqueId());
457-
saveData(); // 保存实体ID
458-
} catch (IllegalArgumentException | IllegalStateException e) {
459-
plugin.getSLF4JLogger().error("重建锚点实体时发生错误: {}", e.getMessage());
460-
}
461-
}
462-
463396
public void cleanup() {
464-
// 清理所有实体
465-
for (Landmark landmark : landmarks.values()) {
466-
removeLandmarkEntities(landmark);
467-
}
468-
469397
// 清理数据结构
470398
landmarks.clear();
471399
unlockedLandmarks.clear();
472400
cooldowns.clear();
473401
}
474402

475-
private void removeLandmarkEntities(Landmark landmark) {
476-
if (landmark.getDisplayEntityId() != null) {
477-
Entity entity = Bukkit.getEntity(landmark.getDisplayEntityId());
478-
if (entity != null) {
479-
entity.remove();
480-
}
481-
landmark.setDisplayEntityId(null);
482-
}
483-
484-
if (landmark.getInteractionEntityId() != null) {
485-
Entity entity = Bukkit.getEntity(landmark.getInteractionEntityId());
486-
if (entity != null) {
487-
entity.remove();
488-
}
489-
landmark.setInteractionEntityId(null);
490-
}
491-
}
492-
493403
public void updateMenuPosition(String landmarkName, int newRow, int newColumn) {
494404
Landmark landmark = landmarks.get(landmarkName.toLowerCase());
495405
if (landmark != null) {
@@ -501,4 +411,17 @@ public void updateMenuPosition(String landmarkName, int newRow, int newColumn) {
501411
}
502412
}
503413
}
414+
415+
// 新增一键解锁所有锚点的方法
416+
public void unlockAllLandmarks(Player player) {
417+
if (!player.hasPermission("landmark.unlock.all")) {
418+
return;
419+
}
420+
Set<String> playerUnlocked = unlockedLandmarks.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
421+
for (String landmarkName : landmarks.keySet()) {
422+
playerUnlocked.add(landmarkName.toLowerCase());
423+
}
424+
savePlayerData(player.getUniqueId());
425+
plugin.getConfigManager().sendMessage(player, "unlock-all-success", "<gradient:green:aqua>✧ 魔法师解开了所有锚点的封印!</gradient>");
426+
}
504427
}

src/main/java/ict/minesunshineone/landmark/model/Landmark.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ public class Landmark {
1010
private Location location;
1111
private String description;
1212
private UUID displayEntityId;
13-
private UUID interactionEntityId;
1413
private int menuRow; // 在菜单中的行位置
1514
private int menuColumn; // 在菜单中的列位置
1615

@@ -62,14 +61,6 @@ public void setDisplayEntityId(UUID displayEntityId) {
6261
this.displayEntityId = displayEntityId;
6362
}
6463

65-
public UUID getInteractionEntityId() {
66-
return interactionEntityId;
67-
}
68-
69-
public void setInteractionEntityId(UUID interactionEntityId) {
70-
this.interactionEntityId = interactionEntityId;
71-
}
72-
7364
public int getMenuRow() {
7465
return menuRow;
7566
}

src/main/resources/config.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,7 @@ messages:
4141
separator: '<gradient:gold:yellow>✧══════════ 魔法锚点咒语书 ══════════✧</gradient>'
4242
command: '%prefix% <yellow>%command%</yellow>'
4343
landmark-exists: '<gradient:red:dark_red>✧ 魔法师,这个锚点名称已被占用了!</gradient>'
44-
create-title: '<gradient:gold:yellow>✧══════════ 魔法锚点 ══════════✧</gradient>'
45-
create-subtitle: '<gradient:green:aqua>成功创造新的锚点!</gradient>'
46-
delete-title: '<gradient:red:dark_red>✧══════════ 魔法锚点 ══════════✧</gradient>'
47-
delete-subtitle: '<gradient:red:dark_red>锚点已被抹除!</gradient>'
48-
rename-title: '<gradient:gold:yellow>✧══════════ 魔法锚点 ══════════✧</gradient>'
49-
rename-subtitle: '<gradient:green:aqua>锚点重命名成功!</gradient>'
44+
unlock-all-success: '<gradient:green:aqua>✧ 魔法师成功解开了所有锚点的封印!</gradient>'
5045

5146
# GUI设置
5247
gui:

src/main/resources/plugin.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,10 @@ permissions:
3939
default: true
4040
landmark.admin:
4141
description: 管理员权限
42+
default: op
43+
landmark.unlock.all:
44+
description: 允许一键解锁所有锚点
45+
default: op
46+
landmark.bypass.cooldown:
47+
description: 允许无视传送冷却
4248
default: op

0 commit comments

Comments
 (0)