Server/src/main/java/de/towerdefence/server/game/GameSession.java

125 lines
4.2 KiB
Java

package de.towerdefence.server.game;
import java.lang.reflect.Constructor;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import de.towerdefence.server.game.callbacks.EnemiesChangedCallback;
import de.towerdefence.server.game.callbacks.PlayerMoneyCallback;
import de.towerdefence.server.game.callbacks.PlayerHitpointsCallback;
import de.towerdefence.server.game.exeptions.InvalidPlacementException;
import de.towerdefence.server.game.exeptions.InvalidPlacementReason;
import de.towerdefence.server.game.exeptions.WaveInProgressException;
import de.towerdefence.server.player.Player;
import lombok.Getter;
import org.joml.Vector2i;
public class GameSession {
final static int START_HITPOINTS = 100;
final static int START_MONEY = 50;
final static Vector2i MAP_SIZE = new Vector2i(10, 20);
final static int WAVE_SPAWN_DELAY = 200; // ms
final static Vector2i WAVE_SPAWN = new Vector2i(5, 0);
final static Vector2i WAVE_TARGET = new Vector2i(5, 19);
private final Player player;
@Getter
private int money;
@Getter
private int playerHitpoints;
private final PlayerMoneyCallback moneyCallback;
private final PlayerHitpointsCallback hitpointsCallback;
private final EnemiesChangedCallback enemyCallback;
private final Tower[][] towers = new Tower[MAP_SIZE.x][MAP_SIZE.y];
private final Enemy[][] enemies = new Enemy[MAP_SIZE.x][MAP_SIZE.y];
private List<Enemy> wave = new ArrayList<>();
private long lastSpawn = Instant.now().toEpochMilli();
public GameSession(
Player player,
PlayerMoneyCallback moneyCallback,
PlayerHitpointsCallback hitpointsCallback,
EnemiesChangedCallback enemyCallback) {
this.player = player;
this.moneyCallback = moneyCallback;
this.hitpointsCallback = hitpointsCallback;
this.enemyCallback = enemyCallback;
this.money = START_MONEY;
this.playerHitpoints = START_HITPOINTS;
}
public void startWave(List<Enemy> enemies) throws WaveInProgressException {
if (wave.size() > 0) {
throw new WaveInProgressException();
}
wave = enemies;
}
public void update() {
List<Enemy> newEnemies = new ArrayList<>();
List<Enemy> changedEnemies = moveEnemies();
if (wave.size() > 0 && shouldSpawn()) {
enemies[WAVE_SPAWN.x][WAVE_SPAWN.y] = wave.removeFirst();
newEnemies.add(enemies[WAVE_SPAWN.x][WAVE_SPAWN.y]);
}
if (newEnemies.size() > 0 || changedEnemies.size() > 0) {
enemyCallback.call(
player,
newEnemies.toArray(new Enemy[newEnemies.size()]),
changedEnemies.toArray(new Enemy[changedEnemies.size()]));
}
}
private boolean shouldSpawn() {
return lastSpawn + WAVE_SPAWN_DELAY < Instant.now().toEpochMilli()
&& enemies[WAVE_SPAWN.x][WAVE_SPAWN.y] == null;
}
private List<Enemy> moveEnemies() {
// List<Enemy> changedEnemies = moveEnemies();
// TODO: Implement Moving of Enemies (possibly through A*)
throw new RuntimeException("NOT IMPLEMENTED");
// return changedEnemies;
}
/**
* @return the next position to go to
*/
private Vector2i pathfinding(Vector2i start, Vector2i target) {
}
public void placeTower(Tower tower, int x, int y) throws InvalidPlacementException {
if (x < 0 || y < 0 || x + 1 > MAP_SIZE.x || y + 1 > MAP_SIZE.y) {
throw new InvalidPlacementException(InvalidPlacementReason.OUT_OF_BOUNDS);
}
if (towers[x][y] != null) {
throw new InvalidPlacementException(InvalidPlacementReason.LOCATION_USED);
}
if (money < Tower.COST) {
throw new InvalidPlacementException(InvalidPlacementReason.NOT_ENOUGH_MONEY);
}
// TODO: Do Pathfinding check for the placement
money -= Tower.COST;
moneyCallback.call(player, money);
tower.x = x;
tower.y = y;
towers[x][y] = tower;
}
public void addMoney(int amount) {
money += amount;
moneyCallback.call(player, money);
}
}