diff --git a/pom.xml b/pom.xml
index e23397d..860f45e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
de.srsoftware
web4rail
- 1.3.26
+ 1.3.27
Web4Rail
jar
Java Model Railway Control
diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation
index b779be0..edeac7d 100644
--- a/resources/translations/Application.de.translation
+++ b/resources/translations/Application.de.translation
@@ -59,6 +59,8 @@ Brake time¹, reverse : Bremszeit¹, rückwärts
Brake time table : Bremszeit-Tabelle
CarInTrain : Fahrzeug im Zug
Car manager : Waggon-Verwaltung
+Car of train : Fahrzeug des Zuges
+Car {} of train : Fahrzeug {} des Zuges
CarOrientation : Wagen-Laufrichtung
Cars : Waggons
cars : Fahrzeugen teilen
@@ -89,9 +91,14 @@ Control : Steuerung
Control unit : Zentrale
copy : kopieren
Counterpart : Gegenstück
+Couple : kupple
+Couple first parked train : ersten geparkten Zug kuppeln
+Couple last parked train : letzten geparkten Zug kuppeln
+CoupleTrain : Zug kuppeln
Create action : Aktion erzeugen
Current location : Aufenthaltsort
Current location\: {} : Aufenthaltsort: {}
+Current orientation : aktuelle Fahrtrichtung
Current velocity\: {} {} : Aktuelle Geschwindigkeit: {} {}
custom fields : benutzerdefinierte Felder
Decoder address : Decoder-Adresse
@@ -145,6 +152,7 @@ Help : Hilfe
Hold : an lassen
(id\: {}, length\: {}) : (Id: {}, Länge: {})
if ({}) : falls ({})
+If car of train\: inspect car number : Falls Fahrzeug aus Zug: Untersuche Fahrzeug Nummer
If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished.
Falls aktiviert, wird die Strecke anhand von Zug- und Kachel-Länge hinter dem Zug freigegeben, Falls deaktiviert wird die Strecke hinter dem Zug erst bei Abschluss der Route freigegeben.
internal contacts : interne Kontakte
@@ -156,6 +164,7 @@ known locomotives : bekannte Lokomotiven
known trains : bekannte Züge
Label for state {} : Beschriftung für Status {}
Last blocks : Letzte Blöcke
+last parked train : letzten geparkten Zug
learn : lernen
LEFT : links
Left port : Port für links
@@ -295,12 +304,15 @@ State : Status
StopAllTrains : Alle Züge stoppen
StartStopAuto : Automatikmodus an/abschalten
Stop autopilot : Autopilot abschalten
+Stopped and reversed {}. : {} angehalten und gewendet.
{} stopping at next block. : {} hält im nächsten Block.
Stopsettings : Halte-Einstellungen
StopTrain : Zug stoppen
Stop train immediately : Zug sofort anhalten
Straight port : Port für gerade
STRAIGHT : gerade
+Swap order : Reihenfolge umkehren
+Swap order of trains : Reihenfolge der Züge tauschen
SwitchFunction : Funktion schalten
Switch power off : Strom ausschalten
Switch power on : Strom anschalten
@@ -325,7 +337,7 @@ train is longer than {} {} : Zug ist länger als {} {}
train is not a push-pull train : Zug ist kein Wendezug
train is not shunting : Zug rangiert nicht
train is shorter than {} {} : Zug ist kürzer als {} {}
-TrainIsShunting : Zug rangiert
+TrainIsShunting : Rangierfahrt
train is shunting : Zug rangiert
train is slower than {} {} : Zug ist langsamer als {} {}
TrainLength : Zug-Länge
@@ -357,6 +369,7 @@ Turnouts : Weichen
turn within train : innerhalb des Zugs drehen
Turns the train, as if it went through a loop. : Dreht den ZUg, als wenn er eine Wendeschleife passiert hätte.
Unknown action\: {} : Unbekannte Aktion: {}
+Use negative number to count from end. : Nutze negative Nummern, um von Ende zu zählen.
unset : ungesetzt
WaitForContact : Auf Kontakt warten
Wait for {}, then : auf {} warten, dann
diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java
index e9d625b..9c00c88 100644
--- a/src/main/java/de/srsoftware/web4rail/Route.java
+++ b/src/main/java/de/srsoftware/web4rail/Route.java
@@ -75,6 +75,11 @@ public class Route extends BaseClass {
private static final String ROUTE_START = "route_start";
private static final String ROUTE_SETUP = "route_setup";
+
+ public static final String DESTINATION_PREFIX = "@";
+ public static final char TURN_FLAG = '±';
+ public static final char FLAG_SEPARATOR = '+';
+ public static final char SHUNTING_FLAG = '¥';
private int startSpeed;
private static HashMap names = new HashMap(); // maps id to name. needed to keep names during plan.analyze()
@@ -508,7 +513,7 @@ public class Route extends BaseClass {
if (endBlock == train.destination()) {
String destTag = null;
for (String tag : train.tags()) {
- if (tag.startsWith("@")) {
+ if (tag.startsWith(DESTINATION_PREFIX)) {
destTag = tag;
break;
}
@@ -517,8 +522,19 @@ public class Route extends BaseClass {
if (isSet(destTag)) {
String[] parts = destTag.split("@");
String destId = parts[1];
- boolean turn = destId.endsWith("+turn");
- if (turn) destId = destId.substring(0,destId.length()-5);
+ boolean turn = false;
+
+ for (int i=destId.length()-1; i>0; i--) {
+ switch (destId.charAt(i)) {
+ case FLAG_SEPARATOR:
+ destId = destId.substring(0,i);
+ i=0;
+ break;
+ case TURN_FLAG:
+ turn = true;
+ break;
+ }
+ }
if (destId.equals(endBlock.id().toString())) {
if (turn) train.turn();
train.removeTag(destTag);
diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java
index 5d7e1a6..09c03bc 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/Action.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/Action.java
@@ -47,6 +47,7 @@ public abstract class Action extends BaseClass {
BrakeCancel.class,
BrakeStart.class,
ConditionalAction.class,
+ CoupleTrain.class,
DelayedAction.class,
DetermineTrainInBlock.class,
DisableEnableBlock.class,
diff --git a/src/main/java/de/srsoftware/web4rail/actions/AddDestination.java b/src/main/java/de/srsoftware/web4rail/actions/AddDestination.java
index 7afb0be..02b1d2d 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/AddDestination.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/AddDestination.java
@@ -10,6 +10,7 @@ import org.json.JSONObject;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Application;
import de.srsoftware.web4rail.BaseClass;
+import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.Window;
import de.srsoftware.web4rail.moving.Train;
import de.srsoftware.web4rail.tags.Checkbox;
@@ -20,8 +21,10 @@ import de.srsoftware.web4rail.tiles.Tile;
public class AddDestination extends Action {
private static final String TURN = "turn";
+ private static final String SHUNTING = "shunting";
private Block destination;
private boolean turnAtDestination;
+ private boolean shunting;
public AddDestination(BaseClass parent) {
super(parent);
@@ -39,9 +42,12 @@ public class AddDestination extends Action {
}
return true;
}
- String dest = "@"+destination.id()+(turnAtDestination?"+turn":"");
+ String flags = "+";
+ if (turnAtDestination) flags += Route.TURN_FLAG;
+ if (shunting) flags += Route.SHUNTING_FLAG;
+ String dest = Route.DESTINATION_PREFIX+destination.id() + (flags.length()>1 ? flags : "");
for (String tag: train.tags()) {
- if (tag.startsWith("@")) {
+ if (tag.startsWith(Route.DESTINATION_PREFIX)) {
train.removeTag(tag);
dest = tag+dest;
break;
@@ -56,12 +62,14 @@ public class AddDestination extends Action {
JSONObject json = super.json();
if (isSet(destination)) json.put(Train.DESTINATION,destination.id().toString());
if (turnAtDestination) json.put(TURN,true);
+ if (shunting) json.put(SHUNTING, true);
return json;
}
@Override
public Action load(JSONObject json) {
if (json.has(TURN)) turnAtDestination = json.getBoolean(TURN);
+ if (json.has(SHUNTING)) shunting = json.getBoolean(SHUNTING);
if (json.has(Train.DESTINATION)) {
Id blockId = new Id(json.getString(Train.DESTINATION));
destination = BaseClass.get(blockId);
@@ -89,6 +97,7 @@ public class AddDestination extends Action {
button(t("Clear destinations"),Map.of(ACTION,ACTION_UPDATE,Train.DESTINATION,"0")).addTo(span);
formInputs.add(t("Destination")+": "+(isNull(destination) ? t("Clear destinations") : destination),span);
formInputs.add(t("Turn at destination"),new Checkbox(TURN, t("Turn"), turnAtDestination));
+ formInputs.add(t("Shunting"),new Checkbox(SHUNTING, t("Shunting"), shunting));
return super.properties(preForm, formInputs, postForm);
}
@@ -113,6 +122,7 @@ public class AddDestination extends Action {
}
}
turnAtDestination = "on".equals(params.get(TURN));
+ shunting = "on".equals(params.get(SHUNTING));
return context().properties();
}
}
diff --git a/src/main/java/de/srsoftware/web4rail/actions/AddRemoveTag.java b/src/main/java/de/srsoftware/web4rail/actions/AddRemoveTag.java
index 1875bcd..fea65b5 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/AddRemoveTag.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/AddRemoveTag.java
@@ -21,15 +21,15 @@ public class AddRemoveTag extends Action{
}
private String tag = "test";
- private boolean add = true;
+ private boolean remove = false;
@Override
public boolean fire(Context context) {
if (isNull(context.train())) return false;
- if (add) {
- context.train().tags().add(tag);
+ if (remove) {
+ context.train().removeTag(tag);
} else {
- context.train().tags().remove(tag);
+ context.train().addTag(tag);
}
return true;
}
@@ -38,13 +38,15 @@ public class AddRemoveTag extends Action{
public JSONObject json() {
JSONObject json = super.json();
json.put(TAG, tag);
+ if (remove) json.put(ACTION_DROP, true);
return json;
}
@Override
public Action load(JSONObject json) {
super.load(json);
- tag = json.getString(TAG);
+ if (json.has(TAG)) tag = json.getString(TAG);
+ if (json.has(ACTION_DROP)) remove = json.getBoolean(ACTION_DROP);
return this;
}
@@ -52,21 +54,21 @@ public class AddRemoveTag extends Action{
protected Window properties(List