/*******************************************************************************
* Copyright (c) 2015 - 2017
*
* 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.buildings.trading;
import jsettlers.common.buildings.EBuildingType;
import jsettlers.common.buildings.IBuilding;
import jsettlers.common.buildings.stacks.RelativeStack;
import jsettlers.common.mapobject.EMapObjectType;
import jsettlers.common.material.EMaterialType;
import jsettlers.common.material.EPriority;
import jsettlers.common.position.ShortPoint2D;
import jsettlers.graphics.action.SetTradingWaypointAction.EWaypointType;
import jsettlers.logic.buildings.Building;
import jsettlers.logic.buildings.IBuildingsGrid;
import jsettlers.logic.buildings.stack.IRequestStack;
import jsettlers.logic.buildings.stack.multi.MultiMaterialRequestSettings;
import jsettlers.logic.buildings.stack.multi.MultiRequestStack;
import jsettlers.logic.buildings.stack.multi.MultiRequestStackSharedData;
import jsettlers.logic.player.Player;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class TradingBuilding extends Building implements IBuilding.ITrading {
private static final short WAYPOINT_SEARCH_RADIUS = (short) 20;
private static final long serialVersionUID = -1760409147232184087L;
private static final EPriority[] SUPPORTED_PRIORITIES = new EPriority[] { EPriority.LOW, EPriority.HIGH, EPriority.STOPPED };
private final boolean isSeaTrading;
/**
* How many materials were requested by the user. Integer#MAX_VALUE for infinity.
*/
private final MultiMaterialRequestSettings requestedMaterials = new MultiMaterialRequestSettings();
private final ShortPoint2D[] waypoints = new ShortPoint2D[EWaypointType.VALUES.length];
public TradingBuilding(EBuildingType type, Player player, ShortPoint2D position, IBuildingsGrid buildingsGrid, boolean isSeaTrading) {
super(type, player, position, buildingsGrid);
this.isSeaTrading = isSeaTrading;
}
@Override
public boolean isOccupied() {
return false;
}
@Override
protected int subTimerEvent() {
return -1;
}
@Override
protected int constructionFinishedEvent() {
return -1;
}
@Override
protected EMapObjectType getFlagType() {
return EMapObjectType.FLAG_DOOR;
}
@Override
public int getRequestedTradingFor(EMaterialType materialType) {
return requestedMaterials.getRequestedAmount(materialType);
}
@Override
public boolean isSeaTrading() {
return isSeaTrading;
}
public void changeRequestedMaterial(EMaterialType materialType, int amount, boolean relative) {
long newValue = amount;
if (relative) {
int old = requestedMaterials.getRequestedAmount(materialType);
if (old == Integer.MAX_VALUE) {
// infinity stays infinity.
return;
}
newValue += old;
}
requestedMaterials.setRequestedAmount(materialType, (short) Math.max(0, Math.min(Short.MAX_VALUE, newValue)));
}
public void setWaypoint(EWaypointType waypointType, ShortPoint2D position) {
if (isSelected()) {
drawWaypointLine(false);
}
if (waypointType != EWaypointType.DESTINATION && !isTargetSet()) {
waypointType = EWaypointType.DESTINATION;
}
if (waypointType == EWaypointType.DESTINATION) {
Arrays.fill(waypoints, null);
}
ShortPoint2D closeReachableLocation = findClosestRechablePosition(waypointType, position);
waypoints[waypointType.ordinal()] = closeReachableLocation;
if (isSelected()) {
drawWaypointLine(true);
}
}
private ShortPoint2D findClosestRechablePosition(EWaypointType waypointType, ShortPoint2D targetPosition) {
ShortPoint2D waypointBefore = this.pos;
for (int index = waypointType.ordinal() - 1; index >= 0; index--) {
if (waypoints[index] != null) {
waypointBefore = waypoints[index];
break;
}
}
return grid.getClosestReachablePosition(waypointBefore, targetPosition, false, (byte) 0, WAYPOINT_SEARCH_RADIUS);
}
protected boolean isTargetSet() {
return waypoints[waypoints.length - 1] != null;
}
protected ShortPoint2D[] getWaypoints() {
return waypoints;
}
@Override
public void setSelected(boolean selected) {
super.setSelected(selected);
drawWaypointLine(selected);
}
@Override
public void kill() {
if (isSelected()) {
drawWaypointLine(false);
}
super.kill();
}
private void drawWaypointLine(boolean draw) {
super.grid.drawTradingPathLine(super.pos, waypoints, draw);
}
@Override
protected List<IRequestStack> createWorkStacks() {
List<IRequestStack> newStacks = new LinkedList<IRequestStack>();
MultiRequestStackSharedData sharedData = new MultiRequestStackSharedData(requestedMaterials);
for (RelativeStack stack : type.getRequestStacks()) {
newStacks.add(new MultiRequestStack(grid.getRequestStackGrid(), stack.calculatePoint(this.pos), type, super.getPriority(), sharedData));
}
return newStacks;
}
@Override
public EPriority[] getSupportedPriorities() {
return SUPPORTED_PRIORITIES;
}
}