Package ch.fusun.baron.basic.command

Source Code of ch.fusun.baron.basic.command.MoveUnitCommand

package ch.fusun.baron.basic.command;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import ch.fusun.baron.city.City;
import ch.fusun.baron.city.api.CityService;
import ch.fusun.baron.core.injection.Configure;
import ch.fusun.baron.core.injection.Inject;
import ch.fusun.baron.core.service.UserService;
import ch.fusun.baron.map.Tile;
import ch.fusun.baron.map.api.GameMapService;
import ch.fusun.baron.player.Dynasty;
import ch.fusun.baron.printing.MessagingService;
import ch.fusun.baron.property.api.PropertyService;
import ch.fusun.baron.unit.Unit;
import ch.fusun.baron.unit.service.UnitService;

/**
* Moves a unit from one tile to the next
*/
public class MoveUnitCommand extends MoneyTurnCommand {

  private Dynasty dynasty;
  private Unit unit;
  private Tile destination;
  @Inject
  private transient PropertyService propertyService;
  @Inject
  private transient UnitService unitService;
  @Inject
  private transient CityService cityService;
  @Inject
  private transient GameMapService mapService;
  @Inject
  private transient MessagingService messagingService;
  @Inject
  private transient UserService userService;
  @Configure(value = "10")
  private transient int MONEY_COST;

  /**
   * Injection constructor
   */
  public MoveUnitCommand() {
  }

  /**
   * @param dynasty
   *            The player
   * @param unit
   *            the unit
   * @param destination
   *            THe destination tile
   */
  public MoveUnitCommand(Dynasty dynasty, Unit unit, Tile destination) {
    this.dynasty = dynasty;
    this.unit = unit;
    this.destination = destination;
  }

  @Override
  public boolean isAllowedImpl() {
    Collection<Unit> units = unitService.getUnits(destination);
    boolean destinationOccupied = false;
    if (!units.isEmpty()) {
      Unit otherUnit = units.iterator().next();
      destinationOccupied = dynasty.equals(propertyService
          .getOwnership(otherUnit));
    }
    return dynasty.equals(propertyService.getOwnership(unit))
        && tileIsReachable() && unitService.unitExists(unit)
        && !destinationOccupied;
  }

  private boolean tileIsReachable() {
    return !(unitService.getLocation(unit).absoluteDistanceTo(destination) > 1f);
  }

  @Override
  public void executeImpl() {
    Unit movingUnit = unitService.getUnits(unitService.getLocation(unit))
        .iterator().next();
    Collection<Unit> units = unitService.getUnits(destination);
    if (units.isEmpty()) {
      unitService.moveUnit(movingUnit, destination);
      if (calculateAnnectionFrom()) {
        messagingService
            .addMessage(
                userService.getUser(),
                "City of " //$NON-NLS-1$
                    + ((Dynasty) propertyService
                        .getOwnership(unit)).getName()
                    + " is lost because no one defended it."); //$NON-NLS-1$
      }
    } else {
      Unit otherUnit = units.iterator().next();
      if (!dynasty.equals(propertyService.getOwnership(otherUnit))) {
        int numberOfUnits = movingUnit.getNumberOfUnits();
        int otherNumberOfUnits = otherUnit.getNumberOfUnits();
        int casualties = 0;
        int otherCasualties = 0;
        for (int i = 1; i <= Math
            .max(numberOfUnits, otherNumberOfUnits); i++) {
          if (i > numberOfUnits) {
            casualties += (Math.random() < 0.5f) ? 1 : 0;
          } else if (i > otherNumberOfUnits) {
            otherCasualties += (Math.random() < 0.5f) ? 1 : 0;
          } else if (Math.random() < 0.5f) {
            casualties += 1;
          } else {
            otherCasualties += 1;
          }
        }
        messagingService
            .addMessage(
                userService.getUser(),
                "Battle between " //$NON-NLS-1$
                    + ((Dynasty) propertyService
                        .getOwnership(unit)).getName()
                    + "(" + casualties + " casualties) and " //$NON-NLS-1$ //$NON-NLS-2$
                    + ((Dynasty) propertyService
                        .getOwnership(otherUnit))
                        .getName() + "(" //$NON-NLS-1$
                    + otherCasualties + " casualties)"); //$NON-NLS-1$
        movingUnit.kill(casualties);
        if (movingUnit.isDead()) {
          unitService.removeUnit(movingUnit);
          messagingService.addMessage(
              userService.getUser(),
              "Attacking unit of " //$NON-NLS-1$
                  + ((Dynasty) propertyService
                      .getOwnership(unit)).getName()
                  + " exploded in a fireball"); //$NON-NLS-1$
        }
        otherUnit.kill(otherCasualties);
        if (otherUnit.isDead()) {
          messagingService.addMessage(
              userService.getUser(),
              "Defending unit of " //$NON-NLS-1$
                  + ((Dynasty) propertyService
                      .getOwnership(unit)).getName()
                  + " was trampled"); //$NON-NLS-1$
          unitService.removeUnit(otherUnit);
          unitService.moveUnit(movingUnit, destination);
          if (calculateAnnectionFrom()) {
            messagingService
                .addMessage(
                    userService.getUser(),
                    "City of " //$NON-NLS-1$
                        + ((Dynasty) propertyService
                            .getOwnership(unit))
                            .getName()
                        + " is lost because defenders were to weak."); //$NON-NLS-1$
          }
        }
      }
    }
  }

  private boolean calculateAnnectionFrom() {
    boolean newLand = false;
    Object o = propertyService.getOwnership(destination);
    if (o instanceof Dynasty) {
      Dynasty ownership = (Dynasty) o;
      if (!dynasty.equals(ownership)) {
        City city = cityService.getCity(destination);
        if (city != null) {
          Collection<City> citiesOfPlayer = getCitiesForDynasty(ownership);
          for (Tile tile : mapService.getTiles()) {
            if (ownership
                .equals(propertyService.getOwnership(tile))) {
              if (getNearestCityLocation(tile, citiesOfPlayer)
                  .equals(destination)) {
                propertyService.setOwnership(dynasty, tile);
                newLand = true;
              }
            }
          }
        }
      }
    }
    return newLand;
  }

  private Tile getNearestCityLocation(Tile tile, Collection<City> cities) {
    Tile nearestLocation = new Tile(Integer.MAX_VALUE, Integer.MAX_VALUE);
    double nearestDistance = Double.MAX_VALUE;
    for (City city : cities) {
      Tile cityLocation = cityService.getLocation(city);
      if (cityLocation.absoluteDistanceTo(tile) < nearestDistance) {
        nearestDistance = cityLocation.absoluteDistanceTo(tile);
        nearestLocation = cityLocation;
      }
    }
    return nearestLocation;
  }

  private Collection<City> getCitiesForDynasty(Dynasty dynasty) {
    List<City> cities = new LinkedList<City>();
    for (Tile tile : mapService.getTiles()) {
      City city = cityService.getCity(tile);
      if (city != null) {
        if (dynasty.equals(propertyService.getOwnership(tile))) {
          cities.add(city);
        }
      }
    }
    return cities;
  }

  @Override
  protected int getTurnCost() {
    return unit.getNumberOfUnits();
  }

  @Override
  protected Dynasty getDynasty() {
    return dynasty;
  }

  @Override
  protected int getMoneyCost() {
    return MONEY_COST;
  }

}
TOP

Related Classes of ch.fusun.baron.basic.command.MoveUnitCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.