Added primitive player health and killing system.
This commit is contained in:
		
							parent
							
								
									4ef355f707
								
							
						
					
					
						commit
						e1456707dd
					
				| 
						 | 
					@ -1,10 +1,13 @@
 | 
				
			||||||
package nl.andrewl.aos_core;
 | 
					package nl.andrewl.aos_core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.joml.Vector3f;
 | 
				
			||||||
 | 
					import org.joml.Vector3fc;
 | 
				
			||||||
import org.joml.Vector3i;
 | 
					import org.joml.Vector3i;
 | 
				
			||||||
import org.joml.Vector3ic;
 | 
					import org.joml.Vector3ic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Directions {
 | 
					public class Directions {
 | 
				
			||||||
	public static final Vector3ic UP = new Vector3i(0, 1, 0);
 | 
						public static final Vector3ic UP = new Vector3i(0, 1, 0);
 | 
				
			||||||
 | 
						public static final Vector3fc UPf = new Vector3f(0, 1, 0);
 | 
				
			||||||
	public static final Vector3ic DOWN = new Vector3i(0, -1, 0);
 | 
						public static final Vector3ic DOWN = new Vector3i(0, -1, 0);
 | 
				
			||||||
	public static final Vector3ic NEGATIVE_X = new Vector3i(-1, 0, 0);
 | 
						public static final Vector3ic NEGATIVE_X = new Vector3i(-1, 0, 0);
 | 
				
			||||||
	public static final Vector3ic POSITIVE_X = new Vector3i(1, 0, 0);
 | 
						public static final Vector3ic POSITIVE_X = new Vector3i(1, 0, 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,7 @@ public final class Net {
 | 
				
			||||||
		serializer.registerType(15, InventorySelectedStackMessage.class);
 | 
							serializer.registerType(15, InventorySelectedStackMessage.class);
 | 
				
			||||||
		serializer.registerType(16, SoundMessage.class);
 | 
							serializer.registerType(16, SoundMessage.class);
 | 
				
			||||||
		serializer.registerType(17, ProjectileMessage.class);
 | 
							serializer.registerType(17, ProjectileMessage.class);
 | 
				
			||||||
 | 
							serializer.registerType(18, ClientHealthMessage.class);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static ExtendedDataInputStream getInputStream(InputStream in) {
 | 
						public static ExtendedDataInputStream getInputStream(InputStream in) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,13 @@
 | 
				
			||||||
package nl.andrewl.aos_core.model;
 | 
					package nl.andrewl.aos_core.model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import nl.andrewl.aos_core.MathUtils;
 | 
					import nl.andrewl.aos_core.MathUtils;
 | 
				
			||||||
 | 
					import org.joml.Math;
 | 
				
			||||||
import org.joml.Vector2f;
 | 
					import org.joml.Vector2f;
 | 
				
			||||||
import org.joml.Vector3f;
 | 
					import org.joml.Vector3f;
 | 
				
			||||||
 | 
					import org.joml.Vector3i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.joml.Math.*;
 | 
					import static org.joml.Math.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,4 +167,35 @@ public class Player {
 | 
				
			||||||
	public float getCurrentHeight() {
 | 
						public float getCurrentHeight() {
 | 
				
			||||||
		return crouching ? HEIGHT_CROUCH : HEIGHT;
 | 
							return crouching ? HEIGHT_CROUCH : HEIGHT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public List<Vector3i> getBlockSpaceOccupied() {
 | 
				
			||||||
 | 
							float playerBodyMinZ = position.z - RADIUS;
 | 
				
			||||||
 | 
							float playerBodyMaxZ = position.z + RADIUS;
 | 
				
			||||||
 | 
							float playerBodyMinX = position.x - RADIUS;
 | 
				
			||||||
 | 
							float playerBodyMaxX = position.x + RADIUS;
 | 
				
			||||||
 | 
							float playerBodyMinY = position.y;
 | 
				
			||||||
 | 
							float playerBodyMaxY = position.y + getCurrentHeight();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Compute the bounds of all blocks the player is intersecting with.
 | 
				
			||||||
 | 
							int minX = (int) Math.floor(playerBodyMinX);
 | 
				
			||||||
 | 
							int minZ = (int) Math.floor(playerBodyMinZ);
 | 
				
			||||||
 | 
							int minY = (int) Math.floor(playerBodyMinY);
 | 
				
			||||||
 | 
							int maxX = (int) Math.floor(playerBodyMaxX);
 | 
				
			||||||
 | 
							int maxZ = (int) Math.floor(playerBodyMaxZ);
 | 
				
			||||||
 | 
							int maxY = (int) Math.floor(playerBodyMaxY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							List<Vector3i> vectors = new ArrayList<>(8);
 | 
				
			||||||
 | 
							for (int x = minX; x <= maxX; x++) {
 | 
				
			||||||
 | 
								for (int y = minY; y <= maxY; y++) {
 | 
				
			||||||
 | 
									for (int z = minZ; z <= maxZ; z++) {
 | 
				
			||||||
 | 
										vectors.add(new Vector3i(x, y, z));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return vectors;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean isSpaceOccupied(Vector3i pos) {
 | 
				
			||||||
 | 
							return getBlockSpaceOccupied().contains(pos);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
package nl.andrewl.aos_core.model.world;
 | 
					package nl.andrewl.aos_core.model.world;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.joml.Vector3f;
 | 
				
			||||||
import org.joml.Vector3i;
 | 
					import org.joml.Vector3i;
 | 
				
			||||||
import org.joml.Vector3ic;
 | 
					import org.joml.Vector3ic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,5 +10,6 @@ import org.joml.Vector3ic;
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public record Hit (
 | 
					public record Hit (
 | 
				
			||||||
		Vector3i pos,
 | 
							Vector3i pos,
 | 
				
			||||||
		Vector3ic norm
 | 
							Vector3ic norm,
 | 
				
			||||||
 | 
							Vector3f rawPos
 | 
				
			||||||
) {}
 | 
					) {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ import java.util.Map;
 | 
				
			||||||
 * that players can interact in.
 | 
					 * that players can interact in.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class World {
 | 
					public class World {
 | 
				
			||||||
	private static final float DELTA = 0.00001f;
 | 
						private static final float DELTA = 0.0001f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected final Map<Vector3ic, Chunk> chunkMap = new HashMap<>();
 | 
						protected final Map<Vector3ic, Chunk> chunkMap = new HashMap<>();
 | 
				
			||||||
	protected ColorPalette palette;
 | 
						protected ColorPalette palette;
 | 
				
			||||||
| 
						 | 
					@ -160,7 +160,7 @@ public class World {
 | 
				
			||||||
					System.err.println("Invalid hit!");
 | 
										System.err.println("Invalid hit!");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return new Hit(hitPos, hitNorm);
 | 
									return new Hit(hitPos, hitNorm, pos);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return null;
 | 
							return null;
 | 
				
			||||||
| 
						 | 
					@ -189,7 +189,7 @@ public class World {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static float factorToNextValue(float n, float dir) {
 | 
						private static float factorToNextValue(float n, float dir) {
 | 
				
			||||||
		if (dir == 0) return 0;
 | 
							if (dir == 0) return Float.MAX_VALUE;
 | 
				
			||||||
		float nextValue;
 | 
							float nextValue;
 | 
				
			||||||
		if (dir > 0) {
 | 
							if (dir > 0) {
 | 
				
			||||||
			nextValue = (Math.ceil(n) == n) ? n + 1 : Math.ceil(n);
 | 
								nextValue = (Math.ceil(n) == n) ? n + 1 : Math.ceil(n);
 | 
				
			||||||
| 
						 | 
					@ -197,6 +197,11 @@ public class World {
 | 
				
			||||||
			nextValue = Math.floor(n) - DELTA;
 | 
								nextValue = Math.floor(n) - DELTA;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		float diff = nextValue - n;
 | 
							float diff = nextValue - n;
 | 
				
			||||||
 | 
							// Testing code!
 | 
				
			||||||
 | 
							if (diff == 0) {
 | 
				
			||||||
 | 
								System.out.printf("n = %.8f, nextValue = %.8f, floor(n) - DELTA = %.8f%n", n, nextValue, Math.floor(n) - DELTA);
 | 
				
			||||||
 | 
								throw new RuntimeException("EEK");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return Math.abs(diff / dir);
 | 
							return Math.abs(diff / dir);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					package nl.andrewl.aos_core.net.client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nl.andrewl.record_net.Message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A message that's sent to update a client with their player's latest health
 | 
				
			||||||
 | 
					 * information.
 | 
				
			||||||
 | 
					 * @param health The player's health.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public record ClientHealthMessage(
 | 
				
			||||||
 | 
							float health
 | 
				
			||||||
 | 
					) implements Message {}
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ package nl.andrewl.aos2_server;
 | 
				
			||||||
import nl.andrewl.aos2_server.model.ServerPlayer;
 | 
					import nl.andrewl.aos2_server.model.ServerPlayer;
 | 
				
			||||||
import nl.andrewl.aos_core.Net;
 | 
					import nl.andrewl.aos_core.Net;
 | 
				
			||||||
import nl.andrewl.aos_core.model.Team;
 | 
					import nl.andrewl.aos_core.model.Team;
 | 
				
			||||||
 | 
					import nl.andrewl.aos_core.net.client.ClientHealthMessage;
 | 
				
			||||||
import nl.andrewl.aos_core.net.client.PlayerJoinMessage;
 | 
					import nl.andrewl.aos_core.net.client.PlayerJoinMessage;
 | 
				
			||||||
import nl.andrewl.aos_core.net.client.PlayerLeaveMessage;
 | 
					import nl.andrewl.aos_core.net.client.PlayerLeaveMessage;
 | 
				
			||||||
import nl.andrewl.aos_core.net.connect.DatagramInit;
 | 
					import nl.andrewl.aos_core.net.connect.DatagramInit;
 | 
				
			||||||
| 
						 | 
					@ -121,6 +122,21 @@ public class PlayerManager {
 | 
				
			||||||
		return server.getWorld().getSpawnPoints().values().stream().findAny().orElse(new Vector3f(0, 0, 0));
 | 
							return server.getWorld().getSpawnPoints().values().stream().findAny().orElse(new Vector3f(0, 0, 0));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * This method is invoked by the server's logic if a player has been
 | 
				
			||||||
 | 
						 * determined to be killed somehow. We will reset their inventory, health,
 | 
				
			||||||
 | 
						 * and respawn them.
 | 
				
			||||||
 | 
						 * @param player The player that died.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public void playerKilled(ServerPlayer player) {
 | 
				
			||||||
 | 
							player.setPosition(getBestSpawnPoint(player));
 | 
				
			||||||
 | 
							player.setVelocity(new Vector3f(0));
 | 
				
			||||||
 | 
							player.setHealth(1);
 | 
				
			||||||
 | 
							getHandler(player.getId()).sendDatagramPacket(new ClientHealthMessage(player.getHealth()));
 | 
				
			||||||
 | 
							broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis()));
 | 
				
			||||||
 | 
							// TODO: Team points or something.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void handleUdpInit(DatagramInit init, DatagramPacket packet) {
 | 
						public void handleUdpInit(DatagramInit init, DatagramPacket packet) {
 | 
				
			||||||
		var handler = getHandler(init.clientId());
 | 
							var handler = getHandler(init.clientId());
 | 
				
			||||||
		if (handler != null) {
 | 
							if (handler != null) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,12 @@ package nl.andrewl.aos2_server;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import nl.andrewl.aos2_server.model.ServerPlayer;
 | 
					import nl.andrewl.aos2_server.model.ServerPlayer;
 | 
				
			||||||
import nl.andrewl.aos2_server.model.ServerProjectile;
 | 
					import nl.andrewl.aos2_server.model.ServerProjectile;
 | 
				
			||||||
 | 
					import nl.andrewl.aos_core.Directions;
 | 
				
			||||||
 | 
					import nl.andrewl.aos_core.model.Player;
 | 
				
			||||||
import nl.andrewl.aos_core.model.Projectile;
 | 
					import nl.andrewl.aos_core.model.Projectile;
 | 
				
			||||||
import nl.andrewl.aos_core.model.world.Hit;
 | 
					import nl.andrewl.aos_core.model.world.Hit;
 | 
				
			||||||
import nl.andrewl.aos_core.net.world.ChunkUpdateMessage;
 | 
					import nl.andrewl.aos_core.net.world.ChunkUpdateMessage;
 | 
				
			||||||
 | 
					import org.joml.Matrix4f;
 | 
				
			||||||
import org.joml.Vector3f;
 | 
					import org.joml.Vector3f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
| 
						 | 
					@ -12,7 +15,13 @@ import java.util.LinkedList;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.Queue;
 | 
					import java.util.Queue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that manages the set of all active projectiles in the world, and
 | 
				
			||||||
 | 
					 * performs tick updates for them.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
public class ProjectileManager {
 | 
					public class ProjectileManager {
 | 
				
			||||||
 | 
						public static final float MOVEMENT_FACTOR = 1f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final Server server;
 | 
						private final Server server;
 | 
				
			||||||
	private int nextProjectileId = 1;
 | 
						private int nextProjectileId = 1;
 | 
				
			||||||
	private final Map<Integer, ServerProjectile> projectiles;
 | 
						private final Map<Integer, ServerProjectile> projectiles;
 | 
				
			||||||
| 
						 | 
					@ -27,8 +36,15 @@ public class ProjectileManager {
 | 
				
			||||||
	public void spawnBullet(ServerPlayer player) {
 | 
						public void spawnBullet(ServerPlayer player) {
 | 
				
			||||||
		int id = nextProjectileId++;
 | 
							int id = nextProjectileId++;
 | 
				
			||||||
		if (nextProjectileId == Integer.MAX_VALUE) nextProjectileId = 1;
 | 
							if (nextProjectileId == Integer.MAX_VALUE) nextProjectileId = 1;
 | 
				
			||||||
		Vector3f pos = new Vector3f(player.getEyePosition());
 | 
							Vector3f pos = new Vector3f();
 | 
				
			||||||
		Vector3f vel = new Vector3f(player.getViewVector()).normalize().mul(300);
 | 
							Matrix4f bulletTransform = new Matrix4f()
 | 
				
			||||||
 | 
									.translate(player.getEyePosition())
 | 
				
			||||||
 | 
									.rotate(player.getOrientation().x + (float) Math.PI, Directions.UPf)
 | 
				
			||||||
 | 
									.translate(-0.35f, -0.4f, 0.35f);
 | 
				
			||||||
 | 
							bulletTransform.transformPosition(pos);
 | 
				
			||||||
 | 
							Vector3f vel = new Vector3f(player.getViewVector()).normalize()
 | 
				
			||||||
 | 
									.mul(200 * MOVEMENT_FACTOR)
 | 
				
			||||||
 | 
									.add(player.getVelocity());
 | 
				
			||||||
		ServerProjectile bullet = new ServerProjectile(id, pos, vel, Projectile.Type.BULLET, player);
 | 
							ServerProjectile bullet = new ServerProjectile(id, pos, vel, Projectile.Type.BULLET, player);
 | 
				
			||||||
		projectiles.put(bullet.getId(), bullet);
 | 
							projectiles.put(bullet.getId(), bullet);
 | 
				
			||||||
		server.getPlayerManager().broadcastUdpMessage(bullet.toMessage(false));
 | 
							server.getPlayerManager().broadcastUdpMessage(bullet.toMessage(false));
 | 
				
			||||||
| 
						 | 
					@ -45,21 +61,82 @@ public class ProjectileManager {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void tickProjectile(ServerProjectile projectile, float dt) {
 | 
						private void tickProjectile(ServerProjectile projectile, float dt) {
 | 
				
			||||||
		projectile.getVelocity().y -= server.getConfig().physics.gravity * dt;
 | 
							projectile.getVelocity().y -= server.getConfig().physics.gravity * dt * MOVEMENT_FACTOR;
 | 
				
			||||||
		// TODO: Check if bullet will hit anything, like blocks or players, if it follows current velocity.
 | 
					
 | 
				
			||||||
 | 
							// Check for if the bullet will move close enough to a player to hit them.
 | 
				
			||||||
		Vector3f movement = new Vector3f(projectile.getVelocity()).mul(dt);
 | 
							Vector3f movement = new Vector3f(projectile.getVelocity()).mul(dt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Check first to see if we'll hit a player this tick.
 | 
				
			||||||
 | 
							Vector3f testPos = new Vector3f();
 | 
				
			||||||
 | 
							Vector3f testMovement = new Vector3f(movement).normalize(0.1f);
 | 
				
			||||||
 | 
							Vector3f playerHit = null;
 | 
				
			||||||
 | 
							ServerPlayer hitPlayer = null;
 | 
				
			||||||
 | 
							int playerHitType = -1;
 | 
				
			||||||
 | 
							for (ServerPlayer player : server.getPlayerManager().getPlayers()) {
 | 
				
			||||||
 | 
								// Don't allow players to shoot themselves.
 | 
				
			||||||
 | 
								if (projectile.getPlayer() != null && projectile.getPlayer().equals(player)) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Vector3f headPos = player.getEyePosition();
 | 
				
			||||||
 | 
								Vector3f bodyPos = new Vector3f(player.getPosition());
 | 
				
			||||||
 | 
								bodyPos.y += 1.0f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Do a really shitty collision detection... check in 10cm increments if we're close to the player.
 | 
				
			||||||
 | 
								// TODO: Come up with a better collision system.
 | 
				
			||||||
 | 
								testPos.set(projectile.getPosition());
 | 
				
			||||||
 | 
								while (testPos.distanceSquared(projectile.getPosition()) < movement.lengthSquared() && playerHit == null) {
 | 
				
			||||||
 | 
									if (testPos.distanceSquared(headPos) < Player.RADIUS * Player.RADIUS) {
 | 
				
			||||||
 | 
										playerHitType = 1;
 | 
				
			||||||
 | 
										playerHit = new Vector3f(testPos);
 | 
				
			||||||
 | 
										hitPlayer = player;
 | 
				
			||||||
 | 
									} else if (testPos.distanceSquared(bodyPos) < Player.RADIUS * Player.RADIUS) {
 | 
				
			||||||
 | 
										playerHitType = 2;
 | 
				
			||||||
 | 
										playerHit = new Vector3f(testPos);
 | 
				
			||||||
 | 
										hitPlayer = player;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									testPos.add(testMovement);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Then check to see if we'll hit the world during this tick.
 | 
				
			||||||
		Vector3f movementDir = new Vector3f(movement).normalize();
 | 
							Vector3f movementDir = new Vector3f(movement).normalize();
 | 
				
			||||||
//		Hit hit = server.getWorld().getLookingAtPos(projectile.getPosition(), movementDir, movement.length());
 | 
							Hit hit = server.getWorld().getLookingAtPos(projectile.getPosition(), movementDir, movement.length());
 | 
				
			||||||
		projectile.getPosition().add(movement);
 | 
					
 | 
				
			||||||
		if (projectile.getDistanceTravelled() > 500) {
 | 
							float playerHitDist = Float.MAX_VALUE;
 | 
				
			||||||
//			if (hit != null) {
 | 
							if (playerHit != null) playerHitDist = projectile.getPosition().distanceSquared(playerHit);
 | 
				
			||||||
//				server.getWorld().setBlockAt(hit.pos().x, hit.pos().y, hit.pos().z, (byte) 0);
 | 
							float worldHitDist = Float.MAX_VALUE;
 | 
				
			||||||
//				server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(hit.pos(), server.getWorld()));
 | 
							if (hit != null) worldHitDist = projectile.getPosition().distanceSquared(hit.rawPos());
 | 
				
			||||||
//			}
 | 
					
 | 
				
			||||||
			removalQueue.add(projectile);
 | 
							// If we hit the world before the player,
 | 
				
			||||||
			server.getPlayerManager().broadcastUdpMessage(projectile.toMessage(true));
 | 
							if (hit != null && (playerHit == null || worldHitDist < playerHitDist)) {
 | 
				
			||||||
 | 
								// Bullet struck the world first.
 | 
				
			||||||
 | 
								server.getWorld().setBlockAt(hit.pos().x, hit.pos().y, hit.pos().z, (byte) 0);
 | 
				
			||||||
 | 
								server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(hit.pos(), server.getWorld()));
 | 
				
			||||||
 | 
								deleteProjectile(projectile);
 | 
				
			||||||
 | 
							} else if (playerHit != null && (hit == null || playerHitDist < worldHitDist)) {
 | 
				
			||||||
 | 
								// Bullet struck the player first.
 | 
				
			||||||
 | 
								System.out.println("Player hit: " + playerHitType);
 | 
				
			||||||
 | 
								float damage = 0.4f;
 | 
				
			||||||
 | 
								if (playerHitType == 1) damage *= 2;
 | 
				
			||||||
 | 
								hitPlayer.setHealth(hitPlayer.getHealth() - damage);
 | 
				
			||||||
 | 
								System.out.println(hitPlayer.getHealth());
 | 
				
			||||||
 | 
								if (hitPlayer.getHealth() == 0) {
 | 
				
			||||||
 | 
									System.out.println("Player killed!!!");
 | 
				
			||||||
 | 
									server.getPlayerManager().playerKilled(hitPlayer);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								deleteProjectile(projectile);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			server.getPlayerManager().broadcastUdpMessage(projectile.toMessage(false));
 | 
								// Bullet struck nothing.
 | 
				
			||||||
 | 
								projectile.getPosition().add(movement);
 | 
				
			||||||
 | 
								if (projectile.getDistanceTravelled() > 500) {
 | 
				
			||||||
 | 
									deleteProjectile(projectile);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									server.getPlayerManager().broadcastUdpMessage(projectile.toMessage(false));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private void deleteProjectile(ServerProjectile p) {
 | 
				
			||||||
 | 
							removalQueue.add(p);
 | 
				
			||||||
 | 
							server.getPlayerManager().broadcastUdpMessage(p.toMessage(true));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,9 +22,16 @@ public class ServerPlayer extends Player {
 | 
				
			||||||
	private final PlayerActionManager actionManager;
 | 
						private final PlayerActionManager actionManager;
 | 
				
			||||||
	private final Inventory inventory;
 | 
						private final Inventory inventory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * The player's health, from 0 to 1, where <= 0 means death, and 1 means
 | 
				
			||||||
 | 
						 * full health.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						private float health;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public ServerPlayer(int id, String username) {
 | 
						public ServerPlayer(int id, String username) {
 | 
				
			||||||
		super(id, username);
 | 
							super(id, username);
 | 
				
			||||||
		this.inventory = new Inventory(new ArrayList<>(), 0);
 | 
							this.inventory = new Inventory(new ArrayList<>(), 0);
 | 
				
			||||||
 | 
							this.health = 1f;
 | 
				
			||||||
		this.actionManager = new PlayerActionManager(this);
 | 
							this.actionManager = new PlayerActionManager(this);
 | 
				
			||||||
		inventory.getItemStacks().add(new GunItemStack(ItemTypes.RIFLE));
 | 
							inventory.getItemStacks().add(new GunItemStack(ItemTypes.RIFLE));
 | 
				
			||||||
		inventory.getItemStacks().add(new BlockItemStack(ItemTypes.BLOCK, 50, (byte) 1));
 | 
							inventory.getItemStacks().add(new BlockItemStack(ItemTypes.BLOCK, 50, (byte) 1));
 | 
				
			||||||
| 
						 | 
					@ -39,6 +46,16 @@ public class ServerPlayer extends Player {
 | 
				
			||||||
		return inventory;
 | 
							return inventory;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public float getHealth() {
 | 
				
			||||||
 | 
							return health;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void setHealth(float health) {
 | 
				
			||||||
 | 
							if (health > 1) health = 1;
 | 
				
			||||||
 | 
							if (health < 0) health = 0;
 | 
				
			||||||
 | 
							this.health = health;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Helper method to build an update message for this player, to be sent to
 | 
						 * Helper method to build an update message for this player, to be sent to
 | 
				
			||||||
	 * various clients.
 | 
						 * various clients.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue