Improved client connection.
This commit is contained in:
		
							parent
							
								
									bd02d89995
								
							
						
					
					
						commit
						4bc994d07e
					
				| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
package nl.andrewlalis.aos_client;
 | 
			
		||||
 | 
			
		||||
import nl.andrewlalis.aos_client.view.ConnectDialog;
 | 
			
		||||
import nl.andrewlalis.aos_client.view.GameFrame;
 | 
			
		||||
import nl.andrewlalis.aos_client.view.GamePanel;
 | 
			
		||||
import nl.andrewlalis.aos_core.model.PlayerControlState;
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +9,6 @@ import nl.andrewlalis.aos_core.net.PlayerControlStateMessage;
 | 
			
		|||
import nl.andrewlalis.aos_core.net.chat.ChatMessage;
 | 
			
		||||
import nl.andrewlalis.aos_core.net.chat.PlayerChatMessage;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
| 
						 | 
				
			
			@ -153,22 +153,7 @@ public class Client {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
	public static void main(String[] args) {
 | 
			
		||||
		String hostAndPort = JOptionPane.showInputDialog("Enter server host and port (host:port):");
 | 
			
		||||
		if (hostAndPort == null) throw new IllegalArgumentException("A host and port is required.");
 | 
			
		||||
		String[] parts = hostAndPort.split(":");
 | 
			
		||||
		if (parts.length != 2) throw new IllegalArgumentException("Invalid host:port.");
 | 
			
		||||
		String host = parts[0].trim();
 | 
			
		||||
		int port = Integer.parseInt(parts[1]);
 | 
			
		||||
		String username = JOptionPane.showInputDialog("Enter a username:");
 | 
			
		||||
		if (username == null || username.isBlank()) throw new IllegalArgumentException("Username is required.");
 | 
			
		||||
 | 
			
		||||
		Client client = new Client();
 | 
			
		||||
		try {
 | 
			
		||||
			client.connect(host, port, username);
 | 
			
		||||
		} catch (IOException | ClassNotFoundException e) {
 | 
			
		||||
			client.shutdown();
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
			JOptionPane.showMessageDialog(null, "Could not connect:\n" + e.getMessage(), "Connection Error", JOptionPane.WARNING_MESSAGE);
 | 
			
		||||
		}
 | 
			
		||||
		ConnectDialog dialog = new ConnectDialog();
 | 
			
		||||
		dialog.setVisible(true);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,109 @@
 | 
			
		|||
package nl.andrewlalis.aos_client.view;
 | 
			
		||||
 | 
			
		||||
import nl.andrewlalis.aos_client.Client;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.awt.event.KeyAdapter;
 | 
			
		||||
import java.awt.event.KeyEvent;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
public class ConnectDialog extends JDialog {
 | 
			
		||||
	private static final Pattern addressPattern = Pattern.compile("(.+):(\\d+)");
 | 
			
		||||
 | 
			
		||||
	public ConnectDialog() {
 | 
			
		||||
		super((Frame) null, "Connect to Server", false);
 | 
			
		||||
		JPanel inputPanel = new JPanel(new GridBagLayout());
 | 
			
		||||
		GridBagConstraints c = new GridBagConstraints();
 | 
			
		||||
		c.insets = new Insets(5, 5, 5, 5);
 | 
			
		||||
 | 
			
		||||
		c.gridx = 0;
 | 
			
		||||
		c.gridy = 0;
 | 
			
		||||
		inputPanel.add(new JLabel("Address"), c);
 | 
			
		||||
		JTextField addressField = new JTextField(20);
 | 
			
		||||
		c.gridx = 1;
 | 
			
		||||
		inputPanel.add(addressField, c);
 | 
			
		||||
 | 
			
		||||
		c.gridy = 1;
 | 
			
		||||
		c.gridx = 0;
 | 
			
		||||
		inputPanel.add(new JLabel("Username"), c);
 | 
			
		||||
		JTextField usernameField = new JTextField(20);
 | 
			
		||||
		c.gridx = 1;
 | 
			
		||||
		inputPanel.add(usernameField, c);
 | 
			
		||||
 | 
			
		||||
		var enterListener = new KeyAdapter() {
 | 
			
		||||
			@Override
 | 
			
		||||
			public void keyPressed(KeyEvent e) {
 | 
			
		||||
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
 | 
			
		||||
					if (validateInput(addressField, usernameField)) {
 | 
			
		||||
						connect(addressField, usernameField);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		addressField.addKeyListener(enterListener);
 | 
			
		||||
		usernameField.addKeyListener(enterListener);
 | 
			
		||||
 | 
			
		||||
		JPanel buttonPanel = new JPanel(new FlowLayout());
 | 
			
		||||
		JButton cancelButton = new JButton("Cancel");
 | 
			
		||||
		cancelButton.addActionListener(e -> this.dispose());
 | 
			
		||||
		JButton connectButton = new JButton("Connect");
 | 
			
		||||
		connectButton.addActionListener(e -> {
 | 
			
		||||
			if (validateInput(addressField, usernameField)) {
 | 
			
		||||
				connect(addressField, usernameField);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		buttonPanel.add(cancelButton);
 | 
			
		||||
		buttonPanel.add(connectButton);
 | 
			
		||||
 | 
			
		||||
		JPanel mainPanel = new JPanel(new BorderLayout());
 | 
			
		||||
		mainPanel.add(inputPanel, BorderLayout.CENTER);
 | 
			
		||||
		mainPanel.add(buttonPanel, BorderLayout.SOUTH);
 | 
			
		||||
 | 
			
		||||
		this.setContentPane(mainPanel);
 | 
			
		||||
		this.pack();
 | 
			
		||||
		this.setLocationRelativeTo(null);
 | 
			
		||||
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean validateInput(JTextField addressField, JTextField usernameField) {
 | 
			
		||||
		List<String> warnings = new ArrayList<>();
 | 
			
		||||
		if (addressField.getText() == null || addressField.getText().isBlank()) {
 | 
			
		||||
			warnings.add("Address must not be empty.");
 | 
			
		||||
		}
 | 
			
		||||
		if (usernameField.getText() == null || usernameField.getText().isBlank()) {
 | 
			
		||||
			warnings.add("Username must not be empty.");
 | 
			
		||||
		}
 | 
			
		||||
		if (addressField.getText() != null && !addressPattern.matcher(addressField.getText()).matches()) {
 | 
			
		||||
			warnings.add("Address must be in the form HOST:PORT.");
 | 
			
		||||
		}
 | 
			
		||||
		if (!warnings.isEmpty()) {
 | 
			
		||||
			JOptionPane.showMessageDialog(
 | 
			
		||||
				this,
 | 
			
		||||
				String.join("\n", warnings),
 | 
			
		||||
				"Invalid Input",
 | 
			
		||||
				JOptionPane.WARNING_MESSAGE
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		return warnings.isEmpty();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void connect(JTextField addressField, JTextField usernameField) {
 | 
			
		||||
		String hostAndPort = addressField.getText();
 | 
			
		||||
		String[] parts = hostAndPort.split(":");
 | 
			
		||||
		String host = parts[0].trim();
 | 
			
		||||
		int port = Integer.parseInt(parts[1]);
 | 
			
		||||
		String username = usernameField.getText();
 | 
			
		||||
		Client client = new Client();
 | 
			
		||||
		try {
 | 
			
		||||
			client.connect(host, port, username);
 | 
			
		||||
		} catch (IOException | ClassNotFoundException ex) {
 | 
			
		||||
			client.shutdown();
 | 
			
		||||
			ex.printStackTrace();
 | 
			
		||||
			JOptionPane.showMessageDialog(null, "Could not connect:\n" + ex.getMessage(), "Connection Error", JOptionPane.WARNING_MESSAGE);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -48,10 +48,12 @@ public class GamePanel extends JPanel {
 | 
			
		|||
		g2.clearRect(0, 0, this.getWidth(), this.getHeight());
 | 
			
		||||
 | 
			
		||||
		World world = client.getWorld();
 | 
			
		||||
		if (world != null) drawWorld(g2, world);
 | 
			
		||||
		drawChat(g2, world);
 | 
			
		||||
		if (world != null) {
 | 
			
		||||
			drawWorld(g2, world);
 | 
			
		||||
			drawStatus(g2, world);
 | 
			
		||||
		}
 | 
			
		||||
		drawChat(g2, world);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void drawWorld(Graphics2D g2, World world) {
 | 
			
		||||
		Player myPlayer = world.getPlayers().get(this.client.getPlayerId());
 | 
			
		||||
| 
						 | 
				
			
			@ -234,5 +236,20 @@ public class GamePanel extends JPanel {
 | 
			
		|||
		Gun gun = myPlayer.getGun();
 | 
			
		||||
		g2.drawString("Clips: " + gun.getClipCount() + " / " + gun.getMaxClipCount(), 5, this.getHeight() - 20);
 | 
			
		||||
		g2.drawString("Bullets: " + gun.getCurrentClipBulletCount() + " / " + gun.getClipSize(), 5, this.getHeight() - 30);
 | 
			
		||||
		if (myPlayer.getHealth() >= 66.0f) {
 | 
			
		||||
			g2.setColor(Color.GREEN);
 | 
			
		||||
		} else if (myPlayer.getHealth() >= 33.0f) {
 | 
			
		||||
			g2.setColor(Color.YELLOW);
 | 
			
		||||
		} else {
 | 
			
		||||
			g2.setColor(Color.RED);
 | 
			
		||||
		}
 | 
			
		||||
		g2.drawString(String.format("Health: %.1f / %.1f", myPlayer.getHealth(), Player.MAX_HEALTH), 5, this.getHeight() - 40);
 | 
			
		||||
 | 
			
		||||
		int y = this.getHeight() - 60;
 | 
			
		||||
		for (Team t : world.getTeams()) {
 | 
			
		||||
			g2.setColor(t.getColor());
 | 
			
		||||
			g2.drawString("Team " + t.getName() + ": " + t.getScore(), 5, y);
 | 
			
		||||
			y -= 15;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
package nl.andrewlalis.aos_core.geom;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.concurrent.ThreadLocalRandom;
 | 
			
		||||
 | 
			
		||||
public record Vec2(double x, double y) implements Serializable {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,4 +58,11 @@ public record Vec2(double x, double y) implements Serializable {
 | 
			
		|||
	public String toString() {
 | 
			
		||||
		return "[ " + x + ", " + y + " ]";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Vec2 random(double min, double max) {
 | 
			
		||||
		Random r = ThreadLocalRandom.current();
 | 
			
		||||
		double x = r.nextDouble() * (max - min) + min;
 | 
			
		||||
		double y = r.nextDouble() * (max - min) + min;
 | 
			
		||||
		return new Vec2(x, y);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,26 +1,34 @@
 | 
			
		|||
package nl.andrewlalis.aos_core.model;
 | 
			
		||||
 | 
			
		||||
import nl.andrewlalis.aos_core.geom.Vec2;
 | 
			
		||||
import nl.andrewlalis.aos_core.model.tools.Gun;
 | 
			
		||||
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.concurrent.ThreadLocalRandom;
 | 
			
		||||
 | 
			
		||||
public class Bullet extends PhysicsObject {
 | 
			
		||||
	private final int playerId;
 | 
			
		||||
	private final Gun gun;
 | 
			
		||||
 | 
			
		||||
	public Bullet(Player player) {
 | 
			
		||||
		super(
 | 
			
		||||
			player.getPosition().add(player.getOrientation().mul(1.5)),
 | 
			
		||||
			player.getOrientation(),
 | 
			
		||||
			null
 | 
			
		||||
		);
 | 
			
		||||
		this.playerId = player.getId();
 | 
			
		||||
		this.setPosition(player.getPosition()
 | 
			
		||||
			.add(player.getOrientation().mul(1.5))
 | 
			
		||||
			.add(player.getOrientation().perp().mul(Player.RADIUS))
 | 
			
		||||
		);
 | 
			
		||||
		this.setOrientation(player.getOrientation());
 | 
			
		||||
 | 
			
		||||
		Random r = ThreadLocalRandom.current();
 | 
			
		||||
		Vec2 perturbation = new Vec2((r.nextDouble() - 0.5) * 2, (r.nextDouble() - 0.5) * 2).mul(player.getGun().getAccuracy());
 | 
			
		||||
		this.setVelocity(player.getOrientation().add(perturbation).mul(player.getGun().getBulletSpeed()));
 | 
			
		||||
		this.setVelocity(this.getOrientation().add(perturbation).mul(player.getGun().getBulletSpeed()));
 | 
			
		||||
		this.gun = player.getGun();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int getPlayerId() {
 | 
			
		||||
		return playerId;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Gun getGun() {
 | 
			
		||||
		return gun;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
package nl.andrewlalis.aos_core.model;
 | 
			
		||||
 | 
			
		||||
import nl.andrewlalis.aos_core.geom.Vec2;
 | 
			
		||||
import nl.andrewlalis.aos_core.model.tools.Gun;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
| 
						 | 
				
			
			@ -8,12 +9,14 @@ public class Player extends PhysicsObject {
 | 
			
		|||
	public static final double MOVEMENT_SPEED = 10; // Movement speed, in m/s
 | 
			
		||||
	public static final double RADIUS = 0.5; // Collision radius, in meters.
 | 
			
		||||
	public static final double RESUPPLY_COOLDOWN = 30; // Seconds between allowing resupply.
 | 
			
		||||
	public static final float MAX_HEALTH = 100.0f;
 | 
			
		||||
 | 
			
		||||
	private final int id;
 | 
			
		||||
	private final String name;
 | 
			
		||||
	private Team team;
 | 
			
		||||
	private PlayerControlState state;
 | 
			
		||||
	private Gun gun;
 | 
			
		||||
	private float health;
 | 
			
		||||
 | 
			
		||||
	private transient long lastShot;
 | 
			
		||||
	private transient long reloadingStartedAt;
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +30,7 @@ public class Player extends PhysicsObject {
 | 
			
		|||
		this.state = new PlayerControlState();
 | 
			
		||||
		this.state.setPlayerId(this.id);
 | 
			
		||||
		this.gun = Gun.winchester();
 | 
			
		||||
		this.health = MAX_HEALTH;
 | 
			
		||||
		this.useWeapon();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -111,6 +115,23 @@ public class Player extends PhysicsObject {
 | 
			
		|||
	public void resupply() {
 | 
			
		||||
		this.lastResupply = System.currentTimeMillis();
 | 
			
		||||
		this.gun.refillClips();
 | 
			
		||||
		this.health = MAX_HEALTH;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public float getHealth() {
 | 
			
		||||
		return health;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void takeDamage(float damage) {
 | 
			
		||||
		this.health = Math.max(this.health - damage, 0.0f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void respawn() {
 | 
			
		||||
		this.resupply();
 | 
			
		||||
		this.gun.emptyCurrentClip();
 | 
			
		||||
		if (this.team != null) {
 | 
			
		||||
			this.setPosition(this.team.getSpawnPoint().add(Vec2.random(-Team.SPAWN_RADIUS / 2, Team.SPAWN_RADIUS / 2)));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,8 @@ public class Team implements Serializable {
 | 
			
		|||
 | 
			
		||||
	private final List<Player> players;
 | 
			
		||||
 | 
			
		||||
	private int score;
 | 
			
		||||
 | 
			
		||||
	public Team(String name, Color color, Vec2 spawnPoint, Vec2 supplyPoint, Vec2 orientation) {
 | 
			
		||||
		this.name = name;
 | 
			
		||||
		this.color = color;
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +28,7 @@ public class Team implements Serializable {
 | 
			
		|||
		this.supplyPoint = supplyPoint;
 | 
			
		||||
		this.orientation = orientation;
 | 
			
		||||
		this.players = new ArrayList<>();
 | 
			
		||||
		this.score = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getName() {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,4 +54,16 @@ public class Team implements Serializable {
 | 
			
		|||
	public List<Player> getPlayers() {
 | 
			
		||||
		return players;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int getScore() {
 | 
			
		||||
		return score;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void incrementScore() {
 | 
			
		||||
		this.score++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void resetScore() {
 | 
			
		||||
		this.score = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,11 @@ public class Gun implements Serializable {
 | 
			
		|||
	 */
 | 
			
		||||
	private final double bulletSpeed;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * How much damage the bullet does for a direct hit.
 | 
			
		||||
	 */
 | 
			
		||||
	private final double baseDamage;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Number of bullets left in the current clip.
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +55,7 @@ public class Gun implements Serializable {
 | 
			
		|||
	 */
 | 
			
		||||
	private int clipCount;
 | 
			
		||||
 | 
			
		||||
	private Gun(GunType type, int maxClipCount, int clipSize, int bulletsPerRound, double accuracy, double shotCooldownTime, double reloadTime, double bulletSpeed) {
 | 
			
		||||
	private Gun(GunType type, int maxClipCount, int clipSize, int bulletsPerRound, double accuracy, double shotCooldownTime, double reloadTime, double bulletSpeed, double baseDamage) {
 | 
			
		||||
		this.type = type;
 | 
			
		||||
		this.maxClipCount = maxClipCount;
 | 
			
		||||
		this.clipSize = clipSize;
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +64,7 @@ public class Gun implements Serializable {
 | 
			
		|||
		this.shotCooldownTime = shotCooldownTime;
 | 
			
		||||
		this.reloadTime = reloadTime;
 | 
			
		||||
		this.bulletSpeed = bulletSpeed;
 | 
			
		||||
		this.baseDamage = baseDamage;
 | 
			
		||||
 | 
			
		||||
		this.currentClipBulletCount = 0;
 | 
			
		||||
		this.clipCount = maxClipCount;
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +102,10 @@ public class Gun implements Serializable {
 | 
			
		|||
		return bulletSpeed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public double getBaseDamage() {
 | 
			
		||||
		return baseDamage;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int getCurrentClipBulletCount() {
 | 
			
		||||
		return currentClipBulletCount;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +122,10 @@ public class Gun implements Serializable {
 | 
			
		|||
		this.currentClipBulletCount = Math.max(this.currentClipBulletCount - 1, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void emptyCurrentClip() {
 | 
			
		||||
		this.currentClipBulletCount = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean canReload() {
 | 
			
		||||
		return this.clipCount > 0;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -124,14 +138,14 @@ public class Gun implements Serializable {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	public static Gun ak47() {
 | 
			
		||||
		return new Gun(GunType.SMG, 4, 30, 1, 0.10, 0.05, 1.2, 90);
 | 
			
		||||
		return new Gun(GunType.SMG, 4, 30, 1, 0.10, 0.05, 1.2, 90, 40);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Gun m1Garand() {
 | 
			
		||||
		return new Gun(GunType.RIFLE, 6, 8, 1, 0.02, 0.75, 1.5, 150);
 | 
			
		||||
		return new Gun(GunType.RIFLE, 6, 8, 1, 0.02, 0.75, 1.5, 150, 100);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Gun winchester() {
 | 
			
		||||
		return new Gun(GunType.SHOTGUN, 8, 4, 3, 0.15, 0.5, 2.0, 75);
 | 
			
		||||
		return new Gun(GunType.SHOTGUN, 8, 4, 3, 0.15, 0.5, 2.0, 75, 60);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,6 +118,15 @@ public class Server {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void resetGame() {
 | 
			
		||||
		for (Team t : this.world.getTeams()) {
 | 
			
		||||
			t.resetScore();
 | 
			
		||||
			for (Player p : t.getPlayers()) {
 | 
			
		||||
				p.respawn();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void broadcastMessage(Message message) {
 | 
			
		||||
		for (ClientHandler handler : this.clientHandlers) {
 | 
			
		||||
			handler.send(message);
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +161,9 @@ public class Server {
 | 
			
		|||
				player.setGun(Gun.winchester());
 | 
			
		||||
			}
 | 
			
		||||
			handler.send(new SystemChatMessage(SystemChatMessage.Level.INFO, "Changed gun to " + player.getGun().getType().name() + "."));
 | 
			
		||||
		} else if (command.equalsIgnoreCase("reset")) {
 | 
			
		||||
			this.resetGame();
 | 
			
		||||
			this.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.INFO, "Game has been reset."));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,9 +77,12 @@ public class WorldUpdater extends Thread {
 | 
			
		|||
		if (p.getState().isMovingBackward()) vy -= Player.MOVEMENT_SPEED;
 | 
			
		||||
		if (p.getState().isMovingLeft()) vx -= Player.MOVEMENT_SPEED;
 | 
			
		||||
		if (p.getState().isMovingRight()) vx += Player.MOVEMENT_SPEED;
 | 
			
		||||
		Vec2 forwardVector = p.getOrientation().mul(vy);
 | 
			
		||||
		Vec2 leftVector = p.getOrientation().perp().mul(vx);
 | 
			
		||||
		Vec2 newPos = p.getPosition().add(forwardVector.mul(t)).add(leftVector.mul(t));
 | 
			
		||||
		Vec2 forwardVector = new Vec2(0, -1);
 | 
			
		||||
		if (p.getTeam() != null) {
 | 
			
		||||
			forwardVector = p.getTeam().getOrientation();
 | 
			
		||||
		}
 | 
			
		||||
		Vec2 leftVector = forwardVector.perp();
 | 
			
		||||
		Vec2 newPos = p.getPosition().add(forwardVector.mul(vy * t)).add(leftVector.mul(vx * t));
 | 
			
		||||
		double nx = newPos.x();
 | 
			
		||||
		double ny = newPos.y();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -171,11 +174,18 @@ public class WorldUpdater extends Thread {
 | 
			
		|||
				n = Math.max(Math.min(n, 1), 0);
 | 
			
		||||
				double dist = p.getPosition().dist(new Vec2(x1 + n * (x2 - x1), y1 + n * (y2 - y1)));
 | 
			
		||||
				if (dist < Player.RADIUS && (p.getTeam() == null || p.getTeam().getSpawnPoint().dist(p.getPosition()) > Team.SPAWN_RADIUS)) {
 | 
			
		||||
					Player killer = this.world.getPlayers().get(b.getPlayerId());
 | 
			
		||||
					this.server.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.SEVERE, p.getName() + " was shot by " + killer.getName() + "."));
 | 
			
		||||
 | 
			
		||||
					// Player was shot!
 | 
			
		||||
					float damage = (float) (((Player.RADIUS - dist) / Player.RADIUS) * b.getGun().getBaseDamage());
 | 
			
		||||
					p.takeDamage(damage);
 | 
			
		||||
					if (p.getHealth() == 0.0f) {
 | 
			
		||||
						Player shooter = this.world.getPlayers().get(b.getPlayerId());
 | 
			
		||||
						this.server.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.SEVERE, p.getName() + " was shot by " + shooter.getName() + "."));
 | 
			
		||||
						world.getSoundsToPlay().add("death.wav");
 | 
			
		||||
					if (p.getTeam() != null) {
 | 
			
		||||
						p.setPosition(p.getTeam().getSpawnPoint());
 | 
			
		||||
						if (shooter.getTeam() != null) {
 | 
			
		||||
							shooter.getTeam().incrementScore();
 | 
			
		||||
						}
 | 
			
		||||
						p.respawn();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue