/*******************************************************************************
* Copyright (c) 2016
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*******************************************************************************/
package jsettlers.logic.movable.strategies.trading;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import jsettlers.common.material.EMaterialType;
import jsettlers.common.material.ESearchType;
import jsettlers.common.position.ShortPoint2D;
import jsettlers.logic.buildings.trading.MarketBuilding;
import jsettlers.logic.constants.MatchConstants;
import jsettlers.logic.movable.Movable;
import jsettlers.logic.movable.MovableStrategy;
/**
*
* @author Andreas Eberle
*
*/
public class DonkeyStrategy extends MovableStrategy {
private static final long serialVersionUID = 1L;
private static final short DONKEY_WAYPOINT_SEARCH_RADIUS = 20;
private EDonkeyState state = EDonkeyState.JOBLESS;
private IDonkeyMarket market;
private Iterator<ShortPoint2D> waypoints;
private EMaterialType materialType1;
private EMaterialType materialType2;
public DonkeyStrategy(Movable movable) {
super(movable);
}
@Override
protected void action() {
switch (state) {
case JOBLESS:
this.market = findNextMarketNeedingDonkey();
if (this.market == null) { // no market found
break;
}
case INIT_GOING_TO_MARKET:
if (market.needsDonkey() && super.goToPos(market.getDoor())) {
state = EDonkeyState.GOING_TO_MARKET;
} else {
reset();
}
break;
case GOING_TO_MARKET:
EMaterialType materialType1 = market.tryToTakeDonkeyMaterial();
EMaterialType materialType2 = market.tryToTakeDonkeyMaterial();
if (materialType1 == null && materialType2 == null) {
reset();
break;
} else {
super.setMaterial(EMaterialType.BASKET);
this.materialType1 = materialType1;
this.materialType2 = materialType2;
this.waypoints = market.getWaypointsIterator();
state = EDonkeyState.GOING_TO_TARGET;
}
case GOING_TO_TARGET:
if (!goToNextWaypoint()) { // no waypoint left
dropMaterialIfPossible();
waypoints = null;
state = EDonkeyState.INIT_GOING_TO_MARKET;
}
break;
default:
break;
}
}
private boolean goToNextWaypoint() {
while (waypoints.hasNext()) {
ShortPoint2D nextPosition = waypoints.next();
if (super.preSearchPath(true, nextPosition.x, nextPosition.y, DONKEY_WAYPOINT_SEARCH_RADIUS, ESearchType.VALID_FREE_POSITION)) {
super.followPresearchedPath();
return true;
}
}
return false;
}
private void reset() {
dropMaterialIfPossible();
market = null;
waypoints = null;
state = EDonkeyState.JOBLESS;
}
private void dropMaterialIfPossible() {
if (movable.getMaterial() != EMaterialType.NO_MATERIAL) {
if (materialType1 != null) {
super.getGrid().dropMaterial(movable.getPos(), materialType1, true, true);
materialType1 = null;
}
if (materialType2 != null) {
super.getGrid().dropMaterial(movable.getPos(), materialType2, true, true);
materialType2 = null;
}
super.setMaterial(EMaterialType.NO_MATERIAL);
}
}
private IDonkeyMarket findNextMarketNeedingDonkey() {
if (this.market != null && this.market.needsDonkey()) {
return this.market;
}
Iterable<? extends IDonkeyMarket> markets = MarketBuilding.getAllMarkets(movable.getPlayer());
List<IDonkeyMarket> marketsNeedingDonkeys = new ArrayList<IDonkeyMarket>();
for (IDonkeyMarket currMarket : markets) {
if (currMarket.needsDonkey()) {
marketsNeedingDonkeys.add(currMarket);
}
}
if (!marketsNeedingDonkeys.isEmpty()) {
// randomly distribute the donkeys onto the markets needing them
return marketsNeedingDonkeys.get(MatchConstants.random().nextInt(marketsNeedingDonkeys.size()));
} else {
return null;
}
}
@Override
protected boolean isAttackable() {
return state == EDonkeyState.GOING_TO_TARGET;
}
@Override
protected boolean receiveHit() {
if (state == EDonkeyState.GOING_TO_TARGET) {
reset();
super.abortPath();
}
return false;
}
private static enum EDonkeyState {
JOBLESS,
INIT_GOING_TO_MARKET,
GOING_TO_MARKET,
GOING_TO_TARGET,
DEAD
}
}