玩家重生后,视情况给予指向死亡位置的导向地图

This commit is contained in:
2024-12-20 12:03:59 +08:00
parent 76421fe12d
commit 31a5d6a963
2 changed files with 107 additions and 6 deletions

View File

@@ -2,10 +2,7 @@ package ling.coordinateRecorder.Listener;
import ling.coordinateRecorder.CoordinateRecorder;
import ling.coordinateRecorder.data.PlayerData;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.entity.ArmorStand;
@@ -20,13 +17,18 @@ import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.map.*;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
/// 玩家事件监听器
public class PlayerEventListener implements Listener {
@@ -158,11 +160,88 @@ public class PlayerEventListener implements Listener {
}
}
/// 玩家死亡时,保管掉落物
/// 玩家重生后,如果距离足够远,则给予一份指向上次死亡地点的地图
@EventHandler
public void opPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer();
PlayerData data = PlayerMap.getCurrent().getPlayerData(player);
if (data == null) {
player.sendMessage("玩家没有注册,跳过提供地图");
return;
}
Location death = data.getDeathLocation();
if (death == null)
return;
data.setDeathLocation(null);
World deathWorld = death.getWorld();
if (deathWorld == null)
return;
//计算距离,如果重生点距离死亡位置很近,则不提供地图
if (PlayerData.isSameWorld(death, player.getLocation()) && death.distance(player.getLocation()) < 128) {
player.sendMessage("你的死亡位置距离重生点过近,本次重生不提供导向地图。");
return;
}
System.out.println("距离:" + death.distance(player.getLocation()));
//创建地图,并设置中心为死亡位置
MapView map = Bukkit.createMap(deathWorld);
map.setCenterX(death.getBlockX());
map.setCenterZ(death.getBlockZ());
//给予一级缩放的地图,避免找不到箱子
map.setScale(MapView.Scale.CLOSEST);
map.setTrackingPosition(true);
map.getRenderers().clear();
map.addRenderer(new MapRenderer() {
private boolean isAdd = false;
@Override
public void render(@NotNull MapView mapView, @NotNull MapCanvas mapCanvas, @NotNull Player player) {
MapCursorCollection cursors = mapCanvas.getCursors();
if (isAdd)
return;
isAdd = true;
// 添加目标位置标记
int scale = 1 << map.getScale().ordinal(); // 当前地图缩放比例
int x = (death.getBlockX() - map.getCenterX()) / scale;
int z = (death.getBlockZ() - map.getCenterZ()) / scale;
// 限制标记范围(避免标记在地图外无法显示)
x = Math.max(-128, Math.min(127, x));
z = Math.max(-128, Math.min(127, z));
cursors.addCursor(x, z, (byte) 0, MapCursor.Type.RED_X.getValue());
}
});
//生成物品形式的地图
ItemStack mapItem = new ItemStack(Material.FILLED_MAP);
MapMeta mapMeta = (MapMeta) mapItem.getItemMeta();
if (mapMeta == null) {
player.sendMessage("生成宝藏地图失败!");
return;
}
mapMeta.setMapView(map);
mapMeta.setLocationName("死亡点");
mapMeta.setDisplayName(player.getName() + "的安息之地");
mapMeta.setLore(Arrays.asList(player.getName() + "曾死在这里", "墓碑已生成!"));
mapItem.setItemMeta(mapMeta);
player.getInventory().addItem(mapItem);
}
/// 在玩家死亡时,保管掉落物并记录死亡位置
@EventHandler
public void playerDeath(PlayerDeathEvent event) {
Player player = event.getEntity();
Location location = player.getLocation();
PlayerData data = PlayerMap.getCurrent().getPlayerData(player);
if (data == null) {
CoordinateRecorder.getCurrent().getLogger().info("没有找到玩家的登录信息,不生成墓碑");
return;
}
data.setDeathLocation(location);
//寻找可以生成墓碑的位置
Location save = getGraveLocation(location);

View File

@@ -36,6 +36,8 @@ public class PlayerData {
protected ScoreboardUI ui;
//正在交互的墓碑
protected Block tombstoneBlock;
//上次死亡位置
protected Location deathLocation;
public PlayerData(Player player) throws SQLException {
@@ -50,6 +52,15 @@ public class PlayerData {
this.tombstoneBlock = tombstone;
}
/// 检查两个地点是否位于同一个世界
public static boolean isSameWorld(Location l1, Location l2) {
World w1 = l1.getWorld();
World w2 = l2.getWorld();
if (w1 == null || w2 == null)
return false;
return w1.getName().equals(w2.getName());
}
/// 解锁墓碑
public void unlockTombstoneBlock() {
if (tombstoneBlock == null) {
@@ -60,7 +71,8 @@ public class PlayerData {
player.sendMessage(ChatColor.RED + "目标不是一个墓碑!");
return;
}
if (player.getLocation().distance(tombstoneBlock.getLocation()) > 8) {
if (!isSameWorld(player.getLocation(), tombstoneBlock.getLocation()) || player.getLocation().distance(
tombstoneBlock.getLocation()) > 8) {
player.sendMessage(ChatColor.RED + "距离太远,无法解锁!");
return;
}
@@ -183,6 +195,16 @@ public class PlayerData {
ui.flashLocations();
}
/// 上次死亡地点
public Location getDeathLocation() {
return deathLocation;
}
/// 设置死亡地点
public void setDeathLocation(Location deathLocation) {
this.deathLocation = deathLocation;
}
/// 检查当前是否还有空余位置显示新的坐标点
public boolean isAddLocations() {
return locationList.size() < 10;