SPIGOT-6829: Add per-player world border API
By: Parker Hawke <hawkeboyz2@hotmail.com>
This commit is contained in:
@@ -127,6 +127,7 @@ import org.bukkit.UnsafeValues;
|
||||
import org.bukkit.Warning.WarningState;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.WorldBorder;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.boss.BarColor;
|
||||
@@ -1184,6 +1185,11 @@ public final class CraftServer implements Server {
|
||||
worlds.put(world.getName().toLowerCase(java.util.Locale.ENGLISH), world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldBorder createWorldBorder() {
|
||||
return new CraftWorldBorder(new net.minecraft.world.level.border.WorldBorder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
|
||||
@@ -16,6 +16,16 @@ public class CraftWorldBorder implements WorldBorder {
|
||||
this.handle = world.getHandle().getWorldBorder();
|
||||
}
|
||||
|
||||
public CraftWorldBorder(net.minecraft.world.level.border.WorldBorder handle) {
|
||||
this.world = null;
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.setSize(6.0E7D);
|
||||
@@ -115,6 +125,14 @@ public class CraftWorldBorder implements WorldBorder {
|
||||
public boolean isInside(Location location) {
|
||||
Preconditions.checkArgument(location != null, "location");
|
||||
|
||||
return location.getWorld().equals(this.world) && this.handle.isWithinBounds(new BlockPosition(location.getX(), location.getY(), location.getZ()));
|
||||
return (world == null || location.getWorld().equals(this.world)) && this.handle.isWithinBounds(new BlockPosition(location.getX(), location.getY(), location.getZ()));
|
||||
}
|
||||
|
||||
public net.minecraft.world.level.border.WorldBorder getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return world == null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,11 @@ import net.minecraft.network.chat.ChatComponentText;
|
||||
import net.minecraft.network.chat.ChatMessageType;
|
||||
import net.minecraft.network.chat.IChatBaseComponent;
|
||||
import net.minecraft.network.protocol.game.ClientboundClearTitlesPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetBorderCenterPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetBorderLerpSizePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetBorderSizePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetBorderWarningDelayPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetBorderWarningDistancePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket;
|
||||
@@ -76,6 +81,7 @@ import net.minecraft.world.item.EnumColor;
|
||||
import net.minecraft.world.level.EnumGamemode;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.TileEntitySign;
|
||||
import net.minecraft.world.level.border.IWorldBorderListener;
|
||||
import net.minecraft.world.level.saveddata.maps.MapIcon;
|
||||
import net.minecraft.world.level.saveddata.maps.WorldMap;
|
||||
import net.minecraft.world.phys.Vec3D;
|
||||
@@ -96,6 +102,7 @@ import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.WeatherType;
|
||||
import org.bukkit.WorldBorder;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@@ -111,6 +118,7 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftSound;
|
||||
import org.bukkit.craftbukkit.CraftStatistic;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.CraftWorldBorder;
|
||||
import org.bukkit.craftbukkit.advancement.CraftAdvancement;
|
||||
import org.bukkit.craftbukkit.advancement.CraftAdvancementProgress;
|
||||
import org.bukkit.craftbukkit.block.CraftSign;
|
||||
@@ -156,6 +164,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
private double health = 20;
|
||||
private boolean scaledHealth = false;
|
||||
private double healthScale = 20;
|
||||
private CraftWorldBorder clientWorldBorder = null;
|
||||
private IWorldBorderListener clientWorldBorderListener = createWorldBorderListener();
|
||||
|
||||
public CraftPlayer(CraftServer server, EntityPlayer entity) {
|
||||
super(server, entity);
|
||||
@@ -663,6 +673,82 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
getHandle().connection.send(new PacketPlayOutEntityEquipment(entity.getEntityId(), equipment));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldBorder getWorldBorder() {
|
||||
return clientWorldBorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorldBorder(WorldBorder border) {
|
||||
CraftWorldBorder craftBorder = (CraftWorldBorder) border;
|
||||
|
||||
if (border != null && !craftBorder.isVirtual() && !craftBorder.getWorld().equals(getWorld())) {
|
||||
throw new UnsupportedOperationException("Cannot set player world border to that of another world");
|
||||
}
|
||||
|
||||
// Nullify the old client-sided world border listeners so that calls to it will not affect this player
|
||||
if (clientWorldBorder != null) {
|
||||
this.clientWorldBorder.getHandle().removeListener(clientWorldBorderListener);
|
||||
}
|
||||
|
||||
net.minecraft.world.level.border.WorldBorder newWorldBorder;
|
||||
if (craftBorder == null || !craftBorder.isVirtual()) {
|
||||
this.clientWorldBorder = null;
|
||||
newWorldBorder = ((CraftWorldBorder) getWorld().getWorldBorder()).getHandle();
|
||||
} else {
|
||||
this.clientWorldBorder = craftBorder;
|
||||
this.clientWorldBorder.getHandle().addListener(clientWorldBorderListener);
|
||||
newWorldBorder = clientWorldBorder.getHandle();
|
||||
}
|
||||
|
||||
// Send all world border update packets to the player
|
||||
PlayerConnection connection = getHandle().connection;
|
||||
connection.send(new ClientboundSetBorderSizePacket(newWorldBorder));
|
||||
connection.send(new ClientboundSetBorderLerpSizePacket(newWorldBorder));
|
||||
connection.send(new ClientboundSetBorderCenterPacket(newWorldBorder));
|
||||
connection.send(new ClientboundSetBorderWarningDelayPacket(newWorldBorder));
|
||||
connection.send(new ClientboundSetBorderWarningDistancePacket(newWorldBorder));
|
||||
}
|
||||
|
||||
private IWorldBorderListener createWorldBorderListener() {
|
||||
return new IWorldBorderListener() {
|
||||
@Override
|
||||
public void onBorderSizeSet(net.minecraft.world.level.border.WorldBorder border, double size) {
|
||||
getHandle().connection.send(new ClientboundSetBorderSizePacket(border));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBorderSizeLerping(net.minecraft.world.level.border.WorldBorder border, double size, double newSize, long time) {
|
||||
getHandle().connection.send(new ClientboundSetBorderLerpSizePacket(border));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBorderCenterSet(net.minecraft.world.level.border.WorldBorder border, double x, double z) {
|
||||
getHandle().connection.send(new ClientboundSetBorderCenterPacket(border));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBorderSetWarningTime(net.minecraft.world.level.border.WorldBorder border, int warningTime) {
|
||||
getHandle().connection.send(new ClientboundSetBorderWarningDelayPacket(border));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBorderSetWarningBlocks(net.minecraft.world.level.border.WorldBorder border, int warningBlocks) {
|
||||
getHandle().connection.send(new ClientboundSetBorderWarningDistancePacket(border));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBorderSetDamagePerBlock(net.minecraft.world.level.border.WorldBorder border, double damage) {} // NO OP
|
||||
|
||||
@Override
|
||||
public void onBorderSetDamageSafeZOne(net.minecraft.world.level.border.WorldBorder border, double blocks) {} // NO OP
|
||||
};
|
||||
}
|
||||
|
||||
public boolean hasClientWorldBorder() {
|
||||
return clientWorldBorder != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMap(MapView map) {
|
||||
if (getHandle().connection == null) return;
|
||||
|
||||
Reference in New Issue
Block a user