diff --git a/go.graphics.android/src/main/java/go/graphics/android/GOSurfaceView.java b/go.graphics.android/src/main/java/go/graphics/android/GOSurfaceView.java
index 4a2fc58e22..984c3b0d36 100644
--- a/go.graphics.android/src/main/java/go/graphics/android/GOSurfaceView.java
+++ b/go.graphics.android/src/main/java/go/graphics/android/GOSurfaceView.java
@@ -282,4 +282,9 @@ public GLDrawContext getDrawContext() {
public void setContextDestroyedListener(IContextDestroyedListener contextDestroyedListener) {
this.contextDestroyedListener = contextDestroyedListener;
}
+
+ @Override
+ protected int getCurrentModifiers() {
+ return GOEvent.MODIFIER_ALT | GOEvent.MODIFIER_CTRL | GOEvent.MODIFIER_SHIFT;
+ }
}
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..531fe6b441 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;
@@ -32,6 +33,7 @@
import java.lang.reflect.Field;
import go.graphics.UIPoint;
+import go.graphics.event.GOEvent;
import go.graphics.event.GOEventHandlerProvider;
import go.graphics.event.interpreter.AbstractEventConverter;
@@ -54,6 +56,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 +112,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) {
+ // ignored - we trace down/up
}
@Override
public void mousePressed(MouseEvent e) {
+ updateModifiers(e);
int mouseButton = e.getButton();
UIPoint local = convertToLocal(e);
if (mouseButton == MouseEvent.BUTTON1) {
@@ -142,6 +151,7 @@ public void mousePressed(MouseEvent e) {
@Override
public void mouseDragged(MouseEvent e) {
+ updateModifiers(e);
UIPoint local = convertToLocal(e);
updateDrawPosition(local);
updatePanPosition(local);
@@ -150,6 +160,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,19 +175,9 @@ public void mouseReleased(MouseEvent e) {
@Override
public void keyPressed(KeyEvent e) {
+ updateModifiers(e);
String text = getKeyName(e);
startKeyEvent(text);
- /*
- * if (ongoingKeyEvent == null) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { ongoingKeyEvent.setHandler(getCancelHandler()); } else if
- * (e.getKeyCode() == KeyEvent.VK_UP) { ongoingKeyEvent.setHandler(getPanHandler(0, -KEYPAN)); } else if (e.getKeyCode() == KeyEvent.VK_DOWN)
- * { ongoingKeyEvent.setHandler(getPanHandler(0, KEYPAN)); } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
- * ongoingKeyEvent.setHandler(getPanHandler(KEYPAN, 0)); } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
- * ongoingKeyEvent.setHandler(getPanHandler(-KEYPAN, 0)); }
- *
- * provider.handleEvent(ongoingKeyEvent);
- *
- * ongoingKeyEvent.started(); }
- */
}
private String getKeyName(KeyEvent e) {
@@ -253,7 +254,7 @@ private String getKeyName(KeyEvent e) {
text = "BACK_SPACE";
break;
default:
- text = "" + e.getKeyChar();
+ text = Character.toString(e.getKeyChar());
}
}
return text;
@@ -261,15 +262,32 @@ private String getKeyName(KeyEvent e) {
@Override
public void keyReleased(KeyEvent e) {
+ updateModifiers(e);
endKeyEvent(getKeyName(e));
}
+ private void updateModifiers(InputEvent e) {
+ int swingMod = e.getModifiers();
+ this.modifiers = 0;
+ if ((swingMod & InputEvent.ALT_MASK) != 0) {
+ this.modifiers |= GOEvent.MODIFIER_ALT;
+ }
+ if ((swingMod & InputEvent.CTRL_MASK) != 0) {
+ this.modifiers |= GOEvent.MODIFIER_CTRL;
+ }
+ if ((swingMod & InputEvent.SHIFT_MASK) != 0) {
+ this.modifiers |= GOEvent.MODIFIER_SHIFT;
+ }
+ }
+
@Override
public void keyTyped(KeyEvent e) {
+ // ignored
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
+ updateModifiers(e);
float factor = (float) Math.exp(-e.getUnitsToScroll() / 20.0);
startZoom();
endZoomEvent(factor, convertToLocal(e));
@@ -277,6 +295,7 @@ public void mouseWheelMoved(MouseWheelEvent e) {
@Override
public void componentResized(ComponentEvent e) {
+ // ignored
}
@Override
@@ -291,6 +310,7 @@ public void componentShown(ComponentEvent componentEvent) {
@Override
public void componentHidden(ComponentEvent e) {
+ // ignored
}
@Override
@@ -310,4 +330,9 @@ void privateRegisterComponentListenerToParentWindowOf(Component component, Compo
privateRegisterComponentListenerToParentWindowOf(component.getParent(), childComponent);
}
}
+
+ @Override
+ protected int getCurrentModifiers() {
+ return modifiers;
+ }
}
diff --git a/go.graphics/src/main/java/go/graphics/area/Area.java b/go.graphics/src/main/java/go/graphics/area/Area.java
index dd4464d598..cc250d99c7 100644
--- a/go.graphics/src/main/java/go/graphics/area/Area.java
+++ b/go.graphics/src/main/java/go/graphics/area/Area.java
@@ -321,6 +321,10 @@ private void changePoint(UIPoint point) {
private class SimpleHoverEvent extends AbstractMouseEvent implements
GOHoverEvent {
+ private SimpleHoverEvent() {
+ super(0);
+ }
+
public void finish() {
this.setPhase(PHASE_FINISHED);
}
diff --git a/go.graphics/src/main/java/go/graphics/event/GOEvent.java b/go.graphics/src/main/java/go/graphics/event/GOEvent.java
index fd20090af8..49adad0998 100644
--- a/go.graphics/src/main/java/go/graphics/event/GOEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/GOEvent.java
@@ -32,6 +32,10 @@
* @author michael
*/
public interface GOEvent {
+ int MODIFIER_SHIFT = 1;
+ int MODIFIER_CTRL = 2;
+ int MODIFIER_ALT = 4;
+
/**
* Indicates that the event is in the initialization phase. In this pahse, the event handler is searched.
*/
@@ -75,4 +79,10 @@ public interface GOEvent {
* @return The phase the event is in.
*/
int getPhase();
+
+ /**
+ * Gets the modifiers for the event
+ * @return The modifiers as bit set
+ */
+ int getModifiers();
}
diff --git a/go.graphics/src/main/java/go/graphics/event/GOKeyEvent.java b/go.graphics/src/main/java/go/graphics/event/GOKeyEvent.java
index 357e229e38..f8f5e3e4a4 100644
--- a/go.graphics/src/main/java/go/graphics/event/GOKeyEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/GOKeyEvent.java
@@ -32,6 +32,19 @@ public class GOKeyEvent extends SingleHandlerGoEvent {
public GOKeyEvent(String keyCode) {
this.keyCode = keyCode;
}
+
+ /**
+ * Creates a new key event for a given key code.
+ *
+ * @param keyCode
+ * The key code.
+ * @param modifiers
+ * The modifiers.
+ */
+ public GOKeyEvent(String keyCode, int modifiers) {
+ super(modifiers);
+ this.keyCode = keyCode;
+ }
/**
* Gets the key code the event has.
diff --git a/go.graphics/src/main/java/go/graphics/event/SingleHandlerGoEvent.java b/go.graphics/src/main/java/go/graphics/event/SingleHandlerGoEvent.java
index fa10310422..5447bef5ee 100644
--- a/go.graphics/src/main/java/go/graphics/event/SingleHandlerGoEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/SingleHandlerGoEvent.java
@@ -24,6 +24,16 @@ public class SingleHandlerGoEvent implements GOEvent {
private int phase = PHASE_INITIALIZING;
+ private final int modifiers;
+
+ public SingleHandlerGoEvent() {
+ this(0);
+ }
+
+ public SingleHandlerGoEvent(int modifiers) {
+ this.modifiers = modifiers;
+ }
+
@Override
public void setHandler(GOEventHandler handler) {
if (getPhase() != PHASE_INITIALIZING) {
@@ -67,4 +77,9 @@ protected void setPhase(int phase) {
public int getPhase() {
return phase;
}
+
+ @Override
+ public int getModifiers() {
+ return modifiers;
+ }
}
diff --git a/go.graphics/src/main/java/go/graphics/event/SingleHandlerGoModalEvent.java b/go.graphics/src/main/java/go/graphics/event/SingleHandlerGoModalEvent.java
index 3f463fc2f2..027feb2a62 100644
--- a/go.graphics/src/main/java/go/graphics/event/SingleHandlerGoModalEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/SingleHandlerGoModalEvent.java
@@ -22,6 +22,13 @@
* @author michael
*/
public class SingleHandlerGoModalEvent extends SingleHandlerGoEvent {
+ public SingleHandlerGoModalEvent() {
+ }
+
+ public SingleHandlerGoModalEvent(int modifiers) {
+ super(modifiers);
+ }
+
/**
* This method notifies the handler, if it supports the {@link GOModalEventHandler}, that the event data has changed.
*/
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..91dba8939b 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
@@ -64,7 +64,7 @@ protected void tryCancelCurrentEvent() {
*/
protected void startDraw(UIPoint start) {
if (ongoingDrawEvent == null) {
- ongoingDrawEvent = new ConvertedDrawEvent(start);
+ ongoingDrawEvent = new ConvertedDrawEvent(start, getCurrentModifiers());
handleEvent(ongoingDrawEvent);
@@ -83,7 +83,8 @@ protected void endDraw(UIPoint position) {
if (ongoingDrawEvent != null) {
if (tryReplaceEvent(position, ReplacableEvent.DRAW,
ongoingDrawEvent.getTime(),
- ongoingDrawEvent.getMouseMoved())) {
+ ongoingDrawEvent.getMouseMoved(),
+ ongoingDrawEvent.getModifiers())) {
abortDraw();
} else {
ongoingDrawEvent.released();
@@ -101,7 +102,7 @@ protected void abortDraw() {
protected void startPan(UIPoint start) {
if (ongoingPanEvent == null) {
- ongoingPanEvent = new ConvertedPanEvent(start);
+ ongoingPanEvent = new ConvertedPanEvent(start, getCurrentModifiers());
handleEvent(ongoingPanEvent);
ongoingPanEvent.initialized();
}
@@ -116,7 +117,9 @@ protected void updatePanPosition(UIPoint current) {
protected void endPan(UIPoint position) {
if (ongoingPanEvent != null) {
if (tryReplaceEvent(position, ReplacableEvent.PAN,
- ongoingPanEvent.getTime(), ongoingPanEvent.getMouseMoved())) {
+ ongoingPanEvent.getTime(),
+ ongoingPanEvent.getMouseMoved(),
+ ongoingPanEvent.getModifiers())) {
abortPan();
} else {
ongoingPanEvent.released();
@@ -127,7 +130,7 @@ protected void endPan(UIPoint position) {
protected void startZoom() {
if (ongoingZoomEvent == null) {
- ongoingZoomEvent = new ConvertedZoomEvent();
+ ongoingZoomEvent = new ConvertedZoomEvent(getCurrentModifiers());
handleEvent(ongoingZoomEvent);
ongoingZoomEvent.initialized();
}
@@ -156,7 +159,7 @@ protected void abortPan() {
protected void startHover(UIPoint start) {
if (ongoingHoverEvent == null) {
- ongoingHoverEvent = new ConvertedHoverEvent(start);
+ ongoingHoverEvent = new ConvertedHoverEvent(start, getCurrentModifiers());
handleEvent(ongoingHoverEvent);
ongoingHoverEvent.initialized();
}
@@ -172,7 +175,8 @@ protected void endHover(UIPoint position) {
if (ongoingHoverEvent != null) {
if (tryReplaceEvent(position, ReplacableEvent.HOVER,
ongoingHoverEvent.getTime(),
- ongoingHoverEvent.getMouseMoved())) {
+ ongoingHoverEvent.getMouseMoved(),
+ ongoingHoverEvent.getModifiers())) {
abortHover();
} else {
ongoingHoverEvent.released();
@@ -188,8 +192,8 @@ protected void abortHover() {
}
}
- protected boolean fireCommandEvent(UIPoint point, boolean isSelect) {
- ConvertedCommandEvent commandEvent = new ConvertedCommandEvent(point, isSelect);
+ protected boolean fireCommandEvent(UIPoint point, boolean isSelect, int modifiers) {
+ ConvertedCommandEvent commandEvent = new ConvertedCommandEvent(point, isSelect, modifiers);
handleEvent(commandEvent);
@@ -200,7 +204,7 @@ protected boolean fireCommandEvent(UIPoint point, boolean isSelect) {
protected synchronized void startKeyEvent(String string) {
if (ongoingKeyEvent == null) {
- ongoingKeyEvent = new GOKeyEvent(string);
+ ongoingKeyEvent = new GOKeyEvent(string, getCurrentModifiers());
replaceKeyEvent(ongoingKeyEvent);
handleEvent(ongoingKeyEvent);
ongoingKeyEvent.started();
@@ -251,7 +255,8 @@ private class ConvertedCommandEvent extends SingleHandlerGoEvent implements
private final UIPoint position;
private final boolean selecting;
- public ConvertedCommandEvent(UIPoint position, boolean selecting) {
+ public ConvertedCommandEvent(UIPoint position, boolean selecting, int modifiers) {
+ super(modifiers);
this.position = position;
this.selecting = selecting;
}
@@ -279,11 +284,11 @@ protected void addReplaceRule(EventReplacementRule r) {
}
private boolean tryReplaceEvent(UIPoint p, ReplacableEvent e, double time,
- double distance) {
+ double distance, int modifiers) {
for (EventReplacementRule r : replace) {
if (r.matches(e, time, distance)) {
boolean success = fireCommandEvent(p,
- r.replaced == Replacement.COMMAND_SELECT);
+ r.replaced == Replacement.COMMAND_SELECT, modifiers);
if (success) {
return true;
}
@@ -300,6 +305,10 @@ protected boolean panStarted() {
return ongoingPanEvent != null;
}
+ protected int getCurrentModifiers() {
+ return 0;
+ }
+
/**
* a rule on when to replace short draw, hover or pan events with other stuff.
*
diff --git a/go.graphics/src/main/java/go/graphics/event/interpreter/AbstractMouseEvent.java b/go.graphics/src/main/java/go/graphics/event/interpreter/AbstractMouseEvent.java
index 1c6c31251c..7e11761bde 100644
--- a/go.graphics/src/main/java/go/graphics/event/interpreter/AbstractMouseEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/interpreter/AbstractMouseEvent.java
@@ -23,8 +23,8 @@ public class AbstractMouseEvent extends SingleHandlerGoModalEvent {
private int mouseMoved = 0;
private long startTime = 0;
- public AbstractMouseEvent() {
- super();
+ public AbstractMouseEvent(int modifiers) {
+ super(modifiers);
startTime = System.currentTimeMillis();
}
diff --git a/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedDrawEvent.java b/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedDrawEvent.java
index 0cc8f1a710..e2d42cefd2 100644
--- a/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedDrawEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedDrawEvent.java
@@ -29,8 +29,10 @@ public class ConvertedDrawEvent extends AbstractMouseEvent implements
*
* @param point
* The point where it starts.
+ * @param modifiers The modifiers
*/
- public ConvertedDrawEvent(final UIPoint point) {
+ public ConvertedDrawEvent(final UIPoint point, int modifiers) {
+ super(modifiers);
this.position = point;
}
diff --git a/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedHoverEvent.java b/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedHoverEvent.java
index ad651d2bc7..c5961d6d42 100644
--- a/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedHoverEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedHoverEvent.java
@@ -25,7 +25,8 @@
public class ConvertedHoverEvent extends AbstractMouseEvent implements
GOHoverEvent {
- public ConvertedHoverEvent(UIPoint start) {
+ public ConvertedHoverEvent(UIPoint start, int modifiers) {
+ super(modifiers);
position = start;
}
diff --git a/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedPanEvent.java b/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedPanEvent.java
index 88cd688929..e0ee15215a 100644
--- a/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedPanEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedPanEvent.java
@@ -31,8 +31,10 @@ class ConvertedPanEvent extends AbstractMouseEvent implements GOPanEvent {
*
* @param point
* THe point the user first put his mouse to.
+ * @param modifiers The modifiers
*/
- protected ConvertedPanEvent(UIPoint point) {
+ protected ConvertedPanEvent(UIPoint point, int modifiers) {
+ super(modifiers);
this.position = point;
this.original = point;
}
diff --git a/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedZoomEvent.java b/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedZoomEvent.java
index dcf6ebf590..51c14f3e26 100644
--- a/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedZoomEvent.java
+++ b/go.graphics/src/main/java/go/graphics/event/interpreter/ConvertedZoomEvent.java
@@ -33,7 +33,8 @@ public class ConvertedZoomEvent extends AbstractMouseEvent implements GOZoomEven
/**
* Constructor
*/
- public ConvertedZoomEvent() {
+ public ConvertedZoomEvent(int modifiers) {
+ super(modifiers);
}
@Override
diff --git a/go.graphics/src/main/java/go/graphics/event/mouse/GOEventProxy.java b/go.graphics/src/main/java/go/graphics/event/mouse/GOEventProxy.java
index 29ebcbd4a4..ca6d07e1cb 100644
--- a/go.graphics/src/main/java/go/graphics/event/mouse/GOEventProxy.java
+++ b/go.graphics/src/main/java/go/graphics/event/mouse/GOEventProxy.java
@@ -45,4 +45,9 @@ public void setHandler(GOEventHandler handler) {
this.baseEvent.setHandler(new EventHandlerProxy(this, handler));
}
+ @Override
+ public int getModifiers() {
+ return this.baseEvent.getModifiers();
+ }
+
}
\ No newline at end of file
diff --git a/jsettlers.common/src/main/java/jsettlers/common/menu/action/EMoveToMode.java b/jsettlers.common/src/main/java/jsettlers/common/menu/action/EMoveToMode.java
new file mode 100644
index 0000000000..9db3e0dc0b
--- /dev/null
+++ b/jsettlers.common/src/main/java/jsettlers/common/menu/action/EMoveToMode.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 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.common.menu.action;
+
+/**
+ * The mode movables should use for move_to
+ * @author Michael Zangl
+ */
+public enum EMoveToMode {
+ /**
+ * Normal move
+ */
+ NORMAL(false, false),
+ /**
+ * Forced move
+ */
+ FORCED(true, false),
+ /**
+ * Work at destination.
+ * For geologists, thieves and pioneers, this implies that they shoud start their work when they reach the destination
+ * For soldiers, they should start to patrol between the start and end point
+ */
+ WORK(true, true),
+ /**
+ * Add a waypoint to the route the movable should take on the next move action of any other type
+ */
+ ADD_WAYPOINT(false, false);
+
+ private final boolean force;
+ private final boolean workAtDestination;
+
+ EMoveToMode(boolean doForce, boolean doWorkAtDestination) {
+ this.force = doForce;
+ this.workAtDestination = doWorkAtDestination;
+ }
+
+ public boolean isForced() {
+ return force;
+ }
+
+ public boolean doWorkAtDestination() {
+ return workAtDestination;
+ }
+}
diff --git a/jsettlers.graphics/src/main/java/jsettlers/graphics/action/MoveToAction.java b/jsettlers.graphics/src/main/java/jsettlers/graphics/action/MoveToAction.java
new file mode 100644
index 0000000000..3d18952647
--- /dev/null
+++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/action/MoveToAction.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 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.graphics.action;
+
+import go.graphics.event.GOEvent;
+import jsettlers.common.menu.action.EActionType;
+import jsettlers.common.menu.action.EMoveToMode;
+import jsettlers.common.position.ShortPoint2D;
+
+public class MoveToAction extends PointAction {
+
+ private final EMoveToMode mode;
+
+ public MoveToAction(ShortPoint2D position, EMoveToMode mode) {
+ super(EActionType.MOVE_TO, position);
+ this.mode = mode;
+ }
+
+ public EMoveToMode getMode() {
+ return mode;
+ }
+
+ @Override
+ public String toString() {
+ return "MoveToAction [mode=" + mode + ", getPosition()=" + getPosition() + "]";
+ }
+
+ public static EMoveToMode modeForModifiers(int modifiers) {
+ if ((modifiers & GOEvent.MODIFIER_ALT) != 0) {
+ return EMoveToMode.WORK;
+ }
+ if ((modifiers & GOEvent.MODIFIER_CTRL) != 0) {
+ return EMoveToMode.FORCED;
+ }
+ if ((modifiers & GOEvent.MODIFIER_SHIFT) != 0) {
+ return EMoveToMode.ADD_WAYPOINT;
+ }
+ return EMoveToMode.NORMAL;
+ }
+}
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 7194f20d8b..8e76237286 100644
--- a/jsettlers.graphics/src/main/java/jsettlers/graphics/map/MapContent.java
+++ b/jsettlers.graphics/src/main/java/jsettlers/graphics/map/MapContent.java
@@ -60,6 +60,7 @@
import jsettlers.graphics.action.ActionFireable;
import jsettlers.graphics.action.ActionHandler;
import jsettlers.graphics.action.ActionThreadBlockingListener;
+import jsettlers.graphics.action.MoveToAction;
import jsettlers.graphics.action.PointAction;
import jsettlers.graphics.action.ScreenChangeAction;
import jsettlers.graphics.action.SelectAreaAction;
@@ -743,7 +744,7 @@ private void changeMousePosition(UIPoint position) {
private Action getActionForCommand(GOCommandEvent commandEvent) {
UIPoint position = commandEvent.getCommandPosition();
if (controls.containsPoint(position)) {
- return controls.getActionFor(position, commandEvent.isSelecting());
+ return controls.getActionFor(position, commandEvent);
} else {
// handle map click
return handleCommandOnMap(commandEvent, position);
@@ -781,7 +782,6 @@ public void eventDataChanged(GOEvent event) {
};
private Action handleCommandOnMap(GOCommandEvent commandEvent, UIPoint position) {
-
float x = (float) position.getX();
float y = (float) position.getY();
ShortPoint2D onMap = this.context.getPositionOnScreen(x, y);
@@ -790,7 +790,7 @@ private Action handleCommandOnMap(GOCommandEvent commandEvent, UIPoint position)
if (commandEvent.isSelecting()) {
action = handleSelectCommand(onMap);
} else {
- action = new PointAction(EActionType.MOVE_TO, onMap);
+ action = new MoveToAction(onMap, MoveToAction.modeForModifiers(commandEvent.getModifiers()));
}
return action;
}
@@ -894,7 +894,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 a6085da724..358ff870e5 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
@@ -16,6 +16,7 @@
import go.graphics.GLDrawContext;
import go.graphics.UIPoint;
+import go.graphics.event.command.GOCommandEvent;
import go.graphics.event.mouse.GODrawEvent;
import jsettlers.common.map.shapes.MapRectangle;
import jsettlers.common.menu.IMapInterfaceListener;
@@ -82,11 +83,11 @@ public interface IControls extends IMapInterfaceListener {
*
* @param position
* The positon.
- * @param selecting
- * If the event is a select event.
+ * @param event
+ * The event
* @return The action for the position.
*/
- Action getActionFor(UIPoint position, boolean selecting);
+ Action getActionFor(UIPoint position, GOCommandEvent event);
/**
* 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 2fbd00fa51..58a0e9aa28 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
@@ -18,9 +18,11 @@
import go.graphics.UIPoint;
import go.graphics.event.GOEvent;
import go.graphics.event.GOModalEventHandler;
+import go.graphics.event.command.GOCommandEvent;
import go.graphics.event.mouse.GODrawEvent;
import jsettlers.common.map.shapes.MapRectangle;
import jsettlers.common.menu.action.EActionType;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.menu.action.IAction;
import jsettlers.common.player.IInGamePlayer;
import jsettlers.common.position.FloatRectangle;
@@ -30,6 +32,7 @@
import jsettlers.graphics.action.ActionFireable;
import jsettlers.graphics.action.ChangePanelAction;
import jsettlers.graphics.action.ExecutableAction;
+import jsettlers.graphics.action.MoveToAction;
import jsettlers.graphics.action.PointAction;
import jsettlers.graphics.map.MapDrawContext;
import jsettlers.graphics.map.controls.IControls;
@@ -198,12 +201,12 @@ private double getMinimapOffset(double y) {
}
@Override
- public Action getActionFor(UIPoint position, boolean selecting) {
+ public Action getActionFor(UIPoint position, GOCommandEvent event) {
float relativex = (float) position.getX() / this.uiBase.getPosition().getWidth();
float relativey = (float) position.getY() / this.uiBase.getPosition().getHeight();
Action action;
if (minimap != null && relativey > layoutProperties.MAIN_PANEL_TOP && getMinimapOffset(position.getY()) < position.getX()) {
- action = getForMinimap(relativex, relativey, selecting);
+ action = getForMinimap(relativex, relativey, event.isSelecting(), MoveToAction.modeForModifiers(event.getModifiers()));
startMapPosition = null; // to prevent it from jumping back.
} else {
action = uiBase.getAction(relativex, relativey);
@@ -226,10 +229,11 @@ public Action getActionFor(UIPoint position, boolean selecting) {
* The position on the minimap.
* @param selecting
* true
if it was a selection click and the view should move there.
+ * @param moveToMode The mode to use for move tos
* @return the action for that point or null
for no action.
*/
private Action getForMinimap(float relativex, float relativey,
- boolean selecting) {
+ boolean selecting, EMoveToMode moveToMode) {
float minimapx = (relativex - layoutProperties.miniMap.MAP_LEFT)
/ layoutProperties.miniMap.MAP_WIDTH;
float minimapy = ((relativey - layoutProperties.MAIN_PANEL_TOP)
@@ -240,7 +244,7 @@ private Action getForMinimap(float relativex, float relativey,
if (selecting) {
return new PointAction(EActionType.PAN_TO, clickPosition);
} else {
- return new PointAction(EActionType.MOVE_TO, clickPosition);
+ return new MoveToAction(clickPosition, moveToMode);
}
} else {
return null;
@@ -296,7 +300,7 @@ private Action getActionForDraw(GODrawEvent event) {
float height = this.uiBase.getPosition().getHeight();
float relativey = (float) position.getY() / height;
- return getForMinimap(relativex, relativey, true);
+ return getForMinimap(relativex, relativey, true, MoveToAction.modeForModifiers(event.getModifiers()));
}
/**
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 689af985c9..adb042fd36 100644
--- a/jsettlers.logic/src/main/java/jsettlers/ai/army/ConfigurableGeneral.java
+++ b/jsettlers.logic/src/main/java/jsettlers/ai/army/ConfigurableGeneral.java
@@ -22,6 +22,7 @@
import jsettlers.ai.highlevel.AiStatistics;
import jsettlers.common.buildings.EBuildingType;
import jsettlers.common.material.EMaterialType;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.movable.EMovableType;
import jsettlers.common.movable.ESoldierType;
import jsettlers.common.player.IPlayer;
@@ -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, EMoveToMode.NORMAL));
}
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 89fe5972b2..ff06a2768f 100644
--- a/jsettlers.logic/src/main/java/jsettlers/ai/highlevel/WhatToDoAi.java
+++ b/jsettlers.logic/src/main/java/jsettlers/ai/highlevel/WhatToDoAi.java
@@ -73,6 +73,7 @@
import jsettlers.common.buildings.EBuildingType;
import jsettlers.common.landscape.EResourceType;
import jsettlers.common.material.EMaterialType;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.movable.EMovableType;
import jsettlers.common.movable.IMovable;
import jsettlers.common.position.ShortPoint2D;
@@ -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()), EMoveToMode.FORCED));
}
}
@@ -442,7 +443,7 @@ private void releaseAllPioneers() {
List pioneerIds = stream(pioneers).map(pioneerPosition -> mainGrid.getMovableGrid().getMovableAt(pioneerPosition.x, pioneerPosition.y).getID()).collect(Collectors.toList());
taskScheduler.scheduleTask(new ConvertGuiTask(playerId, pioneerIds, EMovableType.BEARER));
// 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, EMoveToMode.FORCED));
}
}
@@ -464,7 +465,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(), EMoveToMode.WORK));
}
}
}
@@ -473,7 +474,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(), EMoveToMode.WORK));
}
}
}
diff --git a/jsettlers.logic/src/main/java/jsettlers/input/GuiInterface.java b/jsettlers.logic/src/main/java/jsettlers/input/GuiInterface.java
index 8e0b8a74a1..df20287e79 100644
--- a/jsettlers.logic/src/main/java/jsettlers/input/GuiInterface.java
+++ b/jsettlers.logic/src/main/java/jsettlers/input/GuiInterface.java
@@ -30,6 +30,7 @@
import jsettlers.common.menu.IMapInterfaceListener;
import jsettlers.common.menu.UIState;
import jsettlers.common.menu.action.EActionType;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.menu.action.IAction;
import jsettlers.common.movable.EMovableType;
import jsettlers.common.movable.ESoldierType;
@@ -42,6 +43,7 @@
import jsettlers.graphics.action.BuildAction;
import jsettlers.graphics.action.ChangeTradingRequestAction;
import jsettlers.graphics.action.ConvertAction;
+import jsettlers.graphics.action.MoveToAction;
import jsettlers.graphics.action.PointAction;
import jsettlers.graphics.action.ScreenChangeAction;
import jsettlers.graphics.action.SelectAreaAction;
@@ -217,13 +219,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.getMode());
}
break;
}
@@ -503,9 +505,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, EMoveToMode mode) {
final List selectedIds = getIDsOfSelected();
- scheduleTask(new MoveToGuiTask(playerId, pos, selectedIds));
+ scheduleTask(new MoveToGuiTask(playerId, pos, selectedIds, mode));
}
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..408d255145 100644
--- a/jsettlers.logic/src/main/java/jsettlers/input/GuiTaskExecutor.java
+++ b/jsettlers.logic/src/main/java/jsettlers/input/GuiTaskExecutor.java
@@ -22,6 +22,7 @@
import jsettlers.common.buildings.IBuilding;
import jsettlers.common.map.shapes.HexGridArea;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.position.ShortPoint2D;
import jsettlers.common.utils.mutables.MutableInt;
import jsettlers.input.tasks.ChangeTowerSoldiersGuiTask;
@@ -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.getMode());
break;
}
@@ -293,19 +294,20 @@ private void killSelectedMovables(List selectedMovables) {
* position to move to
* @param movableIds
* A list of the id's of the movables.
+ * @param mode The move to mode to use
*/
- private void moveSelectedTo(ShortPoint2D targetPosition, List movableIds) {
+ private void moveSelectedTo(ShortPoint2D targetPosition, List movableIds, EMoveToMode mode) {
if (movableIds.size() == 1) {
ILogicMovable currMovable = Movable.getMovableByID(movableIds.get(0));
if (currMovable != null) {
- currMovable.moveTo(targetPosition);
+ currMovable.moveTo(targetPosition, mode);
}
} else if (!movableIds.isEmpty()) {
- sendMovablesNew(targetPosition, movableIds);
+ sendMovablesNew(targetPosition, movableIds, mode);
}
}
- private void sendMovablesNew(ShortPoint2D targetPosition, List movableIds) {
+ private void sendMovablesNew(ShortPoint2D targetPosition, List movableIds, EMoveToMode mode) {
List movables = stream(movableIds).map(Movable::getMovableByID).filter(Objects::nonNull).collect(Collectors.toList());
if (movables.isEmpty()) {
return;
@@ -322,7 +324,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), mode);
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..e44d6ea251 100644
--- a/jsettlers.logic/src/main/java/jsettlers/input/tasks/MoveToGuiTask.java
+++ b/jsettlers.logic/src/main/java/jsettlers/input/tasks/MoveToGuiTask.java
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.util.List;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.position.ShortPoint2D;
/**
@@ -28,35 +29,44 @@
*/
public class MoveToGuiTask extends MovableGuiTask {
private ShortPoint2D position;
+ private EMoveToMode mode;
public MoveToGuiTask() {
}
- public MoveToGuiTask(byte playerId, ShortPoint2D pos, List selection) {
+ public MoveToGuiTask(byte playerId, ShortPoint2D pos, List selection, EMoveToMode mode) {
super(EGuiAction.MOVE_TO, playerId, selection);
this.position = pos;
+ this.mode = mode;
}
public ShortPoint2D getPosition() {
return position;
}
+
+ public EMoveToMode getMode() {
+ return mode;
+ }
@Override
protected void serializeTask(DataOutputStream dos) throws IOException {
super.serializeTask(dos);
SimpleGuiTask.serializePosition(dos, position);
+ dos.writeByte(mode.ordinal());
}
@Override
protected void deserializeTask(DataInputStream dis) throws IOException {
super.deserializeTask(dis);
position = SimpleGuiTask.deserializePosition(dis);
+ mode = EMoveToMode.values()[dis.readByte()];
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
+ result = prime * result + ((mode == null) ? 0 : mode.hashCode());
result = prime * result + ((position == null) ? 0 : position.hashCode());
return result;
}
@@ -70,6 +80,8 @@ public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
MoveToGuiTask other = (MoveToGuiTask) obj;
+ if (mode != other.mode)
+ return false;
if (position == null) {
if (other.position != null)
return false;
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 450c8cce1e..53d34084c1 100644
--- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/Movable.java
+++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/Movable.java
@@ -23,6 +23,7 @@
import jsettlers.common.mapobject.EMapObjectType;
import jsettlers.common.material.EMaterialType;
import jsettlers.common.material.ESearchType;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.movable.EDirection;
import jsettlers.common.movable.EMovableAction;
import jsettlers.common.movable.EMovableType;
@@ -72,6 +73,7 @@ public final class Movable implements ILogicMovable {
private ShortPoint2D position;
private ShortPoint2D requestedTargetPosition = null;
+ protected EMoveToMode requestedMoveMode;
private Path path;
private float health;
@@ -125,9 +127,12 @@ private final void readObject(ObjectInputStream ois) throws IOException, ClassNo
*
* @param targetPosition
*/
- public final void moveTo(ShortPoint2D targetPosition) {
+ @Override
+ public final void moveTo(ShortPoint2D targetPosition, EMoveToMode mode) {
if (movableType.isPlayerControllable() && strategy.canBeControlledByPlayer() && !alreadyWalkingToPosition(targetPosition)) {
this.requestedTargetPosition = targetPosition;
+ this.requestedMoveMode = mode;
+ strategy.stopOrStartWorking(!mode.doWorkAtDestination());
}
}
@@ -135,6 +140,7 @@ private boolean alreadyWalkingToPosition(ShortPoint2D targetPosition) {
return this.state == EMovableState.PATHING && this.path.getTargetPos().equals(targetPosition);
}
+ @Override
public void leavePosition() {
if (state != EMovableState.DOING_NOTHING || !enableNothingToDo) {
return;
@@ -217,7 +223,7 @@ public int timerEvent() {
requestedTargetPosition = null;
if (foundPath) {
- this.strategy.moveToPathSet(oldPos, oldTargetPos, path.getTargetPos());
+ this.strategy.moveToPathSet(oldPos, oldTargetPos, path.getTargetPos(), requestedMoveMode);
return animationDuration; // we already follow the path and initiated the walking
} else {
break;
@@ -281,6 +287,7 @@ private void pathingAction() {
// if path is finished, or canceled by strategy return from here
setState(EMovableState.DOING_NOTHING);
movableAction = EMovableAction.NO_ACTION;
+ strategy.pathDone(path.getTargetPos());
path = null;
return;
}
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 d1e76f3c34..a8bfe3afe3 100644
--- a/jsettlers.logic/src/main/java/jsettlers/logic/movable/MovableStrategy.java
+++ b/jsettlers.logic/src/main/java/jsettlers/logic/movable/MovableStrategy.java
@@ -17,6 +17,7 @@
import jsettlers.algorithms.path.Path;
import jsettlers.common.material.EMaterialType;
import jsettlers.common.material.ESearchType;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.movable.EDirection;
import jsettlers.common.movable.EMovableAction;
import jsettlers.common.movable.EMovableType;
@@ -237,8 +238,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 mode The mode for the target
*/
- protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos) {
+ protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos, EMoveToMode mode) {
}
/**
@@ -333,6 +335,9 @@ protected void sleep(short sleepTime) {
protected void pathAborted(ShortPoint2D pathTarget) {
}
+ protected void pathDone(ShortPoint2D pathTarget) {
+ }
+
/**
* This method is called before a material is dropped during a {@link EMovableType}.DROP action.
*
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..2877a3c9dc 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.menu.action.EMoveToMode;
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, EMoveToMode mode);
}
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..ea92003656 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
@@ -16,6 +16,7 @@
import jsettlers.algorithms.path.Path;
import jsettlers.common.buildings.OccupierPlace;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.movable.EDirection;
import jsettlers.common.movable.EMovableType;
import jsettlers.common.movable.ESoldierClass;
@@ -38,6 +39,7 @@ public abstract class SoldierStrategy extends MovableStrategy implements IBuildi
*/
private enum ESoldierState {
AGGRESSIVE,
+ FORCED_MOVE,
SEARCH_FOR_ENEMIES,
HITTING,
@@ -70,6 +72,7 @@ public SoldierStrategy(Movable movable, EMovableType movableType) {
protected void action() {
switch (state) {
case AGGRESSIVE:
+ case FORCED_MOVE:
break;
case HITTING:
@@ -108,7 +111,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, EMoveToMode.NORMAL); // reset moveToRequest, so the soldier doesn't go there after fleeing.
} // else { // we are in the tower, so wait and check again next time.
@@ -312,12 +315,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, EMoveToMode mode) {
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(mode.isForced() ? ESoldierState.FORCED_MOVE : ESoldierState.SEARCH_FOR_ENEMIES);
}
@Override
@@ -388,6 +391,9 @@ protected void strategyKilledEvent(ShortPoint2D pathTarget) {
@Override
protected void pathAborted(ShortPoint2D pathTarget) {
switch (state) {
+ case FORCED_MOVE:
+ changeStateTo(ESoldierState.AGGRESSIVE);
+ break;
case INIT_GOTO_TOWER:
case GOING_TO_TOWER:
notifyTowerThatRequestFailed();
@@ -397,6 +403,15 @@ protected void pathAborted(ShortPoint2D pathTarget) {
break;
}
}
+
+ @Override
+ protected void pathDone(ShortPoint2D pathTarget) {
+ switch (state) {
+ case FORCED_MOVE:
+ changeStateTo(ESoldierState.AGGRESSIVE);
+ break;
+ }
+ }
protected float getCombatStrength() {
return movable.getPlayer().getCombatStrengthInformation().getCombatStrength(isOnOwnGround());
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..f09086e2ae 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
@@ -16,6 +16,7 @@
import jsettlers.common.map.shapes.HexGridArea;
import jsettlers.common.material.ESearchType;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.movable.EMovableAction;
import jsettlers.common.position.MutablePoint2D;
import jsettlers.common.position.ShortPoint2D;
@@ -36,6 +37,7 @@ public final class GeologistStrategy extends MovableStrategy {
private EGeologistState state = EGeologistState.JOBLESS;
private ShortPoint2D centerPos;
+ private boolean working;
public GeologistStrategy(Movable movable) {
super(movable);
@@ -45,7 +47,7 @@ public GeologistStrategy(Movable movable) {
protected void action() {
switch (state) {
case JOBLESS:
- return;
+ break;
case GOING_TO_POS: {
ShortPoint2D pos = movable.getPos();
@@ -53,6 +55,10 @@ protected void action() {
if (centerPos == null) {
this.centerPos = pos;
}
+
+ if (!working) {
+ break;
+ }
super.getGrid().setMarked(pos, false); // unmark the pos for the following check
if (canWorkOnPos(pos)) {
@@ -84,6 +90,11 @@ protected void action() {
}
private void findWorkablePosition() {
+ if (!working) {
+ this.state = EGeologistState.JOBLESS;
+ centerPos = null;
+ return;
+ }
ShortPoint2D closeWorkablePos = getCloseWorkablePos();
if (closeWorkablePos != null && super.goToPos(closeWorkablePos)) {
@@ -141,7 +152,7 @@ protected boolean canBeControlledByPlayer() {
}
@Override
- protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos) {
+ protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos, ShortPoint2D targetPos, EMoveToMode mode) {
this.state = EGeologistState.GOING_TO_POS;
centerPos = null;
@@ -154,6 +165,7 @@ protected void moveToPathSet(ShortPoint2D oldPosition, ShortPoint2D oldTargetPos
@Override
protected void stopOrStartWorking(boolean stop) {
+ working = !stop;
if (stop) {
state = EGeologistState.JOBLESS;
} else {
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..2305f8b45e 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
@@ -16,6 +16,7 @@
import jsettlers.common.map.shapes.HexGridArea;
import jsettlers.common.material.ESearchType;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.movable.EDirection;
import jsettlers.common.movable.EMovableAction;
import jsettlers.common.position.ShortPoint2D;
@@ -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, EMoveToMode mode) {
this.state = EPioneerState.GOING_TO_POS;
centerPos = null;
}
diff --git a/jsettlers.mapcreator/src/main/java/jsettlers/mapcreator/main/map/MapEditorControls.java b/jsettlers.mapcreator/src/main/java/jsettlers/mapcreator/main/map/MapEditorControls.java
index a39da6f7b9..65f40505f0 100644
--- a/jsettlers.mapcreator/src/main/java/jsettlers/mapcreator/main/map/MapEditorControls.java
+++ b/jsettlers.mapcreator/src/main/java/jsettlers/mapcreator/main/map/MapEditorControls.java
@@ -18,6 +18,7 @@
import go.graphics.UIPoint;
import go.graphics.event.GOEvent;
import go.graphics.event.GOModalEventHandler;
+import go.graphics.event.command.GOCommandEvent;
import go.graphics.event.mouse.GODrawEvent;
import jsettlers.common.map.shapes.MapRectangle;
import jsettlers.common.menu.action.IAction;
@@ -103,10 +104,11 @@ public String getDescriptionFor(UIPoint position) {
@Override
public void setMapViewport(MapRectangle screenArea) {
+ //ignored
}
@Override
- public Action getActionFor(UIPoint position, boolean select) {
+ public Action getActionFor(UIPoint position, GOCommandEvent event) {
return 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 ad94babdb5..1aa3519e34 100644
--- a/jsettlers.tools/src/main/java/jsettlers/logic/movable/MovableTestWindow.java
+++ b/jsettlers.tools/src/main/java/jsettlers/logic/movable/MovableTestWindow.java
@@ -20,6 +20,7 @@
import jsettlers.common.ai.EPlayerType;
import jsettlers.common.material.EMaterialType;
import jsettlers.common.menu.IMapInterfaceConnector;
+import jsettlers.common.menu.action.EMoveToMode;
import jsettlers.common.movable.EMovableType;
import jsettlers.common.player.ECivilisation;
import jsettlers.common.position.ShortPoint2D;
@@ -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(((PointAction) action).getPosition(), EMoveToMode.NORMAL);
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), EMoveToMode.NORMAL);
+ m2.moveTo(new ShortPoint2D(49, 63), EMoveToMode.NORMAL);
+ m3.moveTo(new ShortPoint2D(50, 66), EMoveToMode.NORMAL);
}
}
}