package dev.llan.model.state;
import dev.llan.events.PlayerUpdatedEvent;
import dev.llan.events.Events.*;
import dev.llan.model.Game;
import dev.llan.model.cards.Card;
import dev.llan.model.board.Point;
import dev.llan.events.GameEvent;
import dev.llan.model.pieces.Entity;
import dev.llan.model.pieces.enemies.Enemy;
import dev.llan.model.state.combat.CombatManager;
import dev.llan.model.state.combat.CombatManager.CombatPhase;
import dev.llan.model.state.combat.TurnInfo;
import dev.llan.model.state.combat.actions.CardUse;
import dev.llan.model.state.combat.actions.Wait;
import java.util.*;
public class Combat extends BaseGameState {
private CombatManager combatManager;
private boolean canWait;
public Combat(Game game) {
super(game);
combatManager = new CombatManager(game.getPlayer(), game.getEnemies(), game.getMap(), game);
canWait = true;
}
@Override
public List<GameEvent> moveActivePath() {
List<GameEvent> events = super.moveActivePath();
Set<Enemy> notified = new HashSet<>();
for (Enemy enemy : enemies) {
if (!enemy.inCombat() && enemy.withinRadius(player.getPosition())) {
enemy.setInCombat();
notified.add(enemy);
enemy.notifyNearbyEnemies(enemies, notified);
}
}
combatManager.addAllEntities(notified);
canWait = false;
return events;
}
@Override
public List<GameEvent> endTurn() {
List<GameEvent> events = new ArrayList<>();
events.addAll(gameMap.clearAllHighlightedTiles());
events.addAll(combatManager.nextTurn());
events.addAll(combatManager.processUntilPlayer());
player.recalculateActivePath().ifPresent(gameEvent -> events.add(gameEvent));
canWait = true;
return events;
}
@Override
public List<GameEvent> waitTurn() {
List<GameEvent> events = new ArrayList<>();
events.addAll(gameMap.clearAllHighlightedTiles());
if (canWait) {
events.addAll(combatManager.processAction(new Wait(player)));
events.addAll(combatManager.nextTurn());
events.addAll(combatManager.processUntilPlayer());
player.recalculateActivePath().ifPresent(gameEvent -> events.add(gameEvent));
canWait = false;
} else {
System.out.println("Cannot wait again this round!");
}
return events;
}
@Override
public List<GameEvent> selectCard(int cardIndex) {
Optional<GameEvent> event = player.selectCardInHand(cardIndex);
if (event.isPresent()) {
return List.of(event.get());
}
return List.of();
}
@Override
public List<GameEvent> useCardOn(Point position) {
List<GameEvent> events = new ArrayList<>();
Entity entity = gameMap.getGrid().tileAt(position).getEntity().get();
Optional<Card> selectedCard = player.getSelectedCard();
if (selectedCard.isPresent()) {
events.addAll(combatManager.processAction(new CardUse(player, entity, selectedCard.get())));
player.selectCardInHand(-1);
player.getCollection().updatePlayableCards(player.getStats().getMana());
events.add(new PlayerUpdatedEvent(PlayerUpdateType.CARDS));
canWait = false;
}
return events;
}
@Override
public List<GameEvent> onSwapTo() {
canWait = true;
return combatManager.initCombat();
}
@Override
public State getState() {
return State.COMBAT;
}
public CombatPhase getPhase() {
return combatManager.getPhase();
}
public Entity getCurrentTurn() {
return combatManager.getTurn();
}
public List<TurnInfo> getTurnsList() {
return combatManager.getTurnList();
}
}