Added start of weapons refactor.
This commit is contained in:
parent
3e20031e11
commit
27ee1336a7
|
@ -10,9 +10,13 @@ import nl.andrewlalis.aos_core.model.Player;
|
||||||
import nl.andrewlalis.aos_core.model.Team;
|
import nl.andrewlalis.aos_core.model.Team;
|
||||||
import nl.andrewlalis.aos_core.model.World;
|
import nl.andrewlalis.aos_core.model.World;
|
||||||
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.model.tools.Tool;
|
||||||
import nl.andrewlalis.aos_core.net.data.DataTypes;
|
import nl.andrewlalis.aos_core.net.data.DataTypes;
|
||||||
import nl.andrewlalis.aos_core.net.data.PlayerDetailUpdate;
|
import nl.andrewlalis.aos_core.net.data.PlayerDetailUpdate;
|
||||||
import nl.andrewlalis.aos_core.net.data.WorldUpdate;
|
import nl.andrewlalis.aos_core.net.data.WorldUpdate;
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.GunData;
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.ToolData;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -23,7 +27,6 @@ public class Client {
|
||||||
private final MessageTransceiver messageTransceiver;
|
private final MessageTransceiver messageTransceiver;
|
||||||
|
|
||||||
private World world;
|
private World world;
|
||||||
private Player myPlayer;
|
|
||||||
|
|
||||||
private final GameRenderer renderer;
|
private final GameRenderer renderer;
|
||||||
private final SoundManager soundManager;
|
private final SoundManager soundManager;
|
||||||
|
@ -123,8 +126,6 @@ public class Client {
|
||||||
public void updatePlayer(PlayerDetailUpdate update) {
|
public void updatePlayer(PlayerDetailUpdate update) {
|
||||||
if (this.myPlayer == null) return;
|
if (this.myPlayer == null) return;
|
||||||
this.myPlayer.setHealth(update.getHealth());
|
this.myPlayer.setHealth(update.getHealth());
|
||||||
this.myPlayer.setReloading(update.isReloading());
|
|
||||||
this.myPlayer.setGun(new Gun(this.myPlayer.getGun().getType(), update.getGunCurrentClipBulletCount(), update.getGunClipCount()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package nl.andrewlalis.aos_client.model;
|
||||||
|
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.ToolData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about the client's player, which contains more detailed data than
|
||||||
|
* what is provided for any random player in the world.
|
||||||
|
*/
|
||||||
|
public class ClientPlayerData extends PlayerData {
|
||||||
|
private float health;
|
||||||
|
private List<ToolData> tools;
|
||||||
|
private int selectedToolIndex;
|
||||||
|
|
||||||
|
public float getHealth() {
|
||||||
|
return health;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ToolData> getTools() {
|
||||||
|
return tools;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSelectedToolIndex() {
|
||||||
|
return selectedToolIndex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package nl.andrewlalis.aos_client.model;
|
||||||
|
|
||||||
|
import nl.andrewlalis.aos_core.geom.Vec2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data about a player which the client needs to know in order to render it.
|
||||||
|
*/
|
||||||
|
public class PlayerData {
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
private byte teamId;
|
||||||
|
|
||||||
|
private Vec2 position;
|
||||||
|
private Vec2 orientation;
|
||||||
|
private Vec2 velocity;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getTeamId() {
|
||||||
|
return teamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec2 getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec2 getOrientation() {
|
||||||
|
return orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec2 getVelocity() {
|
||||||
|
return velocity;
|
||||||
|
}
|
||||||
|
}
|
|
@ -204,7 +204,7 @@ public class GamePanel extends JPanel {
|
||||||
* @param gun The gun to draw.
|
* @param gun The gun to draw.
|
||||||
*/
|
*/
|
||||||
private void drawGun(Graphics2D g2, Gun gun) {
|
private void drawGun(Graphics2D g2, Gun gun) {
|
||||||
g2.setColor(Color.decode(gun.getType().getColor()));
|
g2.setColor(Color.decode(gun.getType().color()));
|
||||||
Rectangle2D.Double gunBarrel = new Rectangle2D.Double(
|
Rectangle2D.Double gunBarrel = new Rectangle2D.Double(
|
||||||
0,
|
0,
|
||||||
0.5,
|
0.5,
|
||||||
|
@ -307,8 +307,8 @@ public class GamePanel extends JPanel {
|
||||||
g2.drawString("Reloading...", 5, this.getHeight() - 10);
|
g2.drawString("Reloading...", 5, this.getHeight() - 10);
|
||||||
}
|
}
|
||||||
Gun gun = myPlayer.getGun();
|
Gun gun = myPlayer.getGun();
|
||||||
g2.drawString("Clips: " + gun.getClipCount() + " / " + gun.getType().getMaxClipCount(), 5, this.getHeight() - 20);
|
g2.drawString("Clips: " + gun.getClipCount() + " / " + gun.getType().maxClipCount(), 5, this.getHeight() - 20);
|
||||||
g2.drawString("Bullets: " + gun.getCurrentClipBulletCount() + " / " + gun.getType().getClipSize(), 5, this.getHeight() - 30);
|
g2.drawString("Bullets: " + gun.getCurrentClipBulletCount() + " / " + gun.getType().clipSize(), 5, this.getHeight() - 30);
|
||||||
g2.setColor(Color.GREEN);
|
g2.setColor(Color.GREEN);
|
||||||
g2.drawString(String.format("Health: %.1f", myPlayer.getHealth()), 5, this.getHeight() - 40);
|
g2.drawString(String.format("Health: %.1f", myPlayer.getHealth()), 5, this.getHeight() - 40);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ module aos_core {
|
||||||
exports nl.andrewlalis.aos_core.net to aos_server, aos_client;
|
exports nl.andrewlalis.aos_core.net to aos_server, aos_client;
|
||||||
exports nl.andrewlalis.aos_core.net.chat to aos_client, aos_server;
|
exports nl.andrewlalis.aos_core.net.chat to aos_client, aos_server;
|
||||||
exports nl.andrewlalis.aos_core.net.data to aos_server, aos_client;
|
exports nl.andrewlalis.aos_core.net.data to aos_server, aos_client;
|
||||||
|
exports nl.andrewlalis.aos_core.net.data.tool to aos_server, aos_client;
|
||||||
|
|
||||||
exports nl.andrewlalis.aos_core.model to aos_server, aos_client;
|
exports nl.andrewlalis.aos_core.model to aos_server, aos_client;
|
||||||
exports nl.andrewlalis.aos_core.model.tools to aos_client, aos_server;
|
exports nl.andrewlalis.aos_core.model.tools to aos_client, aos_server;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import nl.andrewlalis.aos_core.model.tools.Gun;
|
||||||
* Represents a single projectile bullet fired from a player's gun. When shot by
|
* Represents a single projectile bullet fired from a player's gun. When shot by
|
||||||
* a player, a newly-spawned bullet will be initialized with a velocity in the
|
* a player, a newly-spawned bullet will be initialized with a velocity in the
|
||||||
* general direction of the gun, with some perturbation according to the gun's
|
* general direction of the gun, with some perturbation according to the gun's
|
||||||
* accuracy and player's sprinting/sneaking status.
|
* inaccuracy and player's sprinting/sneaking status.
|
||||||
*/
|
*/
|
||||||
public class Bullet extends PhysicsObject {
|
public class Bullet extends PhysicsObject {
|
||||||
private final int playerId;
|
private final int playerId;
|
||||||
|
@ -34,14 +34,14 @@ public class Bullet extends PhysicsObject {
|
||||||
.add(player.getOrientation().perp().mul(Player.RADIUS))
|
.add(player.getOrientation().perp().mul(Player.RADIUS))
|
||||||
);
|
);
|
||||||
this.setOrientation(player.getOrientation());
|
this.setOrientation(player.getOrientation());
|
||||||
float accuracy = player.getGun().getType().getAccuracy();
|
float inaccuracy = player.getGun().getType().inaccuracy();
|
||||||
if (player.isSneaking()) {
|
if (player.isSneaking()) {
|
||||||
accuracy *= sneakAccuracyModifier;
|
inaccuracy *= sneakAccuracyModifier;
|
||||||
} else if (player.isSprinting()) {
|
} else if (player.isSprinting()) {
|
||||||
accuracy *= sprintAccuracyModifier;
|
inaccuracy *= sprintAccuracyModifier;
|
||||||
}
|
}
|
||||||
Vec2 perturbation = Vec2.random(-1, 1).mul(accuracy);
|
Vec2 perturbation = Vec2.random(-1, 1).mul(inaccuracy);
|
||||||
Vec2 localVelocity = this.getOrientation().add(perturbation).mul(player.getGun().getType().getBulletSpeed());
|
Vec2 localVelocity = this.getOrientation().add(perturbation).mul(player.getGun().getType().bulletSpeed());
|
||||||
this.setVelocity(player.getVelocity().add(localVelocity));
|
this.setVelocity(player.getVelocity().add(localVelocity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,11 @@ 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 nl.andrewlalis.aos_core.model.tools.Gun;
|
||||||
import nl.andrewlalis.aos_core.model.tools.GunType;
|
import nl.andrewlalis.aos_core.model.tools.GunType;
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Tool;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class Player extends PhysicsObject implements Comparable<Player> {
|
public class Player extends PhysicsObject implements Comparable<Player> {
|
||||||
|
@ -14,14 +18,10 @@ public class Player extends PhysicsObject implements Comparable<Player> {
|
||||||
private final String name;
|
private final String name;
|
||||||
private Team team;
|
private Team team;
|
||||||
private PlayerControlState state;
|
private PlayerControlState state;
|
||||||
private Gun gun;
|
private List<Tool> tools;
|
||||||
|
private Tool selectedTool;
|
||||||
private float health;
|
private float health;
|
||||||
|
|
||||||
private transient long lastShot;
|
|
||||||
private transient long reloadingStartedAt;
|
|
||||||
private boolean reloading;
|
|
||||||
private transient long lastResupply;
|
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
private transient int killCount;
|
private transient int killCount;
|
||||||
private transient int deathCount;
|
private transient int deathCount;
|
||||||
|
@ -29,15 +29,18 @@ public class Player extends PhysicsObject implements Comparable<Player> {
|
||||||
private transient int resupplyCount;
|
private transient int resupplyCount;
|
||||||
private transient int killStreak;
|
private transient int killStreak;
|
||||||
|
|
||||||
|
private transient long lastResupply;
|
||||||
|
|
||||||
public Player(int id, String name, Team team, GunType gunType, float maxHealth) {
|
public Player(int id, String name, Team team, GunType gunType, float maxHealth) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.team = team;
|
this.team = team;
|
||||||
this.state = new PlayerControlState();
|
this.state = new PlayerControlState();
|
||||||
this.gun = new Gun(gunType);
|
|
||||||
this.health = maxHealth;
|
this.health = maxHealth;
|
||||||
this.useWeapon();
|
this.tools = new ArrayList<>();
|
||||||
this.lastShot = System.currentTimeMillis();
|
var gun = new Gun(gunType);
|
||||||
|
this.tools.add(gun);
|
||||||
|
this.selectedTool = gun;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
|
@ -64,56 +67,23 @@ public class Player extends PhysicsObject implements Comparable<Player> {
|
||||||
this.team = team;
|
this.team = team;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gun getGun() {
|
public List<Tool> getTools() {
|
||||||
return gun;
|
return this.tools;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGun(Gun gun) {
|
public Tool getSelectedTool() {
|
||||||
this.gun = gun;
|
return this.selectedTool;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHealth(float health) {
|
public void setHealth(float health) {
|
||||||
this.health = health;
|
this.health = health;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReloading(boolean reloading) {
|
public boolean canUseGun() {
|
||||||
this.reloading = reloading;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canUseWeapon() {
|
|
||||||
return this.state.isShooting() &&
|
return this.state.isShooting() &&
|
||||||
!this.state.isReloading() &&
|
this.selectedTool instanceof Gun gun && gun.isUsable() &&
|
||||||
!this.reloading &&
|
|
||||||
this.gun.getCurrentClipBulletCount() > 0 &&
|
|
||||||
this.lastShot + ((long) (this.gun.getType().getShotCooldownTime() * 1000)) < System.currentTimeMillis() &&
|
|
||||||
(this.getTeam() == null || this.getTeam().getSpawnPoint().dist(this.getPosition()) > Team.SPAWN_RADIUS);
|
(this.getTeam() == null || this.getTeam().getSpawnPoint().dist(this.getPosition()) > Team.SPAWN_RADIUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void useWeapon() {
|
|
||||||
this.lastShot = System.currentTimeMillis();
|
|
||||||
this.gun.decrementBulletCount();
|
|
||||||
this.shotCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startReloading() {
|
|
||||||
this.reloading = true;
|
|
||||||
this.reloadingStartedAt = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void finishReloading() {
|
|
||||||
this.gun.reload();
|
|
||||||
this.reloading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReloadingComplete() {
|
|
||||||
long msSinceStart = System.currentTimeMillis() - this.reloadingStartedAt;
|
|
||||||
return msSinceStart > this.gun.getType().getReloadTime() * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReloading() {
|
|
||||||
return reloading;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canResupply(float resupplyCooldown) {
|
public boolean canResupply(float resupplyCooldown) {
|
||||||
return this.team != null &&
|
return this.team != null &&
|
||||||
this.team.getSupplyPoint().dist(this.getPosition()) < Team.SUPPLY_POINT_RADIUS &&
|
this.team.getSupplyPoint().dist(this.getPosition()) < Team.SUPPLY_POINT_RADIUS &&
|
||||||
|
@ -121,9 +91,11 @@ public class Player extends PhysicsObject implements Comparable<Player> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resupply(float maxHealth) {
|
public void resupply(float maxHealth) {
|
||||||
this.lastResupply = System.currentTimeMillis();
|
for (Tool t : this.tools) {
|
||||||
this.gun.refillClips();
|
t.resupply();
|
||||||
|
}
|
||||||
this.health = maxHealth;
|
this.health = maxHealth;
|
||||||
|
this.lastResupply = System.currentTimeMillis();
|
||||||
this.resupplyCount++;
|
this.resupplyCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +109,9 @@ public class Player extends PhysicsObject implements Comparable<Player> {
|
||||||
|
|
||||||
public void respawn(float maxHealth) {
|
public void respawn(float maxHealth) {
|
||||||
this.resupply(maxHealth);
|
this.resupply(maxHealth);
|
||||||
this.gun.emptyCurrentClip();
|
for (Tool t : this.tools) {
|
||||||
|
t.reset();
|
||||||
|
}
|
||||||
if (this.team != null) {
|
if (this.team != null) {
|
||||||
this.setPosition(this.team.getSpawnPoint().add(Vec2.random(-Team.SPAWN_RADIUS / 2, Team.SPAWN_RADIUS / 2)));
|
this.setPosition(this.team.getSpawnPoint().add(Vec2.random(-Team.SPAWN_RADIUS / 2, Team.SPAWN_RADIUS / 2)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package nl.andrewlalis.aos_core.model.tools;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The grenade tool, when equipped, allows the player to throw grenades into the
|
||||||
|
* world, if there are some grenades available.
|
||||||
|
*/
|
||||||
|
public class Grenade implements Tool {
|
||||||
|
private final int maxGrenades = 3;
|
||||||
|
|
||||||
|
private int grenades;
|
||||||
|
|
||||||
|
public Grenade(int grenades) {
|
||||||
|
this.grenades = grenades;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Grenade() {
|
||||||
|
this.grenades = maxGrenades;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGrenadesRemaining() {
|
||||||
|
return grenades;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxGrenades() {
|
||||||
|
return maxGrenades;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use() {
|
||||||
|
this.grenades--;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resupply() {
|
||||||
|
this.grenades = this.maxGrenades;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
this.resupply();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUsable() {
|
||||||
|
return this.grenades > 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
package nl.andrewlalis.aos_core.model.tools;
|
package nl.andrewlalis.aos_core.model.tools;
|
||||||
|
|
||||||
import java.io.Serializable;
|
/**
|
||||||
|
* A type of tool that, when equipped, allows the player to shoot bullets.
|
||||||
public class Gun implements Serializable {
|
*/
|
||||||
|
public class Gun implements Tool {
|
||||||
GunType type;
|
GunType type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,14 +15,20 @@ public class Gun implements Serializable {
|
||||||
*/
|
*/
|
||||||
private int clipCount;
|
private int clipCount;
|
||||||
|
|
||||||
|
private transient long lastShot;
|
||||||
|
private transient long reloadingStartedAt;
|
||||||
|
private boolean reloading;
|
||||||
|
|
||||||
public Gun(GunType type, int currentClipBulletCount, int clipCount) {
|
public Gun(GunType type, int currentClipBulletCount, int clipCount) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.currentClipBulletCount = currentClipBulletCount;
|
this.currentClipBulletCount = currentClipBulletCount;
|
||||||
this.clipCount = clipCount;
|
this.clipCount = clipCount;
|
||||||
|
|
||||||
|
this.lastShot = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gun(GunType type) {
|
public Gun(GunType type) {
|
||||||
this(type, 0, type.getMaxClipCount());
|
this(type, 0, type.maxClipCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public GunType getType() {
|
public GunType getType() {
|
||||||
|
@ -36,10 +43,6 @@ public class Gun implements Serializable {
|
||||||
return clipCount;
|
return clipCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refillClips() {
|
|
||||||
this.clipCount = this.type.getMaxClipCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void decrementBulletCount() {
|
public void decrementBulletCount() {
|
||||||
this.currentClipBulletCount = Math.max(this.currentClipBulletCount - 1, 0);
|
this.currentClipBulletCount = Math.max(this.currentClipBulletCount - 1, 0);
|
||||||
}
|
}
|
||||||
|
@ -52,10 +55,42 @@ public class Gun implements Serializable {
|
||||||
return this.clipCount > 0;
|
return this.clipCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isReloading() {
|
||||||
|
return reloading;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startReloading() {
|
||||||
|
this.reloading = true;
|
||||||
|
this.reloadingStartedAt = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReloadingComplete() {
|
||||||
|
return this.reloading && (System.currentTimeMillis() - this.reloadingStartedAt) > this.type.reloadTime() * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
public void reload() {
|
public void reload() {
|
||||||
if (this.clipCount > 0) {
|
if (this.clipCount > 0) {
|
||||||
this.clipCount--;
|
this.clipCount--;
|
||||||
this.currentClipBulletCount = this.type.getClipSize();
|
this.currentClipBulletCount = this.type.clipSize();
|
||||||
}
|
}
|
||||||
|
this.reloading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use() {
|
||||||
|
this.lastShot = System.currentTimeMillis();
|
||||||
|
this.currentClipBulletCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resupply() {
|
||||||
|
this.clipCount = this.type.maxClipCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUsable() {
|
||||||
|
return !this.reloading &&
|
||||||
|
this.currentClipBulletCount > 0 &&
|
||||||
|
this.lastShot + (this.type.shotCooldownTime() * 1000) < System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,122 +1,19 @@
|
||||||
package nl.andrewlalis.aos_core.model.tools;
|
package nl.andrewlalis.aos_core.model.tools;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relatively constant configuration information about a particular type of gun,
|
* Information about a particular type of gun.
|
||||||
* while not including state data for any single gun.
|
|
||||||
*/
|
*/
|
||||||
public class GunType implements Serializable {
|
public record GunType(
|
||||||
/**
|
String name,
|
||||||
* The name of this type of gun. Should be unique among all guns in a world.
|
GunCategory category,
|
||||||
*/
|
String color,
|
||||||
private final String name;
|
int maxClipCount,
|
||||||
/**
|
int clipSize,
|
||||||
* The category of gun.
|
int bulletsPerRound,
|
||||||
*/
|
float inaccuracy,
|
||||||
private final GunCategory category;
|
float shotCooldownTime,
|
||||||
/**
|
float reloadTime,
|
||||||
* The color of this type of gun, in hex.
|
float bulletSpeed,
|
||||||
*/
|
float baseDamage,
|
||||||
private final String color;
|
float recoil
|
||||||
/**
|
) {}
|
||||||
* Maximum number of clips a player can carry when using this gun.
|
|
||||||
*/
|
|
||||||
private final int maxClipCount;
|
|
||||||
/**
|
|
||||||
* Number of bullets in each clip.
|
|
||||||
*/
|
|
||||||
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. 0 = never miss, 1 = complete random.
|
|
||||||
*/
|
|
||||||
private final float accuracy;
|
|
||||||
/**
|
|
||||||
* How long (in seconds) to wait after each shot, before another is shot.
|
|
||||||
*/
|
|
||||||
private final float shotCooldownTime;
|
|
||||||
/**
|
|
||||||
* How long (in seconds) for reloading a new clip.
|
|
||||||
*/
|
|
||||||
private final float reloadTime;
|
|
||||||
/**
|
|
||||||
* How fast the bullet travels (in m/s).
|
|
||||||
*/
|
|
||||||
private final float bulletSpeed;
|
|
||||||
/**
|
|
||||||
* How much damage the bullet does for a direct hit.
|
|
||||||
*/
|
|
||||||
private final float baseDamage;
|
|
||||||
/**
|
|
||||||
* How fast the gun pushes the player backwards when shot (in m/s).
|
|
||||||
*/
|
|
||||||
private final float recoil;
|
|
||||||
|
|
||||||
public GunType(String name, GunCategory category, String color, int maxClipCount, int clipSize, int bulletsPerRound, float accuracy, float shotCooldownTime, float reloadTime, float bulletSpeed, float baseDamage, float recoil) {
|
|
||||||
this.name = name;
|
|
||||||
this.category = category;
|
|
||||||
this.color = color;
|
|
||||||
this.maxClipCount = maxClipCount;
|
|
||||||
this.clipSize = clipSize;
|
|
||||||
this.bulletsPerRound = bulletsPerRound;
|
|
||||||
this.accuracy = accuracy;
|
|
||||||
this.shotCooldownTime = shotCooldownTime;
|
|
||||||
this.reloadTime = reloadTime;
|
|
||||||
this.bulletSpeed = bulletSpeed;
|
|
||||||
this.baseDamage = baseDamage;
|
|
||||||
this.recoil = recoil;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GunCategory getCategory() {
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getColor() {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxClipCount() {
|
|
||||||
return maxClipCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getClipSize() {
|
|
||||||
return clipSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBulletsPerRound() {
|
|
||||||
return bulletsPerRound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getAccuracy() {
|
|
||||||
return accuracy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getShotCooldownTime() {
|
|
||||||
return shotCooldownTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getReloadTime() {
|
|
||||||
return reloadTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBulletSpeed() {
|
|
||||||
return bulletSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBaseDamage() {
|
|
||||||
return baseDamage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getRecoil() {
|
|
||||||
return recoil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package nl.andrewlalis.aos_core.model.tools;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents some sort of usable tool item that players can equip and use.
|
||||||
|
*/
|
||||||
|
public interface Tool extends Serializable {
|
||||||
|
/**
|
||||||
|
* Uses the tool.
|
||||||
|
*/
|
||||||
|
void use();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resupplies the tool, when a player is resupplied at their team's area.
|
||||||
|
*/
|
||||||
|
void resupply();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the tool to its preferred initial state. This is useful for things
|
||||||
|
* like respawning.
|
||||||
|
*/
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if the player may use the tool to perform an action, or
|
||||||
|
* false if it's not possible to do so.
|
||||||
|
*/
|
||||||
|
boolean isUsable();
|
||||||
|
}
|
|
@ -1,105 +1,75 @@
|
||||||
package nl.andrewlalis.aos_core.net.data;
|
package nl.andrewlalis.aos_core.net.data;
|
||||||
|
|
||||||
import nl.andrewlalis.aos_core.model.Player;
|
import nl.andrewlalis.aos_core.model.Player;
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Grenade;
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Gun;
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Tool;
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.GrenadeData;
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.GunData;
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.ToolData;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PlayerDetailUpdate {
|
public class PlayerDetailUpdate {
|
||||||
public static final int BYTES = Float.BYTES + 1 + 5 * Integer.BYTES;
|
|
||||||
|
|
||||||
private final float health;
|
private final float health;
|
||||||
private final boolean reloading;
|
|
||||||
|
|
||||||
private final int gunMaxClipCount;
|
private List<ToolData> tools;
|
||||||
private final int gunClipSize;
|
private int selectedToolIndex;
|
||||||
private final int gunBulletsPerRound;
|
|
||||||
private final int gunCurrentClipBulletCount;
|
|
||||||
private final int gunClipCount;
|
|
||||||
|
|
||||||
public PlayerDetailUpdate(Player player) {
|
public PlayerDetailUpdate(Player player) {
|
||||||
this.health = player.getHealth();
|
this.health = player.getHealth();
|
||||||
this.reloading = player.isReloading();
|
this.tools = new ArrayList<>(player.getTools().size());
|
||||||
|
for (int i = 0; i < player.getTools().size(); i++) {
|
||||||
this.gunMaxClipCount = player.getGun().getType().getMaxClipCount();
|
var t = player.getTools().get(i);
|
||||||
this.gunClipSize = player.getGun().getType().getClipSize();
|
if (t instanceof Gun g) {
|
||||||
this.gunBulletsPerRound = player.getGun().getType().getBulletsPerRound();
|
this.tools.add(new GunData(g));
|
||||||
this.gunCurrentClipBulletCount = player.getGun().getCurrentClipBulletCount();
|
} else if (t instanceof Grenade g) {
|
||||||
this.gunClipCount = player.getGun().getClipCount();
|
this.tools.add(new GrenadeData(g));
|
||||||
|
}
|
||||||
|
if (t.equals(player.getSelectedTool())) {
|
||||||
|
selectedToolIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlayerDetailUpdate(float health, boolean reloading, int gunMaxClipCount, int gunClipSize, int gunBulletsPerRound, int gunCurrentClipBulletCount, int gunClipCount) {
|
private PlayerDetailUpdate(float health, List<ToolData> tools, int selectedToolIndex) {
|
||||||
this.health = health;
|
this.health = health;
|
||||||
this.reloading = reloading;
|
|
||||||
this.gunMaxClipCount = gunMaxClipCount;
|
|
||||||
this.gunClipSize = gunClipSize;
|
|
||||||
this.gunBulletsPerRound = gunBulletsPerRound;
|
|
||||||
this.gunCurrentClipBulletCount = gunCurrentClipBulletCount;
|
|
||||||
this.gunClipCount = gunClipCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getHealth() {
|
public float getHealth() {
|
||||||
return health;
|
return health;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReloading() {
|
public List<ToolData> getTools() {
|
||||||
return reloading;
|
return tools;
|
||||||
}
|
|
||||||
|
|
||||||
public int getGunMaxClipCount() {
|
|
||||||
return gunMaxClipCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGunClipSize() {
|
|
||||||
return gunClipSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGunBulletsPerRound() {
|
|
||||||
return gunBulletsPerRound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGunCurrentClipBulletCount() {
|
|
||||||
return gunCurrentClipBulletCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGunClipCount() {
|
|
||||||
return gunClipCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "PlayerDetailUpdate{" +
|
|
||||||
"health=" + health +
|
|
||||||
", reloading=" + reloading +
|
|
||||||
", gunMaxClipCount=" + gunMaxClipCount +
|
|
||||||
", gunClipSize=" + gunClipSize +
|
|
||||||
", gunBulletsPerRound=" + gunBulletsPerRound +
|
|
||||||
", gunCurrentClipBulletCount=" + gunCurrentClipBulletCount +
|
|
||||||
", gunClipCount=" + gunClipCount +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] toBytes() {
|
public byte[] toBytes() {
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(BYTES);
|
int size = Float.BYTES + 2 * Integer.BYTES;
|
||||||
buffer.putFloat(health);
|
for (var td : this.tools) {
|
||||||
buffer.put((byte) (this.reloading ? 1 : 0));
|
size += td.getByteSize();
|
||||||
buffer.putInt(this.gunMaxClipCount);
|
}
|
||||||
buffer.putInt(this.gunClipSize);
|
ByteBuffer buffer = ByteBuffer.allocate(size);
|
||||||
buffer.putInt(this.gunBulletsPerRound);
|
buffer.putFloat(this.health);
|
||||||
buffer.putInt(this.gunCurrentClipBulletCount);
|
buffer.putInt(this.selectedToolIndex);
|
||||||
buffer.putInt(this.gunClipCount);
|
buffer.putInt(this.tools.size());
|
||||||
|
for (var td : this.tools) {
|
||||||
|
td.write(buffer);
|
||||||
|
}
|
||||||
return buffer.array();
|
return buffer.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerDetailUpdate fromBytes(byte[] bytes) {
|
public static PlayerDetailUpdate fromBytes(byte[] bytes) {
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
||||||
return new PlayerDetailUpdate(
|
float health = buffer.getFloat();
|
||||||
buffer.getFloat(),
|
int selectedToolIndex = buffer.getInt();
|
||||||
buffer.get() == 1,
|
int toolCount = buffer.getInt();
|
||||||
buffer.getInt(),
|
List<ToolData> tools = new ArrayList<>(toolCount);
|
||||||
buffer.getInt(),
|
for (int i = 0; i < toolCount; i++) {
|
||||||
buffer.getInt(),
|
tools.add(ToolData.read(buffer));
|
||||||
buffer.getInt(),
|
}
|
||||||
buffer.getInt()
|
return new PlayerDetailUpdate(health, tools, selectedToolIndex);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,11 @@ package nl.andrewlalis.aos_core.net.data;
|
||||||
|
|
||||||
import nl.andrewlalis.aos_core.geom.Vec2;
|
import nl.andrewlalis.aos_core.geom.Vec2;
|
||||||
import nl.andrewlalis.aos_core.model.Player;
|
import nl.andrewlalis.aos_core.model.Player;
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Grenade;
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Gun;
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.GrenadeData;
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.GunData;
|
||||||
|
import nl.andrewlalis.aos_core.net.data.tool.ToolData;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
@ -18,22 +23,28 @@ public class PlayerUpdate {
|
||||||
private final Vec2 position;
|
private final Vec2 position;
|
||||||
private final Vec2 orientation;
|
private final Vec2 orientation;
|
||||||
private final Vec2 velocity;
|
private final Vec2 velocity;
|
||||||
private final String gunTypeName;
|
private final ToolData selectedTool;
|
||||||
|
|
||||||
public PlayerUpdate(Player player) {
|
public PlayerUpdate(Player player) {
|
||||||
this.id = player.getId();
|
this.id = player.getId();
|
||||||
this.position = player.getPosition();
|
this.position = player.getPosition();
|
||||||
this.orientation = player.getOrientation();
|
this.orientation = player.getOrientation();
|
||||||
this.velocity = player.getVelocity();
|
this.velocity = player.getVelocity();
|
||||||
this.gunTypeName = player.getGun().getType().getName();
|
if (player.getSelectedTool() instanceof Gun gun) {
|
||||||
|
this.selectedTool = new GunData(gun);
|
||||||
|
} else if (player.getSelectedTool() instanceof Grenade grenade) {
|
||||||
|
this.selectedTool = new GrenadeData(grenade);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid selected tool.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerUpdate(int id, Vec2 position, Vec2 orientation, Vec2 velocity, String gunTypeName) {
|
public PlayerUpdate(int id, Vec2 position, Vec2 orientation, Vec2 velocity) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.orientation = orientation;
|
this.orientation = orientation;
|
||||||
this.velocity = velocity;
|
this.velocity = velocity;
|
||||||
this.gunTypeName = gunTypeName;
|
this.selectedTool = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
|
@ -52,10 +63,6 @@ public class PlayerUpdate {
|
||||||
return velocity;
|
return velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getGunTypeName() {
|
|
||||||
return gunTypeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(DataOutputStream out) throws IOException {
|
public void write(DataOutputStream out) throws IOException {
|
||||||
out.writeInt(this.id);
|
out.writeInt(this.id);
|
||||||
out.writeFloat(this.position.x());
|
out.writeFloat(this.position.x());
|
||||||
|
@ -64,8 +71,6 @@ public class PlayerUpdate {
|
||||||
out.writeFloat(this.orientation.y());
|
out.writeFloat(this.orientation.y());
|
||||||
out.writeFloat(this.velocity.x());
|
out.writeFloat(this.velocity.x());
|
||||||
out.writeFloat(this.velocity.y());
|
out.writeFloat(this.velocity.y());
|
||||||
out.writeInt(this.gunTypeName.length());
|
|
||||||
out.writeBytes(this.gunTypeName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerUpdate read(DataInputStream in) throws IOException {
|
public static PlayerUpdate read(DataInputStream in) throws IOException {
|
||||||
|
@ -73,8 +78,6 @@ public class PlayerUpdate {
|
||||||
Vec2 position = Vec2.read(in);
|
Vec2 position = Vec2.read(in);
|
||||||
Vec2 orientation = Vec2.read(in);
|
Vec2 orientation = Vec2.read(in);
|
||||||
Vec2 velocity = Vec2.read(in);
|
Vec2 velocity = Vec2.read(in);
|
||||||
int gunTypeNameLength = in.readInt();
|
|
||||||
String gunTypeName = new String(in.readNBytes(gunTypeNameLength));
|
|
||||||
return new PlayerUpdate(id, position, orientation, velocity, gunTypeName);
|
return new PlayerUpdate(id, position, orientation, velocity, gunTypeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package nl.andrewlalis.aos_core.net.data.tool;
|
||||||
|
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Grenade;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class GrenadeData extends ToolData {
|
||||||
|
private int grenades;
|
||||||
|
private int maxGrenades;
|
||||||
|
|
||||||
|
public GrenadeData() {
|
||||||
|
super((byte) 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GrenadeData(Grenade grenade) {
|
||||||
|
this();
|
||||||
|
this.grenades = grenade.getGrenadesRemaining();
|
||||||
|
this.maxGrenades = grenade.getMaxGrenades();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getByteSize() {
|
||||||
|
return 2 * Integer.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void putData(ByteBuffer buffer) {
|
||||||
|
buffer.putInt(this.grenades);
|
||||||
|
buffer.putInt(this.maxGrenades);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void getData(ByteBuffer buffer) {
|
||||||
|
this.grenades = buffer.getInt();
|
||||||
|
this.maxGrenades = buffer.getInt();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package nl.andrewlalis.aos_core.net.data.tool;
|
||||||
|
|
||||||
|
import nl.andrewlalis.aos_core.model.tools.Gun;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class GunData extends ToolData {
|
||||||
|
private boolean reloading;
|
||||||
|
private int clipCount;
|
||||||
|
private int currentClipBulletCount;
|
||||||
|
private int bulletsPerRound;
|
||||||
|
private int clipSize;
|
||||||
|
private int maxClipCount;
|
||||||
|
|
||||||
|
public GunData() {
|
||||||
|
super((byte) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GunData(Gun gun) {
|
||||||
|
this();
|
||||||
|
this.reloading = gun.isReloading();
|
||||||
|
this.clipCount = gun.getClipCount();
|
||||||
|
this.currentClipBulletCount = gun.getCurrentClipBulletCount();
|
||||||
|
this.bulletsPerRound = gun.getType().bulletsPerRound();
|
||||||
|
this.clipSize = gun.getType().clipSize();
|
||||||
|
this.maxClipCount = gun.getType().maxClipCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReloading() {
|
||||||
|
return reloading;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClipCount() {
|
||||||
|
return clipCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentClipBulletCount() {
|
||||||
|
return currentClipBulletCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBulletsPerRound() {
|
||||||
|
return bulletsPerRound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClipSize() {
|
||||||
|
return clipSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxClipCount() {
|
||||||
|
return maxClipCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getByteSize() {
|
||||||
|
return 1 + 5 * Integer.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void putData(ByteBuffer buffer) {
|
||||||
|
buffer.put((byte) (this.reloading ? 1 : 0));
|
||||||
|
buffer.putInt(this.clipCount);
|
||||||
|
buffer.putInt(this.currentClipBulletCount);
|
||||||
|
buffer.putInt(this.bulletsPerRound);
|
||||||
|
buffer.putInt(this.clipSize);
|
||||||
|
buffer.putInt(this.maxClipCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void getData(ByteBuffer buffer) {
|
||||||
|
this.reloading = buffer.get() == 1;
|
||||||
|
this.clipCount = buffer.getInt();
|
||||||
|
this.currentClipBulletCount = buffer.getInt();
|
||||||
|
this.bulletsPerRound = buffer.getInt();
|
||||||
|
this.clipSize = buffer.getInt();
|
||||||
|
this.maxClipCount = buffer.getInt();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package nl.andrewlalis.aos_core.net.data.tool;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class ToolData {
|
||||||
|
private static final Map<Byte, Class<? extends ToolData>> dataMapping = new HashMap<>();
|
||||||
|
static {
|
||||||
|
dataMapping.put((byte) 0, GunData.class);
|
||||||
|
dataMapping.put((byte) 1, GrenadeData.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final byte toolType;
|
||||||
|
|
||||||
|
public ToolData(byte toolType) {
|
||||||
|
this.toolType = toolType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(ByteBuffer buffer) {
|
||||||
|
buffer.put(this.toolType);
|
||||||
|
this.putData(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ToolData read(ByteBuffer buffer) {
|
||||||
|
byte type = buffer.get();
|
||||||
|
var dataClass = dataMapping.get(type);
|
||||||
|
if (dataClass == null) {
|
||||||
|
System.err.println("Invalid tool data type byte.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var data = dataClass.getConstructor().newInstance();
|
||||||
|
data.getData(buffer);
|
||||||
|
return data;
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int getByteSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes data for this tool data object into the given buffer.
|
||||||
|
* @param buffer The byte buffer to write data into.
|
||||||
|
*/
|
||||||
|
protected abstract void putData(ByteBuffer buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads data for this tool data object from the given buffer.
|
||||||
|
* @param buffer The byte buffer to read data from.
|
||||||
|
*/
|
||||||
|
protected abstract void getData(ByteBuffer buffer);
|
||||||
|
}
|
|
@ -184,23 +184,23 @@ public class WorldUpdater extends Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePlayerShooting(Player p) {
|
private void updatePlayerShooting(Player p) {
|
||||||
if (p.canUseWeapon()) {
|
if (p.canUseGun()) {
|
||||||
for (int i = 0; i < p.getGun().getType().getBulletsPerRound(); i++) {
|
for (int i = 0; i < p.getGun().getType().bulletsPerRound(); i++) {
|
||||||
Bullet b = new Bullet(p, server.getSettings().getPlayerSettings().getSneakAccuracyModifier(), server.getSettings().getPlayerSettings().getSprintAccuracyModifier());
|
Bullet b = new Bullet(p, server.getSettings().getPlayerSettings().getSneakAccuracyModifier(), server.getSettings().getPlayerSettings().getSprintAccuracyModifier());
|
||||||
this.world.getBullets().add(b);
|
this.world.getBullets().add(b);
|
||||||
this.worldUpdate.addBullet(b);
|
this.worldUpdate.addBullet(b);
|
||||||
}
|
}
|
||||||
SoundType soundType = SoundType.SHOT_SMG;
|
SoundType soundType = SoundType.SHOT_SMG;
|
||||||
if (p.getGun().getType().getCategory() == GunCategory.RIFLE) {
|
if (p.getGun().getType().category() == GunCategory.RIFLE) {
|
||||||
soundType = SoundType.SHOT_RIFLE;
|
soundType = SoundType.SHOT_RIFLE;
|
||||||
} else if (p.getGun().getType().getCategory() == GunCategory.SHOTGUN) {
|
} else if (p.getGun().getType().category() == GunCategory.SHOTGUN) {
|
||||||
soundType = SoundType.SHOT_SHOTGUN;
|
soundType = SoundType.SHOT_SHOTGUN;
|
||||||
} else if (p.getGun().getType().getCategory() == GunCategory.MACHINE) {
|
} else if (p.getGun().getType().category() == GunCategory.MACHINE) {
|
||||||
soundType = ThreadLocalRandom.current().nextFloat() < 0.8f ? SoundType.SHOT_MACHINE_GUN_1 : SoundType.SHOT_MACHINE_GUN_2;
|
soundType = ThreadLocalRandom.current().nextFloat() < 0.8f ? SoundType.SHOT_MACHINE_GUN_1 : SoundType.SHOT_MACHINE_GUN_2;
|
||||||
}
|
}
|
||||||
this.worldUpdate.addSound(new SoundData(p.getPosition(), 1.0f, soundType));
|
this.worldUpdate.addSound(new SoundData(p.getPosition(), 1.0f, soundType));
|
||||||
p.useWeapon();
|
p.useWeapon();
|
||||||
p.setVelocity(p.getVelocity().add(p.getOrientation().mul(-1 * p.getGun().getType().getRecoil())));
|
p.setVelocity(p.getVelocity().add(p.getOrientation().mul(-1 * p.getGun().getType().recoil())));
|
||||||
}
|
}
|
||||||
if (p.getState().isReloading() && !p.isReloading() && p.getGun().canReload()) {
|
if (p.getState().isReloading() && !p.isReloading() && p.getGun().canReload()) {
|
||||||
p.startReloading();
|
p.startReloading();
|
||||||
|
@ -255,7 +255,7 @@ public class WorldUpdater extends Thread {
|
||||||
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 was shot!
|
// Player was shot!
|
||||||
float damage = (float) (((Player.RADIUS - dist) / Player.RADIUS) * b.getGun().getType().getBaseDamage());
|
float damage = (float) (((Player.RADIUS - dist) / Player.RADIUS) * b.getGun().getType().baseDamage());
|
||||||
p.takeDamage(damage);
|
p.takeDamage(damage);
|
||||||
if (p.getHealth() == 0.0f) {
|
if (p.getHealth() == 0.0f) {
|
||||||
Player shooter = this.world.getPlayers().get(b.getPlayerId());
|
Player shooter = this.world.getPlayers().get(b.getPlayerId());
|
||||||
|
|
|
@ -19,13 +19,13 @@ public class GunsCommand implements Command, ChatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(String[] args) {
|
public void execute(String[] args) {
|
||||||
for (var gunType : this.server.getWorld().getGunTypes().values()) {
|
for (var gunType : this.server.getWorld().getGunTypes().values()) {
|
||||||
System.out.println(gunType.getName());
|
System.out.println(gunType.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ClientHandler handler, Player player, String[] args) {
|
public void execute(ClientHandler handler, Player player, String[] args) {
|
||||||
String msg = handler.getServer().getWorld().getGunTypes().values().stream().map(GunType::getName).collect(Collectors.joining(", "));
|
String msg = handler.getServer().getWorld().getGunTypes().values().stream().map(GunType::name).collect(Collectors.joining(", "));
|
||||||
handler.send(new SystemChatMessage(SystemChatMessage.Level.INFO, msg));
|
handler.send(new SystemChatMessage(SystemChatMessage.Level.INFO, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package nl.andrewlalis.aos_server.command;
|
package nl.andrewlalis.aos_server.command;
|
||||||
|
|
||||||
import nl.andrewlalis.aos_core.model.Player;
|
|
||||||
import nl.andrewlalis.aos_server.Server;
|
import nl.andrewlalis.aos_server.Server;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -21,13 +20,12 @@ public class ListPlayersCommand implements Command {
|
||||||
String message = this.server.getWorld().getPlayers().values().stream()
|
String message = this.server.getWorld().getPlayers().values().stream()
|
||||||
.sorted()
|
.sorted()
|
||||||
.map(player -> String.format(
|
.map(player -> String.format(
|
||||||
"%d | %s Team: %s, Health: %.1f / %.1f, Gun: %s",
|
"%d | %s Team: %s, Health: %.1f / %.1f",
|
||||||
player.getId(),
|
player.getId(),
|
||||||
player.getName(),
|
player.getName(),
|
||||||
player.getTeam() == null ? "none" : player.getTeam().getName(),
|
player.getTeam() == null ? "none" : player.getTeam().getName(),
|
||||||
player.getHealth(),
|
player.getHealth(),
|
||||||
this.server.getSettings().getPlayerSettings().getMaxHealth(),
|
this.server.getSettings().getPlayerSettings().getMaxHealth()
|
||||||
player.getGun().getType().getName()
|
|
||||||
))
|
))
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
System.out.println(message);
|
System.out.println(message);
|
||||||
|
|
|
@ -18,7 +18,7 @@ public class GunCommand implements ChatCommand {
|
||||||
String gunName = String.join(" ", args);
|
String gunName = String.join(" ", args);
|
||||||
GunType gunType = null;
|
GunType gunType = null;
|
||||||
for (GunType type : handler.getServer().getWorld().getGunTypes().values()) {
|
for (GunType type : handler.getServer().getWorld().getGunTypes().values()) {
|
||||||
if (type.getName().equalsIgnoreCase(gunName)) {
|
if (type.name().equalsIgnoreCase(gunName)) {
|
||||||
gunType = type;
|
gunType = type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,6 @@ public class GunCommand implements ChatCommand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player.setGun(new Gun(gunType));
|
player.setGun(new Gun(gunType));
|
||||||
handler.send(new SystemChatMessage(SystemChatMessage.Level.INFO, "Changed gun to " + player.getGun().getType().getName() + "."));
|
handler.send(new SystemChatMessage(SystemChatMessage.Level.INFO, "Changed gun to " + player.getGun().getType().name() + "."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,9 +52,9 @@ player-settings:
|
||||||
max-health: 100
|
max-health: 100
|
||||||
# How quickly players regenerate health, in points per second. Set to 0 to disable regeneration.
|
# How quickly players regenerate health, in points per second. Set to 0 to disable regeneration.
|
||||||
health-regen-rate: 1.0
|
health-regen-rate: 1.0
|
||||||
# How much sneaking affects gun accuracy. Values less than 0 increase accuracy, and greater than 0 decrease accuracy.
|
# How much sneaking affects gun inaccuracy. Values less than 0 increase inaccuracy, and greater than 0 decrease inaccuracy.
|
||||||
sneak-accuracy-modifier: 0.5
|
sneak-accuracy-modifier: 0.5
|
||||||
# How much sprinting affects gun accuracy. Values less than 0 increase accuracy, and greater than 0 decrease accuracy.
|
# How much sprinting affects gun inaccuracy. Values less than 0 increase inaccuracy, and greater than 0 decrease inaccuracy.
|
||||||
sprint-accuracy-modifier: 1.5
|
sprint-accuracy-modifier: 1.5
|
||||||
# Should be the name of one of the guns defined in "gun-settings".
|
# Should be the name of one of the guns defined in "gun-settings".
|
||||||
default-gun: M1 Garand
|
default-gun: M1 Garand
|
||||||
|
@ -78,7 +78,7 @@ gun-settings:
|
||||||
max-clip-count: 4 # The maximum number of clips which a player can hold for this gun.
|
max-clip-count: 4 # The maximum number of clips which a player can hold for this gun.
|
||||||
clip-size: 30 # The number of rounds in each clip.
|
clip-size: 30 # The number of rounds in each clip.
|
||||||
bullets-per-round: 1 # The number of bullets spawned for each round fired.
|
bullets-per-round: 1 # The number of bullets spawned for each round fired.
|
||||||
accuracy: 0.10 # The accuracy of the gun, or rather deviation. Increase this to decrease accuracy.
|
inaccuracy: 0.10 # The inaccuracy of the gun, or rather deviation. Increase this to decrease inaccuracy.
|
||||||
shot-cooldown-time: 0.05 # How many seconds to wait after shooting before you can shoot again.
|
shot-cooldown-time: 0.05 # How many seconds to wait after shooting before you can shoot again.
|
||||||
reload-time: 1.2 # How many seconds to wait while reloading.
|
reload-time: 1.2 # How many seconds to wait while reloading.
|
||||||
bullet-speed: 90 # How fast the bullets from this gun fly, in meters per second.
|
bullet-speed: 90 # How fast the bullets from this gun fly, in meters per second.
|
||||||
|
@ -91,7 +91,7 @@ gun-settings:
|
||||||
max-clip-count: 5
|
max-clip-count: 5
|
||||||
clip-size: 16
|
clip-size: 16
|
||||||
bullets-per-round: 1
|
bullets-per-round: 1
|
||||||
accuracy: 0.20
|
inaccuracy: 0.20
|
||||||
shot-cooldown-time: 0.25
|
shot-cooldown-time: 0.25
|
||||||
reload-time: 1.0
|
reload-time: 1.0
|
||||||
bullet-speed: 40
|
bullet-speed: 40
|
||||||
|
@ -104,7 +104,7 @@ gun-settings:
|
||||||
max-clip-count: 3
|
max-clip-count: 3
|
||||||
clip-size: 500
|
clip-size: 500
|
||||||
bullets-per-round: 1
|
bullets-per-round: 1
|
||||||
accuracy: 0.10
|
inaccuracy: 0.10
|
||||||
shot-cooldown-time: 0.04
|
shot-cooldown-time: 0.04
|
||||||
reload-time: 3
|
reload-time: 3
|
||||||
bullet-speed: 60
|
bullet-speed: 60
|
||||||
|
@ -117,7 +117,7 @@ gun-settings:
|
||||||
max-clip-count: 3
|
max-clip-count: 3
|
||||||
clip-size: 100
|
clip-size: 100
|
||||||
bullets-per-round: 1
|
bullets-per-round: 1
|
||||||
accuracy: 0.08
|
inaccuracy: 0.08
|
||||||
shot-cooldown-time: 0.03
|
shot-cooldown-time: 0.03
|
||||||
reload-time: 3.5
|
reload-time: 3.5
|
||||||
bullet-speed: 80
|
bullet-speed: 80
|
||||||
|
@ -130,7 +130,7 @@ gun-settings:
|
||||||
max-clip-count: 10
|
max-clip-count: 10
|
||||||
clip-size: 8
|
clip-size: 8
|
||||||
bullets-per-round: 1
|
bullets-per-round: 1
|
||||||
accuracy: 0.02
|
inaccuracy: 0.02
|
||||||
shot-cooldown-time: 0.75
|
shot-cooldown-time: 0.75
|
||||||
reload-time: 0.75
|
reload-time: 0.75
|
||||||
bullet-speed: 150
|
bullet-speed: 150
|
||||||
|
@ -143,7 +143,7 @@ gun-settings:
|
||||||
max-clip-count: 8
|
max-clip-count: 8
|
||||||
clip-size: 6
|
clip-size: 6
|
||||||
bullets-per-round: 5
|
bullets-per-round: 5
|
||||||
accuracy: 0.15
|
inaccuracy: 0.15
|
||||||
shot-cooldown-time: 0.5
|
shot-cooldown-time: 0.5
|
||||||
reload-time: 2.0
|
reload-time: 2.0
|
||||||
bullet-speed: 75
|
bullet-speed: 75
|
||||||
|
|
Loading…
Reference in New Issue