Added simple commands, reloading, and new gun skins.

This commit is contained in:
Andrew Lalis 2021-06-20 10:36:33 +02:00
parent 49bb724f65
commit bd02d89995
12 changed files with 205 additions and 55 deletions

View File

@ -131,7 +131,7 @@ public class Client {
public void sendChat() { public void sendChat() {
String message = this.chatBuffer.toString().trim(); String message = this.chatBuffer.toString().trim();
if (!message.isBlank()) { if (!message.isBlank() && !message.equals("/")) {
try { try {
this.messageTransceiver.send(new PlayerChatMessage(this.playerId, message)); this.messageTransceiver.send(new PlayerChatMessage(this.playerId, message));
} catch (IOException e) { } catch (IOException e) {

View File

@ -0,0 +1,22 @@
package nl.andrewlalis.aos_client;
import java.io.IOException;
import java.util.concurrent.ThreadLocalRandom;
public class Tester {
private static final String[] names = {
"andrew", "john", "william", "farnsworth", "xXx_noSc0p3r_xXx"
};
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
Client client = new Client();
try {
client.connect("localhost", 8035, names[ThreadLocalRandom.current().nextInt(names.length)]);
} catch (IOException | ClassNotFoundException e) {
client.shutdown();
e.printStackTrace();
}
}
}
}

View File

@ -3,6 +3,7 @@ package nl.andrewlalis.aos_client.view;
import nl.andrewlalis.aos_client.Client; import nl.andrewlalis.aos_client.Client;
import nl.andrewlalis.aos_core.model.*; import nl.andrewlalis.aos_core.model.*;
import nl.andrewlalis.aos_core.model.tools.Gun; import nl.andrewlalis.aos_core.model.tools.Gun;
import nl.andrewlalis.aos_core.model.tools.GunType;
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 nl.andrewlalis.aos_core.net.chat.SystemChatMessage; import nl.andrewlalis.aos_core.net.chat.SystemChatMessage;
@ -63,7 +64,21 @@ public class GamePanel extends JPanel {
this.drawField(g2, world); this.drawField(g2, world);
this.drawPlayers(g2, world); this.drawPlayers(g2, world);
this.drawBullets(g2, world); this.drawBullets(g2, world);
this.drawMarkers(g2, world, myPlayer);
g2.setTransform(pre); g2.setTransform(pre);
// Put shadow gradient.
RadialGradientPaint p = new RadialGradientPaint(
this.getWidth() / 2.0f,
this.getHeight() / 2.0f,
(float) (25 * scale),
new float[]{0.0f, 1.0f},
new Color[]{new Color(0, 0, 0, 0), new Color(0, 0, 0, 255)},
MultipleGradientPaint.CycleMethod.NO_CYCLE
);
g2.setPaint(p);
g2.fillRect(0, 0, this.getWidth(), this.getHeight());
} }
private AffineTransform getWorldTransform(Player player, double scale) { private AffineTransform getWorldTransform(Player player, double scale) {
@ -97,12 +112,19 @@ public class GamePanel extends JPanel {
for (Team t : world.getTeams()) { for (Team t : world.getTeams()) {
g2.setColor(t.getColor()); g2.setColor(t.getColor());
Ellipse2D.Double spawnCircle = new Ellipse2D.Double( Ellipse2D.Double spawnCircle = new Ellipse2D.Double(
t.getSpawnPoint().x() - Player.RADIUS, t.getSpawnPoint().x() - Team.SPAWN_RADIUS,
t.getSpawnPoint().y() - Player.RADIUS, t.getSpawnPoint().y() - Team.SPAWN_RADIUS,
Player.RADIUS * 2, Team.SPAWN_RADIUS * 2,
Player.RADIUS * 2 Team.SPAWN_RADIUS * 2
); );
g2.draw(spawnCircle); g2.draw(spawnCircle);
Rectangle2D.Double supplyMarker = new Rectangle2D.Double(
t.getSupplyPoint().x() - Team.SUPPLY_POINT_RADIUS,
t.getSupplyPoint().y() - Team.SUPPLY_POINT_RADIUS,
Team.SUPPLY_POINT_RADIUS * 2,
Team.SUPPLY_POINT_RADIUS * 2
);
g2.draw(supplyMarker);
} }
} }
@ -110,7 +132,6 @@ public class GamePanel extends JPanel {
for (Player p : world.getPlayers().values()) { for (Player p : world.getPlayers().values()) {
AffineTransform pre = g2.getTransform(); AffineTransform pre = g2.getTransform();
AffineTransform tx = g2.getTransform(); AffineTransform tx = g2.getTransform();
tx.translate(p.getPosition().x(), p.getPosition().y()); tx.translate(p.getPosition().x(), p.getPosition().y());
tx.rotate(p.getOrientation().x(), p.getOrientation().y()); tx.rotate(p.getOrientation().x(), p.getOrientation().y());
g2.setTransform(tx); g2.setTransform(tx);
@ -119,23 +140,30 @@ public class GamePanel extends JPanel {
Color playerColor = p.getTeam() != null ? p.getTeam().getColor() : Color.BLACK; Color playerColor = p.getTeam() != null ? p.getTeam().getColor() : Color.BLACK;
g2.setColor(playerColor); g2.setColor(playerColor);
g2.fill(dot); g2.fill(dot);
this.drawGun(g2, p.getGun());
g2.setColor(Color.GRAY);
Rectangle2D.Double gun = new Rectangle2D.Double(
0,
0.5,
2,
0.25
);
g2.fill(gun);
g2.setTransform(pre); g2.setTransform(pre);
} }
} }
private void drawGun(Graphics2D g2, Gun gun) {
g2.setColor(Color.GRAY);
if (gun.getType() == GunType.RIFLE) {
g2.setColor(new Color(59, 43, 0));
} else if (gun.getType() == GunType.SHOTGUN) {
g2.setColor(new Color(18, 18, 17));
}
Rectangle2D.Double gunBarrel = new Rectangle2D.Double(
0,
0.5,
2,
0.25
);
g2.fill(gunBarrel);
}
private void drawBullets(Graphics2D g2, World world) { private void drawBullets(Graphics2D g2, World world) {
g2.setColor(Color.YELLOW); g2.setColor(Color.BLACK);
double bulletSize = 0.5; double bulletSize = 0.25;
for (Bullet b : world.getBullets()) { for (Bullet b : world.getBullets()) {
Ellipse2D.Double bulletShape = new Ellipse2D.Double( Ellipse2D.Double bulletShape = new Ellipse2D.Double(
b.getPosition().x() - bulletSize / 2, b.getPosition().x() - bulletSize / 2,
@ -147,6 +175,21 @@ public class GamePanel extends JPanel {
} }
} }
private void drawMarkers(Graphics2D g2, World world, Player myPlayer) {
g2.setColor(Color.WHITE);
for (Player p : world.getPlayers().values()) {
if (p.getId() == myPlayer.getId()) continue;
AffineTransform pre = g2.getTransform();
AffineTransform tx = g2.getTransform();
tx.translate(p.getPosition().x(), p.getPosition().y());
tx.rotate(myPlayer.getTeam().getOrientation().perp().angle());
tx.scale(0.1, 0.1);
g2.setTransform(tx);
g2.drawString(p.getName(), 0, 0);
g2.setTransform(pre);
}
}
private void drawChat(Graphics2D g2, World world) { private void drawChat(Graphics2D g2, World world) {
int height = g2.getFontMetrics().getHeight(); int height = g2.getFontMetrics().getHeight();
int y = height; int y = height;

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -7,6 +7,7 @@ import java.util.Objects;
public class Player extends PhysicsObject { 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.
private final int id; private final int id;
private final String name; private final String name;
@ -17,6 +18,7 @@ public class Player extends PhysicsObject {
private transient long lastShot; private transient long lastShot;
private transient long reloadingStartedAt; private transient long reloadingStartedAt;
private boolean reloading; private boolean reloading;
private transient long lastResupply;
public Player(int id, String name, Team team) { public Player(int id, String name, Team team) {
this.id = id; this.id = id;
@ -24,7 +26,7 @@ public class Player extends PhysicsObject {
this.team = team; this.team = team;
this.state = new PlayerControlState(); this.state = new PlayerControlState();
this.state.setPlayerId(this.id); this.state.setPlayerId(this.id);
this.gun = Gun.m1Garand(); this.gun = Gun.winchester();
this.useWeapon(); this.useWeapon();
} }
@ -69,7 +71,8 @@ public class Player extends PhysicsObject {
!this.state.isReloading() && !this.state.isReloading() &&
!this.reloading && !this.reloading &&
this.gun.getCurrentClipBulletCount() > 0 && this.gun.getCurrentClipBulletCount() > 0 &&
this.lastShot + this.gun.getShotCooldownTime() * 1000 < System.currentTimeMillis(); this.lastShot + this.gun.getShotCooldownTime() * 1000 < System.currentTimeMillis() &&
(this.getTeam() == null || this.getTeam().getSpawnPoint().dist(this.getPosition()) > Team.SPAWN_RADIUS);
} }
public void useWeapon() { public void useWeapon() {
@ -99,6 +102,17 @@ public class Player extends PhysicsObject {
return reloading; return reloading;
} }
public boolean canResupply() {
return this.team != null &&
this.team.getSupplyPoint().dist(this.getPosition()) < Team.SUPPLY_POINT_RADIUS &&
System.currentTimeMillis() - this.lastResupply > RESUPPLY_COOLDOWN * 1000;
}
public void resupply() {
this.lastResupply = System.currentTimeMillis();
this.gun.refillClips();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

View File

@ -8,17 +8,22 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Team implements Serializable { public class Team implements Serializable {
public static final double SPAWN_RADIUS = 3;
public static final double SUPPLY_POINT_RADIUS = 2;
private final String name; private final String name;
private final java.awt.Color color; private final java.awt.Color color;
private final Vec2 spawnPoint; private final Vec2 spawnPoint;
private final Vec2 supplyPoint;
private final Vec2 orientation; private final Vec2 orientation;
private final List<Player> players; private final List<Player> players;
public Team(String name, Color color, Vec2 spawnPoint, 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;
this.spawnPoint = spawnPoint; this.spawnPoint = spawnPoint;
this.supplyPoint = supplyPoint;
this.orientation = orientation; this.orientation = orientation;
this.players = new ArrayList<>(); this.players = new ArrayList<>();
} }
@ -35,6 +40,10 @@ public class Team implements Serializable {
return spawnPoint; return spawnPoint;
} }
public Vec2 getSupplyPoint() {
return supplyPoint;
}
public Vec2 getOrientation() { public Vec2 getOrientation() {
return orientation; return orientation;
} }

View File

@ -15,6 +15,12 @@ public class Gun implements Serializable {
*/ */
private final int clipSize; private final int clipSize;
/**
* Number of bullets that are fired simultaneously per round. Usually only
* shotguns fire multiple.
*/
private final int bulletsPerRound;
/** /**
* How accurate shots from this gun are. * How accurate shots from this gun are.
*/ */
@ -44,10 +50,11 @@ public class Gun implements Serializable {
*/ */
private int clipCount; private int clipCount;
private Gun(GunType type, int maxClipCount, int clipSize, 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) {
this.type = type; this.type = type;
this.maxClipCount = maxClipCount; this.maxClipCount = maxClipCount;
this.clipSize = clipSize; this.clipSize = clipSize;
this.bulletsPerRound = bulletsPerRound;
this.accuracy = accuracy; this.accuracy = accuracy;
this.shotCooldownTime = shotCooldownTime; this.shotCooldownTime = shotCooldownTime;
this.reloadTime = reloadTime; this.reloadTime = reloadTime;
@ -69,6 +76,10 @@ public class Gun implements Serializable {
return clipSize; return clipSize;
} }
public int getBulletsPerRound() {
return bulletsPerRound;
}
public double getAccuracy() { public double getAccuracy() {
return accuracy; return accuracy;
} }
@ -93,6 +104,10 @@ public class Gun implements Serializable {
return clipCount; return clipCount;
} }
public void refillClips() {
this.clipCount = this.maxClipCount;
}
public void decrementBulletCount() { public void decrementBulletCount() {
this.currentClipBulletCount = Math.max(this.currentClipBulletCount - 1, 0); this.currentClipBulletCount = Math.max(this.currentClipBulletCount - 1, 0);
} }
@ -109,14 +124,14 @@ public class Gun implements Serializable {
} }
public static Gun ak47() { public static Gun ak47() {
return new Gun(GunType.SMG, 4, 30, 0.10, 0.05, 1.2, 90); return new Gun(GunType.SMG, 4, 30, 1, 0.10, 0.05, 1.2, 90);
} }
public static Gun m1Garand() { public static Gun m1Garand() {
return new Gun(GunType.RIFLE, 6, 8, 0.02, 0.75, 1.5, 150); return new Gun(GunType.RIFLE, 6, 8, 1, 0.02, 0.75, 1.5, 150);
} }
public static Gun winchester() { public static Gun winchester() {
return new Gun(GunType.SHOTGUN, 8, 4, 0.15, 0.5, 2.0, 75); return new Gun(GunType.SHOTGUN, 8, 4, 3, 0.15, 0.5, 2.0, 75);
} }
} }

View File

@ -7,8 +7,11 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.net.Socket; import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ClientHandler extends Thread { public class ClientHandler extends Thread {
private final ExecutorService sendingQueue = Executors.newSingleThreadExecutor();
private final Server server; private final Server server;
private final Socket socket; private final Socket socket;
private final ObjectOutputStream out; private final ObjectOutputStream out;
@ -33,9 +36,15 @@ public class ClientHandler extends Thread {
this.running = false; this.running = false;
} }
public synchronized void send(Message message) throws IOException { public void send(Message message) {
this.out.reset(); this.sendingQueue.submit(() -> {
this.out.writeObject(message); try {
this.out.reset();
this.out.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
});
} }
@Override @Override
@ -48,7 +57,7 @@ public class ClientHandler extends Thread {
IdentMessage ident = (IdentMessage) msg; IdentMessage ident = (IdentMessage) msg;
this.playerId = this.server.registerNewPlayer(ident.getName(), this); this.playerId = this.server.registerNewPlayer(ident.getName(), this);
} else if (msg.getType() == Type.CHAT) { } else if (msg.getType() == Type.CHAT) {
this.server.broadcastPlayerChat(this.playerId, (ChatMessage) msg); this.server.handlePlayerChat(this, this.playerId, (ChatMessage) msg);
} else if (msg.getType() == Type.PLAYER_CONTROL_STATE) { } else if (msg.getType() == Type.PLAYER_CONTROL_STATE) {
this.server.updatePlayerState(((PlayerControlStateMessage) msg).getPlayerControlState()); this.server.updatePlayerState(((PlayerControlStateMessage) msg).getPlayerControlState());
} }

View File

@ -2,6 +2,7 @@ package nl.andrewlalis.aos_server;
import nl.andrewlalis.aos_core.geom.Vec2; import nl.andrewlalis.aos_core.geom.Vec2;
import nl.andrewlalis.aos_core.model.*; import nl.andrewlalis.aos_core.model.*;
import nl.andrewlalis.aos_core.model.tools.Gun;
import nl.andrewlalis.aos_core.net.Message; import nl.andrewlalis.aos_core.net.Message;
import nl.andrewlalis.aos_core.net.PlayerRegisteredMessage; import nl.andrewlalis.aos_core.net.PlayerRegisteredMessage;
import nl.andrewlalis.aos_core.net.WorldUpdateMessage; import nl.andrewlalis.aos_core.net.WorldUpdateMessage;
@ -13,6 +14,7 @@ import java.awt.*;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -37,8 +39,20 @@ public class Server {
world.getBarricades().add(new Barricade(0, 30, 10, 10)); world.getBarricades().add(new Barricade(0, 30, 10, 10));
world.getBarricades().add(new Barricade(40, 30, 10, 10)); world.getBarricades().add(new Barricade(40, 30, 10, 10));
world.getTeams().add(new Team("Red", Color.RED, new Vec2(3, 3), new Vec2(0, 1))); world.getTeams().add(new Team(
world.getTeams().add(new Team("Blue", Color.BLUE, new Vec2(world.getSize().x() - 3, world.getSize().y() - 3), new Vec2(0, -1))); "Red",
Color.RED,
new Vec2(3, 3),
new Vec2(15, 3),
new Vec2(0, 1)
));
world.getTeams().add(new Team(
"Blue",
Color.BLUE,
new Vec2(world.getSize().x() - 3, world.getSize().y() - 3),
new Vec2(world.getSize().x() - 15, world.getSize().y() - 3),
new Vec2(0, -1)
));
this.worldUpdater = new WorldUpdater(this, this.world); this.worldUpdater = new WorldUpdater(this, this.world);
System.out.println("Started AOS-Server TCP on port " + port); System.out.println("Started AOS-Server TCP on port " + port);
@ -63,11 +77,7 @@ public class Server {
} }
Player p = new Player(id, name, team); Player p = new Player(id, name, team);
this.world.getPlayers().put(p.getId(), p); this.world.getPlayers().put(p.getId(), p);
try { handler.send(new PlayerRegisteredMessage(id));
handler.send(new PlayerRegisteredMessage(id));
} catch (IOException e) {
e.printStackTrace();
}
String message = p.getName() + " connected."; String message = p.getName() + " connected.";
this.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.INFO, message)); this.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.INFO, message));
System.out.println(message); System.out.println(message);
@ -97,11 +107,7 @@ public class Server {
public void sendWorldToClients() { public void sendWorldToClients() {
for (ClientHandler handler : this.clientHandlers) { for (ClientHandler handler : this.clientHandlers) {
try { handler.send(new WorldUpdateMessage(this.world));
handler.send(new WorldUpdateMessage(this.world));
} catch (IOException e) {
e.printStackTrace();
}
} }
} }
@ -114,18 +120,39 @@ public class Server {
public void broadcastMessage(Message message) { public void broadcastMessage(Message message) {
for (ClientHandler handler : this.clientHandlers) { for (ClientHandler handler : this.clientHandlers) {
try { handler.send(message);
handler.send(message);
} catch (IOException e) {
e.printStackTrace();
}
} }
} }
public void broadcastPlayerChat(int playerId, ChatMessage msg) { public void handlePlayerChat(ClientHandler handler, int playerId, ChatMessage msg) {
Player p = this.world.getPlayers().get(playerId); Player p = this.world.getPlayers().get(playerId);
if (p == null) return; if (p == null) return;
this.broadcastMessage(new PlayerChatMessage(p.getId(), msg.getText())); if (msg.getText().startsWith("/")) {
String[] words = msg.getText().substring(1).split("\\s+");
if (words.length == 0) return;
String command = words[0];
String[] args = Arrays.copyOfRange(words, 1, words.length);
this.handleCommand(handler, p, command, args);
} else {
this.broadcastMessage(new PlayerChatMessage(p.getId(), msg.getText()));
}
}
public void handleCommand(ClientHandler handler, Player player, String command, String[] args) {
if (command.equalsIgnoreCase("gun")) {
if (args.length < 1) {
return;
}
String gunName = args[0];
if (gunName.equalsIgnoreCase("smg")) {
player.setGun(Gun.ak47());
} else if (gunName.equalsIgnoreCase("rifle")) {
player.setGun(Gun.m1Garand());
} else if (gunName.equalsIgnoreCase("shotgun")) {
player.setGun(Gun.winchester());
}
handler.send(new SystemChatMessage(SystemChatMessage.Level.INFO, "Changed gun to " + player.getGun().getType().name() + "."));
}
} }

View File

@ -1,10 +1,8 @@
package nl.andrewlalis.aos_server; package nl.andrewlalis.aos_server;
import nl.andrewlalis.aos_core.geom.Vec2; import nl.andrewlalis.aos_core.geom.Vec2;
import nl.andrewlalis.aos_core.model.Barricade; import nl.andrewlalis.aos_core.model.*;
import nl.andrewlalis.aos_core.model.Bullet; import nl.andrewlalis.aos_core.model.tools.GunType;
import nl.andrewlalis.aos_core.model.Player;
import nl.andrewlalis.aos_core.model.World;
import nl.andrewlalis.aos_core.net.chat.SystemChatMessage; import nl.andrewlalis.aos_core.net.chat.SystemChatMessage;
import java.util.ArrayList; import java.util.ArrayList;
@ -113,12 +111,24 @@ public class WorldUpdater extends Thread {
if (ny - Player.RADIUS < 0) ny = Player.RADIUS; if (ny - Player.RADIUS < 0) ny = Player.RADIUS;
if (ny + Player.RADIUS > this.world.getSize().y()) ny = this.world.getSize().y() - Player.RADIUS; if (ny + Player.RADIUS > this.world.getSize().y()) ny = this.world.getSize().y() - Player.RADIUS;
p.setPosition(new Vec2(nx, ny)); p.setPosition(new Vec2(nx, ny));
if (p.canResupply()) {
p.resupply();
}
} }
private void updatePlayerShooting(Player p) { private void updatePlayerShooting(Player p) {
if (p.canUseWeapon()) { if (p.canUseWeapon()) {
this.world.getBullets().add(new Bullet(p)); for (int i = 0; i < p.getGun().getBulletsPerRound(); i++) {
this.world.getSoundsToPlay().add("ak47shot1.wav"); this.world.getBullets().add(new Bullet(p));
}
String sound = "ak47shot1.wav";
if (p.getGun().getType() == GunType.RIFLE) {
sound = "m1garand-shot1.wav";
} else if (p.getGun().getType() == GunType.SHOTGUN) {
sound = "shotgun-shot1.wav";
}
this.world.getSoundsToPlay().add(sound);
p.useWeapon(); p.useWeapon();
} }
if (p.getState().isReloading() && !p.isReloading() && p.getGun().canReload()) { if (p.getState().isReloading() && !p.isReloading() && p.getGun().canReload()) {
@ -126,6 +136,7 @@ public class WorldUpdater extends Thread {
} }
if (p.isReloading() && p.isReloadingComplete()) { if (p.isReloading() && p.isReloadingComplete()) {
p.finishReloading(); p.finishReloading();
this.world.getSoundsToPlay().add("reload.wav");
} }
} }
@ -159,7 +170,7 @@ public class WorldUpdater extends Thread {
double n = ((p.getPosition().x() - x1) * (x2 - x1) + (p.getPosition().y() - y1) * (y2 - y1)) / lineDist; double n = ((p.getPosition().x() - x1) * (x2 - x1) + (p.getPosition().y() - y1) * (y2 - y1)) / lineDist;
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) { if (dist < Player.RADIUS && (p.getTeam() == null || p.getTeam().getSpawnPoint().dist(p.getPosition()) > Team.SPAWN_RADIUS)) {
Player killer = this.world.getPlayers().get(b.getPlayerId()); Player killer = this.world.getPlayers().get(b.getPlayerId());
this.server.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.SEVERE, p.getName() + " was shot by " + killer.getName() + ".")); this.server.broadcastMessage(new SystemChatMessage(SystemChatMessage.Level.SEVERE, p.getName() + " was shot by " + killer.getName() + "."));
world.getSoundsToPlay().add("death.wav"); world.getSoundsToPlay().add("death.wav");