Improved client connection.
This commit is contained in:
parent
bd02d89995
commit
4bc994d07e
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.aos_client;
|
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.GameFrame;
|
||||||
import nl.andrewlalis.aos_client.view.GamePanel;
|
import nl.andrewlalis.aos_client.view.GamePanel;
|
||||||
import nl.andrewlalis.aos_core.model.PlayerControlState;
|
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.ChatMessage;
|
||||||
import nl.andrewlalis.aos_core.net.chat.PlayerChatMessage;
|
import nl.andrewlalis.aos_core.net.chat.PlayerChatMessage;
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -153,22 +153,7 @@ public class Client {
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
String hostAndPort = JOptionPane.showInputDialog("Enter server host and port (host:port):");
|
ConnectDialog dialog = new ConnectDialog();
|
||||||
if (hostAndPort == null) throw new IllegalArgumentException("A host and port is required.");
|
dialog.setVisible(true);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
g2.clearRect(0, 0, this.getWidth(), this.getHeight());
|
||||||
|
|
||||||
World world = client.getWorld();
|
World world = client.getWorld();
|
||||||
if (world != null) drawWorld(g2, world);
|
if (world != null) {
|
||||||
drawChat(g2, world);
|
drawWorld(g2, world);
|
||||||
drawStatus(g2, world);
|
drawStatus(g2, world);
|
||||||
}
|
}
|
||||||
|
drawChat(g2, world);
|
||||||
|
}
|
||||||
|
|
||||||
private void drawWorld(Graphics2D g2, World world) {
|
private void drawWorld(Graphics2D g2, World world) {
|
||||||
Player myPlayer = world.getPlayers().get(this.client.getPlayerId());
|
Player myPlayer = world.getPlayers().get(this.client.getPlayerId());
|
||||||
|
@ -234,5 +236,20 @@ public class GamePanel extends JPanel {
|
||||||
Gun gun = myPlayer.getGun();
|
Gun gun = myPlayer.getGun();
|
||||||
g2.drawString("Clips: " + gun.getClipCount() + " / " + gun.getMaxClipCount(), 5, this.getHeight() - 20);
|
g2.drawString("Clips: " + gun.getClipCount() + " / " + gun.getMaxClipCount(), 5, this.getHeight() - 20);
|
||||||
g2.drawString("Bullets: " + gun.getCurrentClipBulletCount() + " / " + gun.getClipSize(), 5, this.getHeight() - 30);
|
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;
|
package nl.andrewlalis.aos_core.geom;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public record Vec2(double x, double y) implements Serializable {
|
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() {
|
public String toString() {
|
||||||
return "[ " + x + ", " + y + " ]";
|
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;
|
package nl.andrewlalis.aos_core.model;
|
||||||
|
|
||||||
import nl.andrewlalis.aos_core.geom.Vec2;
|
import nl.andrewlalis.aos_core.geom.Vec2;
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Gun;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public class Bullet extends PhysicsObject {
|
public class Bullet extends PhysicsObject {
|
||||||
private final int playerId;
|
private final int playerId;
|
||||||
|
private final Gun gun;
|
||||||
|
|
||||||
public Bullet(Player player) {
|
public Bullet(Player player) {
|
||||||
super(
|
|
||||||
player.getPosition().add(player.getOrientation().mul(1.5)),
|
|
||||||
player.getOrientation(),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
this.playerId = player.getId();
|
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();
|
Random r = ThreadLocalRandom.current();
|
||||||
Vec2 perturbation = new Vec2((r.nextDouble() - 0.5) * 2, (r.nextDouble() - 0.5) * 2).mul(player.getGun().getAccuracy());
|
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() {
|
public int getPlayerId() {
|
||||||
return playerId;
|
return playerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Gun getGun() {
|
||||||
|
return gun;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.aos_core.model;
|
package nl.andrewlalis.aos_core.model;
|
||||||
|
|
||||||
|
import nl.andrewlalis.aos_core.geom.Vec2;
|
||||||
import nl.andrewlalis.aos_core.model.tools.Gun;
|
import nl.andrewlalis.aos_core.model.tools.Gun;
|
||||||
|
|
||||||
import java.util.Objects;
|
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 MOVEMENT_SPEED = 10; // Movement speed, in m/s
|
||||||
public static final double RADIUS = 0.5; // Collision radius, in meters.
|
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 double RESUPPLY_COOLDOWN = 30; // Seconds between allowing resupply.
|
||||||
|
public static final float MAX_HEALTH = 100.0f;
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
private final String name;
|
private final String name;
|
||||||
private Team team;
|
private Team team;
|
||||||
private PlayerControlState state;
|
private PlayerControlState state;
|
||||||
private Gun gun;
|
private Gun gun;
|
||||||
|
private float health;
|
||||||
|
|
||||||
private transient long lastShot;
|
private transient long lastShot;
|
||||||
private transient long reloadingStartedAt;
|
private transient long reloadingStartedAt;
|
||||||
|
@ -27,6 +30,7 @@ public class Player extends PhysicsObject {
|
||||||
this.state = new PlayerControlState();
|
this.state = new PlayerControlState();
|
||||||
this.state.setPlayerId(this.id);
|
this.state.setPlayerId(this.id);
|
||||||
this.gun = Gun.winchester();
|
this.gun = Gun.winchester();
|
||||||
|
this.health = MAX_HEALTH;
|
||||||
this.useWeapon();
|
this.useWeapon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +115,23 @@ public class Player extends PhysicsObject {
|
||||||
public void resupply() {
|
public void resupply() {
|
||||||
this.lastResupply = System.currentTimeMillis();
|
this.lastResupply = System.currentTimeMillis();
|
||||||
this.gun.refillClips();
|
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
|
@Override
|
||||||
|
|
|
@ -19,6 +19,8 @@ public class Team implements Serializable {
|
||||||
|
|
||||||
private final List<Player> players;
|
private final List<Player> players;
|
||||||
|
|
||||||
|
private int score;
|
||||||
|
|
||||||
public Team(String name, Color color, Vec2 spawnPoint, Vec2 supplyPoint, Vec2 orientation) {
|
public Team(String name, Color color, Vec2 spawnPoint, Vec2 supplyPoint, Vec2 orientation) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
@ -26,6 +28,7 @@ public class Team implements Serializable {
|
||||||
this.supplyPoint = supplyPoint;
|
this.supplyPoint = supplyPoint;
|
||||||
this.orientation = orientation;
|
this.orientation = orientation;
|
||||||
this.players = new ArrayList<>();
|
this.players = new ArrayList<>();
|
||||||
|
this.score = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -51,4 +54,16 @@ public class Team implements Serializable {
|
||||||
public List<Player> getPlayers() {
|
public List<Player> getPlayers() {
|
||||||
return players;
|
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;
|
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.
|
* Number of bullets left in the current clip.
|
||||||
*/
|
*/
|
||||||
|
@ -50,7 +55,7 @@ public class Gun implements Serializable {
|
||||||
*/
|
*/
|
||||||
private int clipCount;
|
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.type = type;
|
||||||
this.maxClipCount = maxClipCount;
|
this.maxClipCount = maxClipCount;
|
||||||
this.clipSize = clipSize;
|
this.clipSize = clipSize;
|
||||||
|
@ -59,6 +64,7 @@ public class Gun implements Serializable {
|
||||||
this.shotCooldownTime = shotCooldownTime;
|
this.shotCooldownTime = shotCooldownTime;
|
||||||
this.reloadTime = reloadTime;
|
this.reloadTime = reloadTime;
|
||||||
this.bulletSpeed = bulletSpeed;
|
this.bulletSpeed = bulletSpeed;
|
||||||
|
this.baseDamage = baseDamage;
|
||||||
|
|
||||||
this.currentClipBulletCount = 0;
|
this.currentClipBulletCount = 0;
|
||||||
this.clipCount = maxClipCount;
|
this.clipCount = maxClipCount;
|
||||||
|
@ -96,6 +102,10 @@ public class Gun implements Serializable {
|
||||||
return bulletSpeed;
|
return bulletSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getBaseDamage() {
|
||||||
|
return baseDamage;
|
||||||
|
}
|
||||||
|
|
||||||
public int getCurrentClipBulletCount() {
|
public int getCurrentClipBulletCount() {
|
||||||
return currentClipBulletCount;
|
return currentClipBulletCount;
|
||||||
}
|
}
|
||||||
|
@ -112,6 +122,10 @@ public class Gun implements Serializable {
|
||||||
this.currentClipBulletCount = Math.max(this.currentClipBulletCount - 1, 0);
|
this.currentClipBulletCount = Math.max(this.currentClipBulletCount - 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void emptyCurrentClip() {
|
||||||
|
this.currentClipBulletCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean canReload() {
|
public boolean canReload() {
|
||||||
return this.clipCount > 0;
|
return this.clipCount > 0;
|
||||||
}
|
}
|
||||||
|
@ -124,14 +138,14 @@ public class Gun implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Gun ak47() {
|
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() {
|
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() {
|
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) {
|
public void broadcastMessage(Message message) {
|
||||||
for (ClientHandler handler : this.clientHandlers) {
|
for (ClientHandler handler : this.clientHandlers) {
|
||||||
handler.send(message);
|
handler.send(message);
|
||||||
|
@ -152,6 +161,9 @@ public class Server {
|
||||||
player.setGun(Gun.winchester());
|
player.setGun(Gun.winchester());
|
||||||
}
|
}
|
||||||
handler.send(new SystemChatMessage(SystemChatMessage.Level.INFO, "Changed gun to " + player.getGun().getType().name() + "."));
|
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().isMovingBackward()) vy -= Player.MOVEMENT_SPEED;
|
||||||
if (p.getState().isMovingLeft()) vx -= Player.MOVEMENT_SPEED;
|
if (p.getState().isMovingLeft()) vx -= Player.MOVEMENT_SPEED;
|
||||||
if (p.getState().isMovingRight()) vx += Player.MOVEMENT_SPEED;
|
if (p.getState().isMovingRight()) vx += Player.MOVEMENT_SPEED;
|
||||||
Vec2 forwardVector = p.getOrientation().mul(vy);
|
Vec2 forwardVector = new Vec2(0, -1);
|
||||||
Vec2 leftVector = p.getOrientation().perp().mul(vx);
|
if (p.getTeam() != null) {
|
||||||
Vec2 newPos = p.getPosition().add(forwardVector.mul(t)).add(leftVector.mul(t));
|
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 nx = newPos.x();
|
||||||
double ny = newPos.y();
|
double ny = newPos.y();
|
||||||
|
|
||||||
|
@ -171,11 +174,18 @@ public class WorldUpdater extends Thread {
|
||||||
n = Math.max(Math.min(n, 1), 0);
|
n = Math.max(Math.min(n, 1), 0);
|
||||||
double dist = p.getPosition().dist(new Vec2(x1 + n * (x2 - x1), y1 + n * (y2 - y1)));
|
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)) {
|
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");
|
world.getSoundsToPlay().add("death.wav");
|
||||||
if (p.getTeam() != null) {
|
if (shooter.getTeam() != null) {
|
||||||
p.setPosition(p.getTeam().getSpawnPoint());
|
shooter.getTeam().incrementScore();
|
||||||
|
}
|
||||||
|
p.respawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue