198 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.waypoints;
 | |
| 
 | |
| import java.util.Optional;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.network.protocol.game.ClientboundTrackedWaypointPacket;
 | |
| import net.minecraft.server.level.ServerPlayer;
 | |
| import net.minecraft.util.Mth;
 | |
| import net.minecraft.world.entity.LivingEntity;
 | |
| import net.minecraft.world.entity.ai.attributes.Attributes;
 | |
| import net.minecraft.world.level.ChunkPos;
 | |
| import net.minecraft.world.phys.Vec3;
 | |
| 
 | |
| public interface WaypointTransmitter extends Waypoint {
 | |
| 	int REALLY_FAR_DISTANCE = 332;
 | |
| 
 | |
| 	boolean isTransmittingWaypoint();
 | |
| 
 | |
| 	Optional<WaypointTransmitter.Connection> makeWaypointConnectionWith(ServerPlayer player);
 | |
| 
 | |
| 	Waypoint.Icon waypointIcon();
 | |
| 
 | |
| 	static boolean doesSourceIgnoreReceiver(LivingEntity entity, ServerPlayer player) {
 | |
| 		if (player.isSpectator()) {
 | |
| 			return false;
 | |
| 		} else if (!entity.isSpectator() && !entity.hasIndirectPassenger(player)) {
 | |
| 			double d = Math.min(entity.getAttributeValue(Attributes.WAYPOINT_TRANSMIT_RANGE), player.getAttributeValue(Attributes.WAYPOINT_RECEIVE_RANGE));
 | |
| 			return entity.distanceTo(player) >= d;
 | |
| 		} else {
 | |
| 			return true;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	static boolean isChunkVisible(ChunkPos pos, ServerPlayer player) {
 | |
| 		return player.getChunkTrackingView().isInViewDistance(pos.x, pos.z);
 | |
| 	}
 | |
| 
 | |
| 	static boolean isReallyFar(LivingEntity entity, ServerPlayer player) {
 | |
| 		return entity.distanceTo(player) > 332.0F;
 | |
| 	}
 | |
| 
 | |
| 	public interface BlockConnection extends WaypointTransmitter.Connection {
 | |
| 		int distanceManhattan();
 | |
| 
 | |
| 		@Override
 | |
| 		default boolean isBroken() {
 | |
| 			return this.distanceManhattan() > 1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public interface ChunkConnection extends WaypointTransmitter.Connection {
 | |
| 		int distanceChessboard();
 | |
| 
 | |
| 		@Override
 | |
| 		default boolean isBroken() {
 | |
| 			return this.distanceChessboard() > 1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public interface Connection {
 | |
| 		void connect();
 | |
| 
 | |
| 		void disconnect();
 | |
| 
 | |
| 		void update();
 | |
| 
 | |
| 		boolean isBroken();
 | |
| 	}
 | |
| 
 | |
| 	public static class EntityAzimuthConnection implements WaypointTransmitter.Connection {
 | |
| 		private final LivingEntity source;
 | |
| 		private final Waypoint.Icon icon;
 | |
| 		private final ServerPlayer receiver;
 | |
| 		private float lastAngle;
 | |
| 
 | |
| 		public EntityAzimuthConnection(LivingEntity source, Waypoint.Icon icon, ServerPlayer reciever) {
 | |
| 			this.source = source;
 | |
| 			this.icon = icon;
 | |
| 			this.receiver = reciever;
 | |
| 			Vec3 vec3 = reciever.position().subtract(source.position()).rotateClockwise90();
 | |
| 			this.lastAngle = (float)Mth.atan2(vec3.z(), vec3.x());
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public boolean isBroken() {
 | |
| 			return WaypointTransmitter.doesSourceIgnoreReceiver(this.source, this.receiver)
 | |
| 				|| WaypointTransmitter.isChunkVisible(this.source.chunkPosition(), this.receiver)
 | |
| 				|| !WaypointTransmitter.isReallyFar(this.source, this.receiver);
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void connect() {
 | |
| 			this.receiver.connection.send(ClientboundTrackedWaypointPacket.addWaypointAzimuth(this.source.getUUID(), this.icon, this.lastAngle));
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void disconnect() {
 | |
| 			this.receiver.connection.send(ClientboundTrackedWaypointPacket.removeWaypoint(this.source.getUUID()));
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void update() {
 | |
| 			Vec3 vec3 = this.receiver.position().subtract(this.source.position()).rotateClockwise90();
 | |
| 			float f = (float)Mth.atan2(vec3.z(), vec3.x());
 | |
| 			if (Mth.abs(f - this.lastAngle) > 0.008726646F) {
 | |
| 				this.receiver.connection.send(ClientboundTrackedWaypointPacket.updateWaypointAzimuth(this.source.getUUID(), this.icon, f));
 | |
| 				this.lastAngle = f;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public static class EntityBlockConnection implements WaypointTransmitter.BlockConnection {
 | |
| 		private final LivingEntity source;
 | |
| 		private final Waypoint.Icon icon;
 | |
| 		private final ServerPlayer receiver;
 | |
| 		private BlockPos lastPosition;
 | |
| 
 | |
| 		public EntityBlockConnection(LivingEntity source, Waypoint.Icon icon, ServerPlayer reciever) {
 | |
| 			this.source = source;
 | |
| 			this.receiver = reciever;
 | |
| 			this.icon = icon;
 | |
| 			this.lastPosition = source.blockPosition();
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void connect() {
 | |
| 			this.receiver.connection.send(ClientboundTrackedWaypointPacket.addWaypointPosition(this.source.getUUID(), this.icon, this.lastPosition));
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void disconnect() {
 | |
| 			this.receiver.connection.send(ClientboundTrackedWaypointPacket.removeWaypoint(this.source.getUUID()));
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void update() {
 | |
| 			BlockPos blockPos = this.source.blockPosition();
 | |
| 			if (blockPos.distManhattan(this.lastPosition) > 0) {
 | |
| 				this.receiver.connection.send(ClientboundTrackedWaypointPacket.updateWaypointPosition(this.source.getUUID(), this.icon, blockPos));
 | |
| 				this.lastPosition = blockPos;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public int distanceManhattan() {
 | |
| 			return this.lastPosition.distManhattan(this.source.blockPosition());
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public boolean isBroken() {
 | |
| 			return WaypointTransmitter.BlockConnection.super.isBroken() || WaypointTransmitter.doesSourceIgnoreReceiver(this.source, this.receiver);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public static class EntityChunkConnection implements WaypointTransmitter.ChunkConnection {
 | |
| 		private final LivingEntity source;
 | |
| 		private final Waypoint.Icon icon;
 | |
| 		private final ServerPlayer receiver;
 | |
| 		private ChunkPos lastPosition;
 | |
| 
 | |
| 		public EntityChunkConnection(LivingEntity source, Waypoint.Icon icon, ServerPlayer receiver) {
 | |
| 			this.source = source;
 | |
| 			this.icon = icon;
 | |
| 			this.receiver = receiver;
 | |
| 			this.lastPosition = source.chunkPosition();
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public int distanceChessboard() {
 | |
| 			return this.lastPosition.getChessboardDistance(this.source.chunkPosition());
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void connect() {
 | |
| 			this.receiver.connection.send(ClientboundTrackedWaypointPacket.addWaypointChunk(this.source.getUUID(), this.icon, this.lastPosition));
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void disconnect() {
 | |
| 			this.receiver.connection.send(ClientboundTrackedWaypointPacket.removeWaypoint(this.source.getUUID()));
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void update() {
 | |
| 			ChunkPos chunkPos = this.source.chunkPosition();
 | |
| 			if (chunkPos.getChessboardDistance(this.lastPosition) > 0) {
 | |
| 				this.receiver.connection.send(ClientboundTrackedWaypointPacket.updateWaypointChunk(this.source.getUUID(), this.icon, chunkPos));
 | |
| 				this.lastPosition = chunkPos;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public boolean isBroken() {
 | |
| 			return !WaypointTransmitter.ChunkConnection.super.isBroken() && !WaypointTransmitter.doesSourceIgnoreReceiver(this.source, this.receiver)
 | |
| 				? WaypointTransmitter.isChunkVisible(this.lastPosition, this.receiver)
 | |
| 				: true;
 | |
| 		}
 | |
| 	}
 | |
| }
 |