diff --git a/go.graphics.swing/src/main/java/go/graphics/swing/event/swingInterpreter/GOSwingEventConverter.java b/go.graphics.swing/src/main/java/go/graphics/swing/event/swingInterpreter/GOSwingEventConverter.java index 7c1100970b..98c4b2b718 100644 --- a/go.graphics.swing/src/main/java/go/graphics/swing/event/swingInterpreter/GOSwingEventConverter.java +++ b/go.graphics.swing/src/main/java/go/graphics/swing/event/swingInterpreter/GOSwingEventConverter.java @@ -22,6 +22,7 @@ import java.awt.event.ComponentListener; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; +import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; @@ -30,9 +31,12 @@ import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.lang.reflect.Field; +import java.util.EnumSet; +import java.util.Set; import go.graphics.UIPoint; import go.graphics.event.GOEventHandlerProvider; +import go.graphics.event.command.EModifier; import go.graphics.event.interpreter.AbstractEventConverter; /** @@ -54,6 +58,8 @@ public class GOSwingEventConverter extends AbstractEventConverter private int scaleFactor = 1; + private int modifiers; + /** * Creates a new event converter, that converts swing events to go events. * @@ -108,25 +114,30 @@ private void updateScaleFactor(Component component) { @Override public void mouseEntered(MouseEvent e) { + updateModifiers(e); startHover(convertToLocal(e)); } @Override public void mouseMoved(MouseEvent e) { + updateModifiers(e); updateHoverPosition(convertToLocal(e)); } @Override public void mouseExited(MouseEvent e) { + updateModifiers(e); endHover(convertToLocal(e)); } @Override public void mouseClicked(MouseEvent e) { + updateModifiers(e); } @Override public void mousePressed(MouseEvent e) { + updateModifiers(e); int mouseButton = e.getButton(); UIPoint local = convertToLocal(e); if (mouseButton == MouseEvent.BUTTON1) { @@ -142,6 +153,7 @@ public void mousePressed(MouseEvent e) { @Override public void mouseDragged(MouseEvent e) { + updateModifiers(e); UIPoint local = convertToLocal(e); updateDrawPosition(local); updatePanPosition(local); @@ -150,6 +162,7 @@ public void mouseDragged(MouseEvent e) { @Override public void mouseReleased(MouseEvent e) { + updateModifiers(e); UIPoint local = convertToLocal(e); if (e.getButton() == MouseEvent.BUTTON1) { endDraw(local); @@ -164,6 +177,7 @@ public void mouseReleased(MouseEvent e) { @Override public void keyPressed(KeyEvent e) { + updateModifiers(e); String text = getKeyName(e); startKeyEvent(text); /* @@ -261,6 +275,7 @@ private String getKeyName(KeyEvent e) { @Override public void keyReleased(KeyEvent e) { + updateModifiers(e); endKeyEvent(getKeyName(e)); } @@ -270,6 +285,7 @@ public void keyTyped(KeyEvent e) { @Override public void mouseWheelMoved(MouseWheelEvent e) { + updateModifiers(e); float factor = (float) Math.exp(-e.getUnitsToScroll() / 20.0); startZoom(); endZoomEvent(factor, convertToLocal(e)); @@ -310,4 +326,23 @@ void privateRegisterComponentListenerToParentWindowOf(Component component, Compo privateRegisterComponentListenerToParentWindowOf(component.getParent(), childComponent); } } + + private void updateModifiers(InputEvent e) { + modifiers = e.getModifiers(); + } + + @Override + protected Set getCurrentModifiers() { + EnumSet set = EnumSet.noneOf(EModifier.class); + if ((modifiers & (InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK)) != 0) { + set.add(EModifier.CTRL); + } + if ((modifiers & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK)) != 0) { + set.add(EModifier.ALT); + } + if ((modifiers & (InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK)) != 0) { + set.add(EModifier.SHIFT); + } + return set; + } } diff --git a/go.graphics/src/main/java/go/graphics/event/command/EModifier.java b/go.graphics/src/main/java/go/graphics/event/command/EModifier.java new file mode 100644 index 0000000000..be2c030af4 --- /dev/null +++ b/go.graphics/src/main/java/go/graphics/event/command/EModifier.java @@ -0,0 +1,7 @@ +package go.graphics.event.command; + +public enum EModifier { + SHIFT, + CTRL, + ALT +} diff --git a/go.graphics/src/main/java/go/graphics/event/command/GOCommandEvent.java b/go.graphics/src/main/java/go/graphics/event/command/GOCommandEvent.java index 5f0e307be2..d41f58dd7e 100644 --- a/go.graphics/src/main/java/go/graphics/event/command/GOCommandEvent.java +++ b/go.graphics/src/main/java/go/graphics/event/command/GOCommandEvent.java @@ -14,6 +14,8 @@ *******************************************************************************/ package go.graphics.event.command; +import java.util.Set; + import go.graphics.UIPoint; import go.graphics.event.GOEvent; @@ -21,4 +23,6 @@ public interface GOCommandEvent extends GOEvent { UIPoint getCommandPosition(); boolean isSelecting(); + + Set getModifiers(); } diff --git a/go.graphics/src/main/java/go/graphics/event/command/GOCommandEventProxy.java b/go.graphics/src/main/java/go/graphics/event/command/GOCommandEventProxy.java index f1b3b35d9d..4385bdd81c 100644 --- a/go.graphics/src/main/java/go/graphics/event/command/GOCommandEventProxy.java +++ b/go.graphics/src/main/java/go/graphics/event/command/GOCommandEventProxy.java @@ -14,6 +14,8 @@ *******************************************************************************/ package go.graphics.event.command; +import java.util.Set; + import go.graphics.UIPoint; import go.graphics.event.mouse.GOEventProxy; @@ -48,4 +50,9 @@ public UIPoint getCommandPosition() { public boolean isSelecting() { return baseEvent.isSelecting(); } + + @Override + public Set getModifiers() { + return baseEvent.getModifiers(); + } } diff --git a/go.graphics/src/main/java/go/graphics/event/interpreter/AbstractEventConverter.java b/go.graphics/src/main/java/go/graphics/event/interpreter/AbstractEventConverter.java index 6a13f22dc1..f1f91b12d3 100644 --- a/go.graphics/src/main/java/go/graphics/event/interpreter/AbstractEventConverter.java +++ b/go.graphics/src/main/java/go/graphics/event/interpreter/AbstractEventConverter.java @@ -14,13 +14,17 @@ *******************************************************************************/ package go.graphics.event.interpreter; +import java.util.Collections; +import java.util.EnumSet; import java.util.LinkedList; +import java.util.Set; import go.graphics.UIPoint; import go.graphics.event.GOEvent; import go.graphics.event.GOEventHandlerProvider; import go.graphics.event.GOKeyEvent; import go.graphics.event.SingleHandlerGoEvent; +import go.graphics.event.command.EModifier; import go.graphics.event.command.GOCommandEvent; /** @@ -189,7 +193,7 @@ protected void abortHover() { } protected boolean fireCommandEvent(UIPoint point, boolean isSelect) { - ConvertedCommandEvent commandEvent = new ConvertedCommandEvent(point, isSelect); + ConvertedCommandEvent commandEvent = new ConvertedCommandEvent(point, isSelect, getCurrentModifiers()); handleEvent(commandEvent); @@ -198,6 +202,10 @@ protected boolean fireCommandEvent(UIPoint point, boolean isSelect) { return commandEvent.getHandler() != null; } + protected Set getCurrentModifiers() { + return EnumSet.noneOf(EModifier.class); + } + protected synchronized void startKeyEvent(String string) { if (ongoingKeyEvent == null) { ongoingKeyEvent = new GOKeyEvent(string); @@ -250,10 +258,12 @@ private class ConvertedCommandEvent extends SingleHandlerGoEvent implements private final UIPoint position; private final boolean selecting; + private final Set modifiers; - public ConvertedCommandEvent(UIPoint position, boolean selecting) { + public ConvertedCommandEvent(UIPoint position, boolean selecting, Set modifiers) { this.position = position; this.selecting = selecting; + this.modifiers = modifiers; } public void initialized() { @@ -271,6 +281,11 @@ public UIPoint getCommandPosition() { public boolean isSelecting() { return selecting; } + + @Override + public Set getModifiers() { + return Collections.unmodifiableSet(modifiers); + } } diff --git a/jsettlers.common/src/main/java/jsettlers/common/action/EMoveToType.java b/jsettlers.common/src/main/java/jsettlers/common/action/EMoveToType.java new file mode 100644 index 0000000000..f2ef3809d2 --- /dev/null +++ b/jsettlers.common/src/main/java/jsettlers/common/action/EMoveToType.java @@ -0,0 +1,27 @@ +package jsettlers.common.action; + +public enum EMoveToType { + DEFAULT(true, false), FORCED(false, false), + /** + * Work at the target or patrol (for soldiers) + */ + WORK(true, true); + + public static EMoveToType[] VALUES = values(); + + private final boolean attackOnTheWay; + private final boolean workOnDestination; + + EMoveToType(boolean attackOnTheWay, boolean workOnDestination) { + this.attackOnTheWay = attackOnTheWay; + this.workOnDestination = workOnDestination; + } + + public boolean isAttackOnTheWay() { + return attackOnTheWay; + } + + public boolean isWorkOnDestination() { + return workOnDestination; + } +} \ No newline at end of file diff --git a/jsettlers.common/src/main/java/jsettlers/common/action/MoveToAction.java b/jsettlers.common/src/main/java/jsettlers/common/action/MoveToAction.java new file mode 100644 index 0000000000..9175074e98 --- /dev/null +++ b/jsettlers.common/src/main/java/jsettlers/common/action/MoveToAction.java @@ -0,0 +1,21 @@ +package jsettlers.common.action; + +import jsettlers.common.position.ShortPoint2D; + +/** + * Action for {@link EActionType#MOVE_TO} + * @author Michael Zangl + */ +public class MoveToAction extends PointAction { + + private final EMoveToType moveToType; + + public MoveToAction(EMoveToType moveToType, ShortPoint2D position) { + super(EActionType.MOVE_TO, position); + this.moveToType = moveToType; + } + + public EMoveToType getMoveToType() { + return moveToType; + } +} diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/action/ActionHandler.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/action/ActionHandler.java index 60f67c1fd2..982c55a4e4 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/action/ActionHandler.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/action/ActionHandler.java @@ -16,6 +16,7 @@ import go.graphics.event.GOEvent; import go.graphics.event.GOEventHandler; +import java8.util.Optional; import jsettlers.common.action.Action; /** @@ -25,7 +26,7 @@ */ public class ActionHandler implements GOEventHandler { - private final Action action; + private final Optional action; private final ActionFireable connector; /** @@ -36,7 +37,7 @@ public class ActionHandler implements GOEventHandler { * @param connector * The event to fire the action for. */ - public ActionHandler(Action action, ActionFireable connector) { + public ActionHandler(Optional action, ActionFireable connector) { this.action = action; this.connector = connector; } @@ -47,9 +48,7 @@ public void aborted(GOEvent event) { @Override public void finished(GOEvent event) { - if (action != null) { - this.connector.fireAction(this.action); - } + action.ifPresent(this.connector::fireAction); } @Override diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/MapContent.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/MapContent.java index 0e820b4997..706636ef11 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/MapContent.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/MapContent.java @@ -14,6 +14,10 @@ *******************************************************************************/ package jsettlers.graphics.map; +import java8.util.Optional; + +import java.util.Set; + import go.graphics.GLDrawContext; import go.graphics.IllegalBufferException; import go.graphics.UIPoint; @@ -21,6 +25,7 @@ import go.graphics.event.GOEventHandler; import go.graphics.event.GOKeyEvent; import go.graphics.event.GOModalEventHandler; +import go.graphics.event.command.EModifier; import go.graphics.event.command.GOCommandEvent; import go.graphics.event.mouse.GODrawEvent; import go.graphics.event.mouse.GOHoverEvent; @@ -48,7 +53,9 @@ import jsettlers.common.menu.IStartedGame; import jsettlers.common.menu.UIState; import jsettlers.common.action.EActionType; +import jsettlers.common.action.EMoveToType; import jsettlers.common.action.IAction; +import jsettlers.common.action.MoveToAction; import jsettlers.common.menu.messages.IMessage; import jsettlers.common.movable.IMovable; import jsettlers.common.position.FloatRectangle; @@ -580,14 +587,14 @@ public void handleEvent(GOEvent event) { } } else if (event instanceof GOCommandEvent) { GOCommandEvent commandEvent = (GOCommandEvent) event; - Action action = getActionForCommand(commandEvent); + Optional action = getActionForCommand(commandEvent); // also set when action was null, to abort drawing. fireActionEvent(event, action); } else if (event instanceof GOKeyEvent) { - Action actionForKeyboard = getActionForKeyboard(((GOKeyEvent) event).getKeyCode()); - if (actionForKeyboard != null) { - fireActionEvent(event, actionForKeyboard); - } + Optional actionForKeyboard = Optional.ofNullable(getActionForKeyboard(((GOKeyEvent) event).getKeyCode())); + actionForKeyboard.ifPresent(action -> + fireActionEvent(event, actionForKeyboard) + ); } else if (event instanceof GODrawEvent) { GODrawEvent drawEvent = (GODrawEvent) event; if (!controls.handleDrawEvent(drawEvent)) { @@ -635,7 +642,7 @@ public void zoom100() { } } - private void fireActionEvent(GOEvent event, Action action) { + private void fireActionEvent(GOEvent event, Optional action) { event.setHandler(new ActionHandler(action, this)); } @@ -647,7 +654,6 @@ private void fireActionEvent(GOEvent event, Action action) { * @return The action that corresponds to the key */ private static Action getActionForKeyboard(String keyCode) { - System.out.println(keyCode); if ("F12".equalsIgnoreCase(keyCode)) { return new Action(EActionType.FAST_FORWARD); } else if ("P".equalsIgnoreCase(keyCode) @@ -739,10 +745,14 @@ private void changeMousePosition(UIPoint position) { } } - private Action getActionForCommand(GOCommandEvent commandEvent) { + private Optional getActionForCommand(GOCommandEvent commandEvent) { UIPoint position = commandEvent.getCommandPosition(); if (controls.containsPoint(position)) { - return controls.getActionFor(position, commandEvent.isSelecting()); + if (commandEvent.isSelecting()) { + return controls.getActionForSelect(position); + } else { + return controls.getActionForMoveTo(position, moveToForCommand(commandEvent)); + } } else { // handle map click return handleCommandOnMap(commandEvent, position); @@ -779,8 +789,7 @@ public void eventDataChanged(GOEvent event) { } }; - private Action handleCommandOnMap(GOCommandEvent commandEvent, UIPoint position) { - + private Optional handleCommandOnMap(GOCommandEvent commandEvent, UIPoint position) { float x = (float) position.getX(); float y = (float) position.getY(); ShortPoint2D onMap = this.context.getPositionOnScreen(x, y); @@ -789,11 +798,23 @@ private Action handleCommandOnMap(GOCommandEvent commandEvent, UIPoint position) if (commandEvent.isSelecting()) { action = handleSelectCommand(onMap); } else { - action = new PointAction(EActionType.MOVE_TO, onMap); + action = new MoveToAction(moveToForCommand(commandEvent), onMap); } - return action; + return Optional.of(action); + } + return Optional.empty(); + } + + private static EMoveToType moveToForCommand(GOCommandEvent commandEvent) { + Set modifiers = commandEvent.getModifiers(); + if (modifiers.contains(EModifier.CTRL)) { + return EMoveToType.FORCED; + } else if (modifiers.contains(EModifier.ALT)) { + return EMoveToType.WORK; + } else { + return EMoveToType.DEFAULT; } - return null; + // TODO: Add waypoint with SHIFT } private Action handleSelectCommand(ShortPoint2D onMap) { @@ -893,7 +914,7 @@ public void action(IAction action) { } break; case MOVE_TO: - moveToMarker = ((PointAction) action).getPosition(); + moveToMarker = ((MoveToAction) action).getPosition(); moveToMarkerTime = System.currentTimeMillis(); break; case SHOW_MESSAGE: diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/IControls.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/IControls.java index dc80404b1d..62bd5e7a82 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/IControls.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/IControls.java @@ -14,6 +14,8 @@ *******************************************************************************/ package jsettlers.graphics.map.controls; +import java8.util.Optional; + import go.graphics.GLDrawContext; import go.graphics.UIPoint; import go.graphics.event.mouse.GODrawEvent; @@ -23,6 +25,7 @@ import jsettlers.common.position.ShortPoint2D; import jsettlers.common.selectable.ISelectionSet; import jsettlers.common.action.Action; +import jsettlers.common.action.EMoveToType; import jsettlers.graphics.action.ActionFireable; import jsettlers.graphics.map.MapDrawContext; @@ -82,11 +85,19 @@ public interface IControls extends IMapInterfaceListener { * * @param position * The positon. - * @param selecting - * If the event is a select event. * @return The action for the position. */ - Action getActionFor(UIPoint position, boolean selecting); + Optional getActionForSelect(UIPoint position); + /** + * Gets the action for the given ui position, that should be executed if the user right clicked it. + * + * @param position + * The positon. + * @param moveToType + * Move to modifiers + * @return The action for the position. + */ + Optional getActionForMoveTo(UIPoint position, EMoveToType moveToType); /** * Handles a draw event. The event may be fired even if it is outside the interface. diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/OriginalControls.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/OriginalControls.java index c339b213f6..b158072336 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/OriginalControls.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/OriginalControls.java @@ -14,6 +14,8 @@ *******************************************************************************/ package jsettlers.graphics.map.controls.original; +import java8.util.Optional; + import go.graphics.GLDrawContext; import go.graphics.UIPoint; import go.graphics.event.GOEvent; @@ -21,7 +23,9 @@ import go.graphics.event.mouse.GODrawEvent; import jsettlers.common.map.shapes.MapRectangle; import jsettlers.common.action.EActionType; +import jsettlers.common.action.EMoveToType; import jsettlers.common.action.IAction; +import jsettlers.common.action.MoveToAction; import jsettlers.common.player.IInGamePlayer; import jsettlers.common.position.FloatRectangle; import jsettlers.common.position.ShortPoint2D; @@ -198,19 +202,33 @@ private double getMinimapOffset(double y) { } @Override - public Action getActionFor(UIPoint position, boolean selecting) { + public Optional getActionForMoveTo(UIPoint position, EMoveToType moveToType) { + return getActionFor(position, (relativex, relativey) -> getMoveToForMinimap(relativex, relativey, moveToType)); + } + + @Override + public Optional getActionForSelect(UIPoint position) { + return getActionFor(position, this::getScrollForMinimap); + } + + @FunctionalInterface + private interface PositionToAction { + Optional positionToAction(float relativex, float relativey); + } + + private Optional getActionFor(UIPoint position, PositionToAction minimapPositionToAction) { float relativex = (float) position.getX() / this.uiBase.getPosition().getWidth(); float relativey = (float) position.getY() / this.uiBase.getPosition().getHeight(); - Action action; + Optional action; if (minimap != null && relativey > layoutProperties.MAIN_PANEL_TOP && getMinimapOffset(position.getY()) < position.getX()) { - action = getForMinimap(relativex, relativey, selecting); + action = minimapPositionToAction.positionToAction(relativex, relativey); startMapPosition = null; // to prevent it from jumping back. } else { action = uiBase.getAction(relativex, relativey); } - if (action != null - && action.getActionType() == EActionType.CHANGE_PANEL) { - mainPanel.setContent(((ChangePanelAction) action).getContent()); + if (action.isPresent() + && action.get().getActionType() == EActionType.CHANGE_PANEL) { + mainPanel.setContent(((ChangePanelAction) action.get()).getContent()); return null; } else { return action; @@ -224,27 +242,23 @@ public Action getActionFor(UIPoint position, boolean selecting) { * The position on the minimap. * @param relativey * The position on the minimap. - * @param selecting - * true if it was a selection click and the view should move there. * @return the action for that point or null for no action. */ - private Action getForMinimap(float relativex, float relativey, - boolean selecting) { + private Optional getScrollForMinimap(float relativex, float relativey) { + return computeClickPosition(relativex, relativey).map(clickPosition -> new PointAction(EActionType.PAN_TO, clickPosition)); + } + + private Optional getMoveToForMinimap(float relativex, float relativey, EMoveToType moveTo) { + return computeClickPosition(relativex, relativey).map(clickPosition -> new MoveToAction(moveTo, clickPosition)); + } + + private Optional computeClickPosition(float relativex, float relativey) { float minimapx = (relativex - layoutProperties.miniMap.MAP_LEFT) / layoutProperties.miniMap.MAP_WIDTH; float minimapy = ((relativey - layoutProperties.MAIN_PANEL_TOP) / (1 - layoutProperties.MAIN_PANEL_TOP) - layoutProperties.miniMap.MAP_BOTTOM) / layoutProperties.miniMap.MAP_HEIGHT; - ShortPoint2D clickPosition = minimap.getClickPositionIfOnMap(minimapx, minimapy); - if (clickPosition != null) { - if (selecting) { - return new PointAction(EActionType.PAN_TO, clickPosition); - } else { - return new PointAction(EActionType.MOVE_TO, clickPosition); - } - } else { - return null; - } + return Optional.ofNullable(minimap.getClickPositionIfOnMap(minimapx, minimapy)); } @Override @@ -276,8 +290,8 @@ public boolean handleDrawEvent(GODrawEvent event) { return false; } - Action action = getActionForDraw(event); - if (action != null && context != null && minimap != null) { + Optional action = getActionForDraw(event); + if (action.isPresent() && context != null && minimap != null) { float y = context.getScreen().getHeight() / 2; float x = context.getScreen().getWidth() / 2; startMapPosition = context.getPositionOnScreen(x, y); @@ -288,7 +302,7 @@ public boolean handleDrawEvent(GODrawEvent event) { } } - private Action getActionForDraw(GODrawEvent event) { + private Optional getActionForDraw(GODrawEvent event) { UIPoint position = event.getDrawPosition(); float width = this.uiBase.getPosition().getWidth(); @@ -296,7 +310,7 @@ private Action getActionForDraw(GODrawEvent event) { float height = this.uiBase.getPosition().getHeight(); float relativey = (float) position.getY() / height; - return getForMinimap(relativex, relativey, true); + return getScrollForMinimap(relativex, relativey); } /** @@ -353,11 +367,10 @@ public void aborted(GOEvent event) { @Override public void eventDataChanged(GOEvent event) { - Action action = getActionForDraw((GODrawEvent) event); - if (action != null && action.getActionType() == EActionType.PAN_TO) { - minimap.getContext().scrollTo( - ((PointAction) action).getPosition()); - } + getActionForDraw((GODrawEvent) event) + .filter(action -> action.getActionType() == EActionType.PAN_TO) + .ifPresent(action -> minimap.getContext().scrollTo( + ((PointAction) action).getPosition())); } } diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/ActionProvidedBarFill.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/ActionProvidedBarFill.java index 49766da7cf..d827503fd2 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/ActionProvidedBarFill.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/ActionProvidedBarFill.java @@ -14,6 +14,7 @@ */ package jsettlers.graphics.map.controls.original.panel.content; +import java8.util.Optional; import jsettlers.common.action.Action; /** @@ -22,7 +23,7 @@ public class ActionProvidedBarFill extends BarFill { public interface IBarFillActionProvider { - Action getAction(float fillForClick); + Optional getAction(float fillForClick); } private IBarFillActionProvider actionProvider; @@ -33,7 +34,7 @@ public ActionProvidedBarFill(IBarFillActionProvider actionProvider) { } @Override - public Action getAction(final float relativeX, float relativeY) { + public Optional getAction(final float relativeX, float relativeY) { float fillForClick = getFillForClick(relativeX); return actionProvider.getAction(fillForClick); } diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/BarFill.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/BarFill.java index 5522822761..dc9d265925 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/BarFill.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/BarFill.java @@ -14,6 +14,8 @@ *******************************************************************************/ package jsettlers.graphics.map.controls.original.panel.content; +import java8.util.Optional; + import go.graphics.GLDrawContext; import jsettlers.common.images.EImageLinkType; import jsettlers.common.images.ImageLink; @@ -57,9 +59,9 @@ public void drawAt(GLDrawContext gl) { } @Override - public Action getAction(final float relativeX, float relativeY) { + public Optional getAction(final float relativeX, float relativeY) { final float relativeFill = getFillForClick(relativeX); - return new ExecutableAction() { + return Optional.of(new ExecutableAction() { @Override public void execute() { setBarFill(relativeFill, relativeFill); @@ -67,7 +69,7 @@ public void execute() { listener.execute(); } } - }; + }); } protected float getFillForClick(final float relativeX) { diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/material/distribution/DistributionPanel.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/material/distribution/DistributionPanel.java index 51813c3dc4..a087496faf 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/material/distribution/DistributionPanel.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/material/distribution/DistributionPanel.java @@ -41,6 +41,7 @@ import jsettlers.graphics.ui.UIPanel; import java8.util.J8Arrays; +import java8.util.Optional; import java8.util.stream.Collectors; public class DistributionPanel extends AbstractContentProvider implements IUiContentReceiver { @@ -95,9 +96,9 @@ private static class BuildingDistributionSettingPanel extends UIPanel { barFill = new ActionProvidedBarFill(ratio -> { ShortPoint2D position = positionSupplier.getPosition(); if (position != null) { - return new SetMaterialDistributionSettingsAction(position, materialType, buildingType, ratio); + return Optional.of(new SetMaterialDistributionSettingsAction(position, materialType, buildingType, ratio)); } else { - return null; + return Optional.empty(); } }); Label rowTitle = new Label(Labels.getName(buildingType), EFontSize.SMALL, EHorizontalAlignment.LEFT); diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/material/production/MaterialsProductionPanel.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/material/production/MaterialsProductionPanel.java index 5ce9857a28..861f496fba 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/material/production/MaterialsProductionPanel.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/content/material/production/MaterialsProductionPanel.java @@ -24,6 +24,7 @@ import jsettlers.common.position.IPositionSupplier; import jsettlers.common.position.ShortPoint2D; import jsettlers.graphics.action.ActionFireable; +import jsettlers.common.action.Action; import jsettlers.common.action.SetMaterialProductionAction; import jsettlers.graphics.localization.Labels; import jsettlers.graphics.map.controls.original.panel.content.AbstractContentProvider; @@ -38,6 +39,7 @@ import jsettlers.graphics.ui.UIPanel; import java.util.Arrays; +import java8.util.Optional; public class MaterialsProductionPanel extends AbstractContentProvider { private static final float contentHeight_px = 216; @@ -94,7 +96,7 @@ public Row(final EMaterialType materialType) { arrows.addChild(upButton, 0f, 0.5f, 1f, 1f); arrows.addChild(downButton, 0f, 0f, 1f, 0.5f); - barFill = new ActionProvidedBarFill(fillForClick -> new SetMaterialProductionAction(position, materialType, SetMaterialProductionAction.EMaterialProductionType.SET_RATIO, fillForClick)); + barFill = new ActionProvidedBarFill(fillForClick -> Optional.of(new SetMaterialProductionAction(position, materialType, SetMaterialProductionAction.EMaterialProductionType.SET_RATIO, fillForClick))); float left = 0; addChild(goodsIcon, left, 0f, left += iconWidth, 1f); diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/selection/BuildingSelectionContent.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/selection/BuildingSelectionContent.java index bbf27582a1..3b51120564 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/selection/BuildingSelectionContent.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/controls/original/panel/selection/BuildingSelectionContent.java @@ -15,6 +15,7 @@ package jsettlers.graphics.map.controls.original.panel.selection; import java.util.List; +import java8.util.Optional; import go.graphics.GLDrawContext; import go.graphics.text.EFontSize; @@ -201,9 +202,9 @@ public LandTradingPath(ImageLink image) { } @Override - public Action getAction(float relativeX, float relativeY) { + public Optional getAction(float relativeX, float relativeY) { int step = (int) (relativeX * NUMBER_OF_BUTTONS); - return getActionForStep(step); + return Optional.of(getActionForStep(step)); } } @@ -227,12 +228,12 @@ public SeaTradingPath(ImageLink image) { } @Override - public Action getAction(float relativeX, float relativeY) { + public Optional getAction(float relativeX, float relativeY) { int step = (int) (relativeX * NUMBER_OF_BUTTONS) - 1; if (step >= 0) { - return getActionForStep(step); + return Optional.of(getActionForStep(step)); } else { - return new Action(EActionType.ASK_SET_DOCK); + return Optional.of(new Action(EActionType.ASK_SET_DOCK)); } } } diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/Button.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/Button.java index b9916847aa..91467120a2 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/Button.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/Button.java @@ -15,6 +15,10 @@ package jsettlers.graphics.ui; import jsettlers.common.images.ImageLink; + +import java.util.Objects; + +import java8.util.Optional; import jsettlers.common.action.Action; /** @@ -69,8 +73,8 @@ public void setAction(Action action) { } @Override - public Action getAction(float relativex, float relativey) { - return getAction(); + public Optional getAction(float relativex, float relativey) { + return Optional.ofNullable(getAction()); } @Override diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/LabeledButton.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/LabeledButton.java index 176b37e52f..f1aac24e12 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/LabeledButton.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/LabeledButton.java @@ -14,6 +14,8 @@ *******************************************************************************/ package jsettlers.graphics.ui; +import java8.util.Optional; + import go.graphics.GLDrawContext; import go.graphics.text.EFontSize; import go.graphics.text.TextDrawer; @@ -57,10 +59,10 @@ public void drawAt(GLDrawContext gl) { drawer.setColor(1, 1, 1, 1); drawer.renderCentered(getPosition().getCenterX(), getPosition().getCenterY(), text); } - + @Override - public Action getAction(float relativex, float relativey) { - return enabled ? action : null; + public Optional getAction(float relativex, float relativey) { + return enabled ? super.getAction(relativex, relativey) : Optional.empty(); } /** diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIElement.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIElement.java index e9f93619ce..b0d8b37558 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIElement.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIElement.java @@ -15,6 +15,7 @@ package jsettlers.graphics.ui; import go.graphics.GLDrawContext; +import java8.util.Optional; import jsettlers.common.position.FloatRectangle; import jsettlers.common.action.Action; @@ -28,7 +29,7 @@ public interface UIElement { */ void drawAt(GLDrawContext gl); - Action getAction(float relativex, float relativey); + Optional getAction(float relativex, float relativey); String getDescription(float relativex, float relativey); diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIInput.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIInput.java index 26c2840469..d6ef8660e2 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIInput.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIInput.java @@ -14,6 +14,8 @@ *******************************************************************************/ package jsettlers.graphics.ui; +import java8.util.Optional; + import go.graphics.GLDrawContext; import go.graphics.event.GOEvent; import go.graphics.event.GOEventHandler; @@ -96,7 +98,7 @@ public void setInputString(String inputString) { } @Override - public Action getAction(float relativex, float relativey) { - return new FocusAction(this); + public Optional getAction(float relativex, float relativey) { + return Optional.of(new FocusAction(this)); } } diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIList.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIList.java index 6a3041aa31..53ba51abbf 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIList.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIList.java @@ -17,6 +17,7 @@ import go.graphics.GLDrawContext; import java.util.List; +import java8.util.Optional; import jsettlers.common.images.EImageLinkType; import jsettlers.common.images.OriginalImageLink; @@ -45,6 +46,19 @@ public class UIList implements UIElement { private T activeItem; private final ListItemGenerator generator; + private final class ScrollToExecutableAction extends ExecutableAction { + private final int destinationOffset; + + private ScrollToExecutableAction(int destinationOffset) { + this.destinationOffset = destinationOffset; + } + + @Override + public void execute() { + scrollBy(destinationOffset); + } + } + public interface ListItemGenerator { UIListItem getItem(T item); } @@ -138,27 +152,22 @@ public void drawAt(GLDrawContext gl) { } @Override - public Action getAction(float relativex, float relativey) { + public Optional getAction(float relativex, float relativey) { synchronized (itemsMutex) { if (relativex < RIGHTBORDER) { float listy = 1 - relativey + listoffset; int itemIndex = (int) (listy / itemheight); if (itemIndex >= 0 && itemIndex < items.size()) { - return new SelectAction(items.get(itemIndex)); + return Optional.of(new SelectAction(items.get(itemIndex))); } else { - return null; + return Optional.empty(); } } else { final float halfNumberOfDisplayedItems = (int) (0.5f / itemheight); final int destinationOffset = (int) ((1 - relativey) * items.size() - halfNumberOfDisplayedItems); // subtract this to get the center of the scrollbar where the player klicked. - return new ExecutableAction() { - @Override - public void execute() { - scrollBy(destinationOffset); - } - }; + return Optional.of(new ScrollToExecutableAction(destinationOffset)); } } } diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIPanel.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIPanel.java index a18c4a0f03..3924e275e8 100644 --- a/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIPanel.java +++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/ui/UIPanel.java @@ -18,6 +18,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java8.util.Optional; import go.graphics.GLDrawContext; import jsettlers.common.images.ImageLink; @@ -168,13 +169,13 @@ public void drawAt(GLDrawContext gl, float width, float height) { child.drawAt(gl); } - public Action getActionRelative(float parentx, float parenty) { + public Optional getActionRelative(float parentx, float parenty) { if (left <= parentx && parentx <= right && bottom <= parenty && parenty <= top) { float relativex = (parentx - left) / (right - left); float relativey = (parenty - bottom) / (top - bottom); return child.getAction(relativex, relativey); } else { - return null; + return Optional.empty(); } } @@ -208,14 +209,14 @@ public void removeAll() { } @Override - public Action getAction(float relativex, float relativey) { + public Optional getAction(float relativex, float relativey) { for (ChildLink link : children) { - Action action = link.getActionRelative(relativex, relativey); - if (action != null) { + Optional action = link.getActionRelative(relativex, relativey); + if (action.isPresent()) { return action; } } - return null; + return Optional.empty(); } @Override diff --git a/jsettlers.logic/src/main/java/jsettlers/ai/army/ConfigurableGeneral.java b/jsettlers.logic/src/main/java/jsettlers/ai/army/ConfigurableGeneral.java index 7721d559b4..efd6062495 100644 --- a/jsettlers.logic/src/main/java/jsettlers/ai/army/ConfigurableGeneral.java +++ b/jsettlers.logic/src/main/java/jsettlers/ai/army/ConfigurableGeneral.java @@ -26,6 +26,7 @@ import jsettlers.common.movable.ESoldierType; import jsettlers.common.player.IPlayer; import jsettlers.common.position.ShortPoint2D; +import jsettlers.common.action.EMoveToType; import jsettlers.common.action.SetMaterialProductionAction.EMaterialProductionType; import jsettlers.input.tasks.MoveToGuiTask; import jsettlers.input.tasks.SetMaterialProductionGuiTask; @@ -214,7 +215,7 @@ private void sendTroopsTo(List attackerPositions, ShortPoint2D tar } } - taskScheduler.scheduleTask(new MoveToGuiTask(player.playerId, target, attackerIds)); + taskScheduler.scheduleTask(new MoveToGuiTask(player.playerId, target, attackerIds, EMoveToType.DEFAULT)); } private ShortPoint2D getTargetEnemyDoorToAttack(IPlayer enemyToAttack) { diff --git a/jsettlers.logic/src/main/java/jsettlers/ai/highlevel/WhatToDoAi.java b/jsettlers.logic/src/main/java/jsettlers/ai/highlevel/WhatToDoAi.java index b9c3417e16..eb621ffa8b 100644 --- a/jsettlers.logic/src/main/java/jsettlers/ai/highlevel/WhatToDoAi.java +++ b/jsettlers.logic/src/main/java/jsettlers/ai/highlevel/WhatToDoAi.java @@ -70,6 +70,7 @@ import jsettlers.ai.highlevel.pioneers.PioneerGroup; import jsettlers.ai.highlevel.pioneers.target.SameBlockedPartitionLikePlayerFilter; import jsettlers.ai.highlevel.pioneers.target.SurroundedByResourcesFilter; +import jsettlers.common.action.EMoveToType; import jsettlers.common.buildings.EBuildingType; import jsettlers.common.landscape.EResourceType; import jsettlers.common.material.EMaterialType; @@ -233,7 +234,7 @@ private Set occupyMilitaryBuildings() { private void sendMovableTo(IMovable movable, ShortPoint2D target) { if (movable != null) { - taskScheduler.scheduleTask(new MoveToGuiTask(playerId, target, Collections.singletonList(movable.getID()))); + taskScheduler.scheduleTask(new MoveToGuiTask(playerId, target, Collections.singletonList(movable.getID()), EMoveToType.DEFAULT)); } } @@ -455,7 +456,7 @@ private void releasePioneers(int numberOfPioneers) { taskScheduler.scheduleTask(new ConvertGuiTask(playerId, pioneerIds, EMovableType.BEARER)); if (numberOfPioneers == Integer.MAX_VALUE) { // pioneers which can not be converted shall walk into player's land to be converted the next tic - taskScheduler.scheduleTask(new MoveToGuiTask(playerId, aiStatistics.getPositionOfPartition(playerId), pioneerIds)); + taskScheduler.scheduleTask(new MoveToGuiTask(playerId, aiStatistics.getPositionOfPartition(playerId), pioneerIds, EMoveToType.FORCED)); } } } @@ -478,7 +479,7 @@ private void setNewTargetForBroadenerPioneers() { PioneerGroup pioneersWithNoAction = broadenerPioneers.getPioneersWithNoAction(); ShortPoint2D broadenTarget = pioneerAi.findBroadenTarget(); if (broadenTarget != null) { - taskScheduler.scheduleTask(new MoveToGuiTask(playerId, broadenTarget, pioneersWithNoAction.getPioneerIds())); + taskScheduler.scheduleTask(new MoveToGuiTask(playerId, broadenTarget, pioneersWithNoAction.getPioneerIds(), EMoveToType.WORK)); } } } @@ -487,7 +488,7 @@ private void setNewTargetForResourcePioneers() { if (resourcePioneers.isNotEmpty()) { ShortPoint2D resourceTarget = pioneerAi.findResourceTarget(); if (resourceTarget != null) { - taskScheduler.scheduleTask(new MoveToGuiTask(playerId, resourceTarget, resourcePioneers.getPioneerIds())); + taskScheduler.scheduleTask(new MoveToGuiTask(playerId, resourceTarget, resourcePioneers.getPioneerIds(), EMoveToType.WORK)); } } } diff --git a/jsettlers.logic/src/main/java/jsettlers/input/GuiInterface.java b/jsettlers.logic/src/main/java/jsettlers/input/GuiInterface.java index 2b6290de1b..c1a62a80c2 100644 --- a/jsettlers.logic/src/main/java/jsettlers/input/GuiInterface.java +++ b/jsettlers.logic/src/main/java/jsettlers/input/GuiInterface.java @@ -20,7 +20,9 @@ import jsettlers.common.action.BuildAction; import jsettlers.common.action.ConvertAction; import jsettlers.common.action.EActionType; +import jsettlers.common.action.EMoveToType; import jsettlers.common.action.IAction; +import jsettlers.common.action.MoveToAction; import jsettlers.common.action.PointAction; import jsettlers.common.action.SetAcceptedStockMaterialAction; import jsettlers.common.action.SetBuildingPriorityAction; @@ -216,13 +218,13 @@ public void action(IAction action) { break; case MOVE_TO: { - final PointAction moveToAction = (PointAction) action; + final MoveToAction moveToAction = (MoveToAction) action; if (currentSelection.getSelectionType() == ESelectionType.BUILDING && currentSelection.getSize() == 1) { setBuildingWorkArea(moveToAction.getPosition()); } else { - moveTo(moveToAction.getPosition()); + moveTo(moveToAction.getPosition(), moveToAction.getMoveToType()); } break; } @@ -502,9 +504,9 @@ private void stopOrStartWorkingAction(boolean stop) { taskScheduler.scheduleTask(new MovableGuiTask(stop ? EGuiAction.STOP_WORKING : EGuiAction.START_WORKING, playerId, getIDsOfSelected())); } - private void moveTo(ShortPoint2D pos) { + private void moveTo(ShortPoint2D pos, EMoveToType moveToType) { final List selectedIds = getIDsOfSelected(); - scheduleTask(new MoveToGuiTask(playerId, pos, selectedIds)); + scheduleTask(new MoveToGuiTask(playerId, pos, selectedIds, moveToType)); } private List getIDsOfSelected() { diff --git a/jsettlers.logic/src/main/java/jsettlers/input/GuiTaskExecutor.java b/jsettlers.logic/src/main/java/jsettlers/input/GuiTaskExecutor.java index 3bb76ec398..44bb70aa63 100644 --- a/jsettlers.logic/src/main/java/jsettlers/input/GuiTaskExecutor.java +++ b/jsettlers.logic/src/main/java/jsettlers/input/GuiTaskExecutor.java @@ -20,6 +20,7 @@ import java.util.Iterator; import java.util.List; +import jsettlers.common.action.EMoveToType; import jsettlers.common.buildings.IBuilding; import jsettlers.common.map.shapes.HexGridArea; import jsettlers.common.position.ShortPoint2D; @@ -100,7 +101,7 @@ public void executeTask(TaskPacket iTask) { case MOVE_TO: { MoveToGuiTask task = (MoveToGuiTask) guiTask; - moveSelectedTo(task.getPosition(), task.getSelection()); + moveSelectedTo(task.getPosition(), task.getSelection(), task.getMoveToType()); break; } @@ -293,19 +294,21 @@ private void killSelectedMovables(List selectedMovables) { * position to move to * @param movableIds * A list of the id's of the movables. + * @param moveToType + * How to move there. */ - private void moveSelectedTo(ShortPoint2D targetPosition, List movableIds) { + private void moveSelectedTo(ShortPoint2D targetPosition, List movableIds, EMoveToType moveToType) { if (movableIds.size() == 1) { ILogicMovable currMovable = Movable.getMovableByID(movableIds.get(0)); if (currMovable != null) { - currMovable.moveTo(targetPosition); + currMovable.moveTo(targetPosition, moveToType); } } else if (!movableIds.isEmpty()) { - sendMovablesNew(targetPosition, movableIds); + sendMovablesNew(targetPosition, movableIds, moveToType); } } - private void sendMovablesNew(ShortPoint2D targetPosition, List movableIds) { + private void sendMovablesNew(ShortPoint2D targetPosition, List movableIds, EMoveToType moveToType) { List movables = stream(movableIds).map(Movable::getMovableByID).filter(Objects::nonNull).collect(Collectors.toList()); if (movables.isEmpty()) { return; @@ -322,7 +325,7 @@ private void sendMovablesNew(ShortPoint2D targetPosition, List movableI Optional movableOptional = removeMovableThatCanMoveTo(movables, x, y); movableOptional.ifPresent(movable -> { - movable.moveTo(new ShortPoint2D(x, y)); + movable.moveTo(new ShortPoint2D(x, y), moveToType); numberOfSendMovables.value++; }); }); diff --git a/jsettlers.logic/src/main/java/jsettlers/input/tasks/MoveToGuiTask.java b/jsettlers.logic/src/main/java/jsettlers/input/tasks/MoveToGuiTask.java index cadbcc1969..29c02e52d1 100644 --- a/jsettlers.logic/src/main/java/jsettlers/input/tasks/MoveToGuiTask.java +++ b/jsettlers.logic/src/main/java/jsettlers/input/tasks/MoveToGuiTask.java @@ -18,7 +18,9 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.List; +import java.util.Objects; +import jsettlers.common.action.EMoveToType; import jsettlers.common.position.ShortPoint2D; /** @@ -28,29 +30,37 @@ */ public class MoveToGuiTask extends MovableGuiTask { private ShortPoint2D position; + private EMoveToType moveToType; public MoveToGuiTask() { } - public MoveToGuiTask(byte playerId, ShortPoint2D pos, List selection) { + public MoveToGuiTask(byte playerId, ShortPoint2D pos, List selection, EMoveToType moveToType) { super(EGuiAction.MOVE_TO, playerId, selection); this.position = pos; + this.moveToType = moveToType; } public ShortPoint2D getPosition() { return position; } + + public EMoveToType getMoveToType() { + return moveToType; + } @Override protected void serializeTask(DataOutputStream dos) throws IOException { super.serializeTask(dos); SimpleGuiTask.serializePosition(dos, position); + dos.writeByte(moveToType.ordinal()); } @Override protected void deserializeTask(DataInputStream dis) throws IOException { super.deserializeTask(dis); position = SimpleGuiTask.deserializePosition(dis); + moveToType = EMoveToType.VALUES[dis.readByte()]; } @Override @@ -58,6 +68,7 @@ public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((position == null) ? 0 : position.hashCode()); + result = prime * result + ((moveToType == null) ? 0 : moveToType.hashCode()); return result; } @@ -70,11 +81,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; MoveToGuiTask other = (MoveToGuiTask) obj; - if (position == null) { - if (other.position != null) - return false; - } else if (!position.equals(other.position)) + if (!Objects.equals(position, other.position)) { + return false; + } + if (!Objects.equals(moveToType, other.moveToType)) { return false; + } return true; } } diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/Movable.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/Movable.java index 2e16a76b57..2e2ce11488 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/Movable.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/Movable.java @@ -15,6 +15,7 @@ package jsettlers.logic.movable; import jsettlers.algorithms.path.Path; +import jsettlers.common.action.EMoveToType; import jsettlers.common.buildings.EBuildingType; import jsettlers.common.mapobject.EMapObjectType; import jsettlers.common.material.EMaterialType; @@ -43,6 +44,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentLinkedQueue; /** @@ -75,6 +77,10 @@ public final class Movable implements ILogicMovable { private ShortPoint2D position; private ShortPoint2D requestedTargetPosition = null; + /** + * Move to type of current / last path action + */ + private EMoveToType requestedMoveToType = EMoveToType.DEFAULT; private Path path; private float health; @@ -128,9 +134,11 @@ public static void writeStaticState(ObjectOutputStream oos) throws IOException { * * @param targetPosition */ - public final void moveTo(ShortPoint2D targetPosition) { + @Override + public final void moveTo(ShortPoint2D targetPosition, EMoveToType moveToType) { if (movableType.isPlayerControllable() && strategy.canBeControlledByPlayer() && !alreadyWalkingToPosition(targetPosition)) { this.requestedTargetPosition = targetPosition; + this.requestedMoveToType = Objects.requireNonNull(moveToType); } } @@ -220,7 +228,7 @@ public int timerEvent() { requestedTargetPosition = null; if (foundPath) { - this.strategy.moveToPathSet(oldPos, oldTargetPos, path.getTargetPos()); + this.strategy.moveToPathSet(oldPos, oldTargetPos, path.getTargetPos(), requestedMoveToType); return animationDuration; // we already follow the path and initiated the walking } else { break; @@ -280,7 +288,7 @@ public int timerEvent() { } private void pathingAction() { - if (path == null || !path.hasNextStep() || !strategy.checkPathStepPreconditions(path.getTargetPos(), path.getStep())) { + if (path == null || !path.hasNextStep() || !strategy.checkPathStepPreconditions(path.getTargetPos(), path.getStep(), requestedMoveToType)) { // if path is finished, or canceled by strategy return from here setState(EMovableState.DOING_NOTHING); movableAction = EMovableAction.NO_ACTION; @@ -593,6 +601,7 @@ final void lookInDirection(EDirection direction) { * * @param targetPos * position to move to. + * @param type * @return true if it was possible to calculate a path to the given position
* false if it wasn't possible to get a path. */ diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/MovableStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/MovableStrategy.java index 725f6442f2..05c01e0cbd 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/MovableStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/MovableStrategy.java @@ -18,6 +18,7 @@ import java.util.LinkedList; import jsettlers.algorithms.path.Path; +import jsettlers.common.action.EMoveToType; import jsettlers.common.buildings.EBuildingType; import jsettlers.common.material.EMaterialType; import jsettlers.common.material.ESearchType; @@ -211,10 +212,11 @@ protected final void abortPath() { * Target of the current path. * @param step * The number of the current step where 1 means the first step. + * @param moveToType TODO * @return true if the path should be continued
* false if it must be stopped. */ - protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step) { + protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step, EMoveToType moveToType) { return true; } @@ -235,8 +237,9 @@ protected void strategyKilledEvent(ShortPoint2D pathTarget) { // used in overrid * The target position of the old path or null if no old path was set. * @param targetPos * The new target position. + * @param moveToType TODO */ - protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos) { + protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos, EMoveToType moveToType) { } /** diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/interfaces/ILogicMovable.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/interfaces/ILogicMovable.java index 42570260ac..297ac468d7 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/interfaces/ILogicMovable.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/interfaces/ILogicMovable.java @@ -5,6 +5,7 @@ import jsettlers.algorithms.fogofwar.IViewDistancable; import jsettlers.algorithms.path.IPathCalculatable; import jsettlers.algorithms.path.Path; +import jsettlers.common.action.EMoveToType; import jsettlers.common.movable.EMovableType; import jsettlers.common.position.ShortPoint2D; import jsettlers.input.IGuiMovable; @@ -33,5 +34,5 @@ public interface ILogicMovable extends void convertTo(EMovableType newMovableType); Player getPlayer(); IBuildingOccupyableMovable setOccupyableBuilding(IOccupyableBuilding building); - void moveTo(ShortPoint2D targetPosition); + void moveTo(ShortPoint2D targetPosition, EMoveToType moveToType); } diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BearerMovableStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BearerMovableStrategy.java index 45bc0a75d1..f9d1ce8f4a 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BearerMovableStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BearerMovableStrategy.java @@ -14,6 +14,7 @@ *******************************************************************************/ package jsettlers.logic.movable.strategies; +import jsettlers.common.action.EMoveToType; import jsettlers.common.material.EMaterialType; import jsettlers.common.movable.EMovableType; import jsettlers.common.position.ShortPoint2D; @@ -227,7 +228,7 @@ private void reoffer() { } @Override - protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step) { + protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step, EMoveToType moveToType) { if (request != null && !request.isActive()) { return false; } diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BricklayerStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BricklayerStrategy.java index 5b268d6e37..403e4c2e36 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BricklayerStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BricklayerStrategy.java @@ -15,6 +15,7 @@ package jsettlers.logic.movable.strategies; import jsettlers.common.movable.EMovableAction; +import jsettlers.common.action.EMoveToType; import jsettlers.common.movable.EDirection; import jsettlers.common.position.ShortPoint2D; import jsettlers.logic.map.grid.partition.manager.manageables.IManageableBricklayer; @@ -96,7 +97,7 @@ private void tryToBuild() { } @Override - protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step) { + protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step, EMoveToType moveToType) { if (constructionSite == null || constructionSite.isBricklayerRequestActive()) { return true; } else { diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BuildingWorkerStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BuildingWorkerStrategy.java index 6917a00328..70ad29dd94 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BuildingWorkerStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/BuildingWorkerStrategy.java @@ -18,6 +18,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import jsettlers.common.action.EMoveToType; import jsettlers.common.buildings.EBuildingType; import jsettlers.common.buildings.jobs.EBuildingJobType; import jsettlers.common.buildings.jobs.IBuildingJob; @@ -507,7 +508,7 @@ protected void pathAborted(ShortPoint2D pathTarget) { } @Override - protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step) { + protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step, EMoveToType moveToType) { return isJobless() || building != null; } diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/DiggerStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/DiggerStrategy.java index a014d30952..04f5c8d039 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/DiggerStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/DiggerStrategy.java @@ -14,6 +14,7 @@ *******************************************************************************/ package jsettlers.logic.movable.strategies; +import jsettlers.common.action.EMoveToType; import jsettlers.common.landscape.ELandscapeType; import jsettlers.common.movable.EMovableAction; import jsettlers.common.position.RelativePoint; @@ -142,7 +143,7 @@ private void reportJobless() { } @Override - protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step) { + protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step, EMoveToType moveToType) { if (requester == null || requester.isDiggerRequestActive()) { return true; } else { diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/FleeStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/FleeStrategy.java index 5b878cf1f9..ba4c72e2bf 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/FleeStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/FleeStrategy.java @@ -14,6 +14,7 @@ *******************************************************************************/ package jsettlers.logic.movable.strategies; +import jsettlers.common.action.EMoveToType; import jsettlers.common.material.ESearchType; import jsettlers.common.movable.EDirection; import jsettlers.common.position.ShortPoint2D; @@ -81,7 +82,7 @@ protected void action() { } @Override - protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step) { + protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step, EMoveToType moveToType) { if (lastCheckedPathStep == step) { pathStepCheckedCounter++; searchesCounter++; diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/soldiers/SoldierStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/soldiers/SoldierStrategy.java index 49a60e7fdf..de2f5a3362 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/soldiers/SoldierStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/soldiers/SoldierStrategy.java @@ -15,6 +15,7 @@ package jsettlers.logic.movable.strategies.soldiers; import jsettlers.algorithms.path.Path; +import jsettlers.common.action.EMoveToType; import jsettlers.common.buildings.OccupierPlace; import jsettlers.common.movable.EDirection; import jsettlers.common.movable.EMovableType; @@ -44,6 +45,7 @@ private enum ESoldierState { INIT_GOTO_TOWER, GOING_TO_TOWER, + FORCED_MOVE, } private final EMovableType movableType; @@ -71,6 +73,9 @@ protected void action() { switch (state) { case AGGRESSIVE: break; + + case FORCED_MOVE: + break; case HITTING: if (!isEnemyAttackable(enemy, isInTower)) { @@ -108,7 +113,7 @@ protected void action() { if (!isInTower) { // we are in danger because an enemy entered our range where we can't attack => run away EDirection escapeDirection = EDirection.getApproxDirection(toCloseEnemy.getPos(), movable.getPos()); super.goInDirection(escapeDirection, EGoInDirectionMode.GO_IF_ALLOWED_AND_FREE); - movable.moveTo(null); // reset moveToRequest, so the soldier doesn't go there after fleeing. + movable.moveTo(null, EMoveToType.DEFAULT); // reset moveToRequest, so the soldier doesn't go there after fleeing. } // else { // we are in the tower, so wait and check again next time. @@ -290,7 +295,7 @@ public void setDefendingAt(ShortPoint2D pos) { } @Override - protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step) { + protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step, EMoveToType moveToType) { if (state == ESoldierState.INIT_GOTO_TOWER) { return false; // abort previous path when we just got a tower set } @@ -312,12 +317,12 @@ protected boolean checkPathStepPreconditions(ShortPoint2D pathTarget, int step) } @Override - protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos) { + protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos, EMoveToType moveToType) { if (targetPos != null && this.oldPathTarget != null) { oldPathTarget = null; // reset the path target to be able to get the new one when we hijack the path inSaveGotoMode = false; } - changeStateTo(ESoldierState.SEARCH_FOR_ENEMIES); + changeStateTo(moveToType.isAttackOnTheWay() ? ESoldierState.SEARCH_FOR_ENEMIES : ESoldierState.FORCED_MOVE); } @Override @@ -327,7 +332,7 @@ protected boolean canBeControlledByPlayer() { @Override protected Path findWayAroundObstacle(ShortPoint2D position, Path path) { - if (state == ESoldierState.SEARCH_FOR_ENEMIES) { + if (state == ESoldierState.SEARCH_FOR_ENEMIES || state == ESoldierState.FORCED_MOVE) { EDirection direction = EDirection.getDirection(position, path.getNextPos()); EDirection rightDir = direction.getNeighbor(-1); diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/specialists/GeologistStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/specialists/GeologistStrategy.java index 0a31281bb8..fa9fff9eaa 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/specialists/GeologistStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/specialists/GeologistStrategy.java @@ -14,6 +14,7 @@ *******************************************************************************/ package jsettlers.logic.movable.strategies.specialists; +import jsettlers.common.action.EMoveToType; import jsettlers.common.map.shapes.HexGridArea; import jsettlers.common.material.ESearchType; import jsettlers.common.movable.EMovableAction; @@ -141,7 +142,7 @@ protected boolean canBeControlledByPlayer() { } @Override - protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos) { + protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos, EMoveToType moveToType) { this.state = EGeologistState.GOING_TO_POS; centerPos = null; diff --git a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/specialists/PioneerStrategy.java b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/specialists/PioneerStrategy.java index 9ba48724f7..325fcadbcb 100644 --- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/specialists/PioneerStrategy.java +++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/strategies/specialists/PioneerStrategy.java @@ -14,6 +14,7 @@ *******************************************************************************/ package jsettlers.logic.movable.strategies.specialists; +import jsettlers.common.action.EMoveToType; import jsettlers.common.map.shapes.HexGridArea; import jsettlers.common.material.ESearchType; import jsettlers.common.movable.EDirection; @@ -117,7 +118,7 @@ private boolean canWorkOnPos(ShortPoint2D pos) { } @Override - protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos) { + protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos, EMoveToType moveToType) { this.state = EPioneerState.GOING_TO_POS; centerPos = null; } diff --git a/jsettlers.tools/src/main/java/jsettlers/logic/movable/MovableTestWindow.java b/jsettlers.tools/src/main/java/jsettlers/logic/movable/MovableTestWindow.java index 2ff43e6e07..83fbc4529b 100644 --- a/jsettlers.tools/src/main/java/jsettlers/logic/movable/MovableTestWindow.java +++ b/jsettlers.tools/src/main/java/jsettlers/logic/movable/MovableTestWindow.java @@ -33,6 +33,7 @@ import jsettlers.main.swing.lookandfeel.JSettlersLookAndFeelExecption; import jsettlers.main.swing.resources.SwingResourceLoader; import jsettlers.network.synchronic.timer.NetworkTimer; +import jsettlers.common.action.EMoveToType; public class MovableTestWindow { private static final Player PLAYER_0 = new Player((byte) 0, new Team((byte) 0), (byte) 1, EPlayerType.HUMAN, ECivilisation.ROMAN); @@ -57,7 +58,7 @@ private MovableTestWindow() throws InterruptedException, JSettlersLookAndFeelExe connector.addListener(action -> { switch (action.getActionType()) { case MOVE_TO: - movable.moveTo(((PointAction) action).getPosition()); + movable.moveTo(((MoveToAction) action).getPosition(), ((MoveToAction) action).getMoveToType()); break; case SPEED_FASTER: MatchConstants.clock().multiplyGameSpeed(1.2f); @@ -98,9 +99,9 @@ private MovableTestWindow() throws InterruptedException, JSettlersLookAndFeelExe ILogicMovable m2 = new Movable(grid.getMovableGrid(), EMovableType.PIONEER, new ShortPoint2D(51, 65), PLAYER_0); ILogicMovable m3 = new Movable(grid.getMovableGrid(), EMovableType.PIONEER, new ShortPoint2D(50, 64), PLAYER_0); - m1.moveTo(new ShortPoint2D(52, 65)); - m2.moveTo(new ShortPoint2D(49, 63)); - m3.moveTo(new ShortPoint2D(50, 66)); + m1.moveTo(new ShortPoint2D(52, 65), EMoveToType.DEFAULT); + m2.moveTo(new ShortPoint2D(49, 63), EMoveToType.DEFAULT); + m3.moveTo(new ShortPoint2D(50, 66), EMoveToType.DEFAULT); } } }