mourning-ember / src / main / java / dev / llan / model / pieces / player / MainCharacter.java
MainCharacter.java
Raw
package dev.llan.model.pieces.player;

import dev.llan.model.board.Grid;
import dev.llan.model.board.Point;
import dev.llan.model.board.Tile.TileType;
import dev.llan.model.board.pathfinding.Path;
import dev.llan.model.cards.Card;
import dev.llan.model.pieces.BaseEntity;
import dev.llan.model.pieces.Displays;
import dev.llan.model.pieces.Entity;
import dev.llan.model.pieces.attributes.stats.BaseStatsBuilder;
import dev.llan.model.pieces.attributes.inventory.Inventory;
import dev.llan.events.GameEvent;
import dev.llan.events.PlayerUpdatedEvent;
import dev.llan.events.Events.*;
import javafx.scene.image.Image;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class MainCharacter extends BaseEntity implements Player {
  private Inventory inventory;
  private List<Point> inRange;

  public MainCharacter(Point startingPos, Grid grid) {
    super(
        Constants.MAIN_CHARACTER_NAME,
        Constants.RESOURCE_PATH,
        startingPos,
        grid,
        new BaseStatsBuilder().maxHealth(15.0).healthRegen(0.2).scoutingRadius(8.7));
    inventory = new Inventory(this);
    inRange = List.of();
    collection.initCollection(Constants.getInitialDeck(this));
  }

  @Override
  public GameEvent setActivePath(Optional<Path> activePath) {
    this.activePath = activePath;
    return new PlayerUpdatedEvent(PlayerUpdateType.PATH);
  }

  @Override
  public Inventory getInventory() {
    return inventory;
  }

  @Override
  public Optional<GameEvent> selectCardInHand(int cardIndex) {
    if (cardIndex != collection.getSelectedIndex()) {
      if ((cardIndex == -1 || !hasAttacked)) {
        collection.selectCard(cardIndex);
        Optional<Card> selected = collection.getSelectedCard();
        if (selected.isPresent()) {
          double range = selected.get().getRange();
          if(range == 0.0) {
            inRange = new ArrayList<>();
            inRange.add(getPosition().clone());
          } else {
            inRange = getPosition().findWithin(grid, selected.get().getRange(), true);
          }
        } else {
          inRange = List.of();
        }
        return Optional.of(new PlayerUpdatedEvent(PlayerUpdateType.CARDS));
      }
    }
    return Optional.empty();
  }

  @Override
  public Optional<Card> getSelectedCard() {
    return collection.getSelectedCard();
  }

  @Override
  public Optional<Path> generateActivePath(Point to) {
    TileType type = grid.tileAt(to).getType();
    if (type == TileType.INTERACTABLE || type == TileType.VACANT) {
      return pathFinder.findPath(this.getPosition(), to);
    }
    return Optional.empty();
  }

  @Override
  public Optional<GameEvent> recalculateActivePath() {
    if (activePath.isPresent()) {
      Point endpoint = activePath.get().getEndpoint();
      Optional<Path> newPath = pathFinder.findPath(this.getPosition(), endpoint);
      return Optional.of(this.setActivePath(newPath));
    }
    return Optional.empty();
  }

  @Override
  public void removeActivePath() {
    activePath = Optional.empty();
  }

  @Override
  public List<Point> getPointsInRange() {
    return inRange;
  }

  @Override
  public boolean isInRange(Point point) {
    return inRange.contains(point);
  }

  @Override
  public List<GameEvent> onEliminationOf(Entity other) {
    getStats().addExperience(other.getStats().getExperienceOnDeath());
    return List.of(new PlayerUpdatedEvent(PlayerUpdateType.ATTRIBUTES));
  }

  @Override
  public Image getImage() {
    return Displays.PLAYER_RAW;
  }

  @Override
  public Image getIcon() {
    return Displays.PLAYER;
  }

  @Override
  public String[] getNotes() {
    return Constants.NOTES;
  }

  @Override
  public Player clone(Grid grid) {
    MainCharacter clone = new MainCharacter(this.getPosition().clone(), grid);
    clone.setStats(new BaseStatsBuilder().copyAll(this.stats).buildClone());
    clone.activePath = this.cloneActivePath();
    clone.clonedEffects = this.cloneEffects();
    clone.inventory = this.getInventory().clone(clone);

    // NOT DEEP COPIES
    clone.modifiers = this.modifiers;
    clone.effects = this.effects;
    clone.collection = this.collection;
    clone.inRange = this.inRange;
    return clone;
  }

  @Override
  public String toString() {
    final StringBuilder sb = new StringBuilder("MainCharacter{");
    sb.append("stats=").append(stats);
    sb.append(", inventory=").append(inventory);
    sb.append(", position=").append(this.getPosition());
    sb.append('}');
    return sb.toString();
  }
}