diff --git a/build.gradle b/build.gradle index 4dccacb5f7..ef268f7f93 100644 --- a/build.gradle +++ b/build.gradle @@ -138,7 +138,7 @@ sourceSets { run { args = ['-v=' + appSemVer] applicationDefaultJvmArgs = ["-Xss8M", "-Dsun.java2d.d3d=false", "-Dsentry.environment=Development", "-Dfile.encoding=UTF-8", - "-Dpolyglot.engine.WarnInterpreterOnly=false", + "-Dpolyglot.engine.WarnInterpreterOnly=false","-DRUN_FROM_IDE=true", "-DMAPTOOL_DATADIR=.maptool-" + vendor.toLowerCase(), "-XX:+ShowCodeDetailsInExceptionMessages", "--add-opens=java.desktop/java.awt=ALL-UNNAMED", "--add-opens=java.desktop/java.awt.geom=ALL-UNNAMED", "--add-opens=java.desktop/sun.awt.geom=ALL-UNNAMED", "--add-opens=java.base/java.util=ALL-UNNAMED", @@ -219,7 +219,8 @@ runtime { 'jdk.unsupported.desktop', 'jdk.xml.dom', 'jdk.crypto.cryptoki', - 'jdk.crypto.ec' + 'jdk.crypto.ec', + 'jdk.zipfs' ] @@ -233,7 +234,8 @@ runtime { "--add-opens=java.desktop/sun.awt.geom=ALL-UNNAMED", "--add-opens=java.base/java.util=ALL-UNNAMED", "--add-opens=javafx.web/javafx.scene.web=ALL-UNNAMED", "--add-opens=javafx.web/com.sun.webkit=ALL-UNNAMED", "--add-opens=javafx.web/com.sun.webkit.dom=ALL-UNNAMED", "--add-opens=java.desktop/javax.swing=ALL-UNNAMED","--add-opens=java.desktop/sun.awt.shell=ALL-UNNAMED", - "--add-opens=java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED"] + "--add-opens=java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED" + ] imageOptions = [] imageName = project.name + developerRelease @@ -499,7 +501,13 @@ dependencies { implementation 'com.github.jknack:handlebars:4.3.1' implementation 'com.github.jknack:handlebars-helpers:4.3.1' - implementation 'com.miglayout:miglayout-swing:11.0' + + + // Built In Add-on Libraries + implementation 'com.github.RPTools:maptool-builtin-addons:1.3' + + // For advanced dice roller + implementation 'com.github.RPTools:advanced-dice-roller:1.0.3' // libgdx implementation 'com.github.thelsing:libgdx-jogl-backend:1.12.1' @@ -516,8 +524,7 @@ dependencies { implementation "com.badlogicgames.gdx-video:gdx-video-lwjgl3:1.3.2-SNAPSHOT" implementation 'com.badlogicgames.box2dlights:box2dlights:1.5' implementation 'com.badlogicgames.gdx:gdx-box2d:1.12.0' - implementation "com.badlogicgames.gdx:gdx-box2d-platform:1.12.0:natives-desktop" -} + implementation "com.badlogicgames.gdx:gdx-box2d-platform:1.12.0:natives-desktop"} task configSentryRelease(type: Copy) { diff --git a/gradle.properties b/gradle.properties index 058c321c4d..11c7c6b102 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,4 @@ org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAME --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ - --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ No newline at end of file + --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED diff --git a/src/main/java/net/rptools/dicelib/expression/ExpressionParser.java b/src/main/java/net/rptools/dicelib/expression/ExpressionParser.java index e96e0fb8ac..25656a83c3 100755 --- a/src/main/java/net/rptools/dicelib/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/dicelib/expression/ExpressionParser.java @@ -14,6 +14,8 @@ */ package net.rptools.dicelib.expression; +import java.util.List; +import java.util.regex.Pattern; import net.rptools.dicelib.expression.function.ArsMagicaStress; import net.rptools.dicelib.expression.function.CountSuccessDice; import net.rptools.dicelib.expression.function.DropHighestRoll; @@ -36,9 +38,11 @@ import net.rptools.dicelib.expression.function.ShadowRun5Dice; import net.rptools.dicelib.expression.function.ShadowRun5ExplodeDice; import net.rptools.dicelib.expression.function.UbiquityRoll; +import net.rptools.dicelib.expression.function.advanced.AdvancedDiceRolls; import net.rptools.parser.*; import net.rptools.parser.transform.RegexpStringTransformer; import net.rptools.parser.transform.StringLiteralTransformer; +import org.javatuples.Pair; public class ExpressionParser { private static String[][] DICE_PATTERNS = @@ -209,6 +213,11 @@ public class ExpressionParser { private final Parser parser; + private final List> preprocessPatterns = + List.of( + new Pair<>(Pattern.compile("^([A-z]+)!\"([^\"]*)\"$"), "advancedRoll('$1', " + "'$2')"), + new Pair<>(Pattern.compile("^([A-z]+)!'([^']*)'$"), "advancedRoll('$1', " + "'$2')")); + public ExpressionParser() { this(DICE_PATTERNS); } @@ -238,6 +247,7 @@ public ExpressionParser(String[][] regexpTransforms) { parser.addFunction(new DropHighestRoll()); parser.addFunction(new KeepLowestRoll()); parser.addFunction(new ArsMagicaStress()); + parser.addFunction(new AdvancedDiceRolls()); parser.addFunction(new If()); @@ -277,6 +287,9 @@ public Result evaluate(String expression, VariableResolver resolver, boolean mak } RunData.setCurrent(newRunData); + // Some patterns need pre-processing before the parser is called otherwise the parser + // creation will fail + expression = preProcess(expression); synchronized (parser) { final Expression xp = makeDeterministic @@ -292,4 +305,21 @@ public Result evaluate(String expression, VariableResolver resolver, boolean mak return ret; } + + /** + * Pre-process the expression before it is parsed. This is used to convert some patterns into + * function calls that the parser can handle. + * + * @param expression The expression to pre-process + * @return The pre-processed expression + */ + private String preProcess(String expression) { + var trimmed = expression.trim(); + for (Pair p : preprocessPatterns) { + if (p.getValue0().matcher(trimmed).find()) { + return p.getValue0().matcher(trimmed).replaceAll(p.getValue1()); + } + } + return expression; + } } diff --git a/src/main/java/net/rptools/dicelib/expression/function/advanced/AdvancedDiceRolls.java b/src/main/java/net/rptools/dicelib/expression/function/advanced/AdvancedDiceRolls.java new file mode 100644 index 0000000000..b1acc165dd --- /dev/null +++ b/src/main/java/net/rptools/dicelib/expression/function/advanced/AdvancedDiceRolls.java @@ -0,0 +1,51 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.dicelib.expression.function.advanced; + +import java.util.List; +import net.rptools.dicelib.expression.function.advanced.GenesysDiceRolls.DiceType; +import net.rptools.maptool.language.I18N; +import net.rptools.parser.Parser; +import net.rptools.parser.ParserException; +import net.rptools.parser.VariableResolver; +import net.rptools.parser.function.AbstractFunction; + +/** Function to roll dice using the advanced dice roller. */ +public class AdvancedDiceRolls extends AbstractFunction { + + /** Constructor. */ + public AdvancedDiceRolls() { + super(2, 2, false, "advancedRoll"); + } + + @Override + public Object childEvaluate( + Parser parser, VariableResolver resolver, String functionName, List parameters) + throws ParserException { + String diceName = parameters.get(0).toString().toLowerCase(); + String diceExpression = parameters.get(1).toString(); + + try { + return switch (diceName) { + case "sw" -> new GenesysDiceRolls().roll(DiceType.StarWars, diceExpression, resolver); + case "gs" -> new GenesysDiceRolls().roll(DiceType.Genesys, diceExpression, resolver); + default -> throw new ParserException( + I18N.getText("advanced.roll.unknownDiceType", diceName)); + }; + } catch (IllegalArgumentException e) { + throw new ParserException(e.getMessage()); + } + } +} diff --git a/src/main/java/net/rptools/dicelib/expression/function/advanced/GenesysDiceRolls.java b/src/main/java/net/rptools/dicelib/expression/function/advanced/GenesysDiceRolls.java new file mode 100644 index 0000000000..f267147026 --- /dev/null +++ b/src/main/java/net/rptools/dicelib/expression/function/advanced/GenesysDiceRolls.java @@ -0,0 +1,261 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.dicelib.expression.function.advanced; + +import java.util.Map; +import javax.swing.JOptionPane; +import net.rptools.maptool.advanceddice.genesys.GenesysDiceResult; +import net.rptools.maptool.advanceddice.genesys.GenesysDiceRoller; +import net.rptools.maptool.client.MapTool; +import net.rptools.maptool.client.MapToolVariableResolver; +import net.rptools.maptool.client.ui.theme.ThemeSupport; +import net.rptools.maptool.client.ui.theme.ThemeSupport.ThemeColor; +import net.rptools.maptool.language.I18N; +import net.rptools.parser.ParserException; +import net.rptools.parser.VariableResolver; + +/** Function to roll dice using the advanced dice roller. */ +public class GenesysDiceRolls { + + /** Enum to represent the different dice types. */ + public enum DiceType { + StarWars("sw"), + Genesys("gs"); + + /** The variable prefix for the dice type. */ + public final String variablePrefix; + + /** + * Constructor. + * + * @param variablePrefix the prefix to use for variables. + */ + DiceType(String variablePrefix) { + this.variablePrefix = variablePrefix; + } + + /** + * Get the variable prefix for the dice type. + * + * @return the variable prefix. + */ + public String getVariablePrefix() { + return variablePrefix; + } + } + + /** Map of font names for the different systems. */ + private static final Map GS_FONT_NAME_MAP = + Map.of(DiceType.StarWars, "EotE Symbol", DiceType.Genesys, "Genesys Glyphs and Dice"); + + /** + * Roll the given dice string using genesys/starwars dice roll parser. + * + * @param diceType the type of dice to roll. + * @param diceExpression the expression to roll. + * @param resolver the variable resolver. + * @return the result of the roll. + * @throws ParserException if there is an error parsing the expression. + */ + Object roll(DiceType diceType, String diceExpression, VariableResolver resolver) + throws ParserException { + var roller = new GenesysDiceRoller(); + try { + var result = + roller.roll( + diceExpression, + n -> getVariable(resolver, n), + n -> getProperty(resolver, n), + n -> getPromptedValue(resolver, n)); + + if (result.hasErrors()) { + var errorSb = new StringBuilder(); + for (var error : result.getErrors()) { + String msg; + int ind = error.charPositionInLine(); + if (result.getRollString().length() > ind + 3) { + msg = result.getRollString().substring(ind, ind + 3) + "..."; + } else { + msg = result.getRollString().substring(ind); + } + var errorText = I18N.getText("advanced.roll.parserError", error.line(), ind + 1, msg); + errorSb.append(errorText).append("
"); + } + throw new ParserException(errorSb.toString()); + } + var varPrefix = diceType.getVariablePrefix() + ".lastRoll"; + setVars(resolver, varPrefix, result); + + return formatResults(diceType, result); + + } catch (IllegalArgumentException e) { + throw new ParserException(e.getMessage()); + } + } + + /** + * Format the results of the roll. + * + * @param diceType the type of dice. + * @param result the result of the roll. + * @return the formatted results. + */ + private String formatResults(DiceType diceType, GenesysDiceResult result) { + var gray = ThemeSupport.getThemeColorHexString(ThemeColor.GREY); + + var sb = new StringBuilder(); + sb.append(""); + sb.append(""); + for (var dice : result.getRolls()) { + sb.append(dice.resultType().getFontCharacters()); + } + sb.append(""); + sb.append(""); + return sb.toString(); + } + + /** + * Set the variables for the result. + * + * @param resolver the variable resolver. + * @param varPrefix the variable prefix. + * @param result the result. + * @throws ParserException if there is an error setting the variables. + */ + private void setVars(VariableResolver resolver, String varPrefix, GenesysDiceResult result) + throws ParserException { + resolver.setVariable(varPrefix + ".expression", result.getRollString()); + resolver.setVariable(varPrefix + ".success", result.getSuccessCount()); + resolver.setVariable(varPrefix + ".failure", result.getFailureCount()); + resolver.setVariable(varPrefix + ".advantage", result.getAdvantageCount()); + resolver.setVariable(varPrefix + ".threat", result.getThreatCount()); + resolver.setVariable(varPrefix + ".triumph", result.getTriumphCount()); + resolver.setVariable(varPrefix + ".despair", result.getDespairCount()); + resolver.setVariable(varPrefix + ".light", result.getLightCount()); + resolver.setVariable(varPrefix + ".dark", result.getDarkCount()); + + for (var group : result.getGroupNames()) { + var groupResult = result.getGroup(group); + setVars(resolver, varPrefix + ".group." + group, groupResult); + } + } + + /** + * Get the variable value. + * + * @param resolver the variable resolver. + * @param name the name of the variable. + * @return the value of the variable. + */ + private int getVariable(VariableResolver resolver, String name) { + if (!resolver.getVariables().contains(name.toLowerCase())) { + throw new IllegalArgumentException(I18N.getText("advanced.roll.unknownVariable", name)); + } + + try { + var value = resolver.getVariable(name); + var result = integerResult(value, false); + + if (result == null) { + throw new IllegalArgumentException(I18N.getText("advanced.roll.variableNotNumber", name)); + } + + return result; + } catch (ParserException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * Get the property value for the token in context. + * + * @param resolver the variable resolver. + * @param name the name of the property. + * @return the value of the property. + */ + private int getProperty(VariableResolver resolver, String name) { + var mtResolver = (MapToolVariableResolver) resolver; + var token = mtResolver.getTokenInContext(); + if (token == null) { + throw new IllegalArgumentException(I18N.getText("advanced.roll.noTokenInContext")); + } + var value = token.getProperty(name); + + if (value == null) { + throw new IllegalArgumentException(I18N.getText("advanced.roll.unknownProperty", name)); + } + + var result = integerResult(value, true); + if (result == null) { + throw new IllegalArgumentException(I18N.getText("advanced.roll.propertyNotNumber", name)); + } + + return result; + } + + /** + * Prompt the user for a value. + * + * @param resolver the variable resolver. + * @param name the name of the value. + * @return the value. + */ + private int getPromptedValue(VariableResolver resolver, String name) { + var option = + JOptionPane.showInputDialog( + MapTool.getFrame(), + I18N.getText("lineParser.dialogValueFor", name), + I18N.getText("lineParser.dialogTitleNoToken"), + JOptionPane.QUESTION_MESSAGE, + null, + null, + 1); + try { + return Integer.parseInt(option.toString()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(I18N.getText("advanced.roll.inputNotNumber", name)); + } + } + + /** + * Get the integer result. + * + * @param value the value. + * @param parseString attempt to parse string value of object if it is not a number. + * @return the integer result. + */ + private Integer integerResult(Object value, boolean parseString) { + if (value instanceof Integer i) { + return i; + } + + if (value instanceof Number n) { + return n.intValue(); + } + + if (parseString) { + try { + return Integer.parseInt(value.toString()); + } catch (NumberFormatException e) { + return null; + } + } + + return null; + } +} diff --git a/src/main/java/net/rptools/maptool/client/AppActions.java b/src/main/java/net/rptools/maptool/client/AppActions.java index a61ba52407..f2adcbcc9c 100644 --- a/src/main/java/net/rptools/maptool/client/AppActions.java +++ b/src/main/java/net/rptools/maptool/client/AppActions.java @@ -1091,7 +1091,7 @@ private static void pasteTokens(ZonePoint destination, Layer layer) { // Create a set of all tokenExposedAreaGUID's to make searching by GUID much faster. Set allTokensSet = null; { - List allTokensList = zone.getTokens(); + List allTokensList = zone.getAllTokens(); if (!allTokensList.isEmpty()) { allTokensSet = new HashSet(allTokensList.size()); for (Token token : allTokensList) { @@ -2848,27 +2848,28 @@ protected void executeAction() { chooser.setSelectedFile(new File(zr.getZone().getName())); boolean tryAgain = true; while (tryAgain) { - if (chooser.showSaveDialog(MapTool.getFrame()) == JFileChooser.APPROVE_OPTION) { - File mapFile = chooser.getSelectedFile(); - var installDir = AppUtil.getInstallDirectory().toAbsolutePath(); - var saveDir = chooser.getSelectedFile().toPath().getParent().toAbsolutePath(); - if (saveDir.startsWith(installDir)) { - MapTool.showWarning("msg.warning.saveMapToInstallDir"); - } else { - tryAgain = false; - try { - mapFile = getFileWithExtension(mapFile, AppConstants.MAP_FILE_EXTENSION); - if (mapFile.exists()) { - if (!MapTool.confirm("msg.confirm.fileExists")) { - return; - } + if (chooser.showSaveDialog(MapTool.getFrame()) != JFileChooser.APPROVE_OPTION) { + break; + } + File mapFile = chooser.getSelectedFile(); + var installDir = AppUtil.getInstallDirectory().toAbsolutePath(); + var saveDir = chooser.getSelectedFile().toPath().getParent().toAbsolutePath(); + if (saveDir.startsWith(installDir)) { + MapTool.showWarning("msg.warning.saveMapToInstallDir"); + } else { + tryAgain = false; + try { + mapFile = getFileWithExtension(mapFile, AppConstants.MAP_FILE_EXTENSION); + if (mapFile.exists()) { + if (!MapTool.confirm("msg.confirm.fileExists")) { + return; } - PersistenceUtil.saveMap(zr.getZone(), mapFile); - AppPreferences.setSaveMapDir(mapFile.getParentFile()); - MapTool.showInformation("msg.info.mapSaved"); - } catch (IOException ioe) { - MapTool.showError("msg.error.failedSaveMap", ioe); } + PersistenceUtil.saveMap(zr.getZone(), mapFile); + AppPreferences.setSaveMapDir(mapFile.getParentFile()); + MapTool.showInformation("msg.info.mapSaved"); + } catch (IOException ioe) { + MapTool.showError("msg.error.failedSaveMap", ioe); } } } diff --git a/src/main/java/net/rptools/maptool/client/AppPreferences.java b/src/main/java/net/rptools/maptool/client/AppPreferences.java index 6f5f2dc64e..b42ea6471e 100644 --- a/src/main/java/net/rptools/maptool/client/AppPreferences.java +++ b/src/main/java/net/rptools/maptool/client/AppPreferences.java @@ -147,6 +147,9 @@ public class AppPreferences { "hideMousePointerWhileDragging"; private static final boolean DEFAULT_KEY_HIDE_MOUSE_POINTER_WHILE_DRAGGING = true; + private static final String KEY_HIDE_TOKEN_STACK_INDICATOR = "hideTokenStackIndicator"; + private static final boolean DEFAULT_KEY_HIDE_TOKEN_STACK_INDICATOR = false; + private static final String KEY_OBJECTS_START_SNAP_TO_GRID = "newStampsStartSnapToGrid"; private static final boolean DEFAULT_OBJECTS_START_SNAP_TO_GRID = false; @@ -960,6 +963,14 @@ public static boolean getHideMousePointerWhileDragging() { KEY_HIDE_MOUSE_POINTER_WHILE_DRAGGING, DEFAULT_KEY_HIDE_MOUSE_POINTER_WHILE_DRAGGING); } + public static void setHideTokenStackIndicator(boolean flag) { + prefs.putBoolean(KEY_HIDE_TOKEN_STACK_INDICATOR, flag); + } + + public static boolean getHideTokenStackIndicator() { + return prefs.getBoolean(KEY_HIDE_TOKEN_STACK_INDICATOR, DEFAULT_KEY_HIDE_TOKEN_STACK_INDICATOR); + } + public static void setObjectsStartSnapToGrid(boolean flag) { prefs.putBoolean(KEY_OBJECTS_START_SNAP_TO_GRID, flag); } diff --git a/src/main/java/net/rptools/maptool/client/AppStyle.java b/src/main/java/net/rptools/maptool/client/AppStyle.java index 12722e5fb8..e1f3c82d2c 100644 --- a/src/main/java/net/rptools/maptool/client/AppStyle.java +++ b/src/main/java/net/rptools/maptool/client/AppStyle.java @@ -42,9 +42,11 @@ public class AppStyle { public static Color topologyRemoveColor = new Color(255, 255, 255, 128); public static Color hillVblColor = new Color(0, 255, 255, 128); public static Color pitVblColor = new Color(104, 255, 0, 128); + public static Color coverVblColor = new Color(245, 0, 0, 128); public static Color topologyTerrainColor = new Color(255, 0, 255, 128); public static Color tokenTopologyColor = new Color(255, 255, 0, 128); public static Color tokenHillVblColor = new Color(255, 136, 0, 128); public static Color tokenPitVblColor = new Color(255, 0, 0, 128); + public static Color tokenCoverVblColor = new Color(245, 0, 0, 128); public static Color tokenMblColor = new Color(255, 128, 255, 128); } diff --git a/src/main/java/net/rptools/maptool/client/AppUtil.java b/src/main/java/net/rptools/maptool/client/AppUtil.java index d5c18fda29..e89e94caae 100644 --- a/src/main/java/net/rptools/maptool/client/AppUtil.java +++ b/src/main/java/net/rptools/maptool/client/AppUtil.java @@ -213,18 +213,17 @@ public static Path getInstallDirectory() { var path = Path.of(getAppInstallLocation()); if (MapTool.isDevelopment()) { // remove build/classes/java - path = path.getParent().getParent().getParent().getParent(); - } else { + path = path.getParent().getParent().getParent(); + } else { // First try to find MapTool* directory in path while (path != null) { if (path.getFileName().toString().matches("(?i).*maptool.*")) { - path = path.getParent(); break; } path = path.getParent(); } } - if (path == null) { - return Path.of(getAppInstallLocation()); + if (path == null) { // if not found then just return the parent of the app subdir + return Path.of(getAppInstallLocation()).resolve("..").toAbsolutePath(); } else { return path; } diff --git a/src/main/java/net/rptools/maptool/client/ClientMessageHandler.java b/src/main/java/net/rptools/maptool/client/ClientMessageHandler.java index fec8989807..2ac581e873 100644 --- a/src/main/java/net/rptools/maptool/client/ClientMessageHandler.java +++ b/src/main/java/net/rptools/maptool/client/ClientMessageHandler.java @@ -684,7 +684,9 @@ private void handle(RemoveZoneMsg msg) { MapTool.getFrame().removeZoneRenderer(renderer); // Now we have fire off adding the tokens in the zone - new MapToolEventBus().getMainEventBus().post(new TokensRemoved(zone, zone.getTokens())); + new MapToolEventBus() + .getMainEventBus() + .post(new TokensRemoved(zone, zone.getAllTokens())); new MapToolEventBus().getMainEventBus().post(new ZoneRemoved(zone)); }); } @@ -752,7 +754,7 @@ private void handle(PutZoneMsg msg) { new MapToolEventBus().getMainEventBus().post(new ZoneAdded(zone)); // Now we have fire off adding the tokens in the zone - new MapToolEventBus().getMainEventBus().post(new TokensAdded(zone, zone.getTokens())); + new MapToolEventBus().getMainEventBus().post(new TokensAdded(zone, zone.getAllTokens())); }); } diff --git a/src/main/java/net/rptools/maptool/client/DebounceExecutor.java b/src/main/java/net/rptools/maptool/client/DebounceExecutor.java index e432f23438..31e10170ba 100644 --- a/src/main/java/net/rptools/maptool/client/DebounceExecutor.java +++ b/src/main/java/net/rptools/maptool/client/DebounceExecutor.java @@ -50,7 +50,7 @@ public class DebounceExecutor { Executors.newSingleThreadScheduledExecutor(threadFactory); /** The time, in milliseconds, during which to throttle subsequent requests to run the task. */ - private final long delay; + private final AtomicLong delay; /** A {@link Runnable} representing the task to be managed. */ private final Runnable task; @@ -71,14 +71,20 @@ public class DebounceExecutor { * @param task The task to be executed after the delay elapses. */ public DebounceExecutor(long delay, @Nonnull Runnable task) { - this.delay = delay; + this.delay = new AtomicLong(delay); this.task = task; } + public void setDelay(long delay) { + this.delay.set(delay); + } + /** Dispatches a task to be executed by this {@link DebounceExecutor} instance. */ public void dispatch() { - if (this.delay < 1) { - this.task.run(); + final var delay = this.delay.get(); + if (delay < 1) { + // Have to run via the executor otherwise it's possible the task runs in parallel with itself. + this.executor.schedule(this.task, 0, TimeUnit.MILLISECONDS); return; } @@ -93,7 +99,7 @@ public void dispatch() { final var now = System.currentTimeMillis(); if (now >= taskScheduledTime) { // This request is not redundant, so we need to schedule it. - final var nextTargetTime = Math.max(now, taskScheduledTime + this.delay); + final var nextTargetTime = Math.max(now, taskScheduledTime + delay); // If this check fails, that means someone beat us to the punch and our task is now redundant. if (this.taskScheduledTime.compareAndSet(taskScheduledTime, nextTargetTime)) { this.executor.schedule(this.task, nextTargetTime - now, TimeUnit.MILLISECONDS); diff --git a/src/main/java/net/rptools/maptool/client/DeveloperOptions.java b/src/main/java/net/rptools/maptool/client/DeveloperOptions.java index ec695af7dc..2d97e90d6d 100644 --- a/src/main/java/net/rptools/maptool/client/DeveloperOptions.java +++ b/src/main/java/net/rptools/maptool/client/DeveloperOptions.java @@ -18,13 +18,10 @@ import java.util.List; import java.util.prefs.Preferences; import net.rptools.maptool.language.I18N; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; public class DeveloperOptions { - private static final Logger log = LogManager.getLogger(DeveloperOptions.class); private static final Preferences prefs = - Preferences.userRoot().node(AppConstants.APP_NAME + "/prefs"); + Preferences.userRoot().node(AppConstants.APP_NAME + "/dev"); public enum Toggle { /** @@ -57,7 +54,7 @@ public String getKey() { } public boolean isEnabled() { - return prefs.getBoolean(key, true); + return prefs.getBoolean(key, false); } public void setEnabled(boolean enabled) { diff --git a/src/main/java/net/rptools/maptool/client/MapTool.java b/src/main/java/net/rptools/maptool/client/MapTool.java index ceaa5fbab5..98471b7a86 100644 --- a/src/main/java/net/rptools/maptool/client/MapTool.java +++ b/src/main/java/net/rptools/maptool/client/MapTool.java @@ -80,6 +80,7 @@ import net.rptools.maptool.client.ui.zone.ZoneRenderer; import net.rptools.maptool.client.ui.zone.ZoneRendererFactory; import net.rptools.maptool.events.MapToolEventBus; +import net.rptools.maptool.events.TokenHoverListener; import net.rptools.maptool.events.ZoneLoadedListener; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.AssetManager; @@ -741,10 +742,7 @@ public static String getVersion() { } public static boolean isDevelopment() { - return "DEVELOPMENT".equals(version) - || "@buildNumber@".equals(version) - || "0.0.1".equals(version) - || (version != null && version.startsWith("SNAPSHOT")); + return System.getProperty("RUN_FROM_IDE") != null; } public static ServerPolicy getServerPolicy() { @@ -973,7 +971,7 @@ public static void setCampaign(Campaign campaign, GUID defaultRendererId) { } new MapToolEventBus().getMainEventBus().post(new ZoneAdded(zone)); // Now we have fire off adding the tokens in the zone - new MapToolEventBus().getMainEventBus().post(new TokensAdded(zone, zone.getTokens())); + new MapToolEventBus().getMainEventBus().post(new TokensAdded(zone, zone.getAllTokens())); } clientFrame.setCurrentZoneRenderer(currRenderer); clientFrame.getInitiativePanel().setOwnerPermissions(campaign.isInitiativeOwnerPermissions()); @@ -1136,7 +1134,7 @@ public static void removeZone(Zone zone) { MapTool.getCampaign().removeZone(zone.getId()); // Now we have fire off adding the tokens in the zone - new MapToolEventBus().getMainEventBus().post(new TokensRemoved(zone, zone.getTokens())); + new MapToolEventBus().getMainEventBus().post(new TokensRemoved(zone, zone.getAllTokens())); new MapToolEventBus().getMainEventBus().post(new ZoneRemoved(zone)); } @@ -1165,7 +1163,7 @@ public static void addZone(Zone zone, boolean changeZone) { new MapToolEventBus().getMainEventBus().post(new ZoneAdded(zone)); // Now we have fire off adding the tokens in the zone - new MapToolEventBus().getMainEventBus().post(new TokensAdded(zone, zone.getTokens())); + new MapToolEventBus().getMainEventBus().post(new TokensAdded(zone, zone.getAllTokens())); // Show the new zone if (changeZone) { @@ -1399,6 +1397,7 @@ private static void postInitialize() { // Register the instance that will listen for token hover events and create a stat sheet. new MapToolEventBus().getMainEventBus().register(new StatSheetListener()); + new MapToolEventBus().getMainEventBus().register(new TokenHoverListener()); final var enabledDeveloperOptions = DeveloperOptions.getEnabledOptions(); if (!enabledDeveloperOptions.isEmpty()) { @@ -1807,6 +1806,33 @@ public static void main(String[] args) { System.exit(1); } + /* + * Load GenSys and SW RPG fonts + */ + try { + var genv = GraphicsEnvironment.getLocalGraphicsEnvironment(); + var genFont = + Font.createFont( + Font.TRUETYPE_FONT, + Objects.requireNonNull( + MapTool.class + .getClassLoader() + .getResourceAsStream( + "net/rptools/maptool/client/fonts/GenesysGlyphsAndDice-3.0.otf"))); + genv.registerFont(genFont); + var swGenFont = + Font.createFont( + Font.TRUETYPE_FONT, + Objects.requireNonNull( + MapTool.class + .getClassLoader() + .getResourceAsStream( + "net/rptools/maptool/client/fonts/EotE_Symbol-Regular_v1.otf"))); + genv.registerFont(swGenFont); + } catch (Exception e) { + log.error("msg.error.genesysFont", e); + } + /** * This is a tweak that makes the Chinese version work better. * diff --git a/src/main/java/net/rptools/maptool/client/MapToolVariableResolver.java b/src/main/java/net/rptools/maptool/client/MapToolVariableResolver.java index f1489caf77..ed31fbcccb 100644 --- a/src/main/java/net/rptools/maptool/client/MapToolVariableResolver.java +++ b/src/main/java/net/rptools/maptool/client/MapToolVariableResolver.java @@ -276,7 +276,7 @@ public Object getVariable(String name, VariableModifiers mods) throws ParserExce result = JOptionPane.showInputDialog( MapTool.getFrame(), - I18N.getText("lineParser.dialogValueFor") + " " + name, + I18N.getText("lineParser.dialogValueFor", name), DialogTitle, JOptionPane.QUESTION_MESSAGE, null, diff --git a/src/main/java/net/rptools/maptool/client/ServerCommandClientImpl.java b/src/main/java/net/rptools/maptool/client/ServerCommandClientImpl.java index 0f83ff82f1..282a553ef4 100644 --- a/src/main/java/net/rptools/maptool/client/ServerCommandClientImpl.java +++ b/src/main/java/net/rptools/maptool/client/ServerCommandClientImpl.java @@ -674,18 +674,16 @@ public void updateTokenProperty(Token token, Token.Update update, String value) @Override public void updateTokenProperty(Token token, Token.Update update, LightSource value) { - updateTokenProperty( - token, update, TokenPropertyValueDto.newBuilder().setLightSource(value.toDto()).build()); - } - - @Override - public void updateTokenProperty( - Token token, Token.Update update, LightSource value1, String value2) { - updateTokenProperty( - token, - update, - TokenPropertyValueDto.newBuilder().setLightSource(value1.toDto()).build(), - TokenPropertyValueDto.newBuilder().setStringValue(value2).build()); + if (update == Token.Update.createUniqueLightSource) { + // This case requires sending the full light source definition. + updateTokenProperty( + token, update, TokenPropertyValueDto.newBuilder().setLightSource(value.toDto()).build()); + } else { + updateTokenProperty( + token, + update, + TokenPropertyValueDto.newBuilder().setLightSourceId(value.getId().toString()).build()); + } } @Override diff --git a/src/main/java/net/rptools/maptool/client/functions/MacroJavaScriptBridge.java b/src/main/java/net/rptools/maptool/client/functions/MacroJavaScriptBridge.java index ea81cdd92a..56848a78fb 100644 --- a/src/main/java/net/rptools/maptool/client/functions/MacroJavaScriptBridge.java +++ b/src/main/java/net/rptools/maptool/client/functions/MacroJavaScriptBridge.java @@ -206,6 +206,13 @@ public Object HostObjectToJavaScriptType(Object obj) { return jPrim.getAsString(); } } + } else if (obj instanceof BigDecimal) { + BigDecimal bd = (BigDecimal) obj; + try { + return Long.valueOf(bd.longValueExact()); + } catch (ArithmeticException e) { + return Double.valueOf(bd.doubleValue()); + } } return obj; } diff --git a/src/main/java/net/rptools/maptool/client/functions/MapFunctions.java b/src/main/java/net/rptools/maptool/client/functions/MapFunctions.java index 749c62bd67..df0190f68a 100644 --- a/src/main/java/net/rptools/maptool/client/functions/MapFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/MapFunctions.java @@ -39,7 +39,6 @@ import net.rptools.parser.function.AbstractFunction; public class MapFunctions extends AbstractFunction { - public static final String ON_CHANGE_MAP_CALLBACK = "onChangeMap"; private static final MapFunctions instance = new MapFunctions(); private MapFunctions() { diff --git a/src/main/java/net/rptools/maptool/client/functions/TestFunctions.java b/src/main/java/net/rptools/maptool/client/functions/TestFunctions.java index e9a20718db..6fb6747d3d 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TestFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TestFunctions.java @@ -104,7 +104,7 @@ private String runTests() { tokens.add(token); } } else { - tokens.addAll(MapTool.getFrame().getCurrentZoneRenderer().getZone().getTokens()); + tokens.addAll(MapTool.getFrame().getCurrentZoneRenderer().getZone().getAllTokens()); } tokens = diff --git a/src/main/java/net/rptools/maptool/client/functions/TokenCopyDeleteFunctions.java b/src/main/java/net/rptools/maptool/client/functions/TokenCopyDeleteFunctions.java index 3297c5eb65..67fea02cdd 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenCopyDeleteFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenCopyDeleteFunctions.java @@ -126,7 +126,7 @@ private String createToken(MapToolVariableResolver resolver, JsonObject vals) } Zone zone = MapTool.getFrame().getCurrentZoneRenderer().getZone(); - List allTokens = zone.getTokens(); + List allTokens = zone.getAllTokens(); Token t = new Token(name, new MD5Key(tokenImage)); // Make sure the exposedAreaGUID stays unique @@ -174,7 +174,7 @@ private Object copyTokens( Zone zone = MapTool.getFrame().getCurrentZoneRenderer().getZone(); List newTokens = new ArrayList<>(nCopies); - List allTokens = zone.getTokens(); + List allTokens = zone.getAllTokens(); for (int i = 0; i < nCopies; i++) { Token t = new Token(token); diff --git a/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java b/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java index 5a1f8dda96..fcf295768d 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java @@ -15,14 +15,19 @@ package net.rptools.maptool.client.functions; import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; +import java.awt.Color; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; import net.rptools.maptool.client.MapTool; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.*; +import net.rptools.maptool.model.drawing.DrawableColorPaint; import net.rptools.maptool.util.FunctionUtil; import net.rptools.parser.Parser; import net.rptools.parser.ParserException; @@ -32,8 +37,22 @@ public class TokenLightFunctions extends AbstractFunction { private static final TokenLightFunctions instance = new TokenLightFunctions(); + private static final String TOKEN_CATEGORY = "$unique"; + private TokenLightFunctions() { - super(0, 5, "hasLightSource", "clearLights", "setLight", "getLights"); + super( + 0, + 5, + "hasLightSource", + "clearLights", + "setLight", + "getLights", + "createUniqueLightSource", + "updateUniqueLightSource", + "deleteUniqueLightSource", + "getUniqueLightSource", + "getUniqueLightSources", + "getUniqueLightSourceNames"); } public static TokenLightFunctions getInstance() { @@ -76,6 +95,49 @@ public Object childEvaluate( Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 2, 3); return getLights(token, type, delim); } + if (functionName.equalsIgnoreCase("createUniqueLightSource")) { + FunctionUtil.blockUntrustedMacro(functionName); + FunctionUtil.checkNumberParam(functionName, parameters, 1, 3); + + JsonObject lightSource = FunctionUtil.paramAsJsonObject(functionName, parameters, 0); + Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 1, 2); + return createUniqueLightSource(lightSource, token, false).getName(); + } + if (functionName.equalsIgnoreCase("updateUniqueLightSource")) { + FunctionUtil.blockUntrustedMacro(functionName); + FunctionUtil.checkNumberParam(functionName, parameters, 1, 3); + + JsonObject lightSource = FunctionUtil.paramAsJsonObject(functionName, parameters, 0); + Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 1, 2); + return createUniqueLightSource(lightSource, token, true).getName(); + } + if (functionName.equalsIgnoreCase("deleteUniqueLightSource")) { + FunctionUtil.checkNumberParam(functionName, parameters, 1, 3); + + String name = parameters.get(0).toString(); + Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 1, 2); + deleteUniqueLightSource(name, token); + return ""; + } + if (functionName.equalsIgnoreCase("getUniqueLightSource")) { + FunctionUtil.checkNumberParam(functionName, parameters, 1, 3); + + String name = parameters.get(0).toString(); + Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 1, 2); + return Objects.requireNonNullElse(getUniqueLightSource(name, token), ""); + } + if (functionName.equalsIgnoreCase("getUniqueLightSources")) { + FunctionUtil.checkNumberParam(functionName, parameters, 0, 2); + + Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 0, 1); + return getUniqueLightSources(token); + } + if (functionName.equalsIgnoreCase("getUniqueLightSourceNames")) { + FunctionUtil.checkNumberParam(functionName, parameters, 0, 2); + + Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 0, 1); + return getUniqueLightSourceNames(token); + } return null; } @@ -83,8 +145,9 @@ public Object childEvaluate( * Gets the names of the light sources that are on. * * @param token The token to get the light sources for. - * @param category The category to get the light sources for, if null then the light sources for - * all categories will be returned. + * @param category The category to get the light sources for. If "*" then the light sources for + * all categories will be returned. If "$unique" then the light sources defined on the token + * will be returned. * @param delim the delimiter for the list. * @return a string list containing the lights that are on. * @throws ParserException if the light type can't be found. @@ -95,7 +158,13 @@ private static String getLights(Token token, String category, String delim) Map> lightSourcesMap = MapTool.getCampaign().getLightSourcesMap(); - if (category == null || category.equals("*")) { + if (category.equals("*")) { + // Look up on both token and campaign. + for (LightSource ls : token.getUniqueLightSources()) { + if (token.hasLightSource(ls)) { + lightList.add(ls.getName()); + } + } for (Map lsMap : lightSourcesMap.values()) { for (LightSource ls : lsMap.values()) { if (token.hasLightSource(ls)) { @@ -103,18 +172,23 @@ private static String getLights(Token token, String category, String delim) } } } - } else { - if (lightSourcesMap.containsKey(category)) { - for (LightSource ls : lightSourcesMap.get(category).values()) { - if (token.hasLightSource(ls)) { - lightList.add(ls.getName()); - } + } else if (TOKEN_CATEGORY.equals(category)) { + for (LightSource ls : token.getUniqueLightSources()) { + if (token.hasLightSource(ls)) { + lightList.add(ls.getName()); } - } else { - throw new ParserException( - I18N.getText("macro.function.tokenLight.unknownLightType", "getLights", category)); } + } else if (lightSourcesMap.containsKey(category)) { + for (LightSource ls : lightSourcesMap.get(category).values()) { + if (token.hasLightSource(ls)) { + lightList.add(ls.getName()); + } + } + } else { + throw new ParserException( + I18N.getText("macro.function.tokenLight.unknownLightType", "getLights", category)); } + if ("json".equals(delim)) { JsonArray jarr = new JsonArray(); lightList.forEach(l -> jarr.add(new JsonPrimitive(l))); @@ -128,7 +202,8 @@ private static String getLights(Token token, String category, String delim) * Sets the light value for a token. * * @param token the token to set the light for. - * @param category the category of the light source. + * @param category the category of the light source. Use "$unique" for light sources defined on + * the token. * @param name the name of the light source. * @param val the value to set for the light source, 0 for off non 0 for on. * @return 0 if the light was not found, otherwise 1; @@ -140,21 +215,25 @@ private static BigDecimal setLight(Token token, String category, String name, Bi Map> lightSourcesMap = MapTool.getCampaign().getLightSourcesMap(); - if (lightSourcesMap.containsKey(category)) { - for (LightSource ls : lightSourcesMap.get(category).values()) { - if (ls.getName().equals(name)) { - found = true; - if (val.equals(BigDecimal.ZERO)) { - MapTool.serverCommand().updateTokenProperty(token, Token.Update.removeLightSource, ls); - } else { - MapTool.serverCommand().updateTokenProperty(token, Token.Update.addLightSource, ls); - } - } - } + Iterable sources; + if (TOKEN_CATEGORY.equals(category)) { + sources = token.getUniqueLightSources(); + } else if (lightSourcesMap.containsKey(category)) { + sources = lightSourcesMap.get(category).values(); } else { throw new ParserException( I18N.getText("macro.function.tokenLight.unknownLightType", "setLights", category)); } + + final var updateAction = + BigDecimal.ZERO.equals(val) ? Token.Update.removeLightSource : Token.Update.addLightSource; + for (LightSource ls : sources) { + if (name.equals(ls.getName())) { + found = true; + MapTool.serverCommand().updateTokenProperty(token, updateAction, ls); + } + } + return found ? BigDecimal.ONE : BigDecimal.ZERO; } @@ -162,6 +241,7 @@ private static BigDecimal setLight(Token token, String category, String name, Bi * Checks to see if the token has a light source. The token is checked to see if it has a light * source with the name in the second parameter from the category in the first parameter. A "*" * for category indicates all categories are checked; a "*" for name indicates all names are + * checked. The "$unique" category indicates that only light sources defined on the token are * checked. * * @param token the token to check. @@ -180,6 +260,12 @@ public static boolean hasLightSource(Token token, String category, String name) MapTool.getCampaign().getLightSourcesMap(); if ("*".equals(category)) { + // Look up on both token and campaign. + for (LightSource ls : token.getUniqueLightSources()) { + if (ls.getName().equals(name) && token.hasLightSource(ls)) { + return true; + } + } for (Map lsMap : lightSourcesMap.values()) { for (LightSource ls : lsMap.values()) { if (ls.getName().equals(name) && token.hasLightSource(ls)) { @@ -187,21 +273,218 @@ public static boolean hasLightSource(Token token, String category, String name) } } } - } else { - if (lightSourcesMap.containsKey(category)) { - for (LightSource ls : lightSourcesMap.get(category).values()) { - if (ls.getName().equals(name) || "*".equals(name)) { - if (token.hasLightSource(ls)) { - return true; - } - } + } else if (TOKEN_CATEGORY.equals(category)) { + for (LightSource ls : token.getUniqueLightSources()) { + if ((ls.getName().equals(name) || "*".equals(name)) && token.hasLightSource(ls)) { + return true; + } + } + } else if (lightSourcesMap.containsKey(category)) { + for (LightSource ls : lightSourcesMap.get(category).values()) { + if ((ls.getName().equals(name) || "*".equals(name)) && token.hasLightSource(ls)) { + return true; } - } else { - throw new ParserException( - I18N.getText("macro.function.tokenLight.unknownLightType", "hasLightSource", category)); } + } else { + throw new ParserException( + I18N.getText("macro.function.tokenLight.unknownLightType", "hasLightSource", category)); } return false; } + + private static LightSource createUniqueLightSource( + JsonObject lightSourceDef, Token token, boolean isUpdate) throws ParserException { + if (!lightSourceDef.has("name")) { + throw new ParserException(I18N.getText("The light source must have a name.")); + } + final String name = lightSourceDef.get("name").getAsString(); + + // Modifications require the light source to exist. Creation requires it to not exists. + final Optional existingSource = + token.getUniqueLightSources().stream() + .filter(source -> name.equals(source.getName())) + .findFirst(); + if (isUpdate && existingSource.isEmpty()) { + throw new ParserException( + I18N.getText( + "Light source %s is not defined for token %s", name, token.getId().toString())); + } + if (!isUpdate && existingSource.isPresent()) { + throw new ParserException( + I18N.getText( + "Light source %s is already defined for token %s", name, token.getId().toString())); + } + + final LightSource.Type type = + lightSourceDef.has("type") + ? LightSource.Type.valueOf(lightSourceDef.get("type").getAsString().toUpperCase()) + : LightSource.Type.NORMAL; + final boolean scaleWithToken = + lightSourceDef.has("scale") ? lightSourceDef.get("scale").getAsBoolean() : false; + final JsonArray lightDefs = + lightSourceDef.has("lights") ? lightSourceDef.getAsJsonArray("lights") : new JsonArray(); + + final var lights = new ArrayList(); + for (final var light : lightDefs) { + lights.add(parseLightJson(light.getAsJsonObject(), type)); + } + + final var lightSource = + LightSource.createRegular( + name, + existingSource.isPresent() ? existingSource.get().getId() : new GUID(), + type, + scaleWithToken, + lights); + token.addUniqueLightSource(lightSource); + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.createUniqueLightSource, lightSource); + return lightSource; + } + + private static void deleteUniqueLightSource(String name, Token token) { + final var sourcesToRemove = new ArrayList(); + for (final LightSource source : token.getUniqueLightSources()) { + if (name.equals(source.getName())) { + sourcesToRemove.add(source); + } + } + + for (final LightSource source : sourcesToRemove) { + token.removeUniqueLightSource(source.getId()); + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.deleteUniqueLightSource, source); + } + } + + private static JsonObject getUniqueLightSource(String name, Token token) { + for (final LightSource source : token.getUniqueLightSources()) { + if (name.equals(source.getName())) { + return lightSourceToJson(source); + } + } + + return null; + } + + private static JsonArray getUniqueLightSources(Token token) { + final var result = new JsonArray(); + + for (final LightSource source : token.getUniqueLightSources()) { + result.add(lightSourceToJson(source)); + } + + return result; + } + + private static JsonArray getUniqueLightSourceNames(Token token) { + final var result = new JsonArray(); + + for (final LightSource source : token.getUniqueLightSources()) { + result.add(source.getName()); + } + + return result; + } + + private static Light parseLightJson(JsonObject lightDef, LightSource.Type lightSourceType) + throws ParserException { + if (!lightDef.has("range")) { + throw new ParserException(I18N.getText("A range must be provided for each light")); + } + final var range = lightDef.get("range").getAsDouble(); + + final var shape = + lightDef.has("shape") + ? ShapeType.valueOf(lightDef.get("shape").getAsString()) + : ShapeType.CIRCLE; + // Cones permit the fields arc and offset, but no other shape accepts them. + if (shape != ShapeType.CONE) { + if (lightDef.has("offset")) { + throw new ParserException( + I18N.getText("Facing offset provided but the shape is not a cone")); + } + if (lightDef.has("arc")) { + throw new ParserException(I18N.getText("Arc provided but the shape is not a cone")); + } + } + final var offset = lightDef.has("offset") ? lightDef.get("offset").getAsDouble() : 0; + final var arc = lightDef.has("arc") ? lightDef.get("arc").getAsDouble() : 0; + + // Auras permit the gmOnly and ownerOnly flags, but no other type accepts them. + if (lightSourceType != LightSource.Type.AURA) { + if (lightDef.has("gmOnly")) { + throw new ParserException(I18N.getText("gmOnly flag provided but the type is not an aura")); + } + if (lightDef.has("ownerOnly")) { + throw new ParserException( + I18N.getText("ownerOnly flag provided but the type is not an aura")); + } + } + final var gmOnly = lightDef.has("gmOnly") ? !lightDef.get("gmOnly").getAsBoolean() : false; + final var ownerOnly = + lightDef.has("ownerOnly") ? !lightDef.get("ownerOnly").getAsBoolean() : false; + + final DrawableColorPaint colorPaint; + if (lightDef.has("color")) { + var colorString = lightDef.get("color").getAsString(); + if (!colorString.startsWith("#")) { + // Make sure it is parsed as a hex color string, not something else. + colorString = "#" + colorString; + } + + colorPaint = new DrawableColorPaint(Color.decode(colorString)); + } else { + colorPaint = null; + } + + final var lumens = lightDef.has("lumens") ? lightDef.get("lumens").getAsInt() : 100; + if (lumens == 0) { + throw new ParserException(I18N.getText("Lumens must be non-zero.")); + } + + return new Light(shape, offset, range, arc, colorPaint, lumens, gmOnly, ownerOnly); + } + + private static JsonObject lightSourceToJson(LightSource source) { + final var lightSourceDef = new JsonObject(); + lightSourceDef.addProperty("name", source.getName()); + lightSourceDef.addProperty("type", source.getType().toString()); + lightSourceDef.addProperty("scale", source.isScaleWithToken()); + + final var lightDefs = new JsonArray(); + for (final Light light : source.getLightList()) { + lightDefs.add(lightToJson(source, light)); + } + lightSourceDef.add("lights", lightDefs); + return lightSourceDef; + } + + private static JsonObject lightToJson(LightSource source, Light light) { + final var lightDef = new JsonObject(); + lightDef.addProperty("shape", light.getShape().toString()); + + if (light.getShape() == ShapeType.CONE) { + lightDef.addProperty("offset", light.getFacingOffset()); + lightDef.addProperty("arc", light.getArcAngle()); + } + + if (source.getType() == LightSource.Type.AURA) { + lightDef.addProperty("gmOnly", light.isGM()); + lightDef.addProperty("ownerOnly", light.isOwnerOnly()); + } + + lightDef.addProperty("range", light.getRadius()); + if (light.getPaint() instanceof DrawableColorPaint paint) { + lightDef.addProperty("color", toHex(paint.getColor())); + } + lightDef.addProperty("lumens", light.getLumens()); + + return lightDef; + } + + private static String toHex(int rgb) { + return String.format("#%06X", rgb & 0x00FFFFFF); + } } diff --git a/src/main/java/net/rptools/maptool/client/functions/TokenMoveFunctions.java b/src/main/java/net/rptools/maptool/client/functions/TokenMoveFunctions.java index cf7995a6d0..9d3e2fbdba 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenMoveFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenMoveFunctions.java @@ -593,7 +593,8 @@ public static boolean callForMultiTokenMoveVeto(List filteredTokens) { } } catch (InterruptedException | ExecutionException e) { log.error( - I18N.getText("library.error.retrievingEventHandler", ON_TOKEN_MOVE_COMPLETE_CALLBACK), + I18N.getText( + "library.error.retrievingEventHandler", ON_MULTIPLE_TOKENS_MOVED_COMPLETE_CALLBACK), e.getCause()); } return moveDenied; diff --git a/src/main/java/net/rptools/maptool/client/functions/TokenSelectionFunctions.java b/src/main/java/net/rptools/maptool/client/functions/TokenSelectionFunctions.java index 421ef4a393..e535a61b5d 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenSelectionFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenSelectionFunctions.java @@ -137,7 +137,13 @@ private void selectTokens(List parameters) throws ParserException { if (parameters == null || parameters.isEmpty()) { replaceSelection = true; // Select all tokens - List allTokens = zone.getTokens(); + List allTokens = + switch (zr.getActiveLayer()) { + case TOKEN -> zone.getTokens(); + case GM -> zone.getGMStamps(); + case OBJECT -> zone.getStampTokens(); + case BACKGROUND -> zone.getBackgroundStamps(); + }; if (allTokens != null) { for (Token t : allTokens) { GUID tid = t.getId(); diff --git a/src/main/java/net/rptools/maptool/client/functions/Topology_Functions.java b/src/main/java/net/rptools/maptool/client/functions/Topology_Functions.java index 03e77cabb0..42953e4bcc 100644 --- a/src/main/java/net/rptools/maptool/client/functions/Topology_Functions.java +++ b/src/main/java/net/rptools/maptool/client/functions/Topology_Functions.java @@ -69,6 +69,14 @@ * *

getPitVBL(jsonArray) :: Get the Pit VBL for a given area and return as array of points * + *

drawCoverVBL(jsonArray) :: Takes an array of JSON Objects containing information to draw a + * Shape in Cover VBL + * + *

eraseCoverVBL(jsonArray) :: Takes an array of JSON Objects containing information to erase a + * Shape in Cover VBL + * + *

getCoverVBL(jsonArray) :: Get the Cover VBL for a given area and return as array of points + * *

drawMBL(jsonArray) :: Takes an array of JSON Objects containing information to draw a Shape in * MBL * @@ -101,6 +109,14 @@ *

transferPitVBL(direction[, delete][, tokenId] :: move or copy Pit VBL between token and Pit * VBL layer * + *

getTokenCoverVBL(tokenId) :: Get the Pit Cover attached to a token + * + *

setTokenCoverVBL(jsonArray, tokenId) :: Sets the token's Cover VBL to the information contains + * in the JSON Objects. + * + *

transferCoverVBL(direction[, delete][, tokenId] :: move or copy Cover VBL between token and + * Pit VBL layer + * *

getTokenMBL(tokenId) :: Get the MBL attached to a token * *

setTokenMBL(jsonArray, tokenId) :: Sets the token's MBL to the information contains in the @@ -127,20 +143,26 @@ private Topology_Functions() { "drawPitVBL", "erasePitVBL", "getPitVBL", + "drawCoverVBL", + "eraseCoverVBL", + "getCoverVBL", "drawMBL", "eraseMBL", "getMBL", "getTokenVBL", "getTokenHillVBL", "getTokenPitVBL", + "getTokenCoverVBL", "getTokenMBL", "setTokenVBL", "setTokenHillVBL", "setTokenPitVBL", + "setTokenCoverVBL", "setTokenMBL", "transferVBL", "transferHillVBL", "transferPitVBL", + "transferCoverVBL", "transferMBL"); } @@ -160,22 +182,27 @@ public Object childEvaluate( || functionName.equalsIgnoreCase("eraseHillVBL") || functionName.equalsIgnoreCase("drawPitVBL") || functionName.equalsIgnoreCase("erasePitVBL") + || functionName.equalsIgnoreCase("drawCoverVBL") + || functionName.equalsIgnoreCase("eraseCoverVBL") || functionName.equalsIgnoreCase("drawMBL") || functionName.equalsIgnoreCase("eraseMBL")) { childEvaluateDrawEraseTopology(functionName, parameters); } else if (functionName.equalsIgnoreCase("getVBL") || functionName.equalsIgnoreCase("getHillVBL") || functionName.equalsIgnoreCase("getPitVBL") + || functionName.equalsIgnoreCase("getCoverVBL") || functionName.equalsIgnoreCase("getMBL")) { return childEvaluateGetTopology(functionName, parameters); } else if (functionName.equalsIgnoreCase("getTokenVBL") || functionName.equalsIgnoreCase("getTokenHillVBL") || functionName.equalsIgnoreCase("getTokenPitVBL") + || functionName.equalsIgnoreCase("getTokenCoverVBL") || functionName.equalsIgnoreCase("getTokenMBL")) { return childEvaluateGetTokenTopology(resolver, functionName, parameters).toString(); } else if (functionName.equalsIgnoreCase("setTokenVBL") || functionName.equalsIgnoreCase("setTokenHillVBL") || functionName.equalsIgnoreCase("setTokenPitVBL") + || functionName.equalsIgnoreCase("setTokenCoverVBL") || functionName.equalsIgnoreCase("setTokenMBL")) { var results = childEvaluateSetTokenTopology(resolver, functionName, parameters); if (results >= 0) { @@ -184,6 +211,7 @@ public Object childEvaluate( } else if (functionName.equalsIgnoreCase("transferVBL") || functionName.equalsIgnoreCase("transferHillVBL") || functionName.equalsIgnoreCase("transferPitVBL") + || functionName.equalsIgnoreCase("transferCoverVBL") || functionName.equalsIgnoreCase("transferMBL")) { childEvaluateTransferTopology(resolver, functionName, parameters); } else { @@ -210,6 +238,7 @@ private void childEvaluateDrawEraseTopology(String functionName, List pa if (functionName.equalsIgnoreCase("eraseVBL") || functionName.equalsIgnoreCase("eraseHillVBL") || functionName.equalsIgnoreCase("erasePitVBL") + || functionName.equalsIgnoreCase("eraseCoverVBL") || functionName.equalsIgnoreCase("eraseMBL")) { erase = true; } @@ -244,6 +273,9 @@ private void childEvaluateDrawEraseTopology(String functionName, List pa } else if (functionName.equalsIgnoreCase("drawPitVBL") || functionName.equalsIgnoreCase("erasePitVBL")) { topologyType = Zone.TopologyType.PIT_VBL; + } else if (functionName.equalsIgnoreCase("drawCoverVBL") + || functionName.equalsIgnoreCase("eraseCoverVBL")) { + topologyType = Zone.TopologyType.COVER_VBL; } else { topologyType = Zone.TopologyType.MBL; } @@ -273,6 +305,8 @@ private Object childEvaluateGetTopology(String functionName, List parame topologyType = Zone.TopologyType.HILL_VBL; } else if (functionName.equalsIgnoreCase("getPitVBL")) { topologyType = Zone.TopologyType.PIT_VBL; + } else if (functionName.equalsIgnoreCase("getCoverVBL")) { + topologyType = Zone.TopologyType.COVER_VBL; } else { topologyType = Zone.TopologyType.MBL; } @@ -345,6 +379,8 @@ private JsonArray childEvaluateGetTokenTopology( topologyType = Zone.TopologyType.HILL_VBL; } else if (functionName.equalsIgnoreCase("getTokenPitVBL")) { topologyType = Zone.TopologyType.PIT_VBL; + } else if (functionName.equalsIgnoreCase("getTokenCoverVBL")) { + topologyType = Zone.TopologyType.COVER_VBL; } else { topologyType = Zone.TopologyType.MBL; } @@ -392,6 +428,8 @@ private int childEvaluateSetTokenTopology( topologyType = Zone.TopologyType.HILL_VBL; } else if (functionName.equalsIgnoreCase("setTokenPitVBL")) { topologyType = Zone.TopologyType.PIT_VBL; + } else if (functionName.equalsIgnoreCase("setTokenCoverVBL")) { + topologyType = Zone.TopologyType.COVER_VBL; } else { topologyType = Zone.TopologyType.MBL; } @@ -496,6 +534,8 @@ private void childEvaluateTransferTopology( topologyType = Zone.TopologyType.HILL_VBL; } else if (functionName.equalsIgnoreCase("transferPitVBL")) { topologyType = Zone.TopologyType.PIT_VBL; + } else if (functionName.equalsIgnoreCase("transferCoverVBL")) { + topologyType = Zone.TopologyType.COVER_VBL; } else { topologyType = Zone.TopologyType.MBL; } diff --git a/src/main/java/net/rptools/maptool/client/functions/getInfoFunction.java b/src/main/java/net/rptools/maptool/client/functions/getInfoFunction.java index c7201c1202..bae30dca41 100644 --- a/src/main/java/net/rptools/maptool/client/functions/getInfoFunction.java +++ b/src/main/java/net/rptools/maptool/client/functions/getInfoFunction.java @@ -273,7 +273,7 @@ private void getInfoOnTokensOfType( JsonObject libInfo = new JsonObject(); for (ZoneRenderer zr : MapTool.getFrame().getZoneRenderers()) { Zone zone = zr.getZone(); - for (Token token : zone.getTokens()) { + for (Token token : zone.getAllTokens()) { if (token.getName().toLowerCase().startsWith(prefix)) { if (token.getProperty(versionProperty) != null) { libInfo.addProperty(token.getName(), token.getProperty(versionProperty).toString()); diff --git a/src/main/java/net/rptools/maptool/client/functions/json/JSONMacroFunctions.java b/src/main/java/net/rptools/maptool/client/functions/json/JSONMacroFunctions.java index 99cb0ef8e2..1a3c5a9779 100644 --- a/src/main/java/net/rptools/maptool/client/functions/json/JSONMacroFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/json/JSONMacroFunctions.java @@ -18,6 +18,7 @@ import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.Option; +import com.jayway.jsonpath.PathNotFoundException; import com.jayway.jsonpath.spi.json.GsonJsonProvider; import com.jayway.jsonpath.spi.mapper.GsonMappingProvider; import java.math.BigDecimal; @@ -871,7 +872,12 @@ private JsonElement shallowCopy(JsonElement jsonElement) { * @return The resulting json data. */ private JsonElement jsonPathDelete(JsonElement json, String path) { - return JsonPath.using(jaywayConfig).parse(shallowCopy(json)).delete(path).json(); + try { + return JsonPath.using(jaywayConfig).parse(shallowCopy(json)).delete(path).json(); + } catch (PathNotFoundException ex) { + // Return original json, this is to preserve backwards compatability pre library update + return json; + } } /** @@ -886,7 +892,12 @@ private JsonElement jsonPathDelete(JsonElement json, String path) { private JsonElement jsonPathPut(JsonElement json, String path, String key, Object info) { Object value = asJsonElement(info); - return JsonPath.using(jaywayConfig).parse(shallowCopy(json)).put(path, key, value).json(); + try { + return JsonPath.using(jaywayConfig).parse(shallowCopy(json)).put(path, key, value).json(); + } catch (PathNotFoundException ex) { + // Return original json, this is to preserve backwards compatability pre library update + return json; + } } /** @@ -900,7 +911,12 @@ private JsonElement jsonPathPut(JsonElement json, String path, String key, Objec private JsonElement jsonPathSet(JsonElement json, String path, Object info) { Object value = asJsonElement(info); - return JsonPath.using(jaywayConfig).parse(shallowCopy(json)).set(path, value).json(); + try { + return JsonPath.using(jaywayConfig).parse(shallowCopy(json)).set(path, value).json(); + } catch (PathNotFoundException ex) { + // Return original json, this is to preserve backwards compatability pre library update + return json; + } } /** diff --git a/src/main/java/net/rptools/maptool/client/script/javascript/JSMacro.java b/src/main/java/net/rptools/maptool/client/script/javascript/JSMacro.java index 99c345605b..6bcf337adb 100644 --- a/src/main/java/net/rptools/maptool/client/script/javascript/JSMacro.java +++ b/src/main/java/net/rptools/maptool/client/script/javascript/JSMacro.java @@ -14,6 +14,7 @@ */ package net.rptools.maptool.client.script.javascript; +import com.google.gson.*; import java.util.*; import net.rptools.maptool.client.MapToolVariableResolver; import net.rptools.maptool.client.functions.*; @@ -25,6 +26,7 @@ import org.graalvm.polyglot.*; public class JSMacro extends AbstractFunction { + private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); private static JSMacro instance = new JSMacro(); private static HashMap macros = new HashMap<>(); @@ -60,7 +62,11 @@ public Object childEvaluate( if (ret instanceof Value val) { return MacroJavaScriptBridge.getInstance().ValueToMTScriptType(val, new ArrayList()); } - return MacroJavaScriptBridge.getInstance().HostObjectToMTScriptType(ret, new ArrayList()); + Object r = MacroJavaScriptBridge.getInstance().HostObjectToMTScriptType(ret, new ArrayList()); + if (r instanceof List || r instanceof AbstractMap) { + return gson.toJson(r); + } + return r; } return ""; } diff --git a/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPIClientInfo.java b/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPIClientInfo.java index b6ad50eec3..fde7291851 100644 --- a/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPIClientInfo.java +++ b/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPIClientInfo.java @@ -74,7 +74,7 @@ public Map libraryTokens() { Map libInfo = new HashMap<>(); for (ZoneRenderer zr : MapTool.getFrame().getZoneRenderers()) { Zone zone = zr.getZone(); - for (Token token : zone.getTokens()) { + for (Token token : zone.getAllTokens()) { if (token.getName().toLowerCase().startsWith("lib:")) { if (token.getProperty("libversion") != null) { libInfo.put(token.getName(), token.getProperty("libversion").toString()); diff --git a/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPIToken.java b/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPIToken.java index 8e575a0dc8..3045e415e9 100644 --- a/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPIToken.java +++ b/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPIToken.java @@ -15,12 +15,14 @@ package net.rptools.maptool.client.script.javascript.api; import java.util.Iterator; +import java.util.List; import java.util.Set; import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.script.javascript.*; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.GUID; import net.rptools.maptool.model.Token; +import net.rptools.maptool.model.Zone; import net.rptools.parser.ParserException; import org.graalvm.polyglot.HostAccess; @@ -33,6 +35,7 @@ public String serializeToString() { private final Token token; private Set names; private Iterator names_iter; + private Zone map; public JSAPIToken(Token token) { this.token = token; @@ -58,6 +61,7 @@ public void setNotes(String notes) { String playerId = MapTool.getPlayer().getName(); if (trusted || token.isOwner(playerId)) { token.setNotes(notes); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setNotes, notes); } } @@ -77,6 +81,7 @@ public void setName(String name) { String playerId = MapTool.getPlayer().getName(); if (trusted || token.isOwner(playerId)) { token.setName(name); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setName, name); } } @@ -130,6 +135,8 @@ public void setProperty(String name, Object value) { String playerId = MapTool.getPlayer().getName(); if (trusted || token.isOwner(playerId)) { this.token.setProperty(name, value.toString()); + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.setProperty, name, value.toString()); } } @@ -177,4 +184,86 @@ public void setY(int y) { public boolean isOwner(String playerID) { return this.token.isOwner(playerID); } + + @HostAccess.Export + public boolean isOnCurrentMap() { + Token findToken = + MapTool.getFrame().getCurrentZoneRenderer().getZone().getToken(new GUID(this.getId())); + return this.token == findToken; + } + + public void setMap(Zone m) { + this.map = m; + } + + @HostAccess.Export + public String getMapName() { + return this.map.getDisplayName(); + } + + @HostAccess.Export + public boolean getState(String stateName) { + Object currentState = this.token.getState(stateName); + return (currentState instanceof Boolean && (Boolean) currentState); + } + + @HostAccess.Export + public void setState(String stateName, boolean aValue) { + boolean trusted = JSScriptEngine.inTrustedContext(); + String playerId = MapTool.getPlayer().getName(); + if (trusted || token.isOwner(playerId)) { + this.token.setState(stateName, aValue); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setState, stateName, aValue); + } + } + + @HostAccess.Export + public void setAllStates(boolean aValue) { + boolean trusted = JSScriptEngine.inTrustedContext(); + String playerId = MapTool.getPlayer().getName(); + if (trusted || token.isOwner(playerId)) { + this.token.setAllStates(aValue); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setAllStates, aValue); + } + } + + @HostAccess.Export + public List getActiveStates() { + return this.token.getSetStates(); + } + + @HostAccess.Export + public boolean isPC() { + return this.token.getType() == Token.Type.PC; + } + + @HostAccess.Export + public void setPC() { + boolean trusted = JSScriptEngine.inTrustedContext(); + String playerId = MapTool.getPlayer().getName(); + if (trusted || token.isOwner(playerId)) { + this.token.setType(Token.Type.PC); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setPC); + } + } + + @HostAccess.Export + public boolean isNPC() { + return this.token.getType() == Token.Type.NPC; + } + + @HostAccess.Export + public void setNPC() { + boolean trusted = JSScriptEngine.inTrustedContext(); + String playerId = MapTool.getPlayer().getName(); + if (trusted || token.isOwner(playerId)) { + this.token.setType(Token.Type.NPC); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setNPC); + } + } + + @HostAccess.Export + public String getType() { + return this.token.getType().name(); + } } diff --git a/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPITokens.java b/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPITokens.java index e30967cb3b..0e07bfe3d5 100644 --- a/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPITokens.java +++ b/src/main/java/net/rptools/maptool/client/script/javascript/api/JSAPITokens.java @@ -19,6 +19,7 @@ import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.script.javascript.*; import net.rptools.maptool.client.ui.zone.ZoneRenderer; +import net.rptools.maptool.model.GUID; import net.rptools.maptool.model.Token; import org.graalvm.polyglot.HostAccess; @@ -44,7 +45,7 @@ public List getMapTokens(ZoneRenderer zr) { boolean trusted = JSScriptEngine.inTrustedContext(); String playerId = MapTool.getPlayer().getName(); zr.getZone() - .getTokens() + .getAllTokens() .forEach( (t -> { if (trusted || t.isOwner(playerId)) { @@ -91,10 +92,40 @@ public JSAPIToken getSelected() { @HostAccess.Export public JSAPIToken getTokenByID(String uuid) { - JSAPIToken token = new JSAPIToken(uuid); - if (JSScriptEngine.inTrustedContext() || token.isOwner(MapTool.getPlayer().getName())) { + JSAPIToken token = null; + Token findToken = + MapTool.getFrame().getCurrentZoneRenderer().getZone().getToken(new GUID(uuid)); + if (findToken != null) { + token = new JSAPIToken(findToken); + token.setMap(MapTool.getFrame().getCurrentZoneRenderer().getZone()); + } else { + List zrenderers = MapTool.getFrame().getZoneRenderers(); + for (ZoneRenderer zr : zrenderers) { + findToken = zr.getZone().resolveToken(uuid); + if (findToken != null) { + token = new JSAPIToken(findToken); + token.setMap(zr.getZone()); + break; + } + } + } + if (token != null + && (JSScriptEngine.inTrustedContext() || token.isOwner(MapTool.getPlayer().getName()))) { return token; } return null; } + + @HostAccess.Export + public JSAPIToken getMapTokenByID(String uuid) { + JSAPIToken token = null; + Token findToken = + MapTool.getFrame().getCurrentZoneRenderer().getZone().getToken(new GUID(uuid)); + if (findToken != null + && (JSScriptEngine.inTrustedContext() || token.isOwner(MapTool.getPlayer().getName()))) { + token = new JSAPIToken(findToken); + token.setMap(MapTool.getFrame().getCurrentZoneRenderer().getZone()); + } + return token; + } } diff --git a/src/main/java/net/rptools/maptool/client/swing/TopologyModeSelectionPanel.java b/src/main/java/net/rptools/maptool/client/swing/TopologyModeSelectionPanel.java index 70bfcd1abf..23198c9f3d 100644 --- a/src/main/java/net/rptools/maptool/client/swing/TopologyModeSelectionPanel.java +++ b/src/main/java/net/rptools/maptool/client/swing/TopologyModeSelectionPanel.java @@ -68,6 +68,12 @@ public TopologyModeSelectionPanel() { Icons.TOOLBAR_TOPOLOGY_TYPE_PIT_OFF, "tools.topology_mode_selection.pit_vbl.tooltip", initiallySelectedTypes); + createAndAddModeButton( + Zone.TopologyType.COVER_VBL, + Icons.TOOLBAR_TOPOLOGY_TYPE_COVER_ON, + Icons.TOOLBAR_TOPOLOGY_TYPE_COVER_OFF, + "tools.topology_mode_selection.cover_vbl.tooltip", + initiallySelectedTypes); createAndAddModeButton( Zone.TopologyType.MBL, Icons.TOOLBAR_TOPOLOGY_TYPE_MBL_ON, diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/AbstractDrawingTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/AbstractDrawingTool.java index 1dd7d2d847..c4f886c595 100644 --- a/src/main/java/net/rptools/maptool/client/tool/drawing/AbstractDrawingTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/drawing/AbstractDrawingTool.java @@ -279,6 +279,8 @@ protected void paintTopologyOverlay(Graphics2D g, Drawable drawable, int penMode g2.fill(getTokenTopology(Zone.TopologyType.HILL_VBL)); g2.setColor(AppStyle.tokenPitVblColor); g2.fill(getTokenTopology(Zone.TopologyType.PIT_VBL)); + g2.setColor(AppStyle.tokenCoverVblColor); + g2.fill(getTokenTopology(Zone.TopologyType.COVER_VBL)); g2.setColor(AppStyle.topologyTerrainColor); g2.fill(zone.getTopology(Zone.TopologyType.MBL)); @@ -292,6 +294,9 @@ protected void paintTopologyOverlay(Graphics2D g, Drawable drawable, int penMode g2.setColor(AppStyle.pitVblColor); g2.fill(zone.getTopology(Zone.TopologyType.PIT_VBL)); + g2.setColor(AppStyle.coverVblColor); + g2.fill(zone.getTopology(Zone.TopologyType.COVER_VBL)); + g2.dispose(); } diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/DiamondExposeTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/DiamondExposeTool.java index 72b90c3de3..da159270a2 100644 --- a/src/main/java/net/rptools/maptool/client/tool/drawing/DiamondExposeTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/drawing/DiamondExposeTool.java @@ -83,6 +83,6 @@ protected void completeDrawable(GUID zoneId, Pen pen, Drawable drawable) { @Override public String getTooltip() { - return "tool.diamondexpose.tooltip"; + return "tool.isorectangleexpose.tooltip"; } } diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/DiamondTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/DiamondTool.java index 503eaf5884..fc91f60cee 100644 --- a/src/main/java/net/rptools/maptool/client/tool/drawing/DiamondTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/drawing/DiamondTool.java @@ -42,7 +42,7 @@ public String getInstructions() { @Override public String getTooltip() { - return "tool.diamond.tooltip"; + return "tool.isorectangle.tooltip"; } @Override diff --git a/src/main/java/net/rptools/maptool/client/tool/gridtool/GridTool.java b/src/main/java/net/rptools/maptool/client/tool/gridtool/GridTool.java index a356040d73..240c47a0cb 100644 --- a/src/main/java/net/rptools/maptool/client/tool/gridtool/GridTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/gridtool/GridTool.java @@ -97,7 +97,7 @@ public GridTool() { resetTool(); // Lee: just to make the light sources snap to their owners after the tool is closed Zone z = MapTool.getFrame().getCurrentZoneRenderer().getZone(); - z.putTokens(z.getTokens()); + z.putTokens(z.getAllTokens()); }); zoomSlider = (JSlider) controlPanel.getComponent("zoomSlider"); zoomSlider.setMinimum(0); diff --git a/src/main/java/net/rptools/maptool/client/ui/AbstractTokenPopupMenu.java b/src/main/java/net/rptools/maptool/client/ui/AbstractTokenPopupMenu.java index 8cab678f65..05376b49da 100644 --- a/src/main/java/net/rptools/maptool/client/ui/AbstractTokenPopupMenu.java +++ b/src/main/java/net/rptools/maptool/client/ui/AbstractTokenPopupMenu.java @@ -22,7 +22,8 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -143,31 +144,46 @@ protected JMenu createLightSourceMenu() { } menu.addSeparator(); } + + // Add unique light sources for the token. + { + JMenu subMenu = createLightCategoryMenu("Unique", tokenUnderMouse.getUniqueLightSources()); + if (subMenu.getItemCount() != 0) { + menu.add(subMenu); + menu.addSeparator(); + } + } + for (Entry> entry : MapTool.getCampaign().getLightSourcesMap().entrySet()) { - JMenu subMenu = new JMenu(entry.getKey()); - - List lightSources = new ArrayList(entry.getValue().values()); - LightSource[] lightSourceList = new LightSource[entry.getValue().size()]; - lightSources.toArray(lightSourceList); - Arrays.sort(lightSourceList); - LIGHTSOURCES: - for (LightSource lightSource : lightSourceList) { - for (Light light : lightSource.getLightList()) { - if (light.isGM() && !MapTool.getPlayer().isGM()) { - continue LIGHTSOURCES; - } - } + JMenu subMenu = createLightCategoryMenu(entry.getKey(), entry.getValue().values()); + if (subMenu.getItemCount() != 0) { + menu.add(subMenu); + } + } + return menu; + } + + protected JMenu createLightCategoryMenu(String categoryName, Collection sources) { + JMenu subMenu = new JMenu(categoryName); + + List lightSources = new ArrayList<>(sources); + Collections.sort(lightSources); + + for (LightSource lightSource : lightSources) { + // Don't include light sources that don't have lights visible to the player. Note that the + // player must be an owner to use the popup, so don't bother checking `::isOwner()`. + boolean include = + MapTool.getPlayer().isGM() || !lightSource.getLightList().stream().allMatch(Light::isGM); + if (include) { JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(new ToggleLightSourceAction(lightSource)); menuItem.setSelected(tokenUnderMouse.hasLightSource(lightSource)); subMenu.add(menuItem); } - if (subMenu.getItemCount() != 0) { - menu.add(subMenu); - } } - return menu; + + return subMenu; } protected Token getTokenUnderMouse() { @@ -466,9 +482,9 @@ public void actionPerformed(ActionEvent e) { continue; } if (token.hasLightSource(lightSource)) { - token.removeLightSource(lightSource); + token.removeLightSource(lightSource.getId()); } else { - token.addLightSource(lightSource); + token.addLightSource(lightSource.getId()); } MapTool.serverCommand().putToken(renderer.getZone().getId(), token); diff --git a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java index 890669fdd9..f143c3ea49 100644 --- a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java @@ -24,6 +24,7 @@ import java.io.LineNumberReader; import java.io.StringReader; import java.text.ParseException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -203,7 +204,6 @@ private void accept() { .forEach( (o, n) -> { campaign.renameTokenTypes(o, n); - System.out.println("Renaming " + o + " to " + n); }); MapTool.getFrame().hideGlassPane(); copyUIToCampaign(); @@ -489,7 +489,8 @@ private void commitSightMap(final String text) { } // Parse Details double magnifier = 1; - LightSource personalLight = null; + // If null, no personal light has been defined. + List personalLightLights = null; String[] args = value.split("\\s+"); ShapeType shape = ShapeType.CIRCLE; @@ -544,11 +545,10 @@ private void commitSightMap(final String text) { } } - if (personalLight == null) { - personalLight = new LightSource(); - personalLight.setType(LightSource.Type.NORMAL); + if (personalLightLights == null) { + personalLightLights = new ArrayList<>(); } - personalLight.add( + personalLightLights.add( new Light( shape, 0, @@ -560,7 +560,6 @@ private void commitSightMap(final String text) { perRangeLumens, false, false)); - personalLight.setScaleWithToken(scaleWithToken); } else { throw new ParseException( String.format("Unrecognized personal light syntax: %s", arg), 0); @@ -589,6 +588,11 @@ private void commitSightMap(final String text) { errlog.add(I18N.getText(errmsg, reader.getLineNumber(), toBeParsed)); } } + + LightSource personalLight = + personalLightLights == null + ? null + : LightSource.createPersonal(scaleWithToken, personalLightLights); SightType sight = new SightType(label, magnifier, personalLight, shape, arc, scaleWithToken); sight.setDistance(range); @@ -671,14 +675,22 @@ private Map> commitLightMap( continue; } + // region Light source properties. String name = line.substring(0, split).trim(); - LightSource lightSource = new LightSource(name); + GUID id = new GUID(); + LightSource.Type type = LightSource.Type.NORMAL; + boolean scaleWithToken = false; + List lights = new ArrayList<>(); + // endregion + // region Individual light properties ShapeType shape = ShapeType.CIRCLE; // TODO: Make a preference for default shape double arc = 0; double offset = 0; boolean gmOnly = false; boolean owner = false; String distance = null; + // endregion + for (String arg : line.substring(split + 1).split("\\s+")) { arg = arg.trim(); if (arg.length() == 0) { @@ -696,7 +708,7 @@ private Map> commitLightMap( } // Scale with token designation if (arg.equalsIgnoreCase("SCALE")) { - lightSource.setScaleWithToken(true); + scaleWithToken = true; continue; } // Shape designation ? @@ -709,8 +721,7 @@ private Map> commitLightMap( // Type designation ? try { - LightSource.Type type = LightSource.Type.valueOf(arg.toUpperCase()); - lightSource.setType(type); + type = LightSource.Type.valueOf(arg.toUpperCase()); continue; } catch (IllegalArgumentException iae) { // Expected when not defining a shape @@ -771,7 +782,7 @@ private Map> commitLightMap( } } - boolean isAura = lightSource.getType() == LightSource.Type.AURA; + boolean isAura = type == LightSource.Type.AURA; if (!isAura && (gmOnly || owner)) { errlog.add(I18N.getText("msg.error.mtprops.light.gmOrOwner", reader.getLineNumber())); gmOnly = false; @@ -789,24 +800,26 @@ private Map> commitLightMap( perRangeLumens, gmOnly, owner); - lightSource.add(t); + lights.add(t); } catch (ParseException pe) { errlog.add( I18N.getText("msg.error.mtprops.light.distance", reader.getLineNumber(), distance)); } } - // Keep ID the same if modifying existing light - // TODO FJE Why? Is there some benefit to doing so? Changes to light sources require the map - // to be re-rendered anyway, don't they? + // Keep ID the same if modifying existing light. This avoids tokens losing their lights when + // the light definition is modified. if (originalLightSourcesMap.containsKey(currentGroupName)) { for (LightSource ls : originalLightSourcesMap.get(currentGroupName).values()) { if (ls.getName().equalsIgnoreCase(name)) { - lightSource.setId(ls.getId()); + assert ls.getId() != null; + id = ls.getId(); break; } } } - lightSourceMap.put(lightSource.getId(), lightSource); + + final var source = LightSource.createRegular(name, id, type, scaleWithToken, lights); + lightSourceMap.put(source.getId(), source); } // Last group if (currentGroupName != null) { diff --git a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenPropertiesManagementPanel.java b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenPropertiesManagementPanel.java index e3a873ae52..c2e744b88b 100644 --- a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenPropertiesManagementPanel.java +++ b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenPropertiesManagementPanel.java @@ -182,7 +182,6 @@ public void initTypeDeleteButton() { var type = (String) getTokenTypeList().getSelectedValue(); if (type != null) { JPanel renameToPanel = new JPanel(); - // renameToPanel.setLayout(new BoxLayout(renameToPanel, BoxLayout.PAGE_AXIS)); JComboBox types = new JComboBox<>( tokenTypeMap.keySet().stream() @@ -332,6 +331,7 @@ public void initTokenTypeName() { var oldName = (String) ttList.getSelectedValue(); var newName = field.getText(); tokenTypeMap.put(newName, tokenTypeMap.remove(oldName)); + tokenTypeStatSheetMap.put(newName, tokenTypeStatSheetMap.remove(oldName)); ttList.setSelectedValue(newName, true); updateExistingTokenTypes(oldName, newName); } diff --git a/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialog.java b/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialog.java index 87607ebdc4..fcff01d94f 100644 --- a/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialog.java @@ -79,6 +79,7 @@ public class PreferencesDialog extends JDialog { private final JCheckBox tokensStartSnapToGridCheckBox; private final JCheckBox tokensSnapWhileDraggingCheckBox; private final JCheckBox hideMousePointerWhileDraggingCheckBox; + private final JCheckBox hideTokenStackIndicatorCheckBox; private final JCheckBox newMapsVisibleCheckBox; private final JCheckBox newTokensVisibleCheckBox; private final JCheckBox tokensStartFreeSizeCheckBox; @@ -323,6 +324,7 @@ public PreferencesDialog() { tokensStartSnapToGridCheckBox = panel.getCheckBox("tokensStartSnapToGridCheckBox"); tokensSnapWhileDraggingCheckBox = panel.getCheckBox("tokensSnapWhileDragging"); hideMousePointerWhileDraggingCheckBox = panel.getCheckBox("hideMousePointerWhileDragging"); + hideTokenStackIndicatorCheckBox = panel.getCheckBox("hideTokenStackIndicator"); newMapsVisibleCheckBox = panel.getCheckBox("newMapsVisibleCheckBox"); newTokensVisibleCheckBox = panel.getCheckBox("newTokensVisibleCheckBox"); stampsStartFreeSizeCheckBox = panel.getCheckBox("stampsStartFreeSize"); @@ -390,6 +392,9 @@ public PreferencesDialog() { fileSyncPath = panel.getTextField("fileSyncPath"); fileSyncPathButton = (JButton) panel.getButton("fileSyncPathButton"); + final var installDirTextField = (JTextField) panel.getComponent("InstallDirTextField"); + installDirTextField.setText(AppUtil.getInstallDirectory().toString()); + publicKeyTextArea = (JTextArea) panel.getTextComponent("publicKeyTextArea"); regeneratePublicKey = (JButton) panel.getButton("regeneratePublicKey"); copyPublicKey = (JButton) panel.getButton("copyKey"); @@ -599,6 +604,10 @@ public void focusLost(FocusEvent e) { @Override protected void storeNumericValue(Integer value) { AppPreferences.setFrameRateCap(value); + + for (final var renderer : MapTool.getFrame().getZoneRenderers()) { + renderer.setFrameRateCap(value); + } } @Override @@ -654,6 +663,10 @@ public void focusLost(FocusEvent e) { e -> AppPreferences.setHideMousePointerWhileDragging( hideMousePointerWhileDraggingCheckBox.isSelected())); + hideTokenStackIndicatorCheckBox.addActionListener( + e -> + AppPreferences.setHideTokenStackIndicator( + hideTokenStackIndicatorCheckBox.isSelected())); newMapsVisibleCheckBox.addActionListener( e -> AppPreferences.setNewMapsVisible(newMapsVisibleCheckBox.isSelected())); newTokensVisibleCheckBox.addActionListener( @@ -1131,6 +1144,7 @@ private void setInitialState() { tokensSnapWhileDraggingCheckBox.setSelected(AppPreferences.getTokensSnapWhileDragging()); hideMousePointerWhileDraggingCheckBox.setSelected( AppPreferences.getHideMousePointerWhileDragging()); + hideTokenStackIndicatorCheckBox.setSelected(AppPreferences.getHideTokenStackIndicator()); newMapsVisibleCheckBox.setSelected(AppPreferences.getNewMapsVisible()); newTokensVisibleCheckBox.setSelected(AppPreferences.getNewTokensVisible()); stampsStartFreeSizeCheckBox.setSelected(AppPreferences.getObjectsStartFreesize()); diff --git a/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialogView.form b/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialogView.form index c31facaba3..fef0e21d2e 100644 --- a/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialogView.form +++ b/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialogView.form @@ -3,7 +3,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -323,14 +323,33 @@ + - + + + + + + + + + + + + + + + + + + + @@ -966,11 +985,11 @@ - + - + @@ -981,7 +1000,7 @@ - + @@ -1050,7 +1069,7 @@ - + @@ -1140,7 +1159,7 @@ - + @@ -1193,7 +1212,7 @@ - + @@ -1226,7 +1245,7 @@ - + @@ -1259,7 +1278,7 @@ - + @@ -1288,16 +1307,31 @@ - - - - - - + + - + - + + + + + + + + + + + + + + + + + + + + @@ -2004,7 +2038,7 @@ - + @@ -2017,7 +2051,7 @@ - + @@ -2103,7 +2137,7 @@ - + @@ -2171,7 +2205,7 @@ - + @@ -2207,7 +2241,7 @@ - + @@ -2243,7 +2277,7 @@ - + @@ -2265,12 +2299,12 @@ - + - + @@ -2304,7 +2338,7 @@ - + @@ -2315,7 +2349,7 @@ - + diff --git a/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialogView.java b/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialogView.java index 5aceef4a80..9939a1b641 100644 --- a/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialogView.java +++ b/src/main/java/net/rptools/maptool/client/ui/preferencesdialog/PreferencesDialogView.java @@ -14,7 +14,6 @@ */ package net.rptools.maptool.client.ui.preferencesdialog; -import java.awt.*; import javax.swing.*; public class PreferencesDialogView { diff --git a/src/main/java/net/rptools/maptool/client/ui/syntax/MapToolScriptSyntax.java b/src/main/java/net/rptools/maptool/client/ui/syntax/MapToolScriptSyntax.java index 20ef6a676a..a04ab91ab0 100644 --- a/src/main/java/net/rptools/maptool/client/ui/syntax/MapToolScriptSyntax.java +++ b/src/main/java/net/rptools/maptool/client/ui/syntax/MapToolScriptSyntax.java @@ -22,6 +22,7 @@ import net.rptools.maptool.client.functions.DefinesSpecialVariables; import net.rptools.maptool.client.functions.TokenMoveFunctions; import net.rptools.maptool.client.functions.UserDefinedMacroFunctions; +import net.rptools.maptool.events.ZoneLoadedListener; import net.rptools.maptool.model.InitiativeList; import net.rptools.maptool.model.TokenProperty; import net.rptools.parser.function.Function; @@ -97,9 +98,9 @@ public class MapToolScriptSyntax extends MapToolScriptTokenMaker { static String[] RESERVED_WORDS_2 = { "onCampaignLoad", - "onChangeMap", "onChangeSelection", "onMouseOverEvent", + ZoneLoadedListener.ON_CHANGE_MAP_CALLBACK, TokenMoveFunctions.ON_MULTIPLE_TOKENS_MOVED_COMPLETE_CALLBACK, TokenMoveFunctions.ON_TOKEN_MOVE_COMPLETE_CALLBACK, InitiativeList.ON_INITIATIVE_CHANGE_VETOABLE_MACRO_CALLBACK, diff --git a/src/main/java/net/rptools/maptool/client/ui/theme/Icons.java b/src/main/java/net/rptools/maptool/client/ui/theme/Icons.java index b4fe62ae63..dc5a8a1282 100644 --- a/src/main/java/net/rptools/maptool/client/ui/theme/Icons.java +++ b/src/main/java/net/rptools/maptool/client/ui/theme/Icons.java @@ -173,6 +173,8 @@ public enum Icons { TOOLBAR_TOPOLOGY_TYPE_MBL_ON, TOOLBAR_TOPOLOGY_TYPE_PIT_OFF, TOOLBAR_TOPOLOGY_TYPE_PIT_ON, + TOOLBAR_TOPOLOGY_TYPE_COVER_OFF, + TOOLBAR_TOPOLOGY_TYPE_COVER_ON, TOOLBAR_TOPOLOGY_TYPE_VBL_OFF, TOOLBAR_TOPOLOGY_TYPE_VBL_ON, TOOLBAR_VOLUME_OFF, diff --git a/src/main/java/net/rptools/maptool/client/ui/theme/RessourceManager.java b/src/main/java/net/rptools/maptool/client/ui/theme/RessourceManager.java index 4204fa5583..4008dbcc51 100644 --- a/src/main/java/net/rptools/maptool/client/ui/theme/RessourceManager.java +++ b/src/main/java/net/rptools/maptool/client/ui/theme/RessourceManager.java @@ -201,6 +201,8 @@ public class RessourceManager { put(Icons.TOOLBAR_TOPOLOGY_TYPE_MBL_ON, IMAGE_DIR + "tool/mbl-only.png"); put(Icons.TOOLBAR_TOPOLOGY_TYPE_PIT_OFF, IMAGE_DIR + "tool/pit-vbl-only-off.png"); put(Icons.TOOLBAR_TOPOLOGY_TYPE_PIT_ON, IMAGE_DIR + "tool/pit-vbl-only.png"); + put(Icons.TOOLBAR_TOPOLOGY_TYPE_COVER_OFF, IMAGE_DIR + "tool/cover-vbl-only-off.png"); + put(Icons.TOOLBAR_TOPOLOGY_TYPE_COVER_ON, IMAGE_DIR + "tool/cover-vbl-only.png"); put(Icons.TOOLBAR_TOPOLOGY_TYPE_VBL_OFF, IMAGE_DIR + "tool/wall-vbl-only-off.png"); put(Icons.TOOLBAR_TOPOLOGY_TYPE_VBL_ON, IMAGE_DIR + "tool/wall-vbl-only.png"); put(Icons.TOOLBAR_VOLUME_OFF, IMAGE_DIR + "audio/mute.png"); diff --git a/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java b/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java index a3c47793ba..d2bc07cdae 100644 --- a/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java @@ -412,6 +412,12 @@ public void bind(final Token token) { .setSelectedIcon(RessourceManager.getBigIcon(Icons.TOOLBAR_TOPOLOGY_TYPE_PIT_ON)); getPitVblToggle().setIcon(RessourceManager.getBigIcon(Icons.TOOLBAR_TOPOLOGY_TYPE_PIT_ON)); + getCoverVblToggle() + .setSelected(getTokenTopologyPanel().isTopologyTypeSelected(Zone.TopologyType.COVER_VBL)); + getCoverVblToggle() + .setSelectedIcon(RessourceManager.getBigIcon(Icons.TOOLBAR_TOPOLOGY_TYPE_COVER_ON)); + getCoverVblToggle().setIcon(RessourceManager.getBigIcon(Icons.TOOLBAR_TOPOLOGY_TYPE_COVER_ON)); + getMblToggle() .setSelected(getTokenTopologyPanel().isTopologyTypeSelected(Zone.TopologyType.MBL)); getMblToggle().setSelectedIcon(RessourceManager.getBigIcon(Icons.TOOLBAR_TOPOLOGY_TYPE_MBL_ON)); @@ -1082,6 +1088,10 @@ public JToggleButton getPitVblToggle() { return (JToggleButton) getComponent("pitVblToggle"); } + public JToggleButton getCoverVblToggle() { + return (JToggleButton) getComponent("coverVblToggle"); + } + public JToggleButton getMblToggle() { return (JToggleButton) getComponent("mblToggle"); } @@ -1285,6 +1295,13 @@ public void initTokenTopologyPanel() { getTokenTopologyPanel() .setTopologyTypeSelected( Zone.TopologyType.PIT_VBL, ((AbstractButton) e.getSource()).isSelected())); + getCoverVblToggle() + .addActionListener( + e -> + getTokenTopologyPanel() + .setTopologyTypeSelected( + Zone.TopologyType.COVER_VBL, + ((AbstractButton) e.getSource()).isSelected())); getMblToggle() .addActionListener( e -> diff --git a/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenPropertiesDialog.form b/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenPropertiesDialog.form index a3af58f493..d4a0110eb1 100644 --- a/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenPropertiesDialog.form +++ b/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenPropertiesDialog.form @@ -126,7 +126,7 @@ - + @@ -136,7 +136,7 @@ - + @@ -174,6 +174,16 @@ + + + + + + + + + + diff --git a/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenTopologyPanel.java b/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenTopologyPanel.java index 4c4ee64f53..53d751c405 100644 --- a/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenTopologyPanel.java +++ b/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenTopologyPanel.java @@ -304,6 +304,11 @@ protected void paintComponent(Graphics g) { g2d.fill( atArea.createTransformedShape( tokenTopologiesOptimized.getOrDefault(Zone.TopologyType.PIT_VBL, new Area()))); + + g2d.setColor(getTopologyColor(AppStyle.tokenCoverVblColor)); + g2d.fill( + atArea.createTransformedShape( + tokenTopologiesOptimized.getOrDefault(Zone.TopologyType.COVER_VBL, new Area()))); } // Draw the number of points generated diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/FogUtil.java b/src/main/java/net/rptools/maptool/client/ui/zone/FogUtil.java index ca284f26ba..62e3de9dbc 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/FogUtil.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/FogUtil.java @@ -76,7 +76,12 @@ public class FogUtil { * @return the visible area. */ public static @Nonnull Area calculateVisibility( - Point origin, Area vision, AreaTree topology, AreaTree hillVbl, AreaTree pitVbl) { + Point origin, + Area vision, + AreaTree topology, + AreaTree hillVbl, + AreaTree pitVbl, + AreaTree coverVbl) { // We could use the vision envelope instead, but vision geometry tends to be pretty simple. final var visionGeometry = PreparedGeometryFactory.prepare(GeometryUtil.toJts(vision)); @@ -93,6 +98,7 @@ public class FogUtil { topologyConsumers.add(acc -> acc.addWallBlocking(topology)); topologyConsumers.add(acc -> acc.addHillBlocking(hillVbl)); topologyConsumers.add(acc -> acc.addPitBlocking(pitVbl)); + topologyConsumers.add(acc -> acc.addCoverBlocking(coverVbl)); for (final var consumer : topologyConsumers) { final var accumulator = new VisionBlockingAccumulator(geometryFactory, origin, visionGeometry); diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/LightSourceIconOverlay.java b/src/main/java/net/rptools/maptool/client/ui/zone/LightSourceIconOverlay.java index 6561151fcd..c1aed770f3 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/LightSourceIconOverlay.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/LightSourceIconOverlay.java @@ -34,8 +34,7 @@ public void paintOverlay(ZoneRenderer renderer, Graphics2D g) { if (token.hasLightSources()) { boolean foundNormalLight = false; for (AttachedLightSource attachedLightSource : token.getLightSources()) { - LightSource lightSource = - MapTool.getCampaign().getLightSource(attachedLightSource.getLightSourceId()); + LightSource lightSource = attachedLightSource.resolve(token, MapTool.getCampaign()); if (lightSource != null && lightSource.getType() == LightSource.Type.NORMAL) { foundNormalLight = true; break; diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/RenderPathWorker.java b/src/main/java/net/rptools/maptool/client/ui/zone/RenderPathWorker.java index 8598e9f5dd..b936332072 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/RenderPathWorker.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/RenderPathWorker.java @@ -32,6 +32,7 @@ public class RenderPathWorker extends SwingWorker { private final Area tokenWallVbl; private final Area tokenHillVbl; private final Area tokenPitVbl; + private final Area tokenCoverVbl; private final Area tokenMbl; public RenderPathWorker( @@ -42,6 +43,7 @@ public RenderPathWorker( Area tokenWallVbl, Area tokenHillVbl, Area tokenPitVbl, + Area tokenCoverVbl, Area tokenMbl, ZoneRenderer zoneRenderer) { this.walker = walker; @@ -52,6 +54,7 @@ public RenderPathWorker( this.tokenWallVbl = tokenWallVbl; this.tokenHillVbl = tokenHillVbl; this.tokenPitVbl = tokenPitVbl; + this.tokenCoverVbl = tokenCoverVbl; this.tokenMbl = tokenMbl; } @@ -64,6 +67,7 @@ protected Void doInBackground() { tokenWallVbl, tokenHillVbl, tokenPitVbl, + tokenCoverVbl, tokenMbl); return null; } diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneRenderer.java b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneRenderer.java index 12e1b63756..1116026600 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneRenderer.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneRenderer.java @@ -192,9 +192,7 @@ public ZoneRenderer(Zone zone) { } this.zone = zone; - // The interval, in milliseconds, during which calls to repaint() will be debounced. - int repaintDebounceInterval = 1000 / AppPreferences.getFrameRateCap(); - repaintDebouncer = new DebounceExecutor(repaintDebounceInterval, this::repaint); + repaintDebouncer = new DebounceExecutor(1000 / AppPreferences.getFrameRateCap(), this::repaint); setFocusable(true); setZoneScale(new Scale()); @@ -239,6 +237,10 @@ public void mouseMoved(MouseEvent e) { new MapToolEventBus().getMainEventBus().register(this); } + public void setFrameRateCap(int cap) { + this.repaintDebouncer.setDelay(1000 / cap); + } + public void setAutoResizeStamp(boolean value) { this.autoResizeStamp = value; } @@ -3710,7 +3712,9 @@ protected void renderTokens( // Stacks if (!tokenList.isEmpty() && !tokenList.get(0).isStamp()) { // TODO: find a cleaner way to indicate token layer - if (tokenStackMap != null) { // FIXME Needed to prevent NPE but how can it be null? + boolean hideTSI = AppPreferences.getHideTokenStackIndicator(); + if (tokenStackMap != null + && !hideTSI) { // FIXME Needed to prevent NPE but how can it be null? for (Token token : tokenStackMap.keySet()) { Area bounds = getTokenBounds(token); if (bounds == null) { @@ -4270,6 +4274,7 @@ public void setOffset(int x, int y) { token.getTransformedTopology(Zone.TopologyType.WALL_VBL), token.getTransformedTopology(Zone.TopologyType.HILL_VBL), token.getTransformedTopology(Zone.TopologyType.PIT_VBL), + token.getTransformedTopology(Zone.TopologyType.COVER_VBL), token.getTransformedTopology(Zone.TopologyType.MBL), ZoneRenderer.this); renderPathThreadPool.execute(renderPathTask); diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java index 8b0bf21273..e1ebef3454 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java @@ -295,7 +295,7 @@ private List calculateLitAreas(Token lightSourceToken, double for (final var attachedLightSource : lightSourceToken.getLightSources()) { LightSource lightSource = - MapTool.getCampaign().getLightSource(attachedLightSource.getLightSourceId()); + attachedLightSource.resolve(lightSourceToken, MapTool.getCampaign()); if (lightSource == null) { continue; } @@ -332,7 +332,8 @@ private List calculateLitAreaForLightSource( lightSourceArea, getTopologyTree(Zone.TopologyType.WALL_VBL), getTopologyTree(Zone.TopologyType.HILL_VBL), - getTopologyTree(Zone.TopologyType.PIT_VBL)); + getTopologyTree(Zone.TopologyType.PIT_VBL), + getTopologyTree(Zone.TopologyType.COVER_VBL)); if (lightSourceVisibleArea.isEmpty()) { // Nothing illuminated for this source. return Collections.emptyList(); @@ -590,7 +591,8 @@ private Area getTokenVisibleArea(@Nonnull Token token) { visibleArea, getTopologyTree(Zone.TopologyType.WALL_VBL), getTopologyTree(Zone.TopologyType.HILL_VBL), - getTopologyTree(Zone.TopologyType.PIT_VBL)); + getTopologyTree(Zone.TopologyType.PIT_VBL), + getTopologyTree(Zone.TopologyType.COVER_VBL)); tokenVisibleAreaCache.put(token.getId(), tokenVisibleArea); } @@ -651,7 +653,7 @@ public List getDrawableAuras() { Point p = FogUtil.calculateVisionCenter(token, zone); for (AttachedLightSource als : token.getLightSources()) { - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(token, MapTool.getCampaign()); if (lightSource == null) { continue; } @@ -668,7 +670,8 @@ public List getDrawableAuras() { lightSourceArea, getTopologyTree(Zone.TopologyType.WALL_VBL), getTopologyTree(Zone.TopologyType.HILL_VBL), - getTopologyTree(Zone.TopologyType.PIT_VBL)); + getTopologyTree(Zone.TopologyType.PIT_VBL), + getTopologyTree(Zone.TopologyType.COVER_VBL)); // This needs to be cached somehow for (Light light : lightSource.getLightList()) { @@ -718,7 +721,7 @@ private void findLightSources() { if (token.hasLightSources() && token.isVisible()) { if (!token.isVisibleOnlyToOwner() || AppUtil.playerOwns(token)) { for (AttachedLightSource als : token.getLightSources()) { - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(token, MapTool.getCampaign()); if (lightSource == null) { continue; } @@ -908,7 +911,7 @@ private void onTokensRemoved(TokensRemoved event) { for (Token token : event.tokens()) { if (token.hasAnyTopology()) tokenChangedTopology = true; for (AttachedLightSource als : token.getLightSources()) { - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(token, MapTool.getCampaign()); if (lightSource == null) { continue; } @@ -963,7 +966,7 @@ private boolean processTokenAddChangeEvent(List tokens) { token.hasLightSources() && (token.isVisible() || MapTool.getPlayer().isEffectiveGM()); if (token.hasAnyTopology()) hasTopology = true; for (AttachedLightSource als : token.getLightSources()) { - LightSource lightSource = c.getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(token, c); if (lightSource != null) { Set lightSet = lightSourceMap.get(lightSource.getType()); if (hasLightSource) { diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisibilityInspector.java b/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisibilityInspector.java index 147eb00b1d..5ce048204a 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisibilityInspector.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisibilityInspector.java @@ -42,7 +42,7 @@ public class VisibilityInspector extends JPanel { private static final Logger log = LogManager.getLogger(VisibilityInspector.class); private static final double VISION_RANGE_CHANGE_RATE = 15.; - private AreaTree wallVblTree, hillVblTree, pitVblTree; + private AreaTree wallVblTree, hillVblTree, pitVblTree, coverVblTree; private AffineTransform affineTransform; private Point2D point; private double visionRange; @@ -82,15 +82,17 @@ public void mouseWheelMoved(MouseWheelEvent e) { }); } - public void setTopology(Area wallVbl, Area hillVbl, Area pitVbl) { + public void setTopology(Area wallVbl, Area hillVbl, Area pitVbl, Area coverVbl) { wallVbl = new Area(wallVbl); hillVbl = new Area(hillVbl); pitVbl = new Area(pitVbl); + coverVbl = new Area(coverVbl); final var dimensions = getSize(); final var bounds = wallVbl.getBounds(); bounds.add(hillVbl.getBounds()); bounds.add(pitVbl.getBounds()); + bounds.add(coverVbl.getBounds()); affineTransform = AffineTransform.getTranslateInstance(-bounds.getX(), -bounds.getY()); final var scaleX = dimensions.getWidth() / bounds.getWidth(); final var scaleY = dimensions.getHeight() / bounds.getHeight(); @@ -103,6 +105,7 @@ public void setTopology(Area wallVbl, Area hillVbl, Area pitVbl) { wallVblTree = new AreaTree(wallVbl); hillVblTree = new AreaTree(hillVbl); pitVblTree = new AreaTree(pitVbl); + coverVblTree = new AreaTree(coverVbl); } @Override @@ -129,6 +132,8 @@ protected void paintComponent(Graphics g) { g2d.draw(hillVblTree.getArea()); g2d.setColor(Color.green); g2d.draw(pitVblTree.getArea()); + g2d.setColor(Color.red); + g2d.draw(coverVblTree.getArea()); final var CIRCLE_SEGMENTS = 60; final var unobstructedVision = @@ -144,7 +149,8 @@ protected void paintComponent(Graphics g) { unobstructedVision, wallVblTree, hillVblTree, - pitVblTree); + pitVblTree, + coverVblTree); final var obstructedVision = new Area(unobstructedVision); @@ -211,7 +217,7 @@ private static void buildRepeatedSquaredTopology(VisibilityInspector visibilityI } } } - visibilityInspector.setTopology(wallArea, hillArea, pitArea); + visibilityInspector.setTopology(wallArea, hillArea, pitArea, null); } private static void buildTripleIntersectionTopology(VisibilityInspector visibilityInspector) { @@ -225,7 +231,7 @@ private static void buildTripleIntersectionTopology(VisibilityInspector visibili hillArea.add(new Area(new Polygon(new int[] {250, 450, 450}, new int[] {450, 450, 250}, 3))); pitArea.add(new Area(new Polygon(new int[] {275, 325, 325}, new int[] {350, 150, 550}, 3))); - visibilityInspector.setTopology(wallArea, hillArea, pitArea); + visibilityInspector.setTopology(wallArea, hillArea, pitArea, null); } private static void buildSinglePillarTopology(VisibilityInspector visibilityInspector) { @@ -238,6 +244,6 @@ private static void buildSinglePillarTopology(VisibilityInspector visibilityInsp final var pillar = new Area(new Rectangle(300, 300, 50, 50)); wallArea.add(pillar); - visibilityInspector.setTopology(wallArea, hillArea, pitArea); + visibilityInspector.setTopology(wallArea, hillArea, pitArea, null); } } diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisionBlockingAccumulator.java b/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisionBlockingAccumulator.java index 8925173574..52f9af4a00 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisionBlockingAccumulator.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisionBlockingAccumulator.java @@ -212,4 +212,56 @@ public boolean addPitBlocking(AreaTree topology) { return true; } + + /** + * Finds all cover topology segments that can take part in blocking vision. + * + * @param topology The topology to treat as Cover VBL. + * @return false if the vision has been completely blocked by topology, or true if vision can be + * blocked by particular segments. + */ + public boolean addCoverBlocking(AreaTree topology) { + final AreaContainer container = topology.getContainerAt(origin); + if (container == null) { + // Should never happen since the global ocean should catch everything. + return false; + } + + /* + * There are two cases for Cover VBL: + * 1. A token inside Cover VBL can see everything, unobstructed by the cover. + * 2. A token outside Cover VBL can see nothing, as if it were wall. + */ + + if (container instanceof final AreaIsland island) { + + final var parentOcean = island.getParentOcean(); + + for (final var siblingIsland : parentOcean.getIslands()) { + if (siblingIsland == island) { + continue; + } + addVisionBlockingSegments(siblingIsland, true); + } + for (final var childOcean : island.getOceans()) { + for (final var grandchildIsland : childOcean.getIslands()) { + addVisionBlockingSegments(grandchildIsland, true); + } + addVisionBlockingSegments(childOcean, false); + } + addVisionBlockingSegments(parentOcean, false); + + } else if (container instanceof AreaOcean ocean) { + final var parentIsland = ocean.getParentIsland(); + if (parentIsland != null) { + addVisionBlockingSegments(ocean, true); + } + + for (var containedIsland : ocean.getIslands()) { + addVisionBlockingSegments(containedIsland, true); + } + } + + return true; + } } diff --git a/src/main/java/net/rptools/maptool/client/walker/AbstractZoneWalker.java b/src/main/java/net/rptools/maptool/client/walker/AbstractZoneWalker.java index 1bea16bc2b..02ab712942 100644 --- a/src/main/java/net/rptools/maptool/client/walker/AbstractZoneWalker.java +++ b/src/main/java/net/rptools/maptool/client/walker/AbstractZoneWalker.java @@ -35,6 +35,7 @@ public abstract class AbstractZoneWalker implements ZoneWalker { protected Area tokenWallVbl; protected Area tokenHillVbl; protected Area tokenPitVbl; + protected Area tokenCoverVbl; protected Area tokenMbl; protected RenderPathWorker renderPathWorker; @@ -74,7 +75,14 @@ public void addWaypoints(CellPoint... points) { public CellPoint replaceLastWaypoint(CellPoint point) { return replaceLastWaypoint( - point, false, Collections.singleton(TerrainModifierOperation.NONE), null, null, null, null); + point, + false, + Collections.singleton(TerrainModifierOperation.NONE), + null, + null, + null, + null, + null); } @Override @@ -85,6 +93,7 @@ public CellPoint replaceLastWaypoint( Area tokenWallVbl, Area tokenHillVbl, Area tokenPitVbl, + Area tokenCoverVbl, Area tokenMbl) { this.restrictMovement = restrictMovement; @@ -92,6 +101,7 @@ public CellPoint replaceLastWaypoint( this.tokenWallVbl = tokenWallVbl; this.tokenHillVbl = tokenHillVbl; this.tokenPitVbl = tokenPitVbl; + this.tokenCoverVbl = tokenCoverVbl; this.tokenMbl = tokenMbl; if (partialPaths.isEmpty()) { diff --git a/src/main/java/net/rptools/maptool/client/walker/ZoneWalker.java b/src/main/java/net/rptools/maptool/client/walker/ZoneWalker.java index 63f3965795..13ce99626f 100644 --- a/src/main/java/net/rptools/maptool/client/walker/ZoneWalker.java +++ b/src/main/java/net/rptools/maptool/client/walker/ZoneWalker.java @@ -38,6 +38,7 @@ public CellPoint replaceLastWaypoint( Area tokenWallVbl, Area tokenHillVbl, Area tokenPitVbl, + Area tokenCoverVbl, Area tokenMbl); public boolean isWaypoint(CellPoint point); diff --git a/src/main/java/net/rptools/maptool/events/TokenHoverListener.java b/src/main/java/net/rptools/maptool/events/TokenHoverListener.java new file mode 100644 index 0000000000..19e088bbe6 --- /dev/null +++ b/src/main/java/net/rptools/maptool/events/TokenHoverListener.java @@ -0,0 +1,88 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.maptool.events; + +import com.google.common.eventbus.Subscribe; +import java.util.Collections; +import java.util.concurrent.ExecutionException; +import net.rptools.maptool.client.events.TokenHoverEnter; +import net.rptools.maptool.client.events.TokenHoverExit; +import net.rptools.maptool.language.I18N; +import net.rptools.maptool.model.library.Library; +import net.rptools.maptool.model.library.LibraryManager; +import net.rptools.maptool.util.EventMacroUtil; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + +public class TokenHoverListener { + public static final String ON_MOUSE_OVER_CALLBACK = "onMouseOver"; + private static final Logger LOGGER = LogManager.getLogger(EventMacroUtil.class); + + @Subscribe + public void onMouseOverEnter(TokenHoverEnter event) { + var token = event.token(); + var tokX = event.token().getX(); + var tokY = event.token().getY(); + var shiftKey = event.shiftDown(); + var ctrlKey = event.controlDown(); + try { + var libs = new LibraryManager().getLegacyEventTargets(ON_MOUSE_OVER_CALLBACK).get(); + if (libs.isEmpty()) return; + for (Library handler : libs) { + try { + String libraryNamespace = handler.getNamespace().get(); + EventMacroUtil.callEventHandler( + ON_MOUSE_OVER_CALLBACK, + libraryNamespace, + token.getId().toString() + "," + tokX + "," + tokY + "," + shiftKey + "," + ctrlKey, + null, + Collections.emptyMap(), + false); + } catch (InterruptedException | ExecutionException e) { + LOGGER.error(I18N.getText("library.error.namespace"), e); + throw new AssertionError("Error retrieving library namespace"); + } + } + } catch (InterruptedException | ExecutionException e) { + LOGGER.error(I18N.getText("library.error.retrievingEventHandler"), e); + } + } + + @Subscribe + public void onMouseOverExit(TokenHoverExit event) { + var token = event.token(); + try { + var libs = new LibraryManager().getLegacyEventTargets(ON_MOUSE_OVER_CALLBACK).get(); + if (libs.isEmpty()) return; + for (Library handler : libs) { + try { + String libraryNamespace = handler.getNamespace().get(); + EventMacroUtil.callEventHandler( + ON_MOUSE_OVER_CALLBACK, + libraryNamespace, + token.getId().toString() + ",exit", + null, + Collections.emptyMap(), + false); + } catch (InterruptedException | ExecutionException e) { + LOGGER.error(I18N.getText("library.error.namespace"), e); + throw new AssertionError("Error retrieving library namespace"); + } + } + } catch (InterruptedException | ExecutionException e) { + LOGGER.error(I18N.getText("library.error.retrievingEventHandler"), e); + } + } +} diff --git a/src/main/java/net/rptools/maptool/events/ZoneLoadedListener.java b/src/main/java/net/rptools/maptool/events/ZoneLoadedListener.java index 1f9ee6681a..95e8220080 100644 --- a/src/main/java/net/rptools/maptool/events/ZoneLoadedListener.java +++ b/src/main/java/net/rptools/maptool/events/ZoneLoadedListener.java @@ -14,15 +14,22 @@ */ package net.rptools.maptool.events; -import static net.rptools.maptool.client.functions.MapFunctions.ON_CHANGE_MAP_CALLBACK; - import com.google.common.eventbus.Subscribe; import java.util.Collections; +import java.util.concurrent.ExecutionException; +import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.events.ZoneLoaded; -import net.rptools.maptool.model.Token; +import net.rptools.maptool.client.ui.zone.ZoneRenderer; +import net.rptools.maptool.language.I18N; +import net.rptools.maptool.model.library.Library; +import net.rptools.maptool.model.library.LibraryManager; import net.rptools.maptool.util.EventMacroUtil; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; public class ZoneLoadedListener { + private static final Logger LOGGER = LogManager.getLogger(EventMacroUtil.class); + public static final String ON_CHANGE_MAP_CALLBACK = "onChangeMap"; public ZoneLoadedListener() { new MapToolEventBus().getMainEventBus().register(this); @@ -30,12 +37,28 @@ public ZoneLoadedListener() { @Subscribe public void OnChangedMap(ZoneLoaded event) { - var libTokens = EventMacroUtil.getEventMacroTokens(ON_CHANGE_MAP_CALLBACK); - String prefix = ON_CHANGE_MAP_CALLBACK + "@"; - - for (Token handler : libTokens) { - EventMacroUtil.callEventHandlerOld( - prefix + handler.getName(), "", handler, Collections.emptyMap(), true); + ZoneRenderer currentZR = MapTool.getFrame().getCurrentZoneRenderer(); + try { + var libs = new LibraryManager().getLegacyEventTargets(ON_CHANGE_MAP_CALLBACK).get(); + if (libs.isEmpty()) { + return; + } + for (Library handler : libs) { + try { + String libraryNamespace = handler.getNamespace().get(); + EventMacroUtil.callEventHandler( + ON_CHANGE_MAP_CALLBACK, + libraryNamespace, + currentZR.getZone().getId().toString(), + null, + Collections.emptyMap()); + } catch (InterruptedException | ExecutionException e) { + LOGGER.error(I18N.getText("library.error.notFound"), e); + throw new AssertionError("Error retrieving library namespace"); + } + } + } catch (InterruptedException | ExecutionException e) { + LOGGER.error(I18N.getText("library.error.retrievingEventHandler"), e); } } } diff --git a/src/main/java/net/rptools/maptool/model/AttachedLightSource.java b/src/main/java/net/rptools/maptool/model/AttachedLightSource.java index 3502c4f681..03568e342b 100644 --- a/src/main/java/net/rptools/maptool/model/AttachedLightSource.java +++ b/src/main/java/net/rptools/maptool/model/AttachedLightSource.java @@ -14,26 +14,51 @@ */ package net.rptools.maptool.model; +import java.util.Map; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.rptools.maptool.server.proto.AttachedLightSourceDto; -public class AttachedLightSource { +public final class AttachedLightSource { - private GUID lightSourceId; + private final @Nonnull GUID lightSourceId; - public AttachedLightSource() { - // for serialization - } - - private AttachedLightSource(GUID lightSourceId) { + public AttachedLightSource(@Nonnull GUID lightSourceId) { this.lightSourceId = lightSourceId; } - public AttachedLightSource(LightSource source) { - lightSourceId = source.getId(); + /** + * Obtain the attached {@code LightSource} from the token or campaign. + * + * @param token The token in which to look up light source IDs. + * @param campaign The campaign in which to look up light source IDs. + * @return The {@code LightSource} referenced by this {@code AttachedLightSource}, or {@code null} + * if no such light source exists. + */ + public @Nullable LightSource resolve(Token token, Campaign campaign) { + final var uniqueLightSource = token.getUniqueLightSource(lightSourceId); + if (uniqueLightSource != null) { + return uniqueLightSource; + } + + for (Map map : campaign.getLightSourcesMap().values()) { + if (map.containsKey(lightSourceId)) { + return map.get(lightSourceId); + } + } + + return null; } - public GUID getLightSourceId() { - return lightSourceId; + /** + * Check if this {@code AttachedLightSource} references a {@code LightSource} with a matching ID. + * + * @param lightSourceId The ID of the light source to match against. + * @return {@code true} If {@code lightSourceId} is the same as the ID of the attached light + * source. + */ + public boolean matches(@Nonnull GUID lightSourceId) { + return lightSourceId.equals(this.lightSourceId); } public static AttachedLightSource fromDto(AttachedLightSourceDto dto) { @@ -42,7 +67,7 @@ public static AttachedLightSource fromDto(AttachedLightSourceDto dto) { public AttachedLightSourceDto toDto() { var dto = AttachedLightSourceDto.newBuilder(); - dto.setLightSourceId(getLightSourceId().toString()); + dto.setLightSourceId(lightSourceId.toString()); return dto.build(); } } diff --git a/src/main/java/net/rptools/maptool/model/Campaign.java b/src/main/java/net/rptools/maptool/model/Campaign.java index fdcd13ac42..805f477471 100644 --- a/src/main/java/net/rptools/maptool/model/Campaign.java +++ b/src/main/java/net/rptools/maptool/model/Campaign.java @@ -328,23 +328,6 @@ public List getLookupTables() { return list; } - /** - * Convenience method that iterates through {@link #getLightSourcesMap()} and returns the value - * for the key lightSourceId. - * - * @param lightSourceId the id to look for - * @return the {@link LightSource} or null if not found - */ - public LightSource getLightSource(GUID lightSourceId) { - - for (Map map : getLightSourcesMap().values()) { - if (map.containsKey(lightSourceId)) { - return map.get(lightSourceId); - } - } - return null; - } - /** * Stub that calls campaignProperties.getLightSourcesMap(). * @@ -850,7 +833,7 @@ private void compressRenames(RenamePropertyType rename, ArrayList { if (oldName.equals(t.getPropertyType())) { diff --git a/src/main/java/net/rptools/maptool/model/CampaignProperties.java b/src/main/java/net/rptools/maptool/model/CampaignProperties.java index 18e1707555..fc7dbe7fbb 100644 --- a/src/main/java/net/rptools/maptool/model/CampaignProperties.java +++ b/src/main/java/net/rptools/maptool/model/CampaignProperties.java @@ -190,7 +190,11 @@ public StatSheetProperties getTokenTypeDefaultStatSheet(String propertyType) { */ public void setTokenTypeDefaultStatSheet( String propertyType, StatSheetProperties statSheetProperties) { - tokenTypeStatSheetMap.put(propertyType, statSheetProperties); + if (statSheetProperties == null) { + tokenTypeStatSheetMap.remove(propertyType); + } else { + tokenTypeStatSheetMap.put(propertyType, statSheetProperties); + } } public Map getSightTypeMap() { diff --git a/src/main/java/net/rptools/maptool/model/Light.java b/src/main/java/net/rptools/maptool/model/Light.java index 67981b9dce..95315a87a3 100644 --- a/src/main/java/net/rptools/maptool/model/Light.java +++ b/src/main/java/net/rptools/maptool/model/Light.java @@ -23,7 +23,7 @@ import net.rptools.maptool.server.proto.LightDto; import net.rptools.maptool.server.proto.ShapeTypeDto; -public class Light implements Serializable { +public final class Light implements Serializable { private final @Nonnull ShapeType shape; private final double facingOffset; private final double radius; diff --git a/src/main/java/net/rptools/maptool/model/LightSource.java b/src/main/java/net/rptools/maptool/model/LightSource.java index a633a70e99..0da670d38e 100644 --- a/src/main/java/net/rptools/maptool/model/LightSource.java +++ b/src/main/java/net/rptools/maptool/model/LightSource.java @@ -14,6 +14,7 @@ */ package net.rptools.maptool.model; +import com.google.common.collect.ImmutableList; import com.google.protobuf.StringValue; import java.awt.geom.Area; import java.io.IOException; @@ -22,7 +23,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -33,16 +33,35 @@ import net.rptools.maptool.server.proto.LightSourceDto; import org.apache.commons.lang.math.NumberUtils; -public class LightSource implements Comparable, Serializable { +/** + * Represents a light source that can be attached to tokens. + * + *

This class is immutable. + */ +public final class LightSource implements Comparable, Serializable { public enum Type { NORMAL, AURA } - private @Nullable String name; - private @Nullable GUID id; - private @Nonnull Type type; - private boolean scaleWithToken; + private final @Nullable String name; + private final @Nullable GUID id; + private final @Nonnull Type type; + private final boolean scaleWithToken; + + /** + * This light segments that make up the light source. + * + *

In practice this will be an {@code ImmutableList} during runtime. However, previously + * serialized {@code LightSource} instances may have specified that it must be a {@code + * LinkedList} or other specific {@code List} implementation. So we need to keep this as a {@code + * List} in order to deserialize those. + * + *

There is also one case where it won't be an {@code ImmutableList}, and that is during + * serialization. At such a time, a temporary {@code LightSource} is created with an {@code + * ArrayList} instead. (see {@link #writeReplace()}) so that the XML does not depend on the use of + * {@code ImmutableList} or any other particular {@code List} implementation. + */ private final @Nonnull List lightList; // Lumens are now in the individual Lights. This field is only here for backwards compatibility @@ -54,21 +73,32 @@ public enum Type { * *

Since a personal light source is directly attached to a specific sight type, they do not * need (or have) names and GUIDs. + * + * @param scaleWithToken if {@code true}, the size of the lights will scale with the token size. + * @param lights The set of lights that constitute the personal light source. */ - public LightSource() { - this(null, null, Type.NORMAL, false, Collections.emptyList()); + public static LightSource createPersonal(boolean scaleWithToken, Collection lights) { + return new LightSource(null, null, Type.NORMAL, scaleWithToken, ImmutableList.copyOf(lights)); } /** * Constructs a non-personal light source. * - *

These light sources are referenced both by name and GUID, and thus need both. A new GUID - * will be created automatically. + *

These light sources are referenced both by name and GUID, and thus need both. * * @param name The name of the light source. + * @param id The unique ID of the light source. + * @param type The type of light, whether a normal light or an aura. + * @param scaleWithToken if {@code true}, the size of the lights will scale with the token size. + * @param lights The set of lights that constitute the personal light source. */ - public LightSource(@Nonnull String name) { - this(name, new GUID(), Type.NORMAL, false, Collections.emptyList()); + public static LightSource createRegular( + @Nonnull String name, + @Nonnull GUID id, + @Nonnull Type type, + boolean scaleWithToken, + @Nonnull Collection lights) { + return new LightSource(name, id, type, scaleWithToken, ImmutableList.copyOf(lights)); } private LightSource( @@ -76,14 +106,19 @@ private LightSource( @Nullable GUID id, @Nonnull Type type, boolean scaleWithToken, - @Nonnull Collection lights) { + @Nonnull List lights) { this.name = name; this.id = id; this.type = type; this.scaleWithToken = scaleWithToken; + this.lightList = lights; + } - this.lightList = new LinkedList<>(); - this.lightList.addAll(lights); + @Serial + public Object writeReplace() { + // Make sure XStream keeps the serialization nice. We don't need the XML to contain + // implementation details of the ImmutableList in use. + return new LightSource(name, id, type, scaleWithToken, new ArrayList<>(lightList)); } @SuppressWarnings("ConstantConditions") @@ -93,7 +128,7 @@ private LightSource( Objects.requireNonNullElse(lightList, Collections.emptyList()); final List lights; if (lumens == Integer.MIN_VALUE) { - // This is an up-to-date Lightsource with lumens already stored in the Lights. + // This is an up-to-date LightSource with lumens already stored in the Lights. lights = originalLights; } else { // This is an old light source with a lumens value that needs to be pushed into the individual @@ -120,7 +155,7 @@ private LightSource( this.id, Objects.requireNonNullElse(this.type, Type.NORMAL), this.scaleWithToken, - lights); + ImmutableList.copyOf(lights)); } @Override @@ -144,10 +179,6 @@ public int hashCode() { return Objects.hashCode(id); } - public void setId(@Nonnull GUID id) { - this.id = id; - } - public @Nullable GUID getId() { return id; } @@ -156,37 +187,17 @@ public void setId(@Nonnull GUID id) { return name; } - public void setName(@Nonnull String name) { - this.name = name; - } - - public void add(@Nonnull Light source) { - lightList.add(source); - } - - public void remove(@Nonnull Light source) { - lightList.remove(source); - } - /** - * @return the lights belonging to this LightSource. + * @return A read-only list of lights belonging to this LightSource */ public @Nonnull List getLightList() { - return Collections.unmodifiableList(lightList); + return lightList; } public @Nonnull Type getType() { return type; } - public void setType(@Nonnull Type type) { - this.type = type; - } - - public void setScaleWithToken(boolean scaleWithToken) { - this.scaleWithToken = scaleWithToken; - } - public boolean isScaleWithToken() { return scaleWithToken; } @@ -255,7 +266,7 @@ public int compareTo(@Nonnull LightSource o) { dto.hasId() ? GUID.valueOf(dto.getId().getValue()) : null, Type.valueOf(dto.getType().name()), dto.getScaleWithToken(), - dto.getLightsList().stream().map(Light::fromDto).toList()); + dto.getLightsList().stream().map(Light::fromDto).collect(ImmutableList.toImmutableList())); } public @Nonnull LightSourceDto toDto() { diff --git a/src/main/java/net/rptools/maptool/model/SightType.java b/src/main/java/net/rptools/maptool/model/SightType.java index 42abf38eab..083d1db9e5 100644 --- a/src/main/java/net/rptools/maptool/model/SightType.java +++ b/src/main/java/net/rptools/maptool/model/SightType.java @@ -15,6 +15,7 @@ package net.rptools.maptool.model; import java.awt.geom.Area; +import javax.annotation.Nullable; import net.rptools.maptool.server.proto.ShapeTypeDto; import net.rptools.maptool.server.proto.SightTypeDto; @@ -64,12 +65,12 @@ public SightType() { // For serialization } - public SightType(String name, double multiplier, LightSource personalLightSource) { + public SightType(String name, double multiplier, @Nullable LightSource personalLightSource) { this(name, multiplier, personalLightSource, ShapeType.CIRCLE); } public SightType( - String name, double multiplier, LightSource personalLightSource, ShapeType shape) { + String name, double multiplier, @Nullable LightSource personalLightSource, ShapeType shape) { this.name = name; this.multiplier = multiplier; this.personalLightSource = personalLightSource; diff --git a/src/main/java/net/rptools/maptool/model/Token.java b/src/main/java/net/rptools/maptool/model/Token.java index 8e5924c92c..40214fbc7d 100644 --- a/src/main/java/net/rptools/maptool/model/Token.java +++ b/src/main/java/net/rptools/maptool/model/Token.java @@ -211,6 +211,8 @@ public enum Update { setPortraitImage, setCharsheetImage, setLayout, + createUniqueLightSource, + deleteUniqueLightSource, clearLightSources, removeLightSource, addLightSource, @@ -270,6 +272,7 @@ public enum Update { private Area vbl; private Area hillVbl; private Area pitVbl; + private Area coverVbl; private Area mbl; private String name = ""; @@ -334,6 +337,7 @@ public String toString() { private MD5Key charsheetImage; private MD5Key portraitImage; + private Map uniqueLightSources = new LinkedHashMap<>(); private List lightSourceList = new ArrayList<>(); private String sightType; private boolean hasSight; @@ -432,6 +436,7 @@ public Token(Token token) { vbl = token.vbl; hillVbl = token.hillVbl; pitVbl = token.pitVbl; + coverVbl = token.coverVbl; mbl = token.mbl; name = token.name; @@ -471,7 +476,10 @@ public Token(Token token) { ownerType = token.ownerType; ownerList.addAll(token.ownerList); + + uniqueLightSources.putAll(token.uniqueLightSources); lightSourceList.addAll(token.lightSourceList); + state.putAll(token.state); getPropertyMap().clear(); getPropertyMap().putAll(token.propertyMapCI); @@ -916,14 +924,30 @@ public String getImageTableName() { return imageTableName; } - public void addLightSource(LightSource source) { - lightSourceList.add(new AttachedLightSource(source)); + public @Nonnull Collection getUniqueLightSources() { + return uniqueLightSources.values(); + } + + public @Nullable LightSource getUniqueLightSource(GUID lightSourceId) { + return uniqueLightSources.getOrDefault(lightSourceId, null); + } + + public void addUniqueLightSource(LightSource source) { + uniqueLightSources.put(source.getId(), source); + } + + public void removeUniqueLightSource(GUID lightSourceId) { + uniqueLightSources.remove(lightSourceId); + } + + public void addLightSource(GUID lightSourceId) { + lightSourceList.add(new AttachedLightSource(lightSourceId)); } public void removeLightSourceType(LightSource.Type lightType) { for (ListIterator i = lightSourceList.listIterator(); i.hasNext(); ) { AttachedLightSource als = i.next(); - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(this, MapTool.getCampaign()); if (lightSource != null && lightSource.getType() == lightType) { i.remove(); } @@ -933,7 +957,7 @@ public void removeLightSourceType(LightSource.Type lightType) { public void removeGMAuras() { for (ListIterator i = lightSourceList.listIterator(); i.hasNext(); ) { AttachedLightSource als = i.next(); - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(this, MapTool.getCampaign()); if (lightSource != null) { List lights = lightSource.getLightList(); for (Light light : lights) { @@ -948,7 +972,7 @@ public void removeGMAuras() { public void removeOwnerOnlyAuras() { for (ListIterator i = lightSourceList.listIterator(); i.hasNext(); ) { AttachedLightSource als = i.next(); - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(this, MapTool.getCampaign()); if (lightSource != null) { List lights = lightSource.getLightList(); for (Light light : lights) { @@ -962,7 +986,7 @@ public void removeOwnerOnlyAuras() { public boolean hasOwnerOnlyAuras() { for (AttachedLightSource als : lightSourceList) { - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(this, MapTool.getCampaign()); if (lightSource != null) { List lights = lightSource.getLightList(); for (Light light : lights) { @@ -977,7 +1001,7 @@ public boolean hasOwnerOnlyAuras() { public boolean hasGMAuras() { for (AttachedLightSource als : lightSourceList) { - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(this, MapTool.getCampaign()); if (lightSource != null) { List lights = lightSource.getLightList(); for (Light light : lights) { @@ -992,7 +1016,7 @@ public boolean hasGMAuras() { public boolean hasLightSourceType(LightSource.Type lightType) { for (AttachedLightSource als : lightSourceList) { - LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); + LightSource lightSource = als.resolve(this, MapTool.getCampaign()); if (lightSource != null && lightSource.getType() == lightType) { return true; } @@ -1000,12 +1024,8 @@ public boolean hasLightSourceType(LightSource.Type lightType) { return false; } - public void removeLightSource(LightSource source) { - lightSourceList.removeIf( - als -> - als != null - && als.getLightSourceId() != null - && als.getLightSourceId().equals(source.getId())); + public void removeLightSource(GUID lightSourceId) { + lightSourceList.removeIf(als -> als.matches(lightSourceId)); } /** Clear the lightSourceList */ @@ -1014,13 +1034,13 @@ public void clearLightSources() { } public boolean hasLightSource(LightSource source) { - if (lightSourceList.size() == 0) { + if (source.getId() == null) { + // Shouldn't happen as this method should only be used with non-personal lights. return false; } + for (AttachedLightSource als : lightSourceList) { - if (als != null - && als.getLightSourceId() != null - && als.getLightSourceId().equals(source.getId())) { + if (als.matches(source.getId())) { return true; } } @@ -1125,7 +1145,7 @@ public void setName(String name) { public void validateName(String name) throws ParserException { if (!MapTool.getPlayer().isGM() && !MapTool.getParser().isMacroTrusted()) { Zone curZone = getZoneRenderer().getZone(); - List tokensList = curZone.getTokens(); + List tokensList = curZone.getAllTokens(); for (Token token : tokensList) { String curTokenName = token.getName(); @@ -1406,6 +1426,7 @@ public Area getTopology(Zone.TopologyType topologyType) { case WALL_VBL -> vbl; case HILL_VBL -> hillVbl; case PIT_VBL -> pitVbl; + case COVER_VBL -> coverVbl; case MBL -> mbl; }; } @@ -1433,6 +1454,7 @@ public void setTopology(Zone.TopologyType topologyType, @Nullable Area topology) case WALL_VBL -> vbl = topology; case HILL_VBL -> hillVbl = topology; case PIT_VBL -> pitVbl = topology; + case COVER_VBL -> coverVbl = topology; case MBL -> mbl = topology; } ; @@ -1756,6 +1778,18 @@ public Object getState(String property) { return state.get(property); } + public List getSetStates() { + List setStates = new ArrayList(); + for (Map.Entry entry : state.entrySet()) { + if (entry.getValue() instanceof Boolean) { + if ((Boolean) entry.getValue()) { + setStates.add(entry.getKey()); + } + } + } + return setStates; + } + /** * Set the value of state for this Token. * @@ -2506,9 +2540,16 @@ protected Object readResolve() { if (ownerList == null) { ownerList = new HashSet<>(); } + if (uniqueLightSources == null) { + uniqueLightSources = new LinkedHashMap<>(); + } if (lightSourceList == null) { lightSourceList = new ArrayList<>(); } + // There used to be checks elsewhere that elements were not null. In case those were legitimate, + // let's filter them out here instead. + lightSourceList.removeIf(Objects::isNull); + if (macroPropertiesMap == null) { macroPropertiesMap = new HashMap<>(); } @@ -2815,6 +2856,14 @@ public void updateProperty(Zone zone, Update update, List setSizeScale(parameters.get(0).getDoubleValue()); setAnchor(parameters.get(1).getIntValue(), parameters.get(2).getIntValue()); break; + case createUniqueLightSource: + lightChanged = true; + addUniqueLightSource(LightSource.fromDto(parameters.get(0).getLightSource())); + break; + case deleteUniqueLightSource: + lightChanged = true; + removeUniqueLightSource(GUID.valueOf(parameters.get(0).getLightSourceId())); + break; case clearLightSources: if (hasLightSources()) { lightChanged = true; @@ -2825,11 +2874,11 @@ public void updateProperty(Zone zone, Update update, List if (hasLightSources()) { lightChanged = true; } - removeLightSource(LightSource.fromDto(parameters.get(0).getLightSource())); + removeLightSource(GUID.valueOf(parameters.get(0).getLightSourceId())); break; case addLightSource: lightChanged = true; - addLightSource(LightSource.fromDto(parameters.get(0).getLightSource())); + addLightSource(GUID.valueOf(parameters.get(0).getLightSourceId())); break; case setHasSight: if (hasLightSources()) { @@ -2919,6 +2968,7 @@ public static Token fromDto(TokenDto dto) { token.vbl = dto.hasVbl() ? Mapper.map(dto.getVbl()) : null; token.hillVbl = dto.hasHillVbl() ? Mapper.map(dto.getHillVbl()) : null; token.pitVbl = dto.hasPitVbl() ? Mapper.map(dto.getPitVbl()) : null; + token.coverVbl = dto.hasCoverVbl() ? Mapper.map(dto.getCoverVbl()) : null; token.mbl = dto.hasMbl() ? Mapper.map(dto.getMbl()) : null; token.name = dto.getName(); token.ownerList.addAll(dto.getOwnerListList()); @@ -2947,6 +2997,10 @@ public static Token fromDto(TokenDto dto) { dto.hasCharsheetImage() ? new MD5Key(dto.getCharsheetImage().getValue()) : null; token.portraitImage = dto.hasPortraitImage() ? new MD5Key(dto.getPortraitImage().getValue()) : null; + + dto.getUniqueLightSourcesList().stream() + .map(LightSource::fromDto) + .forEach(source -> token.uniqueLightSources.put(source.getId(), source)); token.lightSourceList.addAll( dto.getLightSourcesList().stream() .map(AttachedLightSource::fromDto) @@ -3034,6 +3088,9 @@ public TokenDto toDto() { if (pitVbl != null) { dto.setPitVbl(Mapper.map(pitVbl)); } + if (coverVbl != null) { + dto.setCoverVbl(Mapper.map(coverVbl)); + } if (mbl != null) { dto.setMbl(Mapper.map(mbl)); } @@ -3071,6 +3128,8 @@ public TokenDto toDto() { if (portraitImage != null) { dto.setPortraitImage(StringValue.of(portraitImage.toString())); } + dto.addAllUniqueLightSources( + uniqueLightSources.values().stream().map(LightSource::toDto).collect(Collectors.toList())); dto.addAllLightSources( lightSourceList.stream().map(AttachedLightSource::toDto).collect(Collectors.toList())); if (sightType != null) { diff --git a/src/main/java/net/rptools/maptool/model/Zone.java b/src/main/java/net/rptools/maptool/model/Zone.java index c0c0db65e2..fa001621da 100644 --- a/src/main/java/net/rptools/maptool/model/Zone.java +++ b/src/main/java/net/rptools/maptool/model/Zone.java @@ -179,6 +179,7 @@ public enum TopologyType { WALL_VBL, HILL_VBL, PIT_VBL, + COVER_VBL, MBL; } @@ -294,6 +295,9 @@ public String toString() { /** The Pit VBL topology of the zone. Does not include token Pit VBL. */ private Area pitVbl = new Area(); + /** The Cover VBL topology of the zone. Does not include token Cover VBL. */ + private Area coverVbl = new Area(); + /** The MBL topology of the zone. Does not include token MBL. Should really be called mbl. */ private Area topologyTerrain = new Area(); @@ -632,6 +636,7 @@ public Zone(Zone zone, boolean keepIds) { topology = (Area) zone.topology.clone(); hillVbl = (Area) zone.hillVbl.clone(); pitVbl = (Area) zone.pitVbl.clone(); + coverVbl = (Area) zone.coverVbl.clone(); topologyTerrain = (Area) zone.topologyTerrain.clone(); aStarRounding = zone.aStarRounding; topologyTypes = zone.topologyTypes; @@ -925,6 +930,7 @@ public Area getTopology(TopologyType topologyType) { case WALL_VBL -> topology; case HILL_VBL -> hillVbl; case PIT_VBL -> pitVbl; + case COVER_VBL -> coverVbl; case MBL -> topologyTerrain; }; } @@ -941,6 +947,7 @@ public void addTopology(Area area, TopologyType topologyType) { case WALL_VBL -> this.topology; case HILL_VBL -> hillVbl; case PIT_VBL -> pitVbl; + case COVER_VBL -> coverVbl; case MBL -> topologyTerrain; }; topology.add(area); @@ -966,6 +973,7 @@ public void removeTopology(Area area, TopologyType topologyType) { case WALL_VBL -> this.topology; case HILL_VBL -> hillVbl; case PIT_VBL -> pitVbl; + case COVER_VBL -> coverVbl; case MBL -> topologyTerrain; }; topology.subtract(area); @@ -2184,6 +2192,9 @@ protected Object readResolve() { if (pitVbl == null) { pitVbl = new Area(); } + if (coverVbl == null) { + coverVbl = new Area(); + } // Movement Blocking Layer if (topologyTerrain == null) { topologyTerrain = new Area(); @@ -2321,6 +2332,7 @@ public static Zone fromDto(ZoneDto dto) { zone.topology = Mapper.map(dto.getTopology()); zone.hillVbl = Mapper.map(dto.getHillVbl()); zone.pitVbl = Mapper.map(dto.getPitVbl()); + zone.coverVbl = Mapper.map(dto.getCoverVbl()); zone.topologyTerrain = Mapper.map(dto.getTopologyTerrain()); zone.backgroundPaint = DrawablePaint.fromDto(dto.getBackgroundPaint()); zone.mapAsset = dto.hasMapAsset() ? new MD5Key(dto.getMapAsset().getValue()) : null; @@ -2392,6 +2404,7 @@ public ZoneDto toDto() { } dto.setHillVbl(Mapper.map(hillVbl)); dto.setPitVbl(Mapper.map(pitVbl)); + dto.setCoverVbl(Mapper.map(coverVbl)); dto.setTopologyTerrain(Mapper.map(topologyTerrain)); dto.setBackgroundPaint(backgroundPaint.toDto()); if (mapAsset != null) { diff --git a/src/main/java/net/rptools/maptool/model/library/LibraryManager.java b/src/main/java/net/rptools/maptool/model/library/LibraryManager.java index c0c136e006..3bd991ecdc 100644 --- a/src/main/java/net/rptools/maptool/model/library/LibraryManager.java +++ b/src/main/java/net/rptools/maptool/model/library/LibraryManager.java @@ -23,7 +23,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; -import net.rptools.maptool.client.AppActions; import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.MapToolMacroContext; import net.rptools.maptool.events.MapToolEventBus; @@ -42,7 +41,7 @@ public class LibraryManager { /** Class for logging messages. */ - private static final Logger log = LogManager.getLogger(AppActions.class); + private static final Logger log = LogManager.getLogger(LibraryManager.class); /** The reserved library name prefixes. */ private static final Set RESERVED_PREFIXES = @@ -77,6 +76,7 @@ public class LibraryManager { static { libraryTokenManager.init(); + builtInLibraryManager.loadBuiltIns(); new MapToolEventBus().getMainEventBus().register(addOnSlashCommandManager); } diff --git a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java index df8cc60e26..a24ad46892 100644 --- a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java +++ b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java @@ -616,7 +616,7 @@ void initialize() { } /** Registers the stat sheets that this add-on defines. */ - private void registerSheets() { + public void registerSheets() { var statSheetManager = new StatSheetManager(); statSheetManager.removeNamespace(namespace); for (StatSheet sheet : statSheets) { diff --git a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryImporter.java b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryImporter.java index f3f96e1422..e0b66d3cb4 100644 --- a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryImporter.java +++ b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibraryImporter.java @@ -213,6 +213,33 @@ public AddOnLibrary importFromFile(File file) throws IOException { } } + public AddOnLibrary importFromClassPath(String path) throws IOException { + // Copy the data to temporary file, its a bit hacky, but it works, and we can't create a + // ZipFile from anything but a file. + if (!path.startsWith("/")) { + path = "/" + path; + } + + File tempFile = File.createTempFile("mtlib", "tmp"); + tempFile.deleteOnExit(); + + try (var outputStream = Files.newOutputStream(tempFile.toPath())) { + try (var inputStream = AddOnLibraryImporter.class.getResourceAsStream(path)) { + inputStream.transferTo(outputStream); + } + } + + return importFromFile(tempFile); + } + + /** + * Adds the metadata from the root directory of the zip file to the metadata directory. + * + * @param namespace namespace of the add-on library. + * @param zip the zipfile containing the add-on library. + * @param pathAssetMap the map of asset paths and asset details. + * @throws IOException + */ private void addMetaData( String namespace, ZipFile zip, Map> pathAssetMap) throws IOException { diff --git a/src/main/java/net/rptools/maptool/model/library/builtin/BuiltInLibraryManager.java b/src/main/java/net/rptools/maptool/model/library/builtin/BuiltInLibraryManager.java index 3aef67bb8f..71bb983f78 100644 --- a/src/main/java/net/rptools/maptool/model/library/builtin/BuiltInLibraryManager.java +++ b/src/main/java/net/rptools/maptool/model/library/builtin/BuiltInLibraryManager.java @@ -14,13 +14,21 @@ */ package net.rptools.maptool.model.library.builtin; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.FileSystems; +import java.nio.file.Files; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import net.rptools.maptool.client.MapTool; import net.rptools.maptool.model.library.Library; import net.rptools.maptool.model.library.addon.AddOnLibrary; +import net.rptools.maptool.model.library.addon.AddOnLibraryImporter; /** Class for managing {@link AddOnLibrary} objects. */ public class BuiltInLibraryManager { @@ -117,4 +125,43 @@ public Library getLibrary(URL path) { return null; } } + + /** Initializes the built in libraries. */ + public void loadBuiltIns() { + var classLoader = Thread.currentThread().getContextClassLoader(); + + URI uri; + try { + uri = classLoader.getResource(ClassPathAddOnLibrary.BUILTIN_LIB_CLASSPATH_DIR).toURI(); + } catch (URISyntaxException e) { + MapTool.showError("msg.error.library.builtin.path", e); + return; + } + + try (var fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) { + var resourcePath = fs.getPath(ClassPathAddOnLibrary.BUILTIN_LIB_CLASSPATH_DIR); + var libs = + Files.walk(resourcePath, 1) + .filter(p -> p.toString().endsWith(AddOnLibraryImporter.DROP_IN_LIBRARY_EXTENSION)) + .toList(); + + libs.stream().forEach(System.out::println); + var importer = new AddOnLibraryImporter(); + libs.stream() + .forEach( + l -> { + try { + var lib = importer.importFromClassPath(l.toString()); + var clib = new ClassPathAddOnLibrary(l.toString(), lib); + registerLibrary(clib); + clib.initialize(); + + } catch (Exception e) { + MapTool.showError("msg.error.library.builtin.load", e); + } + }); + } catch (IOException e) { + MapTool.showError("msg.error.library.builtin.load", e); + } + } } diff --git a/src/main/java/net/rptools/maptool/model/library/builtin/ClassPathAddOnLibrary.java b/src/main/java/net/rptools/maptool/model/library/builtin/ClassPathAddOnLibrary.java new file mode 100644 index 0000000000..2341953f96 --- /dev/null +++ b/src/main/java/net/rptools/maptool/model/library/builtin/ClassPathAddOnLibrary.java @@ -0,0 +1,201 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.maptool.model.library.builtin; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import net.rptools.lib.MD5Key; +import net.rptools.maptool.client.MapToolMacroContext; +import net.rptools.maptool.client.macro.MacroManager.MacroDetails; +import net.rptools.maptool.model.Asset; +import net.rptools.maptool.model.Token; +import net.rptools.maptool.model.library.LibraryInfo; +import net.rptools.maptool.model.library.MTScriptMacroInfo; +import net.rptools.maptool.model.library.addon.AddOnLibrary; +import net.rptools.maptool.model.library.data.LibraryData; + +public class ClassPathAddOnLibrary implements BuiltInLibrary { + + private final String resourceFilePath; + + private final AddOnLibrary addOnLibrary; + + /** + * Creates a new instance of {@link ClassPathAddOnLibrary}. + * + * @param resourceFilePath the resource path for the library. + * @param addOnLibrary the add-on library that was loaded. + */ + public ClassPathAddOnLibrary(String resourceFilePath, AddOnLibrary addOnLibrary) { + this.resourceFilePath = resourceFilePath; + this.addOnLibrary = addOnLibrary; + } + + /** The directory on the class path for the built in libraries. */ + public static final String BUILTIN_LIB_CLASSPATH_DIR = "net/rptools/maptool/libraries/builtin"; + + @Override + public CompletableFuture getVersion() { + return addOnLibrary.getVersion(); + } + + @Override + public CompletableFuture locationExists(URL location) throws IOException { + return addOnLibrary.locationExists(location); + } + + @Override + public CompletableFuture isAsset(URL location) { + return addOnLibrary.isAsset(location); + } + + @Override + public CompletableFuture> getAssetKey(URL location) { + return addOnLibrary.getAssetKey(location); + } + + @Override + public CompletableFuture readAsString(URL location) throws IOException { + return addOnLibrary.readAsString(location); + } + + @Override + public CompletableFuture readAsHTMLContent(URL location) throws IOException { + return BuiltInLibrary.super.readAsHTMLContent(location); + } + + @Override + public CompletableFuture read(URL location) throws IOException { + return addOnLibrary.read(location); + } + + @Override + public CompletableFuture getWebsite() { + return addOnLibrary.getWebsite(); + } + + @Override + public CompletableFuture getGitUrl() { + return addOnLibrary.getGitUrl(); + } + + @Override + public CompletableFuture getAuthors() { + return addOnLibrary.getAuthors(); + } + + @Override + public CompletableFuture getLicense() { + return addOnLibrary.getLicense(); + } + + @Override + public CompletableFuture getNamespace() { + return addOnLibrary.getNamespace(); + } + + @Override + public CompletableFuture getName() { + return addOnLibrary.getName(); + } + + @Override + public CompletableFuture getDescription() { + return addOnLibrary.getDescription(); + } + + @Override + public CompletableFuture getShortDescription() { + return addOnLibrary.getShortDescription(); + } + + @Override + public CompletableFuture allowsUriAccess() { + return addOnLibrary.allowsUriAccess(); + } + + @Override + public CompletableFuture getLibraryInfo() { + return addOnLibrary.getLibraryInfo(); + } + + @Override + public CompletableFuture> getMTScriptMacroInfo(String macroName) { + return addOnLibrary.getMTScriptMacroInfo(macroName); + } + + @Override + public CompletableFuture> getPrivateMacroInfo(String macroName) { + return addOnLibrary.getPrivateMacroInfo(macroName); + } + + @Override + public CompletableFuture> getAllFiles() { + return addOnLibrary.getAllFiles(); + } + + @Override + public CompletableFuture getLibraryData() { + return addOnLibrary.getLibraryData(); + } + + @Override + public CompletableFuture> getLegacyEventHandlerName(String eventName) { + return addOnLibrary.getLegacyEventHandlerName(eventName); + } + + @Override + public CompletableFuture> getAssociatedToken() { + return addOnLibrary.getAssociatedToken(); + } + + @Override + public boolean canMTScriptAccessPrivate(MapToolMacroContext context) { + return addOnLibrary.canMTScriptAccessPrivate(context); + } + + @Override + public CompletableFuture> getReadMeAsset() { + return addOnLibrary.getReadMeAsset(); + } + + @Override + public CompletableFuture> getLicenseAsset() { + return addOnLibrary.getLicenseAsset(); + } + + @Override + public void cleanup() { + addOnLibrary.cleanup(); + } + + @Override + public Set getSlashCommands() { + return addOnLibrary.getSlashCommands(); + } + + public String getResourceFilePath() { + return resourceFilePath; + } + + void initialize() { + addOnLibrary.registerSheets(); + } +} diff --git a/src/main/java/net/rptools/maptool/server/ServerCommand.java b/src/main/java/net/rptools/maptool/server/ServerCommand.java index ae411df169..7edec64833 100644 --- a/src/main/java/net/rptools/maptool/server/ServerCommand.java +++ b/src/main/java/net/rptools/maptool/server/ServerCommand.java @@ -204,8 +204,6 @@ void updateTokenProperty( void updateTokenProperty(Token token, Token.Update update, LightSource value); - void updateTokenProperty(Token token, Token.Update update, LightSource value1, String value2); - void updateTokenProperty(Token token, Token.Update update, int value1, int value2); void updateTokenProperty(Token token, Token.Update update, boolean value); diff --git a/src/main/java/net/rptools/maptool/server/ServerMessageHandler.java b/src/main/java/net/rptools/maptool/server/ServerMessageHandler.java index 3f2d320a83..387a824958 100644 --- a/src/main/java/net/rptools/maptool/server/ServerMessageHandler.java +++ b/src/main/java/net/rptools/maptool/server/ServerMessageHandler.java @@ -488,7 +488,9 @@ private void handle(RemoveZoneMsg msg) { server.getCampaign().removeZone(zoneGUID); // Now we have fire off adding the tokens in the zone - new MapToolEventBus().getMainEventBus().post(new TokensRemoved(zone, zone.getTokens())); + new MapToolEventBus() + .getMainEventBus() + .post(new TokensRemoved(zone, zone.getAllTokens())); new MapToolEventBus().getMainEventBus().post(new ZoneRemoved(zone)); }); } @@ -544,7 +546,7 @@ private void handle(PutZoneMsg msg) { // Now we have fire off adding the tokens in the zone new MapToolEventBus().getMainEventBus().post(new ZoneAdded(zone)); - new MapToolEventBus().getMainEventBus().post(new TokensAdded(zone, zone.getTokens())); + new MapToolEventBus().getMainEventBus().post(new TokensAdded(zone, zone.getAllTokens())); }); } diff --git a/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java b/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java index a6d2fe74bf..0379f1eb29 100644 --- a/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java +++ b/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; import net.rptools.lib.FileUtil; +import net.rptools.maptool.model.GUID; import net.rptools.maptool.model.Light; import net.rptools.maptool.model.LightSource; import net.rptools.maptool.model.ShapeType; @@ -57,28 +58,30 @@ public static void main(String[] args) { } private static LightSource createLightSource(String name, double radius, double arcAngle) { - LightSource source = new LightSource(name); - // source.add(new Light(0, 5, arcAngle, new DrawableColorPaint(new Color(255, 255, 0, 50)))); - source.add(new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false)); - return source; + return LightSource.createRegular( + name, + new GUID(), + LightSource.Type.NORMAL, + false, + List.of(new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false))); } private static LightSource createD20LightSource(String name, double radius, double arcAngle) { - LightSource source = new LightSource(name); - - // source.add(new Light(0, 5, arcAngle, new DrawableColorPaint(new Color(255, 255, 0, 50)))); - source.add(new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false)); - source.add( - new Light( - ShapeType.CIRCLE, - 0, - radius * 2, - arcAngle, - new DrawableColorPaint(new Color(0, 0, 0, 100)), - 100, - false, - false)); - - return source; + return LightSource.createRegular( + name, + new GUID(), + LightSource.Type.NORMAL, + false, + List.of( + new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false), + new Light( + ShapeType.CIRCLE, + 0, + radius * 2, + arcAngle, + new DrawableColorPaint(new Color(0, 0, 0, 100)), + 100, + false, + false))); } } diff --git a/src/main/java/net/rptools/maptool/webapi/WebTokenInfo.java b/src/main/java/net/rptools/maptool/webapi/WebTokenInfo.java index 885f593a93..5832955549 100644 --- a/src/main/java/net/rptools/maptool/webapi/WebTokenInfo.java +++ b/src/main/java/net/rptools/maptool/webapi/WebTokenInfo.java @@ -115,7 +115,7 @@ public Token findTokenFromId(String tokenId) { private Zone findZoneTokenIsOn(Token token) { List zrenderers = MapTool.getFrame().getZoneRenderers(); for (ZoneRenderer zr : zrenderers) { - if (zr.getZone().getTokens().contains(token)) { + if (zr.getZone().getAllTokens().contains(token)) { return zr.getZone(); } } diff --git a/src/main/proto/data_transfer_objects.proto b/src/main/proto/data_transfer_objects.proto index 03bbe08b7b..bf17d44571 100644 --- a/src/main/proto/data_transfer_objects.proto +++ b/src/main/proto/data_transfer_objects.proto @@ -263,6 +263,7 @@ enum TopologyTypeDto { WALL_VBL = 0; HILL_VBL = 1; PIT_VBL = 2; + COVER_VBL = 4; MBL = 3; } @@ -319,6 +320,7 @@ message TokenDto { AreaDto vbl = 29; AreaDto hillVbl = 65; AreaDto pitVbl = 66; + AreaDto coverVbl = 71; AreaDto mbl = 67; string name = 30; repeated string owner_list = 31; @@ -340,6 +342,7 @@ message TokenDto { bool is_flipped_iso = 47; google.protobuf.StringValue charsheet_image = 48; google.protobuf.StringValue portrait_image = 49; + repeated LightSourceDto unique_light_sources = 72; repeated AttachedLightSourceDto light_sources = 50; google.protobuf.StringValue sight_type = 51; bool has_sight = 52; @@ -535,6 +538,7 @@ message ZoneDto { AreaDto topology = 22; AreaDto hill_vbl = 23; AreaDto pit_vbl = 24; + AreaDto cover_vbl = 39; AreaDto topology_terrain = 25; DrawablePaintDto background_paint = 26; google.protobuf.StringValue map_asset = 27; @@ -641,16 +645,18 @@ enum TokenUpdateDto { setPortraitImage = 43; setCharsheetImage = 44; setLayout = 45; - clearLightSources = 46; - removeLightSource = 47; - addLightSource = 48; - setHasSight = 49; - setSightType = 50; - flipX = 51; - flipY = 52; - flipIso = 53; - setSpeechName = 54; - removeFacing = 55; + createUniqueLightSource = 46; + deleteUniqueLightSource = 47; + clearLightSources = 48; + removeLightSource = 49; + addLightSource = 50; + setHasSight = 51; + setSightType = 52; + flipX = 53; + flipY = 54; + flipIso = 55; + setSpeechName = 56; + removeFacing = 57; } message AssetTransferHeaderDto { @@ -671,12 +677,13 @@ message TokenPropertyValueDto { string string_value = 3; double double_value = 4; MacroButtonPropertiesListDto macros = 5; - LightSourceDto light_source = 6; - AreaDto area = 7; - StringListDto string_values = 8; - GridDto grid = 9; - TokenFootPrintDto token_foot_print = 10; - string topology_type = 11; + string light_source_id = 6; + LightSourceDto light_source = 7; + AreaDto area = 8; + StringListDto string_values = 9; + GridDto grid = 10; + TokenFootPrintDto token_foot_print = 11; + string topology_type = 12; } } diff --git a/src/main/resources/net/rptools/maptool/client/fonts/EotE_Symbol-Regular_v1.otf b/src/main/resources/net/rptools/maptool/client/fonts/EotE_Symbol-Regular_v1.otf new file mode 100644 index 0000000000..ea1ebfcc76 Binary files /dev/null and b/src/main/resources/net/rptools/maptool/client/fonts/EotE_Symbol-Regular_v1.otf differ diff --git a/src/main/resources/net/rptools/maptool/client/fonts/GenesysGlyphsAndDice-3.0.otf b/src/main/resources/net/rptools/maptool/client/fonts/GenesysGlyphsAndDice-3.0.otf new file mode 100644 index 0000000000..88fa4c37ca Binary files /dev/null and b/src/main/resources/net/rptools/maptool/client/fonts/GenesysGlyphsAndDice-3.0.otf differ diff --git a/src/main/resources/net/rptools/maptool/client/image/tool/cover-vbl-only-off.png b/src/main/resources/net/rptools/maptool/client/image/tool/cover-vbl-only-off.png new file mode 100644 index 0000000000..73937e1698 Binary files /dev/null and b/src/main/resources/net/rptools/maptool/client/image/tool/cover-vbl-only-off.png differ diff --git a/src/main/resources/net/rptools/maptool/client/image/tool/cover-vbl-only.png b/src/main/resources/net/rptools/maptool/client/image/tool/cover-vbl-only.png new file mode 100644 index 0000000000..2cd9680dde Binary files /dev/null and b/src/main/resources/net/rptools/maptool/client/image/tool/cover-vbl-only.png differ diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index 2d7975a06f..c87099c8c0 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Fit GM view Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? Preferences.label.client.default.username = Default Username Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonymous User @@ -1654,7 +1655,7 @@ lineParser.countNonNeg = Count option requires a non negative numbe # Notice there are no double quotes around {0}. lineParser.dialogTitle = Input Value for {0}. lineParser.dialogTitleNoToken = Input Value. -lineParser.dialogValueFor = Value For +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Duplicate "{0}" tokens found. lineParser.emptyTokenName = Cannot assign a blank or empty string to the variable token.name lineParser.errorBodyRoll = Error in body of roll. @@ -2162,6 +2163,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can't remove player {0} to a database which doesn't support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can't load built-in library {0}. msg.info.action.disableFoW = FoW disabled. @@ -2504,8 +2507,8 @@ tool.crosstopology.instructions = LClick: set initial/final point; Shift LClick tool.crosstopology.tooltip = Draw a cross VBL tool.deletedrawing.instructions=LClick: Select drawings Double-Click: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = Draw a diamond. -tool.diamondexpose.tooltip = Expose/Hide a diamond on the Fog of War. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Unused tool.facing.tooltip = Set the token facing. tool.filltopology.tooltip = Fill in closed areas of VBL. @@ -2549,7 +2552,7 @@ tool.rectexpose.tooltip = Expose/Hide a rectangle on the Fog of War. tool.recttopology.instructions = LClick: set initial/final point, Shift+LClick: erase rectangle; Ctrl: snap-to-grid tool.recttopology.tooltip = Draw a rectangular VBL. tool.recttopologyhollow.tooltip = Draw a hollow rectangular VBL. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick: set initial/final point, Shift+LClick: erase isometric rectangle; Ctrl: snap-to-grid tool.stamp.tooltip = Stamp tool @@ -2557,10 +2560,10 @@ tool.walltemplate.instructions = LClick: set starting cell, move mouse in dire tool.walltemplate.tooltip = Draw a wall template. tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Drawing Tools tools.fog.tooltip = Fog of War Tools tools.interaction.tooltip = Interaction Tools @@ -2797,10 +2800,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label: @@ -2808,3 +2811,15 @@ Label.label=Label: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_cs.properties b/src/main/resources/net/rptools/maptool/language/i18n_cs.properties index 61dcfae064..4362ea8b5f 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_cs.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_cs.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Fit GM view Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? Preferences.label.client.default.username = Default Username Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonymous User @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Count option requires a non negative numbe # Notice there are no double quotes around {0}. lineParser.dialogTitle = Input Value for {0}. lineParser.dialogTitleNoToken = Input Value. -lineParser.dialogValueFor = Value For +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Duplicate "{0}" tokens found. lineParser.emptyTokenName = Cannot assign a blank or empty string to the variable token.name lineParser.errorBodyRoll = Error in body of roll. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = FoW disabled. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = LClick\: set initial/final point; Shift LClic tool.crosstopology.tooltip = Draw a cross VBL tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = Draw a diamond. -tool.diamondexpose.tooltip = Expose/Hide a diamond on the Fog of War. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Unused tool.facing.tooltip = Set the token facing. tool.filltopology.tooltip = Fill in closed areas of VBL. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Expose/Hide a rectangle on the Fog of War. tool.recttopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase rectangle; Ctrl\: snap-to-grid tool.recttopology.tooltip = Draw a rectangular VBL. tool.recttopologyhollow.tooltip = Draw a hollow rectangular VBL. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Stamp tool @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = LClick\: set starting cell, move mouse in dir tool.walltemplate.tooltip = Draw a wall template. tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Drawing Tools tools.fog.tooltip = Fog of War Tools tools.interaction.tooltip = Interaction Tools @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_da.properties b/src/main/resources/net/rptools/maptool/language/i18n_da.properties index 6ce1883104..7d32219c10 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_da.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_da.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Følg spilleder udsyn Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? Preferences.label.client.default.username = Standard brugernavn Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonym bruger @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Count option requires a non negative numbe # Notice there are no double quotes around {0}. lineParser.dialogTitle = Angiv værdi for {0}. lineParser.dialogTitleNoToken = Inputværdi. -lineParser.dialogValueFor = Værdi for +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Duplikerede "{0}" poletter fundet. lineParser.emptyTokenName = Cannot assign a blank or empty string to the variable token.name lineParser.errorBodyRoll = Fejl i brødtekst for terningslaget. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = Krigståge er slået fra. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = LClick\: set initial/final point; Shift LClic tool.crosstopology.tooltip = Tegn et kryds VBL tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Slet tegneværktøj -tool.diamond.tooltip = Tegn en diamant. -tool.diamondexpose.tooltip = Skjul/afslør en diamand på krigstågen. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Ubrugt tool.facing.tooltip = Sæt polettens retning. tool.filltopology.tooltip = Fill in closed areas of VBL. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Expose/Hide a rectangle on the Fog of War. tool.recttopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase rectangle; Ctrl\: snap-to-grid tool.recttopology.tooltip = Tegn en rektangulær VBL. tool.recttopologyhollow.tooltip = Draw a hollow rectangular VBL. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Stempelværktøj @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = LClick\: set starting cell, move mouse in dir tool.walltemplate.tooltip = Tegn en væg skabelon. tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. tools.ignore_vbl_on_move.tooltip = Poletter vil navigere rundt om VBL hvis valgt, ellers vil de frit bevæge sig ind i VBL. -tools.topology_mode_selection.vbl.tooltip = Tegn væg VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Tegn bakke VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Tegn grube VBL. -tools.topology_mode_selection.mbl.tooltip = Tegn MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Tegneværktøjer tools.fog.tooltip = Krigståge værktøjer tools.interaction.tooltip = Interaktionsværktøjer @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_de.properties b/src/main/resources/net/rptools/maptool/language/i18n_de.properties index 65fb925060..a3702e9c56 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_de.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_de.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Auf SL-Ansicht anpassen Preferences.label.client.fitview.tooltip = Wenn Spieler zur Ansicht des SLs gezwungen werden, sollte die Kartengröße des Spielers so eingestellt werden, dass der Bildschirm mindestens den gleichen Inhalt wie der Bildschirm des SLs anzeigt? Preferences.label.client.default.username = Standard-Benutzername Preferences.label.client.default.username.tooltip = Der Standard-Benutzername, der in der MapTool-Werkzeugleiste dargestellt wird. +Preferences.label.installDir = Installationsverzeichnis Preferences.client.webEndPoint.port = End-Point-Port des internen Webservers Preferences.client.webEndPoint.port.tooltip = Webserver End-Point-Port (nur MapTool-intern) Preferences.client.default.username.value = Anonymer Benutzer @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Die Zähloption benötigt eine nicht negat # Notice there are no double quotes around {0}. lineParser.dialogTitle = Eingabewert für {0}. lineParser.dialogTitleNoToken = Eingabewert. -lineParser.dialogValueFor = Wert für +lineParser.dialogValueFor = Wert für "{0}" lineParser.duplicateLibTokens = Doppelte "{0}" Spielmarken gefunden. lineParser.emptyTokenName = Kann keine leere Zeichenkette der Variablen token.name zuweisen lineParser.errorBodyRoll = Fehler in der Liste. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Fehler beim Aktualisieren von Sp msg.error.playerDB.cantRemovePlayer = Spieler {0} kann aus einer Datenbank, die Aktualisierung nicht unterstützt, nicht entfernt werden. msg.error.playerDB.noSuchPlayer = Spieler {0} existiert in der aktiven Spieler-Datenbank nicht. msg.error.parsing.handlebars = Fehler beim Einlesen der "handlebar"-Vorlage {0} +msg.error.library.builtin.path = Integrierter Bibliothekspfad nicht lesbar. +msg.error.library.builtin.load = Integrierter Bibliothekspfad {0} nicht ladbar. msg.info.action.disableFoW = Kriegsnebel deaktiviert. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = LKlick\: Setze Start-/Endpunkt; Shift LKlick\ tool.crosstopology.tooltip = Zeichne eine Kreuz VBL tool.deletedrawing.instructions=LKlick\: Zeichnungen wählen mit Doppelklick\: Ausgewählte Zeichnungen löschen. tool.deletedrawing.tooltip=Zeichenwerkzeug löschen -tool.diamond.tooltip = Zeichnen Sie ein Diamant. -tool.diamondexpose.tooltip = Diamant im Kriegsnebel aufdecken/verdecken. +tool.isorectangle.tooltip = Zeichne ein isometrisches Rechteck. +tool.isorectangleexpose.tooltip = Isometrisches Rechteck im Kriegsnebel ausblenden/verstecken. tool.facing.instructions = Ungenutzt tool.facing.tooltip = Bestimme die Blickrichtung der Spielmarke. tool.filltopology.tooltip = Fülle geschlossene Bereiche der VBL. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Rechteck im Kriegsnebel aufdecken/verdecken. tool.recttopology.instructions = LKlick\: Setze Start/Endpunkt; Shift LKlick\: Lösche Rechteck; Strg\: im Raster einrasten tool.recttopology.tooltip = Zeichne eine rechteckige VBL. tool.recttopologyhollow.tooltip = Zeichne eine nicht ausgefüllte, rechteckige VBL. -tool.isorectangletopology.tooltip = Zeichne ein isometrisches Rechteck VBL. +tool.isorectangletopology.tooltip = Zeichne ein isometrisches VBL-Rechteck. tool.isorectangletopologyhollow.tooltip = Zeichnen Sie ein hohles isometrisches Rechteck VBL. tool.isorectangletopology.instructions = LKlick\: Setze Start/Endpunkt; Shift+LKlick\: Lösche isometrisches Rechteck; Strg\: Einrasten tool.stamp.tooltip = Stempelwerkzeug @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = LKlick\: Setze Startpunkt, bewege Maus in Wan tool.walltemplate.tooltip = Zeichne eine Wandvorlage. tools.ai_selector.tooltip = Spielmarken bewegen sich um MBL, VBL herum (falls ausgewählt) und berücksichtigen Spielmarken mit Geländemodifikatoren. tools.ignore_vbl_on_move.tooltip = Spielmarken bewegen sich um VBL herum falls ausgewählt, andernfalls bewegen sie sich frei in SBS. -tools.topology_mode_selection.vbl.tooltip = Zeichne Wand VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Zeichne Hügel VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Zeichne Gruben VBL. -tools.topology_mode_selection.mbl.tooltip = Zeichne MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Zeichenwerkzeuge tools.fog.tooltip = Kriegsnebelwerkzeuge tools.interaction.tooltip = Interaktionswerkzeuge @@ -2624,10 +2627,10 @@ Label.icontheme=Icon-Design Preferences.label.icontheme.tooltip=Das Design für Applikations-Icons. Label.theme.macroeditor=Makroeditordesign TEXT_TYPE=Text-Typ -EditTokenDialog.button.movevbltoggle.tooltip=Wall Blocking Layer (VBL) beim Verschieben oder Kopieren einbeziehen -EditTokenDialog.button.movembltoggle.tooltip=Move Blocking Layer (MBL) beim Verschieben oder Kopieren einbeziehen -EditTokenDialog.button.movehbltoggle.tooltip=Hill Blocking Layer (HillVBL) beim Verschieben oder Kopieren einbeziehen -EditTokenDialog.button.movepbltoggle.tooltip=Pit Blocking Layer (PitVBL) beim Verschieben oder Kopieren einbeziehen +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Markierte Blocklayer von Karte verschieben oder kopieren EditTokenDialog.button.movetomap.tooltip=Markierte Blocklayer auf Karte verschieben oder kopieren Label.label=Bezeichnung\: @@ -2635,3 +2638,15 @@ Label.label=Bezeichnung\: # StatSheet token.statSheet.legacyStatSheetDescription = Werteblatt (Altversion vor 1.14) token.statSheet.useDefault = Standard-Werteblatt des Spielmarkentyps + +# Advanced Dice Rolls +advanced.roll.parserError = Fehler in Würfelwurfanweisung Zeile {0}, Zeichen {1} "{2}". +advanced.roll.unknownDiceType = Unbekannter "Dice Roll"-Typ {0}. +advanced.roll.unknownVariable = Unbekannte Variable {0}. +advanced.roll.variableNotNumber = Variable {0} ist keine Zahl. +advanced.roll.unknownProperty = Unbekannte Eigenschaft {0}. +advanced.roll.propertyNotNumber = Variable {0} ist keine Zahl. +advanced.roll.noTokenInContext = Keine Spielmarke im Kontext. +advanced.roll.inputNotNumber = Eingabe {0} ist keine Zahl. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties b/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties new file mode 100644 index 0000000000..09270fc578 --- /dev/null +++ b/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties @@ -0,0 +1,2825 @@ + +#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/) +# This software copyright by various authors including the RPTools.net +# development team, and licensed under the LGPL Version 3 or, at your +# option, any later version. +# +# Portions of this software were originally covered under the Apache +# Software License, Version 1.1 or Version 2.0. +# +# See the file LICENSE elsewhere in this distribution for license details. +#_____________________________________________________________________ +# +# This is the English translation file for MapTool 1.3. If you are +# translating MapTool to another language and leave out a translation +# for any key that appears here (the "key" is the text before the "=") +# then the values in this file will be used. +# +# Please submit all translations using the UTF-8 encoding! If you MUST +# use a different encoding, please document it INSIDE your translation +# file. I use an automated technique to detect the encoding and convert +# the file to the Unicode format that Java needs. (For those who are +# interested, it involves the "native2ascii" program which is part of +# the Java Software Development Kit.) +# +# Some of the keys used in this file are not consistent. :( For example, +# the NewMap menu option has the key "action.newMap" but the QuickMap +# menu option is "menu.QuickMap". IMO this should be fixed, but MapTool +# 1.4 will likely have a completely different (i.e. consistent) set of +# keys, so we're not going to bother for 1.3. +# +# In all cases in this file, any accelerator keystroke will automatically +# have the 'menuShortcut' key added to it. For Windows this is the Ctrl +# key, on the Mac it's the Command (Cmd) key. Other platforms may have yet +# other keys. +# +# IMPORTANT: Do not add the platform-dependent menu modifier key to this +# file! If you add "ctrl", for example, the modifier will be ignored +# on Windows but will require Mac users to use Cmd-Ctrl-C for a copy +# operation. This is an ugly situation and we should find some way to +# define a menuShortcutKey (such as "menu") and then be able to use +# that in our definition strings. I expect that MapTool 1.4 will have +# a user interface for changing these keystrokes so perhaps it's all +# moot anyway. +# +# Note that the accelerator keys are not case-sensitive. So if you +# specify "F" as the accelerator, that means lowercase "F". If you +# want an uppercase "F", add the word "shift": "shift F" or "shift f". +# There are a lot of examples of this throughout the file. +# +# Check the javadoc for the 'MessageFormat' class for more details on +# the formatting of text in this file, as you'll see below (basically +# anything with braces): +# http://download.oracle.com/javase/7/docs/api/java/text/MessageFormat.html +# Localization contributed by David Herman ("aku" on forums.rptools.net) +ActivityMonitorPanel.colorDefinition = Green:Sending, Red:Receiving + +AppHomeDiskSpaceStatusBar.toolTip = Current free space in users home directory. + +AssetCacheStatusBar.toolTip = Current size of Asset cache directory, Double-Click to clear this cache. + +AssetViewerDialog.leftDragMove = Left button drag to move +AssetViewerDialog.rightDragResize = Right button drag to resize + +AutoSaveManager.failed = Autosave failed: +AutoSaveManager.failed_badState = Autosave failed:\nBad application state?! Please report this! +AutoSaveManager.status.autoSaveComplete = Autosave complete. Elapsed time (ms): {0,number} +AutoSaveManager.status.autoSaving = Autosaving campaign... +AutoSaveManager.status.lockFailed = Autosave skipped. Background operation in progress. + +CampaignProperties.error.initLightSources = Cannot initialize light sources. +CampaignProperties.error.noGenericLight = Can''t get light source "Generic : 5"?! + +ChatAutoSave.status.chatAutosave = Autosaving chat log... + +Color.aqua = aqua +Color.black = black +Color.blue = blue +Color.cyan = cyan +Color.darkgray = dark gray +Color.fuchsia = fuchsia +Color.gray = gray +Color.gray25 = 25% gray +Color.gray50 = 50% gray +Color.gray75 = 75% gray +Color.green = green +Color.lightgray = light gray +Color.lime = lime +Color.magenta = magenta +Color.maroon = maroon +Color.navy = navy +color.olive = olive +Color.orange = orange +Color.pink = pink +Color.purple = purple +Color.red = red +Color.silver = silver +Color.teal = teal +Color.white = white +Color.yellow = yellow +Color.none = None +Color.custom = Custom +Color.default = Default + +Button.ok = OK +Button.cancel = Cancel +Button.refresh = Refresh +Button.rescan = Rescan +Button.revert = Revert +Button.close = Close +Button.import = Import +Button.export = Export +Button.delete = Delete +Button.add = Add +Button.new = New +Button.browse = Browse +Button.update = Update +Button.apply = APPLY +Button.accept = Accept +Button.up = Move Up +Button.down = Move Down +Button.background = Background +Button.map = Map +Button.fog = Fog +Button.clear = Clear +Button.clearall = Clear All +Button.yes = Yes +Button.no = No +Button.install = Install +Button.runmacro = RUN MACRO +Button.hide = Hide + +Label.lights = Vision: +Label.name = Name: +Label.gmname = GM Name: +Label.speechName = Speech Bubble Name: +Label.optional = Optional +Label.options = Options +Label.maps = Maps +Label.objects = Objects +Label.token = Token +Label.tokens = Tokens +Label.backgrounds = Backgrounds +Label.macroeditor = Macro Editor +Label.styletheme = Style Theme +Label.currentTheme = Current Theme +Label.filterTheme = Theme Filter +Label.useThemeForChat = Use Theme Colours for Chat Window +Label.facing = Facing +Label.accessibility = Accessibility +Label.sounds = Sounds +Label.auth = Authentication +Label.version = MapTool Version: +Label.startup = Startup +Label.themes = Themes +Label.application = Application +Label.preferences = Preferences +Label.save = Save +Label.minute = min +Label.performance = Performance +Label.client = Client +Label.macropanels = Macro Panels +Label.upnp = UPnP +Label.macropermissions = Macro Permissions +Label.path = Path: +Label.url = URL +Label.url2 = URL: +Label.library = RPTools Library +Label.progress = Progress +Label.about = About +Label.dimensions = Dimensions: +Label.layer = Layer: +Label.grid = Grid +Label.tile = Tile +Label.ready = Ready +Label.saved = Saved +Label.filesystem = Filesystem ... +Label.filesystem2 = Filesystem +Label.roll = Roll: +Label.table.image = Table Image +Label.blankdefault = (Leave blank for default) +Label.range = Range +Label.image = Image +Label.value = Value +Label.image.choose = Choose Image +Label.table.import = Import Table +Label.table.export = Export Table +Label.preview = Preview +Label.foreground = Foreground: +Label.showbackground = Show Background: +Label.layers = Layers: +Label.view.current = Current View +Label.host = Host: +Label.location = Location: +Label.advanced = Advanced +Label.view = View: +Label.board = Board +Label.visibility = Visibility +Label.pathfilename = Path/Filename: +Label.allowURIAccess = Allow URI Access + +CampaignPropertyDialog.error.parenthesis = Missing right parenthesis ")" in the following property: {0} + +ColorPicker.tooltip.gridSnap = Snap to Grid +ColorPicker.tooltip.lineType = Line Type +ColorPicker.tooltip.eraser = Eraser +ColorPicker.tooltip.penWidth = Pen Width +ColorPicker.tooltip.opacity = Opacity + +ConnectToServerDialog.msg.headingServer = Server Name +ConnectToServerDialog.msg.headingVersion = Version +ConnectToServerDialog.msg.title = Connect to Server +# This next string will use the results of looking up 'menu.file' for {0} and the lookup of 'action.showConnectionInfo' for {1}. +ConnectToServerDialog.warning.doNotUseExternalAddress = It is unlikely that using your own external IP address will work.

Use your local address or localhost.

To see the current values, use the {1} option of the {0} menu.


Attempt connection anyway? +ConnectToServerDialog.username = Username: +ConnectToServerDialog.password = Password +ConnectToServerDialog.usePublicKey = Connect using public key +ConnectToServerDialog.role = Role: +ConnectToServerDialog.server.name = Server Name: +ConnectToServerDialog.server.local = Local Servers: +ConnectToServerDialog.server.address = Address: +ConnectToServerDialog.server.port = Port: +ConnectToServerDialog.tab.lan = LAN +ConnectToServerDialog.tab.direct = Direct + +ConnectionInfoDialog.title = Server Info +ConnectionInfoDialog.address.local = Local Address: +ConnectionInfoDialog.address.external = External Address: +ConnectionInfoDialog.port = Port: +ConnectionInfoDialog.discovering = Discovering... + +ConnectionStatusPanel.notConnected = Not connected +ConnectionStatusPanel.runningServer = Running a Server +ConnectionStatusPanel.playersLoadedZone = {0} out of {1} players have loaded their zone +ConnectionStatusPanel.serverConnected = Connected to Server + +CoordinateStatusBar.mapCoordinates = Map Coordinates + +DrawPanelPopupMenu.menu.group = Group Drawings +DrawPanelPopupMenu.menu.ungroup = Ungroup +DrawPanelPopupMenu.menu.merge = Merge Drawings +DrawPanelPopupMenu.menu.getProperties = Get Properties +DrawPanelPopupMenu.menu.setProperties = Set Properties +DrawPanelPopupMenu.menu.setName = Set Name +DrawPanelPopupMenu.menu.getId = Get Drawing ID +DrawPanelPopupMenu.menu.pathVbl = Path to VBL +DrawPanelPopupMenu.menu.shapeVbl = Shape to VBL +DrawPanelPopupMenu.menu.vbl.add = Add to VBL +DrawPanelPopupMenu.menu.vbl.remove = Remove from VBL +DrawPanelPopupMenu.dialog.name.title = Set Name +DrawPanelPopupMenu.dialog.name.msg = Enter a name: + +EditLookupTablePanel.error.badRange = Table "{0}" contains bad range "{1}" on row {2,number}. +EditLookupTablePanel.error.invalidSize = Table "{0}" must have at least one row. +EditLookupTablePanel.error.noName = Table must have a name. +EditLookupTablePanel.error.sameName = Table name "{0}" duplicates existing table. +EditLookupTablePanel.tooltip.allowLookup = Selecting this box allows players to execute a lookup against this table (i.e. double-click the table, use /table, or macro functions). +EditLookupTablePanel.tooltip.visible = Selecting this box allows players to see this table in their Tables panel. +EditLookupTablePanel.create.tooltip = Create a new lookup table. +EditLookupTablePanel.edit.tooltip = Edit selected table. +EditLookupTablePanel.delete.tooltip = Delete table. +EditLookupTablePanel.duplicate.tooltip = Duplicate selected table. +EditLookupTablePanel.showplayer = Show Table to Players +EditLookupTablePanel.lookup = Allow Lookup by Players + +EditTokenDialog.label.label = Label: +EditTokenDialog.tab.notes = Notes +EditTokenDialog.label.gmnotes = GM Notes +EditTokenDialog.menu.notes.sendChat = Send to Chat +EditTokenDialog.menu.notes.sendEmit = Send as Emit +EditTokenDialog.label.shape = Shape: +EditTokenDialog.label.snaptogrid = Snap To Grid: +EditTokenDialog.label.size = Size: +EditTokenDialog.label.visible = Visible to players: +EditTokenDialog.label.properties = Properties: +EditTokenDialog.label.visible.owner = Visible to Owners Only: +EditTokenDialog.label.sight.has = Has Sight: +EditTokenDialog.label.terrain.mod = Terrain Modifier: +EditTokenDialog.label.terrain.mod.tooltip= Adjust the cost of movement other tokens will may to move over or through this token. Default multiplier of 1 equals no change (1 * 1 = 1). +EditTokenDialog.label.image = Image Table: +EditTokenDialog.label.opacity = Token Opacity: +EditTokenDialog.label.opacity.tooltip = Change the opacity of the token. +EditTokenDialog.label.opacity.100 = 100% +EditTokenDialog.label.terrain.ignore = Ignore Terrain: +EditTokenDialog.label.terrain.ignore.tooltip= Select any terrain modifier types this token should ignore. +EditTokenDialog.label.statSheet = Stat Sheet +EditTokenDialog.label.defaultStatSheet = Default Stat Sheet +EditTokenDialog.combo.terrain.mod = Set whether the cell cost should be added or multiplied. Use negative numbers to subtract and decimal values to divide costs. +EditTokenDialog.border.title.layout = Layout +EditTokenDialog.border.title.portrait = Portrait +EditTokenDialog.border.title.handout = Handout +EditTokenDialog.border.title.charsheet = Charsheet +EditTokenDialog.status.layout.instructions = Mouse Wheel to zoom; double-LClick to reset position and zoom +EditTokenDialog.label.allplayers = All Players +EditTokenDialog.tab.properties = Properties +EditTokenDialog.tab.vbl = Topology +EditTokenDialog.tab.state = State +EditTokenDialog.tab.speech = Speech +EditTokenDialog.tab.ownership = Ownership +EditTokenDialog.tab.config = Config +EditTokenDialog.tab.hero = Hero Lab +EditTokenDialog.tab.libToken = Lib:Token properties +EditTokenDialog.button.vbl = Generate Token Topology +EditTokenDialog.button.vbl.tooltip = This will create VBL/MBL based on non-transparent pixels. +EditTokenDialog.button.vbl.clear = Clear Token Topology +EditTokenDialog.button.vbl.clear.tooltip = Clear VBL/MBL from token. +EditTokenDialog.button.vbl.tomap = Move Topology To Map +EditTokenDialog.button.vbl.frommap = Move Topology From Map +EditTokenDialog.button.vbl.preview = VBL Preview +EditTokenDialog.option.vbl.erase = Erase Source Topology on Move +EditTokenDialog.option.vbl.erase.tooltip = Move the VBL/MBL vs Copy it. +EditTokenDialog.label.vbl.visiblity = Token Visibility +EditTokenDialog.label.vbl.tolerance = Visibility Tolerance +EditTokenDialog.label.vbl.preview = Hide Token Image Preview +EditTokenDialog.label.vbl.preview.tooltip= Do not generate a preview of the VBL/MBL in this window. +EditTokenDialog.label.vbl.sensitivity = Colour Sensitivity +EditTokenDialog.label.vbl.sensitivity.tooltip = Adjust the sensitivity to the colour match that will be used to generate VBL, values 0-255 with 0 being an exact colour match. +EditTokenDialog.label.vbl.invert = Inverse Topology Colour Selection +EditTokenDialog.label.vbl.invert.tooltip = Generate VBL/MBL where the colour does not match on the token when checked. +EditTokenDialog.label.vbl.level = Level +EditTokenDialog.label.vbl.method = Method +EditTokenDialog.label.vbl.optimize = Topology Optimization +EditTokenDialog.drop.vbl.optimize.tooltip= Advanced Use: Choose the algorithm used to decimate curves in the generated polygon.

The default is generally the best but unique polygons may benifit from one of the other selected algorithms. +EditTokenDialog.label.vbl.over = Is Visible over FoW +EditTokenDialog.label.vbl.over.tooltip = Always show this token over FoW when in sight of another token. Useful for doors, statues, columns, roofs, etc. +EditTokenDialog.label.vbl.color = Colour Selection +EditTokenDialog.label.vbl.toggle = Pick a colour from the image to match against when generating token VBL/MBL. +EditTokenDialog.label.vbl.well = Manually pick a colour to match against when generating token VBL/MBL. +EditTokenDialog.border.title.vbl.preview = Topology Preview +EditTokenDialog.status.vbl.instructions = Mouse Wheel to zoom; double-LClick to reset position and zoom +EditTokenDialog.label.hero.summary = Summary: +EditTokenDialog.label.hero.portfolio = Portfolio: +EditTokenDialog.label.hero.last = Last Modified: +EditTokenDialog.button.hero.setAsTokenPortrait = Set as Token Portrait +EditTokenDialog.button.hero.setAsTokenImage = Set as Token Image +EditTokenDialog.button.hero.setAsTokenHandout = Set as Token Handout +EditTokenDialog.label.hero.isAlly = Ally? +EditTokenDialog.label.hero.statBlockSearch = Expression: +EditTokenDialog.button.hero.statBlockSearch.tooltip = Search the statblock using the expression provided. +EditTokenDialog.label.hero.statBlockSearch.tooltip = Enter raw text, a regular expression or an xPath expression to search the statblock for. +EditTokenDialog.action.hero.statBlockRTextScroll = Find +EditTokenDialog.tab.hero.images = Images +EditTokenDialog.tab.hero.text = TEXT +EditTokenDialog.tab.hero.xml = XML +EditTokenDialog.tab.hero.html = HTML +EditTokenDialog.spinner.tolerance.tooltip= Sets the tolerance for the optimization, a value of 0 disables optimization and values > 0 reduce the number of polygon points for better performance. +EditTokenDialog.vbl.explanation.tooltip = Controls how many of the tokens regions must be seen before showing over FoW, range is 1-9 regions.

The image is sliced into an even 3 x 3 grid for a total of 9 regions. The tolerance controls how many of these "regions" must be "seen" by another token before it's image is revealed.

For a very large roof, because of vision distance, you may want to use a value of 1.
Where as for a smaller token like a statue, you may not want to show the image until more of it is visable and use a value of 3 or 4. +EditTokenDialog.confirm.clearSpeech = Are you sure you want to clear all speech for this token? +EditTokenDialog.confirm.vbl.autoGenerate = Are you sure you want to reset all VBL/MBL \n and automatically generate VBL/MBL for this token? +EditTokenDialog.confirm.vbl.clearVBL = Are you sure you want to clear all VBL/MBL for this token? +# These "generic" entries are currently not used; they're supposed to be +# overridden with specific entries in the code. So if they show up, +# it's a software bug. ;-) +EditTokenDialog.msg.generic.colKey = Key (Bug!) +EditTokenDialog.msg.generic.colValue = Value (Bug!) +EditTokenDialog.msg.speech.colID = ID +EditTokenDialog.msg.speech.colSpeechText = Speech Text +EditTokenDialog.msg.title = Edit Token +EditTokenDialog.msg.wrap = Wrap +EditTokenDialog.vbl.label.originalPointCount = Original Point Count +EditTokenDialog.vbl.label.optimizedPointCount = Optimized Point Count +EditTokenDialog.vbl.label.working = Working... +EditTokenDialog.checkbox.state.hide = Hide +EditTokenDialog.button.hero.refresh.tooltip.on = Refresh data from Hero Lab
Changes detected! +EditTokenDialog.button.hero.refresh.tooltip.off = Refresh data from Hero Lab
No changes detected... +EditTokenDialog.libTokenURI.error.notLibToken = {0} is not a valid name for a lib:Token. +EditTokenDialog.libTokenURI.error.reserved = lib:Tokens can not be named {0} if you want to enable URI access. + +MapPropertiesDialog.label.playerMapAlias = Display Name: +MapPropertiesDialog.label.playerMapAlias.tooltip = This is how players will see the map identified. Must be unique within campaign. +MapPropertiesDialog.label.Name.tooltip = This is how the map is referred to in macros and is only visible to the GM. +MapPropertiesDialog.label.cell.type = Cell Type: +MapPropertiesDialog.label.cell.dist = Distance per cell: +MapPropertiesDialog.label.cell.pixels = Pixels per Cell: +MapPropertiesDialog.label.cell.ai = AI Cell Rounding: +MapPropertiesDialog.label.vision.dist = Vision Distance: +MapPropertiesDialog.label.lights.tooltip = Can be Off, Day or Night. Can be changed after the map is created. +MapPropertiesDialog.image.nogrid = No Grid +MapPropertiesDialog.label.cell.ai.tooltip = This controls how the AI will round the distance per cell after terrain modifiers have been applied. The default is no rounding, which may leave the cell cost as a fraction and/or not in even multiples of cell units. +MapPropertiesDialog.label.image = Select Map Image +MapPropertiesDialog.label.background = Choose Background +MapPropertiesDialog.label.fog = Choose Fog +MapPropertiesDialog.label.lightingStyle = Lighting style: +MapPropertiesDialog.label.lightingStyle.tooltip = Controls how lights will be rendered. The default is "Overtop", which renders lights as a translucent overlay on top of the map (useful for black & white maps and similar). "Environmental" renders lights as though they illuminate the map itself (useful for full-colour artwork maps). + +AddResourcesDialog.label.localdirectory = Local Directory +AddResourcesDialog.label.example = (e.g. c:\\data\\cmpgn_images) +AddResourcesDialog.label.none = None + +AdjustBoardDialog.title = Adjust Board Position +AdjustBoardDialog.snapto = Snap to: +AdjustBoardDialog.none.tooltip = No snap. +AdjustBoardDialog.grid.tooltip = Snap to the token grid. +AdjustBoardDialog.tile.tooltip = Snap to the repeating background texture. + +GridControlPanel.size = Grid Size +GridControlPanel.size.second = 2nd Size +GridControlPanel.offset.x = Offset X +GridControlPanel.offset.y = Offset Y +GridControlPanel.colour = Colour +GridControlPanel.secondColour = 2nd Colour + +GridlessGrid.error.notLoaded = Could not load gridless grid footprints. + + + +# Handshake messages +Handshake.msg.duplicateName = Someone is already using that player name. Please choose another name and try again. +Handshake.msg.wrongPassword = You entered the wrong password. Please try again. +Handshake.msg.unknownPlayer = Player {0} is unknown. +Handshake.msg.wrongVersion = The versions used do not match. You are trying to connect a client running version {0} to a server running version {1}.
Please update your client to the correct version. +Handshake.msg.failedLogin = Failed login attempt from {0}, errors decoding handshake follow. +Handshake.msg.failedLoginDecode = Failed decoding handshake with password. +Handshake.msg.encodeInitFail = Failed to initialize encoding for handshake. +Handshake.msg.badChallengeResponse = Bad Handshake challenge response by client for player {0}. +Handshake.msg.errorValidating = Error validating handshake. +Handshake.msg.unableToConnectPublicKey = Unable to connect using public key. +Handshake.msg.invalidHandshake = Unable to connect due to Invalid Handshake. +Handshake.msg.playerBlocked = Player is blocked: {0}. +Handshake.msg.incorrectPassword = Incorrect Password during handshake. +Handshake.msg.incorrectPublicKey = Incorrect public key used during handshake. +Handshake.msg.deniedEasyConnect = Easy connect request denied. +Handshake.msg.gmDeniedRequest = GM has denied your request to connect. +Handshake.msg.playerAlreadyConnected = That player name is already connected. + +Update.title = Update Available +Update.msg1 = A new version of MapTool is available! +Update.msg2 = Would you like to download {0}? +Update.button = Skip this Version +Update.chkbox = Never check for updates again! + +ExportCampaign.desc = Export campaign to a previous version + +ExportScreenshot.view.current.tooltip = What you see is what you get. +ExportScreenshot.view.asselected = As Selected +ExportScreenshot.view.asselected.tooltip = Pick which layers to include in the screenshot. +ExportScreenshot.view.entiremap = Entire Map +ExportScreenshot.view.entiremap.tooltip = Entire map, respects visibility and fog. +ExportScreenshot.view.fog.tooltip = Entire Map: Same as enabling fog on the Map menu. Entire Map As Layers: If checked, a separate file will be exported with the current fog mask. +ExportScreenshot.view.gm.tooltip = Everything the GM sees. +ExportScreenshot.view.player.tooltip = Only what a Player can see. +ExportScreenshot.view.layer.tooltip = Include this layer. +ExportScreenshot.view.board.tooltip = The tiling background and/or the image used in "New Map". +ExportScreenshot.view.layer.vbl.tooltip = Saves Visibility Blocking Layer (VBL) as a monochrome image. +ExportScreenshot.ftp.path.note = NOTE: path must already exist +ExportScreenshot.ftp.host.example = (ex: myhost.com) +ExportScreenshot.ftp.username.example = (ex: pbpuser) +ExportScreenshot.ftp.path.example = (ex: path/to/my/images/map.png) +ExportScreenshot.method.label = Rendering Method: +ExportScreenshot.method.buffered = Buffered Image +ExportScreenshot.method.buffered.tooltip = Renders the image into a single bitmap then saves that to the chosen location. Can use a lot of memory, and may fail if the image is too large. +ExportScreenshot.method.iw = Image Writer +ExportScreenshot.method.iw.tooltip = Renders the image incrementally as it is needed by the file output formatting code. Uses less memory. Extremely large files can take a long time. The UI will not update during the file output, so the program may be unresponsive for several minutes while the file is saved. +ExportScreenshot.method.bg = Background Thread +ExportScreenshot.method.bg.tooltip = NOT IMPLEMENTED! Uses the Image Writer technique in a background thread so that the UI can be updated with the progress. + + +ImageCacheStatusBar.toolTip = Current size of Image thumbs cache directory, Double-Click to clear this cache. + +# {0} is the table name to be deleted. +LookupTablePanel.confirm.delete = Delete table "{0}"? +LookupTablePanel.confirm.export = Export table "{0}"? +LookupTablePanel.confirm.import = Import table "{0}"? +LookupTablePanel.confirm.overwrite = Overwrite table "{0}"? +LookupTablePanel.error.loadFailed = Could not load table. +LookupTablePanel.error.saveFailed = Could not save table "{0}". +LookupTablePanel.info.saved = Table saved as "{0}". +LookupTablePanel.msg.titleEdit = Edit Table +LookupTablePanel.msg.titleNew = New Table + +# Unfortunately, the Details button has not been localized yet. :( +MapToolEventQueue.details = Click the Details... button to see more information.
Please copy/paste the contents to a forum post when reporting errors. +MapToolEventQueue.stackOverflow = A stack overflow has occurred.\n\nThis is commonly because a macro being used has exceeded the stack space specified when MapTool was executed.\n\nPlease specify a larger stack size for MapTool and run again. +MapToolEventQueue.stackOverflow.title = Error: Stack Overflow +MapToolEventQueue.unexpectedError = An unexpected error has occurred. +MapToolEventQueue.warning.title = Warning + +MemoryStatusBar.tooltip = Used Memory: {0}M, Total Memory: {1}M, Maximum Memory:{2}M + +PaintChooser.title = Choose Paint + +PersistenceUtil.error.campaignPropertiesLegacy = This campaign properties file is not a legacy format file readable by this version of MapTool. +PersistenceUtil.error.campaignPropertiesVersion = This campaign properties file is not readable by this version of MapTool. +PersistenceUtil.error.campaignPropertiesRead = Error while reading campaign properties data from file. +PersistenceUtil.warn.campaignProperties.importWrongFileType = File is not a MapTool campaign properties file. File is {0}. + +PersistenceUtil.error.campaignRead = Error while reading campaign file. +PersistenceUtil.error.campaignVersion = This campaign file is not readable by this version of MapTool.
We will attempt to load using the legacy format... +# The keys ending with "Read" are for reporting IOExceptions. +# The ones ending with "Version" are for reporting ConversionExceptions (from XStream). +PersistenceUtil.error.macroRead = Error while reading macro button data from file. +PersistenceUtil.error.macroVersion = This macro button file is not readable by this version of MapTool. +PersistenceUtil.error.macrosetVersion = This macroset file is not readable by this version of MapTool. +PersistenceUtil.error.mapRead = Error while reading map data from file. +PersistenceUtil.error.mapVersion = This map file is not readable by this version of MapTool. +PersistenceUtil.error.tableRead = Error while reading table data from file. +PersistenceUtil.error.tableVersion = This table file is not readable by this version of MapTool. +PersistenceUtil.warn.campaignNotLoaded = Cannot determine campaign file format; not loaded. +PersistenceUtil.warn.campaignWrongFileType = File is not a MapTool campaign file. File is {0}. +PersistenceUtil.warn.importWrongFileType = File is not a MapTool map file. File is {0}. +PersistenceUtil.warn.macroWrongFileType = File is not a MapTool macro file. File is {0}. +PersistenceUtil.warn.macroSet = a Macro Set +PersistenceUtil.warn.macrosetWrongFileType = File is not a MapTool macro set file. File is {0}. + +Preferences.tab.developer = Developer +Preferences.tab.developer.warning = These options are not meant for normal use. If you aren't developing or debugging MapTool, don't enable them! +Preferences.developer.info.developerOptionsInUse = The following developer options are enabled: +Preferences.developer.autoSaveMeasuredInSeconds.label = Measure auto-save time in seconds +Preferences.developer.autoSaveMeasuredInSeconds.tooltip = When enabled, increases the frequency of auto-saves by reinterpreting the number as measuring seconds instead of minutes. +Preferences.developer.showPartitionDrawableBoundaries.label = Show spatial partitions when rendering drawings +Preferences.developer.showPartitionDrawableBoundaries.tooltip = When enabled, draws a boundary around each spatial partition that is used in drawing rendering. +Preferences.developer.showAiDebugging.label = Enable AI debugging +Preferences.developer.showAiDebugging.tooltip = When enabled, adds labels containing the f, g, and h costs calculated by A* during pathfinding, as well as the moves blocked by VBL. +Preferences.developer.ignoreGridShapeCache.label = Ignore grid shape cache +Preferences.developer.ignoreGridShapeCache.tooltip = When enabled, the grid's shape is recalculated every time it is needed. +Preferences.developer.info.developerOptionsInUsePost = If this is not intended, go to {0} > {1} > {2} tab and disable the options there. +Preferences.tab.interactions = Interactions +Preferences.label.maps.fow = New maps have Fog of War +Preferences.label.maps.fow.tooltip = Fog of War can be enabled or disabled on individual maps. +Preferences.label.maps.visible = New maps visible to players +Preferences.label.maps.visible.tooltip = Individual maps may or may not be visible to players. +Preferences.label.maps.grid = New Map Grid Type +Preferences.label.maps.grid.tooltip = The grid type for new maps. Cannot be changed once the map has been created. +Preferences.combo.maps.grid.square = Square +Preferences.combo.maps.grid.hexHori = Horizontal Hex +Preferences.combo.maps.grid.hexVert = Vertical Hex +Preferences.combo.maps.grid.isometric = Isometric +Preferences.label.maps.grid.new = New Map Grid Size +Preferences.label.maps.grid.new.tooltip = Number of map pixels that represents one unit of distance. +Preferences.label.maps.units = New Map Units Per Cell +Preferences.label.maps.units.tooltip = The size of a grid cell in game-system units. +Preferences.label.maps.vision = New Map Vision Distance +Preferences.label.maps.vision.tooltip = The distance at which MapTool should stop calculating sight lines. +Preferences.label.maps.light = New Map Vision +Preferences.label.maps.light.tooltip = The type of vision selected in a new map. +Preferences.label.maps.metric = Movement metric +Preferences.label.maps.metric.tooltip = Determines how MapTool handles movement on the selected grid type. +Preferences.label.maps.sortType = Sorting Method +Preferences.label.maps.sortType.tooltip = Determines if the maps are sorted by Name or Display Name +Preferences.label.objects.snap = Start Snap to Grid +Preferences.label.objects.snap.tooltip = Whether images dropped on the Object layer have snap-to-grid turned on by default. +Preferences.label.objects.free = Start Freesize +Preferences.label.objects.free.tooltip = If enabled, new objects will be shown at their native resolution with a resizing handle attached. +Preferences.label.background.snap.tooltip = Whether images dropped on the Background layer have snap-to-grid turned on by default. +Preferences.label.background.free.tooltip = If enabled, new background images will be shown at their native resolution with a resizing handle attached. +Preferences.label.tokens.snap.tooltip = Whether tokens have snap-to-grid turned on by default. +Preferences.label.tokens.free.tooltip = Whether new tokens will be shown at their native resolution. +Preferences.label.tokens.visible = New tokens visible to players +Preferences.label.tokens.visible.tooltip = Whether tokens dropped by the GM are immediately visible to players. (Note that token owners can always see their tokens.) +Preferences.label.tokens.delete = Warn when tokens are deleted +Preferences.label.tokens.delete.tooltip = There is no "undo" for token deletion. You probably want this enabled. +Preferences.label.tokens.duplicate = Duplicate Token Numbering +Preferences.label.tokens.duplicate.tooltip = When a token is pasted or dropped onto a map, how should duplicate names be resolved. +Preferences.combo.tokens.duplicate.increment = Increment +Preferences.combo.tokens.duplicate.random = Random +Preferences.label.tokens.numbering = Show Numbering on +Preferences.combo.tokens.numbering.name = Name +Preferences.combo.tokens.numbering.gm = GM Name +Preferences.combo.tokens.numbering.both = Both +Preferences.label.tokens.naming = New Token Naming +Preferences.label.tokens.naming.tooltip = Determines how new tokens are initially named. +Preferences.combo.tokens.naming.filename = Use Filename +# {0} is the localized version of "Creature" (See: Token.name.creature) +Preferences.combo.tokens.naming.creature = Use "{0}" +Preferences.label.tokens.dialog = Show Dialog on New Token +Preferences.label.tokens.dialog.tooltip = Determines whether the New Token dialog appears when a token is dropped onto the map. +Preferences.label.tokens.statsheet = Statsheet Portrait Size +Preferences.label.tokens.statsheet.tooltip = Size of the image that appears next to the statsheet on mouseover. Set to zero to disable portraits. +Preferences.label.tokens.portrait.mouse = Show Portrait on mouseover +Preferences.label.tokens.portrait.mouse.tooltip = Whether to show the portrait when the mouse hovers over a Token. +Preferences.label.tokens.statsheet.mouse = Show statsheet on mouseover +Preferences.label.tokens.statsheet.mouse.tooltip = Whether to show the statsheet when the mouse hovers over a Token. +Preferences.label.tokens.statsheet.shift = Stat sheet requires Shift key +Preferences.label.tokens.statsheet.shift.tooltip = The stat sheet will only show when the mouse hovers over a Token if the Shift key is also held down. Otherwise, Shift key will hide stat sheet on mouse hovers. +Preferences.label.tokens.arrow = Force Token Facing Arrow +Preferences.label.tokens.arrow.tooltip = Forces the display of the token facing arrow for Top Down tokens and tokens with image tables. +Preferences.label.tokens.drag.snap = Snap Token while dragging +Preferences.label.tokens.drag.snap.tooltip = Token image snaps to movement path while dragging. +Preferences.label.tokens.drag.hide = Hide Mouse Pointer while dragging +Preferences.label.tokens.drag.hide.tooltip = When dragging tokens the mouse pointer will be hidden. +Preferences.label.chat.avatar = Show Avatar per line +Preferences.label.chat.avatar.tooltip = Causes an icon of the impersonated token to appear at the beginning of each chat message. +Preferences.label.chat.smilies = Insert Smilies +Preferences.label.chat.smilies.tooltip = Certain strings of text are treated as smilies and replaced with images. A popup panel of smilies appears to the right of the chat input box. +Preferences.label.chat.rolls = Use ToolTips for Inline Rolls +Preferences.label.chat.rolls.tooltip = Die rolls are normally expanded and included in the chat window output. This options changes them into tooltips, although the result is still shown normally. +Preferences.checkbox.chat.rolls.tooltip = Enabled: [ ] acts like [t: ]
Disabled: [ ] acts like [h: ] +Preferences.label.chat.type.duration = Typing Notification Duration Seconds +Preferences.label.chat.type.duration.tooltip = Time before typing notifications disappear, in seconds. +Preferences.label.chat.type.color = Typing Notification Colour +Preferences.label.chat.type.color.tooltip = Colour of the text for typing notifications. +Preferences.label.chat.type.background = Typing Notification Background +Preferences.label.chat.type.background.tooltip = If enabled, shows a background frame underneath the typing notification. +Preferences.label.chat.trusted.background = Trusted Prefix Background +Preferences.label.chat.trusted.background.tooltip = Text generated by trusted macros is forced to a particular background colour. +Preferences.label.chat.trusted.foreground = Trusted Prefix Foreground +Preferences.label.chat.trusted.foreground.tooltip = Text generated by trusted macros is forced to a particular foreground colour. +Preferences.label.macroeditor.tooltip = Theme of the macro editor. +Preferences.label.facing.edge = On Edges +Preferences.label.facing.edge.tooltip = Causes token facing rotation to snap to edges of the grid cell. +Preferences.label.facing.vertices = On Vertices +Preferences.label.facing.vertices.tooltip = Causes token facing rotation to snap to the vertices of the grid cell. +Preferences.label.access.delay = ToolTip Initial Delay +Preferences.label.access.delay.tooltip = The initial delay (in milliseconds) before a tooltip is displayed. +Preferences.label.access.delay.dismiss = ToolTip Dismiss Delay +Preferences.label.access.delay.dismiss.tooltip = The amount of time (in milliseconds) the tooltip will remain before being removed. +Preferences.label.access.size = Chat Font Size +Preferences.label.access.size.tooltip = Point size for all chat window text (both input and output). +Preferences.label.sound.system = Play system sounds +Preferences.label.sound.system.tooltip = Turn this off to prevent all sounds from within MapTool. Needed for some Java implementations as too many sounds queued up can crash the JVM. +Preferences.label.sound.stream = Play clips and streams +Preferences.label.sound.stream.tooltip = Turn this off to prevent audio clips and streams from playing. +Preferences.label.sound.focus = Only when window not focused +Preferences.label.sound.focus.tooltip = Only turn off sounds when the window is not focused. +Preferences.label.sound.syrinscape = Turn on Syrinscape Integration +Preferences.label.sound.syrinscape.tooltip = Allow MapTool to launch Syrinscape via 3rd party integration URI. This will take affect on next launch of MapTool. +Preferences.label.auth.publicKey = Client Public Key +Preferences.label.auth.publicKey.tooltip = Key used for authentication with servers using public/private key authentication. +Preferences.label.auth.copyKey = Copy Public Key +Preferences.label.auth.regenKey = Regenerate Key +Preferences.label.language.tooltip = Select Language for User Interface. +Preferences.label.language.override = Language Override +Preferences.label.options = Additional Options +Preferences.label.options.directory = Data Directory +Preferences.label.options.directory.tooltip = Override default data directory. Default is .maptool under user directory. +Preferences.label.advanced = Advanced Options +Preferences.label.advanced.assert = Enable assertions +Preferences.label.advanced.direct3d = Disable Direct3d Pipeline +Preferences.label.advanced.opengl = Enable OpenGL Pipeline +Preferences.label.advanced.javafx = Intialize AWT before JavaFX +Preferences.label.jvm = JVM Memory Settings +Preferences.label.jvm.heap = Maximum heap size (-Xmx) +Preferences.label.jvm.heap.tooltip = -Xmx size in bytes Sets the maximum size to which the Java heap can grow. +Preferences.label.jvm.min = Initial & minimum heap size (-Xms) +Preferences.label.jvm.min.tooltip = Oracle recommends setting the minimum heap size (-Xms) equal to the maximum heap size (-Xmx) to minimize garbage collections. +Preferences.label.jvm.stack = Thread stack size (-Xss) +Preferences.label.jvm.stack.tooltip = Thread stacks are memory areas allocated for each Java thread for their internal use. This is where the thread stores its local execution state. +Preferences.label.autosave = Campaign autosave every +Preferences.label.autosave.tooltip = Autosaved campaigns are in ${appHome}/autosave. Autosaving a campaign is memory-intensive. Be sure to take that into account. Set to 0 to disable. +Preferences.label.save.reminder = Save reminder on close +Preferences.label.save.reminder.tooltip = Whether a prompt appears before MapTool closes. +Preferences.label.autosave.chat = Time between chat log autosaves +Preferences.label.autosave.chat.tooltip = The chat log will be autosaved at this interval (in minutes) using the filename pattern below. Set to 0 to disable. +Preferences.label.autosave.chat.filename = Autosave chat log filename +Preferences.label.autosave.chat.filename.tooltip = Specify a filename. Without a directory name is relative to ${appHome}/autosave. +Preferences.label.directory.sync = File Sync Directory +Preferences.label.directory.sync.tooltip = Specify the path to your cloud sync directy, eg Google Drive, Dropbox, One Drive, etc. This will be used to determine the relative path external files such as Hero Lab portfolios. +Preferences.label.directory.sync.set = Click the eclipses to the right to set the directory. +Preferences.label.map = Map Visuals +Preferences.label.halo.width = Halo line width +Preferences.label.halo.width.tooltip = The width of the single-colour halo around individual tokens. +Preferences.label.halo.color = Use halo colour for vision +Preferences.label.halo.color.tooltip = If enabled, the area visible to a token will be coloured the same as the halo. +Preferences.label.halo.opacity = Halo opacity +Preferences.label.halo.opacity.tooltip = Measures how opaque the halo vision overlay is drawn (0-255). +Preferences.label.aura.opacity = Aura opacity +Preferences.label.aura.opacity.tooltip = Measures how opaque the aura overlay is drawn (0-255). +Preferences.label.lumens.opacity = Lumens overlay opacity +Preferences.label.lumens.opacity.tooltip = Measures how opaque the lumens overlay is drawn (0-255). +Preferences.label.lumens.borderThickness = Lumens overlay border thickness +Preferences.label.lumens.borderThickness.tooltip = How thick to draw the border between lumens regions. Set to 0 for no border. +Preferences.label.lumens.startEnabled = Show lumens overlay by default +Preferences.label.lumens.startEnabled.tooltip = Toggle on to show the lumens overlay whenever MapTool is started. +Preferences.label.lights.startEnabled = Show environmental lights by default +Preferences.label.lights.startEnabled.tooltip = Toggle on to show the environmental lights whenever MapTool is started. +Preferences.label.light.opacity = Light opacity +Preferences.label.light.opacity.tooltip = Measures how opaque the light overlay is drawn (0-255). Has no effect on maps with environmental lighting. +Preferences.label.fog.opacity = Fog opacity +Preferences.label.fog.opacity.tooltip = Measures how opaque the "soft fog" overlay is drawn (0-255). +Preferences.label.fog.mapvisibilitywarning = Hide 'Map not visible to players' Warning +Preferences.label.fog.mapvisibilitywarning.tooltip= Hide warning from players telling that map is not visible. +Preferences.label.fog.autoexpose = Auto-expose fog on token movement (personal server) +Preferences.label.fog.autoexpose.tooltip = If enabled, the fog of war is automatically exposed as a token moves on maps with a grid. Gridless maps cannot auto-expose fog. When running a server, this setting is ignored in favor of the settings in the 'Start Server' dialog. +Preferences.label.performance.fillselection = Fill selection box +Preferences.label.performance.fillselection.tooltip = If enabled, a shaded area is used when dragging the mouse to select multiple tokens. +Preferences.label.performance.cap = Frame Rate Cap +Preferences.label.performance.cap.tooltip = Frame rate cap for map renderer in FPS. +Preferences.label.performance.render = Image Scaling Quality +Preferences.label.performance.render.tooltip = Quality of scaled images. +Preferences.combo.render.low = Low (Fastest) +Preferences.combo.render.pixel = Pixel Art +Preferences.combo.render.medium = Medium +Preferences.combo.render.high = High (Slowest) +Preferences.label.initiative.defaults = Campaign Defaults +Preferences.label.initiative.hidenpc = Hide NPCs from players on new maps +Preferences.label.initiative.hidenpc.tooltip = If enabled, NPCs will not appear in the players views of the Initiative panel. +Preferences.label.initiative.owner = Give Owners Permission in new campaigns +Preferences.label.initiative.owner.tooltip = Owner Permission allows players to perform certain actions on their tokens in the Initiative panel. +Preferences.label.initiative.lock = Lock Player Movement in new campaigns +Preferences.label.initiative.lock.tooltip = When enabled, players will only be able to move their token when that token has initiative. +Preferences.label.initiative.msg = Show Initiative Gain Message +Preferences.label.initiative.msg.tooltip = When enabled, a message is sent to chat when a token gains initiative. +Preferences.label.client.fitview = Fit GM view +Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? +Preferences.label.client.default.username = Default Username +Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory +Preferences.client.webEndPoint.port = Internal Web Server End Point Port +Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) +Preferences.client.default.username.value = Anonymous User +Preferences.label.macros.edit = Default: Allow players to edit macros +Preferences.label.macros.edit.tooltip = Player-editable macros cannot call trusted functions. When developing a framework, this should be disabled. +Preferences.label.upnp.timeout = Discovery Timeout +Preferences.label.upnp.timeout.tooltip = Timeout period in milliseconds to wait when looking for UPnP gateways. +Preferences.label.macros.permissions = Enable External Macro Access +Preferences.label.macros.permissions.tooltip = Enable macros to call functions that can access your drive and http services. The following functions will be enabled: getRequest, postRequest, exportData, getEnvironmentVariable. +Preferences.label.chat.macrolinks = Suppress ToolTips for MacroLinks +Preferences.label.chat.macrolinks.tooltip = MacroLinks show normally tooltips that state informations about the link target. This is a anti cheating device. This options let you disable this tooltips for aesthetic reasons. +Preference.checkbox.chat.macrolinks.tooltip = Enabled: do not show tooltips for macroLink
Disabled (default): show tooltips for macroLinks +PreferencesDialog.themeChangeWarning = Changing the theme requires a restart of MapTool to take effect. +PreferencesDialog.themeChangeWarningTitle = Theme Change. +Preferences.combo.themes.filter.all = All +Preferences.combo.themes.filter.dark = Dark +Preferences.combo.themes.filter.light = Light + +ServerDialog.error.port = You must enter a numeric port. +ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535. +ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?! Web server bug? +ServerDialog.error.server = You must enter a server name or IP address. +ServerDialog.error.serverNotFound = Server "{0}" not found. +ServerDialog.error.username = A username must be provided. +ServerDialog.error.noConnectPassword = You must enter a password to connect to a server. +ServerDialog.error.passwordMissing = Both Player and GM Password must be provided. +ServerDialog.error.playerPasswordMissing = Player Password must be provided. +ServerDialog.error.gmPasswordMissing = GM Password must be provided. +ServerDialog.error.passwordMustDiffer = Player and GM Password can not be the same. +ServerDialog.error.serverAlreadyExists = A server with the same name already exists. + +# The connection test has been disabled so these are not currently used. +ServerDialog.msg.test1 = Setting Up For Connection Test... +ServerDialog.msg.test2 = Performing connection test. Success is usually quick; failure often takes longer... +ServerDialog.msg.test3 = Success! I successfully connected to your computer from the Internet. +# Yes, I know these are similar. But I wanted *some* difference so the +# programmer can easily locate specific areas of the code. +ServerDialog.msg.test4 = Could not see your computer from the Internet.

It could be a port forwarding issue. Visit the RPTools forum (Tools -> MapTool -> HOWTO) to find the Networking FAQ. +ServerDialog.msg.test5 = Unable to see your computer from the Internet.

It could be a port forwarding issue. Visit the RPTools forum (Tools -> MapTool -> HOWTO) to find the Networking FAQ. +ServerDialog.msg.test6 = Communication error during test... +ServerDialog.msg.test7 = Unknown or unexpected exception during test. +ServerDialog.msg.title = Start Server +ServerDialog.label.usePasswordFile = Use MapTool Password file. +ServerDialog.tooltip.usePasswordFile = Use MapTool Password file for player and GM passwords. +ServerDialog.label.useEasyConnect = Use MapTool Easy Connect. +ServerDialog.tooltip.useEasyConnect = Use MapTool Easy Connect to simplify public key authentication. +ServerDialog.label.usepnp = Use UPnP +ServerDialog.option.hidemapselectui = Hide the map select UI from players +ServerDialog.option.hidemapselectui.tooltip = Hides the top right map select UI so that a custom one may be used or players are unable to change maps. +ServerDialog.option.disablePlayerLibrary = Hide Players' Library +ServerDialog.option.disablePlayerLibrary.tooltip = Prevents players from importing tokens from their libraries. +ServerDialog.tooltip.useupnp = Attempt to map ports automatically. Most people should try this option first, and forward ports manually only if UPnP does not work. If you have set up port forwarding, leave this option unchecked. +ServerDialog.label.alias = RPTools.net Alias: +ServerDialog.tooltip.alias = Allows players to find this server by name. If not provided,
\ + players will need your external address to use Direct Connect.
\ + must be specified if using WebRTC. +ServerDialog.label.gmpassword = GM Password: +ServerDialog.label.password = Player Password: +ServerDialog.label.metric = Movement metric +ServerDialog.label.metric.tooltip = Determines how MapTool handles movement on the selected grid type. +ServerDialog.option.ownership = Strict token ownership +ServerDialog.option.ownership.tooltip = Only the owner of a particular token may perform any actions on it. +ServerDialog.option.reveal.gm = GM reveals vision On Movement for Unowned Tokens +ServerDialog.option.reveal.gm.tooltip = If a token has no ownership, FoW will not be revealed on movement unless this is selected. +ServerDialog.option.reveal.player = Players can reveal vision +ServerDialog.option.reveal.move = Auto Reveal On Movement +ServerDialog.option.reveal.move.tooltip = Allows tokens to automatically reveal FoW at the end of movement. +ServerDialog.option.vision.individual = Use Individual Views +ServerDialog.option.vision.individual.tooltip = Players do not share vision. +ServerDialog.option.fow.individual = Use Individual FOW +ServerDialog.option.fow.individual.tooltip = Each token has it's own FOW. +ServerDialog.option.impersonate = Allow Players to Impersonate any token +ServerDialog.option.impersonate.tooltip = Gives players the ability to impersonate any character as if they had GM status. +ServerDialog.option.macros = Players Receive Campaign Macros +ServerDialog.option.macros.tooltip = The campaign panel macros will be available for players to use (but not edit). +ServerDialog.option.rolls = Use ToolTips for [] Rolls +ServerDialog.option.rolls.tooltip = Tool Tips will be used for [ ] rolls where no format options are specified. +ServerDialog.button.networkinghelp = Networking Help +ServerDialog.generatePassword = Generate Password + + +CampaignPropertiesDialog.tab.token = Token Properties +CampaignPropertiesDialog.tab.repo = Repositories +CampaignPropertiesDialog.tab.sight = Sight +CampaignPropertiesDialog.tab.light = Light +CampaignPropertiesDialog.tab.states = States +CampaignPropertiesDialog.tab.bars = Bars +CampaignPropertiesDialog.button.import = Import predefined +campaignPropertiesDialog.newTokenTypeName = Enter the name for the new token type +campaignPropertiesDialog.newTokenTypeTitle = New Token Type +campaignPropertiesDialog.newTokenTypeDefaultName = New Token Type {0} +campaignPropertiesDialog.newTokenPropertyDefaultName = New Prop {0} +campaignPropertiesDialog.tokenTypeNameChangeWarning = Changing the token type name will update all tokens with this type which could take a while. +campaignPropertiesDialog.tokenTypeNameChangeTitle = Token Type Name Change +campaignPropertiesDialog.tokenTypeNameDeleteTitle = Delete Token Type {0} +campaignPropertiesDialog.tokenTypeNameDeleteMessage =Change existing Tokens to: +campaignPropertiesDialog.tokenTypeNameRename = Renaming Token Types... +campaignProperties.macroEditDialog.default.title = Default value for Property +campaignPropertiesTable.column.name = Name +campaignPropertiesTable.column.shortName = Short Name +campaignPropertiesTable.column.displayName = Display Name +campaignPropertiesTable.column.onStatSheet = Stat Sheet +campaignPropertiesTable.column.gmStatSheet = GM +campaignPropertiesTable.column.ownerStatSheet = Owner +campaignPropertiesTable.column.defaultValue = Default + +# Bar propertyType +CampaignPropertiesDialog.combo.bars.type.twoImages = Two Images +CampaignPropertiesDialog.combo.bars.type.singleImage = Single Image +CampaignPropertiesDialog.combo.bars.type.multipleImages = Multiple Images +CampaignPropertiesDialog.combo.bars.type.solid = Solid +CampaignPropertiesDialog.combo.bars.type.twoTone = Two Tone +# Bar side +CampaignPropertiesDialog.combo.bars.side.top = Top +CampaignPropertiesDialog.combo.bars.type.bottom = Bottom +CampaignPropertiesDialog.combo.bars.type.left = Left +CampaignPropertiesDialog.combo.bars.type.right = Right +# State propertyType +CampaignPropertiesDialog.combo.states.type.image = Image +CampaignPropertiesDialog.combo.states.type.cornerImage = Corner Image +CampaignPropertiesDialog.combo.states.type.gridImage = Grid Image +CampaignPropertiesDialog.combo.states.type.dot = Dot +CampaignPropertiesDialog.combo.states.type.gridDot = Grid Dot +CampaignPropertiesDialog.combo.states.type.circle = Circle +CampaignPropertiesDialog.combo.states.type.shaded = Shaded +CampaignPropertiesDialog.combo.states.type.x = X +CampaignPropertiesDialog.combo.states.type.cross = Cross +CampaignPropertiesDialog.combo.states.type.diamond = Diamond +CampaignPropertiesDialog.combo.states.type.gridDiamond = Grid Diamond +# "Yield" here refers to the shape of the traffic sign (an inverted triangle) +CampaignPropertiesDialog.combo.states.type.yield = Yield +CampaignPropertiesDialog.combo.states.type.gridYield = Grid Yield +CampaignPropertiesDialog.combo.states.type.triangle = Triangle +CampaignPropertiesDialog.combo.states.type.gridTriangle = Grid Triangle +CampaignPropertiesDialog.combo.states.type.gridSquare = Grid Square +# Positions +position.corner.topLeft = Top Left +position.corner.topRight = Top Right +position.corner.bottomLeft = Bottom Left +position.corner.bottomRight = Bottom Right +position.side.left = Left +position.side.right = Right +position.side.top = Top +position.side.bottom = Bottom + + +CampaignPropertiesDialog.label.sight = \ + Format:\ +

Name : options
\ +

Each sight type can have zero or more options, use spaces between each option. Having zero options implies using \ + defaults for all values (e.g. Normal vision).

\ +

Options:

\ +
\ +
shape
shape may be circle, square, hex, grid or cone
\ +
distance=y
Distance is the range at which this vision type ends. Can be a decimal value. Ex: distance=10
\ +
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ +
arc=y
When used with the cone shape, it signifies how large a field of vision the token has. Can be an interger value. Ex: arc=120
\ +
offset=y
When used with the cone shape, it signifies how much offset the cone begins from the center of the tokens facing. Can be an integer value. Ex: offset=120
\ +
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value. Ex: x2
\ +
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\ +

Can have an optional #rrggbb hex colour component appended to it as per typical CSS rules.

\ +

Can also have an optional +x lumens value. Lumens defaults to 100, meaning it will see through any darkness with a lumens value from -1 to -99. See discussion of lumens on the Light tab for more info.

\ +

Ex: r60#bb0000+120

\ +
\ + +CampaignPropertiesDialog.label.light = \ +Format: \ +
Group name
\ +----------
\ +name: type shape OPTIONS scale range#rrggbb+x
\ +

Define groups of light types with a line of text to indicate the group \ +name followed by one or more name definitions. End a group with a \ +blank line. All text is case-insensitive. Lines that start with a "-" are \ +considered comments and are ignored. The group name becomes an entry on \ +the token's popup menu under the Light Sources element, and \ +individual light source definitions become sub-entries. Group names are \ +displayed in sorted order, and the sub-entries are alphabetically sorted \ +as well.

\ +
\ +
name
A user-visible name for light definition.
\ +
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\ +
shape
An optional shape for the light emanation. Can be circle (default), \ + square, cone (cones also have arc=angle and \ + offset=y fields) or grid (for systems like Pathfinder if \ + you want to see exactly which grid cells are affected by a Light/Aura). Shapes \ + apply from the point they are included in the definition until the end of the \ + definition or until another shape is specified. This means multiple light shapes \ + can be created under a single name and turned on or off as a unit.
\ +
scale
An optional keyword that adds the token's footprint (size) to the range so the light/aura starts at token's edge vs the token's center.
\ +
range

A distance measured in map units (defined when the map is created). Units are \ + measured from the centerpoint of the grid cell, hence the extra 2 ½ feet \ + added in the below example to make neat squares.

\ +

Can have an optional #rrggbb hex colour component appended to it as per \ + typical CSS rules.

\ +

Can have an optional +x lumens value, with x equaling an integer \ + (-x can instead be used to provide a negative lumens value). If not \ + provided, the value will default to 100. If set to a negative number, the \ + light will instead act as darkness and subtract it's area from the FoW. \ + Lights are processed in order of their absolute value of lumens. eg. Darkness \ + with lumens=-20 will cover over any light with lumens <= 20 and any light \ + with lumens >= 21 will expose through any darkness with a lumens value of \ + -1 to -20.

\ +

*Note: Personal Lights defined in Sight have a default lumens \ + value of 100. So a typical sight defined for Darkvision will see through \ + any lights with a lumens value of -1 through -99. To overcome Darkvision, use \ + lumens values <= -100.

\ +
OPTIONS
The only valid options are GM and OWNER and they apply only to auras (see below).
\ +
\ +

Example:

\ +
\
+Sample Lights - 5' square grid 
\ +----
\ +Candle - 5 : 7.5 12.5#000000
\ +Lamp - 15 : 17.5 32.5#000000
\ +Torch - 20 : 22.5 42.5#000000
\ +Lantern, bullseye - 60 : cone arc=60 62.5 122.5#000000
\ +Lantern, bullseye (leaks light) - 60 : cone arc=60 62.5 122.5#000000 circle 2.5#000000
\ +Daylight Spell - 60 : 62.5+50 122.5#000000+50
\ +Nightvision goggles - 40 : cone arc=30 42.5#00e000+30
\ +
\ +Magical Darkness
\ +----
\ +Deeper Darkness - 60: circle 62.5-130
\ +Darkness - 20 (CL2): circle 22.5-20
\ +Darkness - 20 (CL4): circle 22.5-40
\ +
\ +
\ +

Auras:

\ +

To create an aura, put the keyword aura at the beginning of the \ +definition. Auras radiate a coloured area and interact with the vision \ +blocking layer (i.e. are blocked by VBL), but do not actually cast any \ +visible light and therefore do not expose any fog-of-war. GM-only auras \ +are only visible by clients logged into the server as GM. They remain \ +visible even when the map is in Show As Player mode. Owner-only \ +auras are only visible to the player(s) who owns the token they are \ +attached to and are always visible to the GM. See examples, below.

\ +

In the following example, the GM-only auras are red, the owner-only \ +auras are green, and the player auras are blue. You can of course define \ +your own colours.

\ +
\
+Sample Auras - 5" square grid
\ +----
\ +Aura red 5 : aura square GM 2.5#ff0000
\ +Aura red 10 : aura GM 7.5#ff0000
\ +Aura Owner Also 5 : aura square owner 2.5#00ff00
\ +Aura Owner Also 10 : aura owner 7.5#00ff00
\ +Aura Player Also 5 : aura square 2.5#0000ff
\ +Aura Player Also 10 : aura 7.5#0000ff
\ +
\ +

The first line creates a square GM-only aura in red that is 5-feet across. \ +The second creates a round GM-only aura in red with a 15-foot diameter. \ +Lines three and four do the same thing, but with a green aura that is only \ +visible to players who own the token with the aura attached to it. Lines \ +five and six are visible to all players and are in blue.

\ + +CampaignPropertiesDialog.label.title = Campaign Properties +CampaignPropertiesDialog.label.group = Group: +CampaignPropertiesDialog.label.image = Image: +CampaignPropertiesDialog.label.images = Images: +CampaignPropertiesDialog.label.show = Show To: +CampaignPropertiesDialog.label.corner = Corner: +CampaignPropertiesDialog.label.preview = Preview: +CampaignPropertiesDialog.label.side = Side: +CampaignPropertiesDialog.label.bar = Bar Colour: +CampaignPropertiesDialog.label.background = Background: +CampaignPropertiesDialog.label.thick = Thickness: +CampaignPropertiesDialog.label.opacity = Opacity: +CampaignPropertiesDialog.label.inc = Increments: +CampaignPropertiesDialog.label.mouse = Mouseover: +CampaignPropertiesDialog.label.order = Order: +CampaignPropertiesDialog.label.order.tooltip = Position in the list of states, change to move up or down the list. +CampaignPropertiesDialog.label.else = Everybody Else +CampaginPropertiesDialog.label.owner = Owner + +TextureChooserPanel.title = Texture + +TokenPropertiesPanel.label.list = List the token properties for this token type below, one property per line: +TokenPropertiesPanel.label.type = Token Type +TokenPropertiesPanel.label.statSheet = Stat Sheet +TokenPropertiesPanel.button.statSheetProps = Stat Sheet Properties +TokenPropertiesPanel.button.setAsDefault = Set as Default +TokenPropertiesPanel.defaultPropertyType = Default Property Type + + +# Token terrain modifier operations +Token.TerrainModifierOperation.NONE = None +Token.TerrainModifierOperation.MULTIPLY = Multiply +Token.TerrainModifierOperation.ADD = Add +Token.TerrainModifierOperation.BLOCK = Block +Token.TerrainModifierOperation.FREE = Free + +# Token shapes +Token.TokenShape.TOP_DOWN = Top Down +Token.TokenShape.CIRCLE = Circle +Token.TokenShape.SQUARE = Square +Token.TokenShape.FIGURE = Figure + +Token.Type.PC = PC +Token.Type.NPC = NPC + +# Token sizes, from smallest to largest +TokenFootprint.name.fine = Fine +TokenFootprint.name.diminutive = Diminutive +TokenFootprint.name.tiny = Tiny +TokenFootprint.name.small = Small +TokenFootprint.name.medium = Medium +TokenFootprint.name.large = Large +TokenFootprint.name.huge = Huge +# Humongous is only used on hex grids, comes after huge +TokenFootprint.name.humongous = Humongous +# The following are only used on square grids, come after huge +TokenFootprint.name.gargantuan = Gargantuan +TokenFootprint.name.colossal = Colossal + +# Token VBL Optimization methods +TokenVBL.JTS_SimplifyMethodType.DOUGLAS_PEUCKER_SIMPLIFIER = Douglas Peucker +TokenVBL.JTS_SimplifyMethodType.TOPOLOGY_PRESERVING_SIMPLIFIER = Topology Preserving +TokenVBL.JTS_SimplifyMethodType.VW_SIMPLIFIER = VW Simplifier +TokenVBL.JTS_SimplifyMethodType.NONE = No Optimization + +TransferProgressDialog.title = Assets in Transit +TransferProgressDialog.desc = These are images that are currently being retrieved from the server or a repository. + +SquareGrid.error.pathhighlightingNotLoaded = Could not load path highlighting image. +SquareGrid.error.squareGridNotLoaded = Could not load square grid footprints. + +Token.dropped.byPlayer = Tokens dropped onto map "{0}" by player {1} +# This is the name given to new tokens if the New Token Naming preference +# is set to "Use "Creature"" +Token.name.creature = Creature +Token.error.unableToPaste = Failed to paste token(s) with duplicate name(s): {0} +Token.error.unableToRename = Cannot rename token to "{0}" as there is already another token with this name on the map.
Only the GM can create multiple tokens with the same name! + +ToolbarPanel.manualFogActivated = Modifying the fog-of-war manually without a server running affects only the global exposed area (i.e. the entire map), even
if one or more tokens are selected. If you want your changes to apply to individual tokens, start a MapTool server with
Individual Fog enabled (you can leave the Alias field empty to make an anonymous server, if you wish).

This warning will not appear again for this campaign. + +TransferableHelper.error.ioException = I/O error during drag/drop operation. +TransferableHelper.error.unrecognizedAsset = Could not retrieve drag/drop asset. +TransferableHelper.error.unsupportedFlavorException = Unsupported data type during drag/drop operation. +TransferableHelper.error.urlFlavor = Cannot read URL_FLAVOR. +TransferableHelper.warning.badObject = Unable to obtain data from dropped object.
Likely causes are an empty object due to a network error (such as proxy settings or missing authentication)
or possibly an incompatible object was dropped (such as an invalid file type). +TransferableHelper.warning.tokensAddedAndExcluded = Added {0,number} tokens. There were {1,number} tokens that could not be added
because they were missing names or images. + +VisionDialog.error.EmptyDistance = Distance Text Field is empty, enter a distance. +VisionDialog.error.numericDistanceOnly = Distance must be numeric. +# These are for a first cut at a true vision UI but the code is +# currently not accessible by the user. +VisionDialog.msg.title = Vision + +# Movement metrics +WalkerMetric.NO_DIAGONALS = No Diagonals +# "Manhattan" refers to Manhattan Distance (See: https://en.wikipedia.org/wiki/Taxicab_geometry) +WalkerMetric.MANHATTAN = Manhattan +WalkerMetric.ONE_TWO_ONE = One-Two-One +WalkerMetric.ONE_ONE_ONE = One-One-One + +# AI cell rounding options +Zone.AStarRoundingOptions.NONE = None +Zone.AStarRoundingOptions.CELL_UNIT = Cell Unit +Zone.AStarRoundingOptions.INTEGER = Integer + +# This message appears when a campaign is loaded and MapTool is scanning +# the maps and optimizing their memory footprint by collapsing +# drawables, if possible. +Zone.status.optimizing = Optimizing map: "{0}" + +ZoomStatusBar.tooltip = Zoom level + +action.addDefaultTables = Add Default Tables... +action.addDefaultTables.description = Adds several dice image and card tables to the campaign. +action.addIconSelector = Add Resource to &Library... +action.addIconSelector.description = Opens a dialog to add local and remote content to your Resource Library. +action.addOnLibraries = Add On Libraries... +action.adjustBoard = Adjust Map Board... +action.adjustBoard.description = Open dialog to adjust the position of the embedded map image. +action.adjustGrid = &Adjust Grid... +action.adjustGrid.accel = shift A +action.adjustGrid.description = Open dialog to adjust the grid settings. +action.autohideNewIcons = Autohide New Tokens +action.autohideNewIcons.description = New tokens start invisible to players. +action.autohideNewMaps = Autohide New Maps +action.autohideNewMaps.description = New maps start invisible to players. +# Other actions which are not necessarily on the top menu but may +# appear on a context (i.e. right-click) menu or be connected to +# an editable field on a dialog. NOTE: MapTool 1.3 does not properly +# localize dialog labels yet! Only one or two dialogs have the +# necessary code for localization. +action.bootConnectedPlayer = Boot... +action.campaignProperties = Campaign Properties... +action.campaignProperties.description = Opens dialog for setting Campaign Properties. +action.cancelCommand = Not used (action.cancelCommand) +action.clearDrawing = Clear All Drawings +action.clearDrawing.accel = shift D +action.clearDrawing.description = Clear will clear all drawings from the active layer and clear all drawing undo history. +action.clientConnect = Connect to Server... +action.clientConnect.description = Connect as a client to a server. +action.clientDisconnect = Disconnect from Server... +action.clientDisconnect.description = Disconnect from or shutdown the server. +action.collectPerformanceData = Collect Performance Data +action.collectPerformanceData.description = Opens a floating panel that reports various performance statistics. +action.commandPanel = Command Panel +# These next two are used internally but never appear on a menu item. +# In order to prevent I18N from warning that they don't exist these +# lines have been added. +action.commitCommand = Not used (action.commitCommand) +action.copyTokens = Copy +action.copyTokens.accel = C +action.copyTokens.description = Copy selected tokens to an internal clipboard. +action.copyZone = Copy... +action.copyZone.description = Make a copy of the current map. +action.cutTokens = Cut +action.cutTokens.accel = X +action.cutTokens.description = Cut selected tokens to an internal clipboard. +action.debug.duplicateLastIcon = Duplicate Last Icon (debug) +action.editMap = Edit Map... +action.editMap.description = Open a dialog to edit settings for the current map. +# Is this accelerator a bad choice on OSX? The Mac uses Cmd-W to mean +# "close focused window"... Even if we answer "yes", should we change this? +# I hate to start putting os-specific settings into the properties file. :( +# Unless we add the "os.name" field as a prefix to all properties +# as a way to override what's here. For example, adding a property named +# mac os x.action.enabledFogOfWar.accel=f +# to indicate a platform-specific change to the accelerator...? +# With MapTool 1.4 expected to allow users to define their own accelerators +# this probably doesn't matter much. +action.enableFogOfWar = Fog-of-&War +action.enableFogOfWar.accel = W +action.enableFogOfWar.description = Enable the fog of war for the current map. +action.enforceNotification = Enforce Typing Notifications +action.enforceNotification.description = Enforce Typing Notifications. +action.enforceView = &Center Players on Current View +action.enforceView.accel = F +action.enforceView.description = Causes all clients to zoom to your current view. +action.enforceZone = &Enforce Players to Current Map +action.enforceZone.accel = E +action.enforceZone.description = Causes all clients to change to the map you are on. +action.error.noMapBoard = There is no map image. Use "Edit Map..." to add one. +# Not used on the Mac, as the application menu will have 'Quit' added to +# it instead and Meta-Q set as the accelerator. Kind of ugly that it is +# hard-coded in the application, but that's OSX for you. ;-) +action.exit = E&xit +action.exit.description = Exit out of MapTool. +action.exportCampaignAs = Campaign As... +action.exportCampaignAs.description = Export current campaign to a version compatible with older MapTool releases. +action.exportScreenShot = Screenshot +action.exportScreenShot.title = Export Screenshot +action.exportScreenShot.accel = shift S +action.exportScreenShot.description = Export an image of the current map. Use Export Screenshot As first. +action.exportScreenShotAs = Screenshot As... +action.exportScreenShotAs.description = Opens a dialog to export an image of the current map. +action.fullscreen = Fullscreen Mode +action.fullscreen.accel = alt ENTER +action.fullscreen.description = Change to full screen mode hiding everything else but the map view. +action.toggleFullScreenTools = Enable tools in full screen mode. +action.toggleFullScreenTools.accel = alt T +action.gatherDebugInfo = Gather Debug Information... +action.gatherDebugInfoWait = Gathering information, please wait... +action.gatherDebugInfo.description = Collects information about your system to aid in troubleshooting or reporting bugs. +action.gridSize = Grid &Line Width +# These are url menu actions. Each item consists of three keys. The first key is +# action.url.## which contains the displayed string. The second key is +# action.url.##.description which contains the url to load when the action is +# executed. The last key is action.url.##.icon which contains the image embedded +# inside the MapTool JAR file which appears on the menu item. +action.helpurl.01 = Documentation +action.helpurl.01.description = https://www.rptools.net/toolbox/maptool/ +action.helpurl.02 = Tutorials +action.helpurl.02.description = https://www.rptools.net/tutorials/ +action.helpurl.03 = Forums +action.helpurl.03.description = http://forums.rptools.net/ +action.helpurl.04 = Networking Setup (forum thread) +action.helpurl.04.description = http://forums.rptools.net/viewtopic.php?f=22&t=3370 +action.helpurl.05 = Macro Scripting +action.helpurl.05.description=https://wiki.rptools.info/index.php/Main_Page +action.helpurl.06 = Frameworks +action.helpurl.06.description = https\://wiki.rptools.info/index.php/Frameworks +action.hideMap = &Player Visible +action.hideMap.accel = H +action.hideMap.description = Toggle visibility of map for the players. +action.linkPlayerView = Center Players on Current View (Continuous) +action.linkPlayerView.accel = shift F +action.linkPlayerView.description = Causes all clients to continuously track your view. +action.loadCampaign = &Open Campaign... +action.playerDatabase = Player Database +action.loadCampaign.accel = O +action.loadCampaign.description = Load a previously saved campaign. +action.loadMap = &Import Map... +action.loadMap.description = Load a previously saved map. +action.loadMap.warning1 = This is an experimental feature. Save your campaign before using this feature (you are a GM logged in remotely). +action.loadMap.warning2 = Help opens a browser to the forum thread discussion and aborts this import. +action.loadMap.warning3 = Yes acknowledges the issues and proceeds to import the map. +action.loadMap.warning4 = No closes this panel and aborts the import. +action.import.dungeondraft = Import Universal VTT... +action.import.dungeondraft.dialog.title = Import Universal VTT File +action.loadSaveDialog = DEBUG LOAD/SAVE +action.loadSaveDialog.accel = F5 +action.macro.addNewToSelected = Add New to Selected +action.macro.clearGroup = Clear Group... +action.macro.clearPanel = Clear Panel... +action.macro.delete = Delete... +action.macro.deleteFromCommon = Delete from Common... +action.macro.duplicate = Duplicate +action.macro.duplicateOnSelected = Duplicate Macro on Selected +action.macro.edit = Edit... +action.macro.export = Export... +action.macro.exportCommon = Export Common Macro... +action.macro.exportCommonSet = Export Common Macro Set... +action.macro.exportSet = Export Macro Set... +action.macro.exportGroup = Export Macro Group... +action.macro.import = Import... +action.macro.importSet = Import Macro Set... +action.macro.importSetToSelected = Import Macro Set to Selected... +action.macro.importToSelected = Import Macro to Selected... +action.macro.new = Add New Macro +action.macro.renameGroup = Rename Macro Group... +action.macro.reset = Reset +action.macro.runForEachSelected = Run for Each Selected +action.macroEditor.gotoLine = &Go to Line... +action.macroEditor.gotoLine.accel = L +action.macroEditor.searchFind = &Find... +action.macroEditor.searchFind.accel = F +action.macroEditor.searchReplace = &Replace... +action.macroEditor.searchReplace.accel = H +action.macroEditor.showFindSearchBar = Show Find Search Bar +action.macroEditor.showFindSearchBar.accel = shift F +action.macroEditor.showReplaceSearchBar = Show Replace Search Bar +action.macroEditor.showReplaceSearchBar.accel = shift H +# File Menu +action.newCampaign = &New Campaign +action.newCampaign.description = Discards current campaign and creates a new campaign with a single Grasslands map. +# Map Menu +action.newMap = New Map... +action.newMap.accel = N +action.newMap.description = Opens a dialog to add a new map to the current campaign. +action.newToken = New Token... +action.newUnboundedMap = New Tiled Map... +action.newUnboundedMap.accel = shift n +action.openLogConsole = Open Log Console +action.openLogConsole.title = Log Console +action.openLogConsole.description = Opens the Log Console to display the log output. +action.pasteTokens = Paste +action.pasteTokens.accel = V +action.pasteTokens.description = Paste internal clipboard to the current mouse location. +action.preferences = Preferences... +action.preferences.description = Opens Preferences dialog. +action.redoDrawing = Redo Drawing +action.redoDrawing.accel = R +action.redoDrawing.description = Redo the most recent drawing in the undo history. +action.refresh = Refresh +action.refresh.accel = F5 +action.removeAssetRoot = Remove... +action.removeZone = Delete... +action.removeZone.description = Delete the current map from the campaign. +action.renameMap = Rename... +action.renameMap.description = Rename the current map. +action.rescanNode = Rescan... +action.restoreDefaultImages = Restore &Default Images... +action.restoreDefaultImages.description = Restores the default tokens, textures, dice and other images to the Resource Library. +action.restoreFogOfWar = Restore Fog-of-&War +action.restoreFogOfWar.accel = shift R +action.restoreFogOfWar.description = Restore the fog of war for the current map (erase all revealed FoW). +action.revealFogAtWaypoints.description = Reveal Fog-of-War only at start and end points, as well as set way points. +action.revealFogAtWaypoints = FoW: Expose only at way points +action.revealFogAtWaypoints.accel = shift W +action.runMacro = &Run Macro +action.runMacro.accel = typed / +action.runMacro.description = Makes the chat window active and begins the line with a slash(/). +action.saveCampaign = &Save Campaign +action.saveCampaign.accel = S +action.saveCampaign.description = Save all resources (maps, tokens, tables, etc) in a single file. +action.saveCampaignAs = Save Campaign &As... +action.saveCampaignAs.accel = A +action.saveCampaignAs.description = Save all resources (maps, tokens, tables, etc) in a single file. +action.saveMapAs = &Export Map... +action.saveMapAs.description = Save a map to an external file. +action.saveMessageHistory = Save Chat Log &History... +action.saveMessageHistory.description = Save the contents of your chat log, including whispers. +# Tool +action.sendChat = C&hat +action.sendChat.accel = ENTER +action.chat.color.tooltip = Set the colour of your speech text +action.chat.scrolllock.tooltip = Scroll lock +action.chat.showhide.tooltip = Show/hide typing notification +#action.addIconSelector.accel=ctrl shift i +action.serverStart = Start Server... +action.serverStart.description = Start a server so that other MapTool clients can connect to you. +action.setZoneGridColor = Set Grid Colour... +# Help +action.showAboutDialog = &About... +action.showAboutDialog.description = Show information about MapTool. +action.showConnectionInfo = &Connection Information... +action.showConnectionInfo.description = Opens window displaying the Local and External IP addresses of your connection as well as the Port being used. +action.showCoordinates = Show &Coordinates +action.showCoordinates.description = Display row/column coordinates. For square grids only. +action.showGrid = Show &Grid +action.showGrid.accel = G +action.showGrid.description = Toggles display of the grid on and off. +action.showLightRadius = Show Token &Lights +action.showLightRadius.accel = L +action.showLightRadius.description = Causes light overlays to be enabled for all tokens that have a light source. +action.showLightSources = Show Light Sources +action.showLightSources.accel = K +action.showLightSources.description = Displays a light bulb icon on all tokens with a Light Source. GM Only +# Currently unused but the code is in place which searches for this key, so... +action.showMapSelector = &MiniMap +action.showMapSelector.accel = M +action.showMovementMeasures = Show Movement &Distances +action.showMovementMeasures.accel = D +action.showTextLabels = Show Text Labels +action.showMovementMeasures.description = Show the distance traveled by a token while dragging it. +action.showNames = Show &Token Names +action.showNames.accel = T +action.showNames.description = Displays names below tokens.
Visible NPC: White on Blue
Visible PC: Black on Grey
Not Visible: White on Dark Grey. +action.showPlayerView = Show As Player +action.showPlayerView.accel = shift P +action.showPlayerView.description = Causes your view to (mostly) show what a player would see. +action.toggleDoubleWide = &Straight Line Width Doubled +action.toggleDoubleWide.description = When selected the line template will draw straight lines at double width. +action.showLumensOverlay = Show Lumens Overlay +action.showLumensOverlay.description = Render the lumens levels on top of the map. +action.showLights = Show Lights +action.showLights.description = Draw lights onto the map as part of the environment. + +action.toggleDrawMeasurements = Display Drawing &Distances +action.toggleDrawMeasurements.description = When selected the drawing tools will display distances during drawing. +action.toggleMovementLock = &Lock Player Movement +action.toggleMovementLock.accel = shift L +action.toggleMovementLock.description = Locks movement for player-owned tokens. +action.toggleTokenEditorLock = Lock Player Token Editor +action.toggleTokenEditorLock.description = Locks access to the Token Editor. +action.toggleNewZonesHaveFOW = New Maps have Fog of War +action.toggleTokensStartSnapToGrid = Tokens Start Snap to Grid +# Edit Menu +action.undoDrawing = Undo Drawing +action.undoDrawing.accel = Z +action.undoDrawing.description = Removes the last drawing placing it in the undo history. +action.useAlphaFog = Toggle Translucent Fog +action.zoom100 = Zoom 1:1 +action.zoom100.accel = typed + +# View +action.zoomIn = Zoom &In +action.zoomIn.accel = typed = +action.zoomLock = Lock Zoom +action.zoomOut = Zoom &Out +action.zoomOut.accel = typed - + +addtokenstate.added = Token state "{0}" was added +# Slash command info +addtokenstate.description = Add a new token state that can be set on tokens. +addtokenstate.exists = A token state with the name "{0}" already exists. +addtokenstate.invalidColor = An invalid colour "{0}" was passed as a parameter. Valid values are hex or integer numbers or the name of a common colour (black, blue, cyan, darkgray, gray, green, lightgray, magenta, orange, pink, red, white, yellow). +addtokenstate.invalidCorner = An invalid corner name "{0}" was passed as a parameter. Valid values are nw, ne, sw, se. +addtokenstate.invalidNumber = An invalid number "{0}" was passed as a parameter. +addtokenstate.noOverlyType = There is no overlay type with the name "{0}". Valid types are "dot, circle, shade, X, cross, diamond, yield or triangle". +addtokenstate.param = A token state name and overlay name are required. + +admin.exportCampaignRepo = Campaign Repository File... +admin.exportCampaignRepo.description = Export a campaign repository file. +admin.updateCampaignRepo = Update Campaign Repository... + +alias.added = Alias "{0}" added. +alias.commandHeader = Command +alias.descriptionHeader = Description +alias.description = Create an alias. +alias.header = Alias +alias.removed = Alias "{0}" removed. +alias.notFound = Alias "{0}" not found. +alias.campaign.title = Campaign Aliases +alias.client.title = Client Aliases +alias.addon.title = Aliases defined by {0} ({1}) Add-On . + + +changecolor.description = Change your chat text colour via macros. Colour must be in hexadecimal format. Example: /cc #ff0099 + +clear.description = Clear the message panel. + +clearaliases.description = Clear all aliases. +clearaliases.prompt = Clear all aliases? + + + +component.areaGroup.macro.commonMacros = Common Macros +component.areaGroup.macro.noMacros = No Macros +component.dialogTitle.macro.macroID = Macro ID +component.label.macro.allowPlayerEdits = Allow Players to Edit Macro +component.label.macro.applyToSelected = Apply to Selected Tokens +component.label.macro.autoExecute = Auto Execute +component.label.macro.buttonColor = Button Colour +component.label.macro.command = Command +component.label.macro.compareApplyToSelected = Use Apply to Selected Tokens +component.label.macro.compareUseAutoExecute = Use Auto Execute +component.label.macro.compareUseCommand = Use Command +component.label.macro.compareUseGroup = Use Group +component.label.macro.compareUseIncludeLabel = Use Include Label +component.label.macro.compareUseSortPrefix = Use Sort Prefix +component.label.macro.displayHotKey = Display Hot Key? +component.label.macro.fontColor = Font Colour +component.label.macro.fontSize = Font Size +component.label.macro.group = Group +component.label.macro.hotKey = Hot Key +component.label.macro.includeLabel = Include Label +component.label.macro.label = Label +component.label.macro.macroCommonality = Macro Commonality +component.label.macro.maxWidth = Max Width +component.label.macro.minWidth = Min Width +component.label.macro.sortPrefix = Sort Prefix +component.label.macro.toolTip = Tooltip +component.tab.macro.details = Details +component.tab.macro.editor = Editor +component.tab.macro.options = Options +component.tooltip.macro.allowPlayerEdits = Select this to allow players to edit this macro. +component.tooltip.macro.applyToSelected = Check here to run this macro against the currently selected tokens. Uncheck to run this macro outside of the context of any selected tokens. If this macro references one or more token properties, it should be checked. +component.tooltip.macro.autoExecute = Check to run the macro as soon as its button is pressed. Uncheck to impersonate (if applicable) and prepare the macro command in the command box. +#TODO: Write tooltip for this. +component.tooltip.macro.buttonColor = Select the colour of the face of this macro's button. +component.tooltip.macro.compareUseApplyToSelected = Check here to consider this macro's Use Apply to Selected Tokens state when determining its commonality with other macros. +component.tooltip.macro.compareUseAutoExecute = Check here to consider this macro's Auto Execute state when determining its commonality with other macros. +component.tooltip.macro.compareUseCommand = Check here to consider this macro's Command when determining its commonality with other macros. +component.tooltip.macro.compareUseGroup = Check here to consider this macro's Group when determining its commonality with other macros. +component.tooltip.macro.compareUseIncludeLabel = Check here to consider this macro's Include Label state when determining its commonality with other macros. +component.tooltip.macro.compareUseSortPrefix = Check here to consider this macro's Sort Prefix when determining its commonality with other macros. +component.tooltip.macro.displayHotKey = Display or Hide the Hot Key on the macro button. +component.tooltip.macro.fontColor = Select the colour in which the label for this macro's button will appear in the macro button panels. +component.tooltip.macro.fontSize = Selected the size of the font in which the label for this macro's button will appear in the macro button panels. +component.tooltip.macro.group = This is the group in the macro button panel in which this macro will appear. If the group does not already exist, it will be created. +component.tooltip.macro.hotKey = This sets a hot key for this macro. These hot keys are common across all macro panels. +component.tooltip.macro.includeLabel = Check here to include the macro's label with the macro output in chat. Uncheck to only have the macro output appear in chat. +# These really should use the ".description" style that is used by the menu +# selections, above. We'll convert these to new names later on and when +# we do, we'll convert all translation files at the same time. +component.tooltip.macro.label = This is the name that will appear on the macro button. +component.tooltip.macro.maxWidth = Specify the maximum width this macro button should fill in a macro button panel. If the label for the macro button exceeds this width, the label will be cut off. Leaving this field blank will let the button auto-fit to the label length. +component.tooltip.macro.minWidth = Specify the minimum width this macro button should fill in a macro button panel. If the label for the macro button exceeds this width, the button will grow to accommodate it. Leaving this filed blank will allow the button to shrink to auto-fit smaller labels. +component.tooltip.macro.sortPrefix = This determines the order within its group that this macro will appear. +component.tooltip.macro.tooltip = Enter a tool tip for the macro button to display here. +component.msg.macro.textfound = Text found; occurrences marked: {0} +component.msg.macro.occurrences = Occurrences marked: {0} +component.msg.macro.notfound = Text not found + +# The IP address in these next two messages comes from the results of the ConnectionInfoDialog contacting the RPTools Registry and asking for it. +# It's obviously possible that this will fail. In those cases the string returned will be "Unknown". The first line is for the confirmation dialog and the +# other two appear as output in the chat window. +confirm.info.heartbeat.registryFailure = Connection refresh to the MapTool registry failed.

The registry server will purge records periodically, making it difficult for future clients to connect.
If this persists, you will need to provide clients with your contact information directly (IP address "{0}" and port {1}). +confirm.macro.allowPlayerEdits = Are you sure you wish to allow players to edit any macro common to this one?

Select "Yes" to continue with the change. Select "No" to revert. +confirm.macro.checkComparisons = Do you want to check comparison criteria for each common macro before adding it to the export list?

If you select "No", MapTool will not prompt you if any of a particular macro's commonality criteria are deselected. A macro with deselected macro criteria may be exported with missing information. For example, if a macro with "Command" comparison deselected is added to the export list, that macro will be exported without a command. +confirm.macro.clearGroup = You are about to clear the {0} macro group. Are you sure you want to continue? +confirm.macro.clearPanel = You are about to clear the {0} macro panel. Are you sure you want to continue? +confirm.macro.commonSelectionLocation = within the common selection macros +# The only parameter for *most* translation strings is the +# player's name (as it appears in the Connection panel). Some +# strings, particularly the ones dealing with macro messages, have +# multiple parameters. It's usually pretty obvious what propertyType of +# value is being used as a parameter, but some messages have a comment +# directly above them to clarify, if appropriate. +# +# Valid patterns used to express parameters are: +# {num} replace the parameter with a string +# {num,propertyType,size} +# propertyType can be 'time' or 'date' (for java.util.Date objects), +# 'number' to indicate a numeric propertyType, +# and size can be +# 'short', 'int', or 'long' for numeric arguments of the same propertyType. +# +# Check the javadoc for the 'MessageFormat' class for more details on the +# formatting of values in this file (the time and date ones are particularly +# tricky, but thankfully aren't used much in MapTool). The URL is in the +# comments at the top of this file. +# General confirmation-propertyType messages +confirm.macro.delete = You are about to delete the {0} macro.

Do you wish to continue? +confirm.macro.disallowPlayerEdits = Are you sure you wish to prevent players from editing any macro common to this one?

Select "Yes" to continue with the change. Select "No" to revert. +confirm.macro.exportInto = You are about to export the {0} macro.

Do you wish to continue? +confirm.macro.exportOverwrite = You are about to overwrite an existing macro file.

Do you wish to continue? +confirm.macro.exportSetInto = You are about to export the current macro set.

Do you wish to continue? +confirm.macro.exportSetOverwrite = You are about to overwrite an existing macro set file.

Do you wish to continue? +confirm.macro.failComparison = Macro {0} has the following comparison criteria deselected:

    {1}

Do you wish to add this macro to the export list?

Selecting "Yes" will result in the macro being exported without the information listed. +confirm.macro.import = The import macro {0} appears to match a macro that already exists {1}. Do you wish to import the macro again?

Select "Yes" to import the macro anyway. Select "No" to cancel import of the macro.

If you believe the macros are not the same, select "No" and verify the commonality criteria of the existing macro on the "Options" tab of its edit dialog. +# {0} is the name of the frame that contains the macro: Global, Campaign, etc. +confirm.macro.panelLocation = within the {0} panel +confirm.macro.reset = You are about to reset all fields of the {0} macro.

Do you wish to continue? +# {0} is the token's Name field +confirm.macro.tokenLocation = on {0} + +defaultTool.barMenu = Bar +defaultTool.ownerMenu = Owner +defaultTool.stateAction.AFK = Away From Keyboard +defaultTool.stateAction.AFK.accel = typed Pause +defaultTool.stateAction.StableHP = Stabilized +defaultTool.stateAction.clear = Clear State +# My campaign has the following states. Putting their descriptions +# here is decidedly obscure. :) There should be fields on the Campaign +# Properties' States tab for this instead. Although it's questionable +# whether user-defined states need to be translated anyway! +# AFK Dead Fly Other4 Song +# Bless Deafened Haste Paralyzed StableHP +# Blind Disabled Hidden Poisoned Staggered +# Bloody25 Dying Incapacitated Prayer Stunned +# Bloody50 EnergyDrained Levitate PrayerFOE Turned +# Bloody75 Enraged Marked Prone Unconscious +# Bloody100 Entangled Other Shield Update +# Confused Fatigued Other2 Sickened +# Dazed Fear Other3 Slowed +defaultTool.stateAction.light = Light... +defaultTool.stateMenu = &State +defaultTool.visionMenu = Vision + +dialog.addresource.downloading = Downloading List ... +dialog.addresource.errorDownloading = Error downloading list. +dialog.addresource.warn.badpath = Invalid path +dialog.addresource.warn.couldnotload = Error while downloading library +dialog.addresource.warn.directoryrequired = Must be a directory +dialog.addresource.warn.filenotfound = Could not find resource "{0}" +dialog.addresource.warn.invalidurl = Invalid URL: {0} +dialog.addresource.warn.musthavename = Must supply a name for the library +dialog.addresource.warn.mustselectone = Must select at least one library to download +dialog.addresource.error.malformedurl = Artpack URL {0} is malformed. Please check your installation. +dialog.addresource.warn.badresourceid = Bad resource identifier: {0}. Report error to MapTool team. +dialog.campaignExport.notes.version.1.4.0.0 = Exporting to this version will strip out any drawables and any campaign settings for Lumens.
Tokens with VBL will loose this functionality as well as any Always Visible values.
Merged Drawings will still be present but their label in Draw Explorer will not show as normal.

Note: Macros will remain unchanged, so any reference to newer functionality not available in this version will cause normal errors when ran. +dialog.campaignExport.notes.version.1.4.0.1 = Exporting to this version will strip out any campaign settings for Lumens.
Tokens with VBL will loose this functionality as well as any Always Visible values.
Merged Drawings will still be present but their label in Draw Explorer will not show as normal.

Note: Macros will remain unchanged, so any reference to newer functionality not available in this version will cause normal errors when ran. +dialog.campaignExport.notes.version.1.4.1..1.5.0 = Exporting to this version will make sure the former format of the content.xml inside the campaign file is kept and the unitsPerCell value for zones/maps is an integer (vs. double in the newer versions). +dialog.campaignExport.notes.version.1.5.1 = Exporting to this version will make sure the former format of the content.xml inside the campaign file is kept. +dialog.campaignexport.error.invalidversion = Unable to export, an invalid version number was detected. +dialog.colorChooser.title = Choose Colour +dialog.copyZone.msg = New map name: +# {0} is the current map name +dialog.copyZone.initial = Copy of {0} +dialog.resizeStamp.title = Automatically Resize Stamp +dialog.resizeStamp.checkbox.horizontal.anchor = Adjust Horizontal Anchor? +dialog.resizeStamp.checkbox.vertical.anchor = Adjust Vertical Anchor? +dialog.resizeStamp.label.height = Height: +dialog.resizeStamp.label.height.selected = Number of Vertical Cells Selected: +dialog.resizeStamp.label.px = px +dialog.resizeStamp.label.stampDimensions = Stamp Dimensions +dialog.resizeStamp.label.width = Width: +dialog.resizeStamp.label.width.selected = Number of Horizontal Cells Selected: +dialog.resizeStamp.toolTip = Adjust the Anchor point so when snapping to grid, the grid aligns. Useful when the left edge of the stamp has a partial cell. +dialog.screenshot.error.failedExportingImage = Failed to export image. +dialog.screenshot.error.failedImageGeneration = Failed to generate image. +dialog.screenshot.error.invalidDialogSettings = Invalid dialog settings... Please report bug! +dialog.screenshot.error.mustSelectView = Must select a view. +dialog.screenshot.error.negativeFogExtents = Error computing fog extents... Please send campaign for debugging. +dialog.screenshot.error.noArea = Screenshot has no area. +dialog.screenshot.layer.button.uiImplementationError = Enums in class do not match Abeille form variables. Please report bug. +dialog.screenshot.msg.GeneratingScreenshot = Generating screenshot. +dialog.screenshot.msg.screenshotSaved = Screenshot saved +dialog.screenshot.msg.screenshotSaving = Screenshot saving +dialog.screenshot.msg.screenshotStreaming = Screenshot streaming +dialog.screenshot.radio.button.uiImplementationError = Enums in class do not match Abeille form variables. Please report bug. +dialog.stampTool.error.badSelection = Please create a larger selection area. +dialog.stampTool.error.noSelection = Please select an area that starts and stops over the token. +dialog.mapProperties.title = Map Properties +dialog.importedMapProperties.title = Imported Map Properties + +dungeondraft.import.unknownFormat = Unrecognized format value in Universal VTT file: {0}. +dungeondraft.import.missingFormatField = No format specifier found. Invalid file format. +dungeondraft.import.ioError = IO Error importing map. +dungeondraft.import.missingResolution = Resolution field missing in import file. +dungeondraft.import.missingPixelsPerGrid = Pixels per grid field missing in import file. +dungeondraft.import.image = Image field missing in import file. +dungeondraft.import.lightsIgnored = Some lights where ignored as X,Y co-ordinates where missing. + + +emit.description = Broadcast text to all connected players without indicating who sent it (GM only command). + +emote.description = Broadcast an emote to all connected players. + +emoteplural.description = Broadcast plural emote to all connected players. + +experiments.description = Start experimental features. +# Experimental features +experiments.listTitle = Experimental Features (use at own risk). + +# Filename extension descriptions +# (These should be more consistent. Maybe in 1.4. Sigh.) +file.ext.cmpgn = MapTool Campaign +file.ext.mtmacro = MapTool Macro +file.ext.mtmacset = MapTool Macro Set +file.ext.mtprops = MapTool Campaign Properties +file.ext.mttable = MapTool Table +file.ext.rpmap = MapTool Map +file.ext.rptok = MapTool Token +file.ext.dungeondraft = Universal VTT Map (.dd2vtt, .df2vtt, .uvtt) +file.ext.addOnLib = Maptool Add-On Library + +goto.description = Goto location or token. /goto X,Y or /goto tokenname. + +help.description = Display list of available commands. +help.header.aliases = Aliases +# Next three are for the titles generated in the table of commands in /help +help.header.command = Slash Command +help.header.description = Description + +impersonate.description = Speak as if you were something/one else. +impersonate.mustOwn = Only {0}''s owners can impersonate or run macros on it. + +initPanel.addAll = Add All +initPanel.addPCs = Add PCs +initPanel.center = Center On Map +initPanel.clearInitState = Clear Initiative +initPanel.displayMessage = {0} has received initiative. +initPanel.enterState = Enter the initiative for {0}: +initPanel.enterStateMany = Enter the initiative for the selected tokens: +initPanel.initStateSecondLine = Initiative on Line 2 +initPanel.makeCurrent = Make Current +initPanel.moveDown = Move Down +initPanel.moveUp = Move Up +initPanel.next = Next +initPanel.next.description = Move the initiative to the next token. +initPanel.prev = Previous +initPanel.prev.description = Move the initiative to the previous token. +initPanel.remove = Remove Token +initPanel.removeAll = Remove All +# Initiative Panel +initPanel.round = Round: +initPanel.round.description = Reset the Round counter and clear current initiative. +initPanel.setInitState = Set Initiative... +initPanel.showInitStates = Show Initiative +initPanel.showTokenStates = Show Token States +initPanel.showTokens = Show Tokens +initPanel.sort = Sort +initPanel.sort.description = Sort the list by initiative values. Uses Descending order by default, with any non-numeric values coming after any numbers, and any blank values coming last. +initPanel.toggleHideNPCs = Hide NPCs +initPanel.toggleHideNPCs.description = When enabled, players will not see any NPC tokens in this list. +initPanel.toggleHold = Toggle Hold +initPanel.toggleHold.description = Toggle Hold for selected token. +initPanel.toggleMovementLock = Lock Movement +initPanel.toggleMovementLock.description = When enabled, only the token with initiative can be moved (unless by GMs). +initPanel.toggleOwnerPermissions = Owner Permissions +initPanel.toggleOwnerPermissions.description = Allow players with token ownership to add/remove their tokens, and use the Next button when it is their turn. +initPanel.toggleReverseSort = Use Reverse Sort Order +initPanel.toggleReverseSort.description = Use the Reverse (Ascending) Order when Sorting from this menu. +initPanel.togglePanelButtonsDisabled = Disable Panel Buttons +initPanel.togglePanelButtonsDisabled.description = Disable the Next/Previous buttons on the Initiative Panel. Useful to prevent mistakes when managing initiative through other macros. +initPanel.buttonsAreDisabled = Panel buttons have been disabled by GM. + +# Initiative menu on the token popup. +initiative.menu = Initiative +initiative.menu.add = Add +initiative.menu.addToInitiative = Add To Initiative +initiative.menu.clearState = Clear Initiative +initiative.menu.enterState = Set the initiative for selected tokens: +initiative.menu.hold = Hold +initiative.menu.remove = Remove +initiative.menu.resume = Resume +initiative.menu.setState = Set Initiative... + + +layer.token = Token +layer.gm = Hidden +layer.object = Object +layer.background = Background + +lightDialog.cancel = &Cancel +lightDialog.off = O&ff +lightDialog.ok = &OK + +lineParser.atTokenNotFound = Macro not found: "{0}@token". +lineParser.badOptionFound = Bad option found! Options String = "{0}", Roll String = "{1}". +# {0} is the roll options string. +lineParser.badRollOpt = Bad Roll option "{0}". +lineParser.countNonNeg = Count option requires a non negative number, got {0}. +# {0} = token name or gm name. +# Notice there are no double quotes around {0}. +lineParser.dialogTitle = Input Value for {0}. +lineParser.dialogTitleNoToken = Input Value. +lineParser.dialogValueFor = Value For "{0}" +lineParser.duplicateLibTokens = Duplicate "{0}" tokens found. +lineParser.emptyTokenName = Cannot assign a blank or empty string to the variable token.name +lineParser.errorBodyRoll = Error in body of roll. +# {0} = the error, {1} = the expression +lineParser.errorExecutingExpression = {0} error executing expression {1}. +# {0} = the option (e.g. FOR, COUNT), {1} = error message. +# Notice that {1} doesn't have quotes around it. +lineParser.errorProcessingOpt = Error processing "{0}" option: {1}. +lineParser.errorStmtBody = Statement Body +lineParser.errorStmtBodyFirst200 = Statement Body (first 200 characters) +lineParser.errorStmtOpts = Statement options (if any) +lineParser.forNoZeroStep = Step size for FOR loop cannot be zero. +lineParser.forVarMissing = FOR: variable missing. +lineParser.foreachVarMissing = FOREACH: variable missing. +lineParser.ifError = Error in roll for IF option. +lineParser.invalidCondition = Invalid condition in {0}({1}) roll option. +lineParser.invalidExpr = Invalid expression: {0}. +lineParser.invalidIfCond = Invalid IF condition: {0}, evaluates to: {1}. +lineParser.invalidMacroLoc = Must specify a location for the macro "{0}" to be run from. +lineParser.invalidWhile = Invalid condition in WHILE({0}) roll option. +lineParser.libUnableToExec = Unable to execute macro from "{0}": not visible to player. +lineParser.cantAssignToConstant = Constant "{0}" is not a valid assignment target. +# MapToolLineParser errors +# Note that many of the errors detected by the line parser will include +# single and/or double quotes. That means we don't want to add any here +# unless we are absolutely sure that they should always be printed and +# will be useful to the user. Don't change these without testing... +lineParser.maxRecursion = Maximum recurse limit reached. +lineParser.nonDefLoopSep = To specify a non-default loop separator, you must use the format "FOR(var,start,end,step,separator)" +lineParser.notALibToken = Macros from other tokens are only available if the token name starts with "Lib:". +lineParser.notValidNumber = "{0}" is not a valid number. +lineParser.notValidVariableName = "{0}" is not a valid variable name. +# Map Tool Variable Resolver +lineParser.onlyGMCanGet = Only GM can get "{0}". +lineParser.onlyGMCanSet = Only GM can set "{0}". +lineParser.optBadParam = Roll option "{0}": bad option parameters {1}. +lineParser.optRequiresParam = Roll option "{0}" requires a list of no more than {1} parameters in parentheses. +lineParser.optReservedName = Roll option "{0}": "{1}" is a reserved name. +lineParser.optWrongParam = Roll option "{0}" must have between {1} and {2} parameters; found {3}: parameter list = "{4}" +lineParser.rollOptionComma = Roll option list can't end with a comma. +lineParser.switchError = Error in roll for SWITCH option. +lineParser.switchNoMatch = SWITCH option found no match for "{0}". +lineParser.tooManyLoops = Too many loop iterations (possible infinite loop?) +lineParser.unknownCampaignMacro = Unknown campaign macro "{0}". +lineParser.unknownGlobalMacro = Unknown global macro "{0}". +lineParser.unknownLibToken = Unknown library token "{0}". +lineParser.unknownMacro = Unknown macro "{0}". +lineParser.unknownOptionName = Unknown option name "{0}". +lineParser.unresolvedValue = Unresolved value "{0}". + +# Notice that the error messages don't have double quotes around them... +# +# {0} is the file name +loadaliases.cantFindFile = Could not find alias file: "{0}" +# {0} is the error message +loadaliases.couldNotLoad = Could not load alias file: {0} +loadaliases.description = Load a file that contains aliases, one per line, with a : between the name and the value (just as if you were typing it in). +loadaliases.dialogTitle = Load Aliases +loadaliases.ignoring = Ignoring alias "{0}" +loadaliases.loading = Loading aliases: + +# {0} is the file name +loadtokenstates.cantFindFile = Could not find token states file: "{0}" +# {0} is the error message +loadtokenstates.couldNotLoad = Could not load token states file: {0} +loadtokenstates.description = Load all of the token states from a file. +loadtokenstates.dialogTitle = Load Token States +# {0} is the number of states loaded +# Note that this numeric value is declared as such. This is to provide +# for localization support, i.e. in English adding a comma in the thousands +# position and a period for the decimal separator (it's a whole number though, +# so there will never be a decimal point). +loadtokenstates.loaded = There were {0,number} token states loaded. + +lookuptable.couldNotPerform = Could not do table lookup: "{0}" +lookuptable.description = Run a table lookup. Usage: /tbl [value to lookup, can be a dice roll] +lookuptable.specifyTable = Must specify a table + +macro.function.LookupTableFunctions.invalidSize = Invalid image size in function "{0}". +macro.function.LookupTableFunctions.noImage = No Image available in function "{0}" for table "{1}". +# LookupTableFunctions +macro.function.LookupTableFunctions.unknownTable = Unknown table name "{1}" in function "{0}". +macro.function.MacroFunctions.missingCommand = "{0}": Missing command. +macro.function.MacroFunctions.missingLabel = "{0}": Missing label. +macro.function.MacroFunctions.noPerm = "{0}": You do not have permissions to edit macro button at index {1} on token {2}. +macro.function.MacroFunctions.noPermOther = "{0}": You do not have permissions to edit macro button {1} at index {2} on token {3}. +macro.function.MacroFunctions.noPermMove = "{0}": You do not have permissions to move macro button {1} at index {2}. +macro.function.MacroFunctions.noPermCommand = "{0}": You do not have permissions to change the command of macro button at index {1} on token {2}. +macro.function.MacroFunctions.noPermEditable = "{0}": You do not have permissions to change the player editable status of macro button at index {1} on token {2}. +macro.function.MacroFunctions.outOfRange = "{0}": Macro at index {1} does not exist for token {2}. +macro.function.TokenInit.notOnList = The token is not in the initiative list. +# TokenInitFunctions +macro.function.TokenInit.notOnListSet = The token is not in the initiative list so no value can be set. +# abort Function +# Note that I'm leaving off the double quotes on this one. I think it +# will look better that way. +macro.function.abortFunction.messge = {0} function called. +# addAllToInitiativeFunction +macro.function.addAllToInitiativeFunction.mustBeGM = Only the GM has the permission to execute the "{0}" function. +# MacroArgsFunctions +macro.function.args.incorrectParam = Function "{0}" must be called with exactly 1 numeric parameter. +macro.function.args.outOfRange = Argument index {1} out of range (max of {2}) in function "{0}". +# assert Function +# {0} is the error message specified when calling assert() for message. +# Note that I'm leaving off the double quotes on this one, too. I think it +# will look better that way. +macro.function.assert.message = Macro-defined error: {0} +macro.function.assert.mustBeString = Second argument to "{0}": "{1}" must be of type String. +macro.function.defineFunction.functionDefined = "{0}" function defined. +# DefineMacroFunctions +macro.function.defineFunction.notEnoughParam = Not enough parameters for "defineFunction". +# FindTokenFunctions +macro.function.findTokenFunctions.offsetArray = Offset array for Area must contain JSON object with (x,y) coordinates in function "{0}". +macro.function.findTokenFunctions.unknownEnum = Program error: unknown enum "{1}" in switch block in function "{0}". +macro.function.general.accessDenied = Access is denied for the "{0}" function. Enable access via Preferences option. +macro.function.general.argumentKeyTypeA = Argument key "{1}" to function "{0}" must be a JSON Array. +macro.function.general.argumentKeyTypeD = Argument key "{1}" to function "{0}" must be an number. +macro.function.general.argumentKeyTypeG = Argument key "{1}" to function "{0}" must be a GUID. +macro.function.general.argumentKeyTypeI = Argument key "{1}" to function "{0}" must be an integer. +macro.function.general.argumentTypeA = Argument number {1} to function "{0}" must be a JSON Array. +macro.function.general.argumentTypeI = Argument number {1} "{2}" to function "{0}" must be an integer. +macro.function.general.argumentTypeInvalid = Argument number {1} invalid argument type for function "{0}". +macro.function.general.argumentTypeJ = Argument number {1} to function "{0}" must be a JSON Array or Object. +macro.function.general.argumentTypeN = Argument number {1} "{2}" to function "{0}" must be a number. +macro.function.general.argumentTypeO = Argument number {1} to function "{0}" must be a JSON Object. +macro.function.general.argumentTypeS = Argument number {1} to function "{0}" must be a string. +# {0} = function name, {1} = argument number, {2} = content of argument {1} +macro.function.general.argumentTypeT = Argument number {1} to function "{0}" must be a Token id or name. +macro.function.general.noImpersonated = Error executing "{0}": there is no impersonated token. +# Externalized strings for Macro Functions errors +# +# Unless otherwise specified {0} is the name of the function that was called +# +# General messages used in several functions. +# You'll see {1} and {2} used as numbers, below. Technically they +# should actually be {1,number} and {2,number}. However, there's no +# reason to localize these values as they will always be whole numbers +# so the decimal separator is not needed, and they will always be small +# enough that no thousands separator will be needed either. So leaving +# off the ",number" means they'll be treated as strings and simply +# output as-is. Which is fine. :) +macro.function.general.reservedJS = {0} is a reserved function in the js. prefix. +macro.function.general.noPermJS = You do not have permission to use the "{0}" namespace. +macro.function.general.noPerm = You do not have permission to call the "{0}" function. +macro.function.general.noPermOther = You do not have permission to access another token in the "{0}" function. +macro.function.general.notEnoughParam = Function "{0}" requires at least {1} parameters; {2} were provided. +macro.function.general.onlyGM = Only the GM can call the "{0}" function. +macro.function.general.tooManyParam = Function "{0}" requires no more than {1} parameters; {2} were provided. +macro.function.general.unknownFunction = Unknown function name "{0}". +macro.function.general.unknownToken = Error executing "{0}": the token name or id "{1}" is unknown. +macro.function.general.unknownPropertyType = Error executing "{0}": the property type "{1}" is unknown. +macro.function.general.unknownProperty = Error executing "{0}": the property "{1}" is unknown for type "{2}". +macro.function.general.unknownTokenOnMap = Error executing "{0}": the token name or id "{1}" is unknown on map "{2}". +macro.function.general.wrongNumParam = Function "{0}" requires exactly {1} parameters; {2} were provided. +macro.function.general.listCannotBeEmpty = {0}: string list at argument {1} cannot be empty +# Token Distance functions +# I.e. ONE_TWO_ONE or ONE_ONE_ONE +macro.function.getDistance.invalidMetric = Invalid metric type "{0}". +#getInfo function {0} is the value that was passed in +macro.function.getInfo.invalidArg = Invalid value "{0}" for getInfo(). +# InitiativeRoundFunctions +macro.function.getInitiativeRound.mustBeGM = Only the GM can set the round. +# ExecFunction +macro.function.execFunction.incorrectName = Error executing "{0}": the function name "{1}" is unknown. +# Token Halo functions {0} is the colour +macro.function.haloFunctions.invalidColor = Invalid halo colour "{0}". +macro.function.herolab.null = HeroLab data does not exist for this token. +macro.function.herolab.xpath.invalid = Provided XPath expression "{0}" was invalid or did not point to a text or attribute node. +# Initiative functions general errors +macro.function.initiative.gmOnly = Only the GM can perform "{0}". +macro.function.initiative.gmOrOwner = Only the GM or owner can perform "{0}". +macro.function.initiative.noImpersonated = Error executing initiative function: there is no impersonated token. +macro.function.initiative.oneParam = Must call "{0}" with one parameter. +macro.function.initiative.unknownToken = Unknown token id "{0}" on map "{1}". +macro.function.input.illegalArgumentType = Illegal argument type "{0}", expecting "{1}". +macro.function.parse.enum.illegalArgumentType = Error executing "{0}": Illegal argument type "{1}", expecting one of "{2}". +# {0} = the option key, {1} = the option value, {2} = the option propertyType, {3} = the option specifier +macro.function.input.invalidOptionType = The option "{0}={1}" is invalid for input type "{2}" in specifier "{3}". +#input function +macro.function.input.invalidSpecifier = Empty variable name in the specifier string "{0}". +macro.function.input.invalidTAB = To use inputType of TAB in input(), the first entry must have the TAB type. +macro.function.input.invalidType = Invalid input type "{0}" in the specifier string "{1}". +macro.function.json.append.onlyArray = You can only append to the end of JSON Arrays. +macro.function.json.arrayMustContainObjects = Fields specified for json.sort but not all items in array are JSON objects; found "{0}". +macro.function.json.arrayCannotBeEmpty = {0}: JSON Array at argument {1} cannot be empty +macro.function.json.getInvalidEndIndex = Invalid end index "{1}" for array (size of {2}) in function "{0}". +macro.function.json.getInvalidStartIndex = Invalid start index "{1}" for array (size of {2}) in function "{0}". +macro.function.json.matchingArrayOrRoll = The 3rd argument must be a string containing a roll or a JSON array the same size as the 2nd argument. +macro.function.json.notAllContainKey = Not all objects contain field "{0}" in json.sort. +macro.function.json.arrayArgMustBeNumber = Argument number {2} to {1} must be a number for JSON Arrays. +macro.function.json.indentMustBeNumeric = Indentation value passed to {0} must be numeric +# General JSON macro function errors +macro.function.json.onlyArray = Got {0} but "{1}" only accepts JSON Arrays. +macro.function.json.onlyJSON = Got {0} but "{1}" only accepts JSON Arrays or Objects. +macro.function.json.onlyObject = Got {0} but "{1}" only accepts JSON Objects. +macro.function.json.setNoMatchingValue = No matching value for key in "{0}". +macro.function.json.unknownType = Unknown JSON type "{0}" in function "{1}". +macro.function.json.path = Error with function "{0}": {1} +macro.function.macroLink.arguments = Arguments +# Informational messages for Macro functions. +macro.function.macroLink.autoExecToolTip = Auto Execute Macro Link +# {0} is the error message +macro.function.macroLink.errorRunning = Error Running Macro Link: "{0}" +macro.function.macroLink.executeOn = Execute On +macro.function.macroLink.impersonated = Impersonated Tokens +# MacroLinkFunctions +macro.function.macroLink.missingName = Missing macro name in function "{0}". +macro.function.macroLink.selected = Selected Tokens +macro.function.macroLink.unknown = Unknown +macro.function.map.none = {0}: function requires a current map, but none is present. +# {0} is the function name +macro.function.map.notFound = {0}: indicated map in first parameter not found. +macro.function.map.invalidAsset = {0}: "{1}" is not a valid asset ID or URL +# {0} is the function name +macro.function.moveTokenMap.alreadyThere = Can not use "{0}" to move tokens to a map that they are already on! +# {0} is the token name/id, {1} is the map it's moved to. +macro.function.moveTokenMap.movedToken = Moved Token "{0}" to map "{1}" from map "{2}". +# moveTokenToMap/moveTokenFromMap, {0} is the function name, {1} is the +# map name or token id +macro.function.moveTokenMap.unknownMap = Can not find map "{1}" in function "{0}". +macro.function.moveTokenMap.unknownToken = Can not find token "{1}" in function "{0}". +# number function +macro.function.number.invalid = Invalid number format "{1}" in "{0}". +# RESTful Function Errors +macro.function.rest.error.response = Unable to process function "{0}", HTTP Status Code: {1} +macro.function.rest.error.unknown = Unable to process function "{0}", An Exception has occurred: {1} +macro.function.rest.syrinscape.error = Unable to launch Syrinscape. Check that Syrinscape is installed and a proper URI was passed. +# [token():...] roll option +macro.function.roll.noPerm = You do not have enough permissions to run the [token(...): ...] roll command. +macro.function.stateImage.notImage = State "{1}" is not an image state in function "{0}". +# StateImageFunction {1} is the state name +macro.function.stateImage.unknownState = Unknown state "{1}" in function "{0}". +macro.function.barImage.notImage = Bar "{1}" is not an (multi-)image bar in function "{0}". +# BarImageFunction {1} is the state name +macro.function.barImage.unknownBar = Unknown bar "{1}" in function "{0}". +macro.function.strLst.incorrectParam = "{0}" requires between {1} and {2} parameters. +# String List +macro.function.strLst.incorrectParamExact = "{0}" requires exactly {1} parameters. +# {0} = function name, {1} = argument number, {2} = expected propertyType, +# {3} = value user passed, {4} = propertyType of the value user passed. +macro.function.strLst.incorrectParamType = Argument number {1} to function "{0}" must be type "{2}", but was passed "{3}" of type "{4}". +macro.function.strPropFromVar.wrongArgs = strPropFromVars second parameter "{0}" is invalid. +macro.function.sound.illegalargument = Error executing "{0}", parameter "{1}" is invalid: {2} +macro.function.sound.mediaexception = Error executing "{0}" with media "{1}" +macro.function.syrinscape.inactive = This client has not enabled Syrinscape integration in preference. +# TokenLightFunctions +macro.function.tokenLight.unknownLightType = Unknown light type "{1}" in function "{0}". +# name setting functions +macro.function.tokenName.emptyTokenNameForbidden = Error executing "{0}": the token name cannot be empty. +# TokenPropertyFunctions +macro.function.tokenProperty.invalidSize = Invalid token size "{1}" in function "{0}". +macro.function.tokenProperty.unknownLayer = Unknown layer "{1}" in function "{0}". +macro.function.tokenProperty.unknownLibToken = Unknown Lib: token "{1}" in function "{0}". +macro.function.tokenProperty.unknownPropType = Unknown property type "{1}" in function "{0}". +# CopyTokenFunctions +macro.function.tokenCopy.oxymoronicParameters = In "{0}": Parameters "delta" and "relativeto" can't be used at the same time. ("delta" parameter is deprecated as of 1.9.0). Visit https://wiki.rptools.info/index.php/copyToken +macro.function.tokenCopy.noCurrentToken = No current token found. Try using switchToken() or impersonate one. See https://wiki.rptools.info/index.php/Current_Token +macro.function.tokenCopy.unrecognizedRelativeValue = In "{0}": "relativeto" value within 4th parameter (json properties) not recognized. Visit https://wiki.rptools.info/index.php/copyToken +macro.function.tokenCopy.invalidPropertyType = The property type {0} does not exist in the campaign properties. +# TokenStateFunctions +macro.function.tokenStateFunctions.unknownState = Unknown state "{0}". +# TokenBarFunction +macro.function.tokenBarFunction.unknownBar = Error with function "{0}": unknown bar "{1}". +# String Property +# {0} = value the user passed. +macro.function.varsFromstrProp.wrongArgs = varsFromStrProp called with 3 arguments, but second argument "{0}" was not one of NONE, SUFFIXED, or UNSUFFIXED. +macro.function.tokenCopyDelete.noName = No name specified for token. +macro.function.tokenCopyDelete.noImage = No image specified for token. + +macro.function.markdown.unknownType = Unknown Markdown type {0}. + +macro.function.html5.invalidURI = Invalid URI {0}. +macro.function.html5.unknownType = Unknown HTML5 Container specified. +macro.function.jsevalURI.invalidURI = Can not access JavaScript from URI {0}. + +macro.setAllowsURIAccess.notLibToken = {0} is not a valid lib:token name, URI access can only be set on lib:tokens. +macro.setAllowsURIAccess.reservedPrefix = Can not set URI access on lib:tokens starting with {0} +macro.setAllowsURIAccess.reserved = Can not set URI access on lib:token named {0} +# Macro Link +macroLink.error.running = Error running macro link. +macroLink.error.tooltip.bad.href = Invalid or missing HREF + +macromanager.alias.indexNotFound = (error: "{0}" is not found) +# {0} is the command, {1} is the exception +macromanager.couldNotExecute = Could not execute the command: "{0}", exception = {1} +# {0} is the command +macromanager.tooManyResolves = Too many resolves running "{0}"; perhaps an infinite loop? +macromanager.ambiguous = Command {0} is ambiguous, please specify the namespace as well, matching options are: + +menu.QuickMap = Quick Map +menu.edit = &Edit +menu.export = Export +menu.file = &File +menu.help = &Help +menu.map = &Map +menu.overlay = &Overlays +menu.recent = &Recent Campaigns +menu.tools = &Tool +menu.view = &View +#action.enableVision=Use Vision +#action.enableVision.description=Use the Vision Blocking Layer on this map +menu.vision = Vision +menu.window = &Window +menu.zoom = &Zoom + + +dragdrop.unsupportedType = MapTool does not support adding this file type to the campaign. + + +msg.button.close = Close +msg.commandPanel.hasEnteredText = {0} has entered text. +# Command Panel; {0} is the player name +msg.commandPanel.liveTyping = {0} is typing... +msg.commandPanel.cheater.self = Cheater. You have been reported. +# {0} is the player name, {1} is their input +msg.commandPanel.cheater.gm = {0} was caught cheating: {1} +msg.commandPanel.div = Unexpected </div> tag without matching <div>. +msg.confirm.aboutToBeginFTP = About to begin FTP process of {0,number} file(s)... +msg.confirm.bootPlayer = Are you sure you want to boot {0}? +msg.confirm.campaignExported = Campaign exported. +msg.confirm.clearAllDrawings = This will clear all drawings on layer {0} and completely empty the undo queue for ALL layers.
This cannot be undone. Are you sure? +msg.confirm.deleteDraw = Are you sure you want to delete the selected drawings? +msg.confirm.deleteDraw.removed = This will no longer ask for permission when deleting drawing. If you want to turn this back on look in Preferences. +msg.confirm.deleteToken = Are you sure you want to delete the selected tokens? +msg.confirm.deleteToken.removed = This will no longer ask for permission when deleting tokens. If you want to turn this back on look in Preferences. +msg.confirm.disconnecting = You will be disconnected. Are you sure you want to exit? +msg.confirm.fileExists = Overwrite existing file? +msg.confirm.hostingDisconnect = You are hosting a server. Disconnecting will disconnect all connected clients.
Are you sure? +msg.confirm.jvm.options = Some Java JVM startup options for MapTool may have changed.
You will need to restart MapTool before these will take affect.

Invalid settings could prevent MapTool from starting, are you sure you wish to save these settings? +msg.confirm.legacySave = You are saving in an old format -- you may lose some information by doing this. Continue? +msg.confirm.loseChanges = Changes to your campaign will be lost. Continue? +msg.confirm.newCampaign = Discard current campaign? +msg.confirm.webServerStartTitle = Start Experimental Web App? +msg.confirm.webServerStart =
\ + If you did not start the server press cancel\ +

The experimental Server App is deprecated and will be removed \ + in an upcoming version.

If you currently make use of this feature please \ + visit discord channel to let us know how you are using it so we can \ + include this in our plans for its replacement

\ +

(link will appear in chat after server has started)

+ +msg.confirm.newerVersion = You are attempting to load a campaign created by MapTool {1}.
There may be loading errors because you are running version {0}.

Are you sure? +msg.confirm.overwriteExistingCampaign = That file already exists. Overwrite? +# Notice in this message how {0} is used twice? The first one is a +# Date object interpreted as a time, and the second one is a Date object +# interpreted as a date. +msg.confirm.recoverAutosave = An autosave file created at {0,time} on {0,date} exists.
Would you like to retrieve it? +msg.confirm.removeFacings = Are you sure you want to delete the facing of the selected tokens? +msg.confirm.removeZone = Removing a map cannot be undone.
Are you sure? +msg.confirm.renameMap = Rename "{0}"? +msg.confirm.restoreFoW = Map contains exposed areas of fog.
Do you want to reset all of the fog? +msg.confirm.saveCampaign = Would you like to save your campaign before you exit? +msg.error.alreadyRegistered = That ID is already in use -- server not registered. +msg.error.alreadyRunningServer = You are already running a server. +msg.error.browser.cannotStart = Browser could not be started.
{0} +msg.error.browser.notFound = System browser could not be identified.
Please specify your system browser in the {0} environment variable. +msg.error.cantAdjustGridInfMaps = Cannot adjust grid on infinite maps. +msg.error.cantApplyMacroToSelected = Commonality of this macro is not based on the command field. The macro cannot be applied to the entire selection set. +msg.error.cantBootGM = You can't boot another GM. +msg.error.cantBootSelf = You can't boot yourself. Disconnect the server via the File menu. +msg.error.credits = Unable to load credits or version. +msg.error.creatingBackupManager = Error creating BackupManager. +msg.error.dialog.js.id = Error executing "{0}": the Javascript identifier "{1}" is invalid. +msg.error.dialog.js.name = Error executing "{0}": the {1} named {2} does not exist or cannot run Javascript. +msg.error.dialog.js.type = Error executing "{0}": the html type "{1}" is invalid. +msg.error.errorResolvingCacheDir = Error resolving cache dir for id {0}, error = {1} +msg.error.frame.reservedName = {0} is a reserved name and can not be used by macros. +# token naming errors +msg.error.emptyTokenName = The token name cannot be blank. +msg.error.evaluatingExpr = Error evaluating expression: {0} +msg.error.failedAddingDefaultImages = Could not restore default images. +msg.error.failedAddingDefaultTables = Could not restore default tables. +msg.error.failedCannotRegisterServer = Unable to register your server. +msg.error.failedConnect = Could not connect to server. +msg.error.fetchingRegistryInformation = Error fetching server information from registry. +msg.error.initializeCrypto = Failed to initialize Cryptology library. +msg.error.initializePlayerDatabase = Failed to initialize Player Database. +msg.error.failedExportingCampaignRepo = Could not export campaign repository file. +msg.error.failedExportingImage = Could not export image. +msg.error.failedLoadCampaign = Could not load campaign. +msg.error.failedLoadCampaign_Timeout = Could not load campaign; timeout waiting for autosave to complete. +msg.error.failedLoadMap = Could not load map. +msg.error.failedLoadCampaignLock = Could not load campaign while background task is active. Try again later. +msg.error.failedSaveCampaignLock = Could not save campaign while background task is active. Try again later. +msg.error.failedSaveCampaign = Could not save campaign. +msg.error.failedSaveCampaignOOM = Out of memory while saving campaign!

Try creating a new/empty map and perform the save with that map active. +msg.error.failedSaveCampaignPreview = Could not save the campaign preview image. +msg.error.failedSaveMap = Could not save map. +msg.error.failedSavingNewVersion = Could not save the new version. +msg.error.fileAlreadyExists = File {0} already exists. +msg.error.directoryNotWriteable = Directory {0} is not writeable. +# When the user attempts to save the chat log and we fail, it's an Error. +# When we try to autosave the chat log and fail, it's a Warning. +# It's all about the semantics, baby. ;-) +msg.error.failedSavingMessageHistory = Could not save message history. +msg.error.failedScreenCapture = Could not get screen capture. +msg.error.failedStartPersonalServer = Could not restart personal server. +msg.error.failedToBoot = Boot attempt failed: player not found. +msg.error.failedUpdatingCampaignRepo = Could not update campaign repository; I/O error. +msg.error.inaccessibleRepo = Repository not available: "{0}". +msg.error.host.inaccessibleRepo = The following repositories are not available: \n{0}\nTo change or remove an invalid repo, go to Campaign Properties and edit the Repositories list. +msg.error.fileNotFound = File Not found. +msg.error.fogexpose = Must be a GM to change the fog of war. +msg.error.gmRequired = Only GMs can do that. +msg.error.invalidLocalhost = "localhost" is not a valid address?! Check your /etc/hosts file. +msg.error.renderingStatSheet = Error while trying to render stat sheet. +msg.error.encryptionSetup = Unable to initialize encryption library. +# JVM Related +msg.error.jvm.options = "{0}" is an invalid memory setting.

Be sure to enter a valid Java JVM value that includes a memory size that ends in K, M, or G.
e.g. 4M, 6G, 2048M, 1024K, etc.

Warning: An improper setting could prevent MapTool from starting. +msg.error.lafSetup = Exception during look and feel setup. +msg.error.cantLoadThemeTitle = Unable to load theme +msg.error.cantLoadTheme = Unable to load theme {0}, using default theme. +msg.error.cantSaveTheme = Unable to save theme details. +msg.error.layoutInitial = Could not load the initial layout. +msg.error.layoutParse = Error parsing the layout file. +msg.error.loadingIconImage = Could not load icon image. +msg.error.loadingQuickMaps = Error loading quickmaps. +msg.error.copyingStartupConfig = Error copying Startup Configuration file. +msg.error.copyingStartupConfig.unixLike = Can not copy configuration file, see Preferences -> Startup for details. +msg.error.macro.buttonGroupDnDFail = Drag & Drop problem +msg.error.macro.buttonPropsAreNull = Button properties are null. +msg.error.macro.buttonNullToken = Macro {0} cannot be saved; token {1} no longer valid. +msg.error.macro.exportFail = Macro could not be exported:

{0} +msg.error.macro.exportSetFail = Macro set could not be exported:

{0} +msg.error.macro.importFail = Macro could not be imported:

{0} +msg.error.macro.importSetFail = Macro set could not be imported:

{0} +msg.error.mtprops.light.arc = Light:line {0,number}:unrecognizable arc "{1}" +msg.error.mtprops.light.definition = Error(s) in Light definitions. Correct error(s) or select Cancel on the Campaign Properties dialog. +msg.error.mtprops.light.distance = Light:line {0,number}:unrecognizable distance "{1}" +msg.error.mtprops.light.gmOrOwner = Light:line {0,number}:GM and OWNER can only be specified for auras. +msg.error.mtprops.light.ioexception = Error reading Light definition from string -- shouldn't happen! +msg.error.mtprops.light.lumens = Light:line {0,number}:unrecognizable lumens "{1}" +msg.error.mtprops.light.zerolumens = Light:line {0,number}: lumens must not be zero +msg.error.mtprops.properties.duplicate = Property name in "{0}" duplicates the one in "{1}". +msg.error.mtprops.properties.duplicateComment = The line "{0}" appears to be a comment, but duplicates "{1}" and must be unique to prevent this warning. +msg.error.mtprops.properties.ending = You will be placed back into edit mode. +msg.error.mtprops.properties.title = The following errors occurred: +msg.error.mtprops.sight.arc = Sight:line {0,number}:unrecognizable arc "{1}" +msg.error.mtprops.sight.definition = Error(s) in Sight definitions. Correct error(s) or select Cancel on the Campaign Properties dialog. +msg.error.mtprops.sight.distance = Sight:line {0,number}:unrecognizable distance "{1}" +msg.error.mtprops.sight.ioexception = Error reading Sight definition from string -- shouldn't happen! +msg.error.mtprops.sight.zerolumens = Sight:line {0,number}: lumens must not be zero + +# For parsing anything in the Campaign Properties dialog. Each tab +# should have its own subcategory underneath "msg.error.mtprops" +# Notice how {0} has the ",number" suffix to denote that a numeric +# value is being used by the program; that tells the program how to +# display the result (i.e. this value should be a localized number). +msg.error.mtprops.sight.multiplier = Sight:line {0,number}:unrecognizable multiplier "{1}" +msg.error.mtprops.sight.offset = Sight:line {0,number}:unrecognizable offset "{1}" +msg.error.mtprops.sight.range = Sight:line {0,number}:unrecognizable range "{1}" +msg.error.mtprops.sight.lumensWithoutLight = Sight:line {0,number}:Cannot use field lumens without range for personal light +msg.error.mtprops.sight.unknownField = Sight:line {0,number}:unknown field name "{1}" +msg.error.mustDisconnectFirst = You are connected to a server. Please disconnect. +msg.error.mustSelectAssetGroupFirst = Select an asset group first. +msg.error.mustSelectPlayerFirst = Select a player first. +msg.error.mustSelectRootGroup = Must select a root group. +msg.error.noTokensSelected = No Tokens Selected. +msg.error.playerNotConnected = Player "{0}" is not connected. +msg.error.server.disconnected = Server has disconnected. +msg.error.server.cantrestart = Could not restart personal server. +msg.error.server.upnp.noigd = UPnP Error - No Internet Gateway Devices found.

This means that your router either does not have UPnP enabled, or is incompatible with the version of UPnP used by MapTool.
Your server will still start, but you will need to manually configure port forwarding to allow connections from the outside Internet.

For more details and assistance, please see the Networking Setup guide from the Help menu. +msg.error.tableAccessProhibited = The GM has disallowed player use of table. +msg.error.tableDoesNotExist = No such table. +msg.error.tableUnknown = Unknown table. +msg.error.toolCannotInstantiate = Could not instantiate tool class: {0} +msg.error.toolConstructorFailed = Failed in constructor of tool: {0} +msg.error.toolNeedPublicConstructor = Constructor must be public for tool: {0} +msg.error.toolNeedValidConstructor = Class must have a public constructor with a Toolbox argument for tool: {0} +msg.error.trace = Error trace : {0} +msg.error.udf.tooltip.loading = Error retrieving description for "{0}": {1} +msg.error.udf.tooltip.missingTarget = Error retrieving description for "{0}": target not found. +msg.error.unableToCreateClientIdFile = Can''t create the client id file. +msg.error.unableToCreateDataDir = Can''t create the data directory "{0}". Try manually specifying the data directory by setting the environment variable "MAPTOOL_DATADIR". Search our forums for that name if you need help. +msg.error.unableToReadClientIdFile = Can''t read the client id file. +msg.error.unknownHost = Unknown host. +msg.error.unknownJavaVersion = Cannot determine Java version?! Will attempt to continue anyway... +msg.error.unusableDataDir = Can''t use the data directory "{0}" because it contains potentially dangerous characters. Try manually specifying the data directory by setting the environment variable "MAPTOOL_DATADIR". Search our forums for that name if you need help. +msg.error.unusableDir = Directory "{0}" contains potentially dangerous characters and will not be used. +msg.error.versionFile = Can't find version file: {0} +msg.error.unableToGetThemeList = Error fetching theme list. +msg.error.wrongJavaVersion = You are running MapTool using a version of Java too old to be 100% compatible with some of the third-party libraries used.
If you continue to use MapTool, you may experience unexpected crashes do to this incompatibility. Do you want to continue? + +msg.error.cantStartWebEndPoint = Unable to start the webserver end point, please change the port + +# Errors when dealing with the passwords file +# for missingPasswordsField the "passwords" text should not be translated as its the field name in the file +msg.error.playerNotInDatabase = The specified player {0} does not exist in the database. +msg.error.passFile.missingPasswordsField = Missing "passwords" field in the +msg.error.passFile.errorInJson = Error reading passsword file, invalid JSON. +msg.error.passFile.errorReadingFile = Error reading password file. +msg.error.passFile.errorCopyingBackup = Error while backing up current password file. +msg.error.passFile.errorWritingFile = Error while writing password file. +msg.error.passFile.cantDisablePlayer = Player Database does not support disabling players. +msg.error.passFile.cantSetPlayTimes = Player Database does not support setting play times. +msg.error.passFile.playerExists = {0} already exists. +msg.error.passFile.publicKeyNotFound = Public key not found. +msg.error.passFile.publicKeyWriteFailed = Failed to write public key file {0}. +msg.error.playerDB.errorAdding = Error while trying to add {0} to the player database. +msg.error.playerDB.cantAddPlayer = Can't add player {0} to a database which doesn't support adding players. +msg.error.playerDB.cantAddPlayerPublicKey = Can't add player {0} to a database with public key as its unsupported. +msg.error.playerDB.errorAddingPlayer = Error adding player {0}. +msg.error.playerDB.cantUpdatePlayer = Can't update player {0} for a database that does't support updating. +msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. +msg.error.playerDB.cantRemovePlayer = Can't remove player {0} to a database which doesn't support removing players. +msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. +msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can't load built-in library {0}. + + +msg.info.action.disableFoW = FoW disabled. +msg.info.action.disableRevealFogAtWaypoints = FoW will now expose at all cell points along the path. +msg.info.action.enableFoW = FoW enabled. +msg.info.action.enableRevealFogAtWaypoints = FoW will now only expose at designated waypoints. +msg.info.action.FoWDisabled = FoW is disabled. +msg.info.campaignLoading = Loading Campaign +msg.info.campaignSaved = Campaign Saved. +msg.info.campaignSaving = Saving Campaign +msg.info.connecting = Connecting +msg.info.disconnected = You have disconnected. +msg.info.heartbeat.registryFailure = Connection refresh to the MapTool registry failed (total of {2} failures so far). The registry server will purge records periodically, making it difficult for future clients to connect. If this persists, you will need to provide clients with the server information directly (IP address "{0}" and port {1}). +msg.info.heartbeat.registrySuccess = Connection refresh to the MapTool registry succeeded (after {0} past failures). As long as success is maintained, you will not see this message again. +msg.info.macro.exportCancel = Macro export canceled. +msg.info.macro.exportSuccess = Macro exported successfully. +msg.info.mapLoading = Loading Map +msg.info.mapSaved = Map Saved. +msg.info.noCampaignPreview = No campaign preview available. +msg.info.playerBooted = {0} has been disconnected. +msg.info.playerConnected = {0} has connected. +msg.info.playerDisconnected = {0} is disconnected. +msg.info.restoreLayout = Restore layout +msg.info.restoreLayout.description = Restore the MapTool user interface to the default layout. +msg.info.screenshotSaved = Saved screenshot. +msg.info.screenshotSaving = Saving screenshot... +msg.info.server.forumNFAQ_URL = http://forums.rptools.net/viewtopic.php?f=22&t=3370 +msg.info.server.networkingHelp = Hosting a MapTool server involves proper network setup.
Do you want to visit the forum post that describes this process? +msg.info.showTransferWindow = Show Transfer Window +msg.info.showTransferWindow.description = Open a window showing the pending asset transfers. +msg.info.startServer = Server started; please wait for map to refresh. +msg.info.startWebEndWebPoint = Starting web end point on port {0}. +msg.info.stopWebEndWebPoint = Stopping web end point. +# Some of these don't have the "..." appended to them because the +# code adds that, if appropriate, based on the situation. +msg.info.versionFile = CAN'T FIND VERSION FILE +msg.info.assetsDisabled = The GM has disabled insertion of player assets. + + +msg.title.exportMacro = Export Macro +msg.title.exportMacroSet = Export Macro Set +msg.title.exportProperties = Export Properties +msg.title.importMacro = Import Macro +msg.title.importMacroSet = Import Macro Set +msg.title.importProperties = Import Properties +msg.title.loadAssetTree = Load Asset Tree +msg.title.loadCampaign = Load Campaign +msg.autosave.wait = Waiting up to {0} seconds for autosave to finish... +# I'm trying to add some consistency to the property names. So... +# "msg.title.*" are strings used as the titles of dialogs and frames +# created by the application. +msg.title.loadMap = Load Map +msg.title.messageDialog.cancel = &Cancel +msg.title.messageDialog.continue = Continue +msg.title.messageDialog.dontAskAgain = Yes, and &don't ask me again +msg.title.messageDialog.no = &No +msg.title.messageDialog.ok = &Ok +# Just adding in some choices for s +msg.title.messageDialog.yes = &Yes +msg.title.messageDialogConfirm = Confirmation +msg.title.messageDialogError = Error +msg.title.messageDialogFeedback = Feedback +msg.title.messageDialogInfo = Information +msg.title.messageDialogWarning = Warning +msg.title.saveCampaign = Save Campaign +msg.title.saveMessageHistory = Save Message History +msg.warn.failedAutoSavingMessageHistory = Could not autosave message history. +msg.warning.macro.playerChangesNotAllowed = The GM has not allowed players to change this macro. +msg.warning.macro.willNotExport = The macro "{0}" will not be exported. Either it has been flagged by the GM as not player editable or you do not have ownership privileges over the source. +msg.warning.prerelease.only = Warning {0} is for pre-release testing only and may not be available in the actual release. +msg.warning.loadCampaignFromInstallDir = Saving to the installation directory is not supported. After loading you will need to save to a different location. +msg.warning.saveCampaignToInstallDir = Saving to the installation directory is not supported, please choose a different location to save to. +msg.warning.exportRepoToInstallDir = Exporting Repository to the installation directory is not supported, please choose a different location to save to. +msg.warning.saveTokenToInstallDir = Saving Tokens to the installation directory is not supported, please choose a different location to save to. +msg.warning.saveMapToInstallDir = Saving Maps to the installation directory is not supported, please choose a different location to save to. +msg.warning.saveTableToInstallDir = Saving Tables to the installation directory is not supported, please choose a different location to save to. +msg.warning.savePropToInstallDir = Saving Campaign Properties to the installation directory is not supported, please choose a different location to save to. +msg.warning.saveMacrosToInstallDir = Saving Macros to the installation directory is not supported, please choose a different location to save to. + +msg.error.serverOnly = Function {0} can only be used on the server. + +msg.asset.error.invalidAsset = An invalid asset has been selected. If you get this message please report it on the MapTool forums or Discord server. + +ooc.description = Out-Of-Character chat + +panel.Asset.ImageModel.checkbox.extractRenderedPages = Render Pages +panel.Asset.ImageModel.checkbox.tooltip.extractRenderedPages = Extract each page from PDF to a single image. +panel.Asset.ImageModel.checkbox.searchSubDir1 = Search subdirectories? +panel.Asset.ImageModel.checkbox.searchSubDir2 = results +panel.Asset.ImageModel.slider.toolTip = Slide to adjust the thumbnail preview size... +panel.Asset.Mouseover.dimensions = Dimensions: {0} x {1} +panel.Asset.Mouseover.type = Type: {0} +panel.Asset.Mouseover.size = Size: {0} + +panel.Campaign = Campaign +panel.Campaign.description = Dockable window for Campaign macros. +panel.Gm = GM +panel.Gm.description = Dockable window for GM-visible macros +panel.Chat = Chat +panel.Chat.description = Dockable chat window. +panel.Connections = Connections +connections.tab.connected = Connected +connections.tab.pending = Pending +connections.playerIsInZone = {0} is in zone {1}. +connections.playerIsLoadingZone = {0} is loading zone {1}. +pendingConnection.label.playerName = Name +pendingConnection.label.pin = PIN +pendingConnection.column.title = Players attempting to connect +pendingConnection.sendPublicKey.title = Sending Public Key to Server +pendingConnection.sendPublicKey = Sending public key to server, let the GM know \ + your PIN is {0} so they can approve your connection. +panel.Connections.description = Dockable window showing connected clients. +panel.DrawExplorer = Draw Explorer +panel.DrawExplorer.description = Dockable window for managing drawings. +panel.DrawExplorer.LineSegment.Line = points({0}) pen width({1}) +panel.DrawExplorer.ShapeDrawable.Area = width({0}) height({1}) +panel.DrawExplorer.ShapeDrawable.Float = width({0}) height({1}) +panel.DrawExplorer.ShapeDrawable.Polygon = width({0}) height({1}) +panel.DrawExplorer.ShapeDrawable.Rectangle = width({0}) height({1}) +panel.DrawExplorer.Template.BlastTemplate = Blast ({0}) +panel.DrawExplorer.Template.BurstTemplate = Burst ({0}) +panel.DrawExplorer.Template.ConeTemplate = Cone ({0}) +panel.DrawExplorer.Template.LineTemplate = Line ({0}) +panel.DrawExplorer.Template.LineCellTemplate = Line ({0}) +panel.DrawExplorer.Template.RadiusTemplate = Radius ({0}) +panel.DrawExplorer.Template.RadiusCellTemplate = Radius ({0}) +panel.DrawExplorer.Template.WallTemplate = Wall ({0}) +# "Group" is a noun +panel.DrawExplorer.group = Group +panel.DrawExplorer.opacity = opacity({0}%) +# Prefix added when a drawing was done with the eraser +panel.DrawExplorer.eraser = CUT: {0} +# DrawExplorer panel +panel.DrawExplorer.Unknown.Shape = Unknown Shape +panel.Global = Global +panel.Global.description = Dockable window showing macros stored on the local computer. +panel.Impersonate = Impersonate +panel.Impersonate.description = Dockable window showing the macros stored on the currently impersonated token. +panel.Impersonate.button.impersonateSelected = Impersonate Selected +panel.Impersonate.identity = Speaking as: {0} +panel.Initiative = Initiative +panel.Initiative.description = Dockable window for managing combat initiative. +panel.Library = Library +panel.Library.description = Dockable window to access assets in your Resource Library. +panel.MapExplorer = Map Explorer +panel.MapExplorer.description = Dockable window showing the tokens and other assets on the current map. +panel.MapExplorer.View.BACKGROUND = Background +panel.MapExplorer.View.CLIPBOARD = Clipboard +panel.MapExplorer.View.GM = Hidden +panel.MapExplorer.View.GROUPS = Groups +panel.MapExplorer.View.LIGHT_SOURCES = Light Sources +panel.MapExplorer.View.OBJECTS = Objects +panel.MapExplorer.View.PLAYERS = Players +panel.MapExplorer.View.TOKENS = Tokens +panel.NewGroupName = New Group Name +panel.Selected = Selected +panel.Selected.description = Dockable window showing the macros on the currently selected token(s). +panel.Selected.tooltip.deslectAll = Deselect all tokens +panel.Selected.tooltip.next = Select next token +panel.Selected.tooltip.previous = Select previous token +panel.Selected.tooltip.revertToPrevious = Revert to previous selection +panel.Selected.tooltip.selectAll = Select all tokens on the map +panel.Tables = Tables +panel.Tables.description = Dockable window for managing the tables in the current campaign. + +dialog.NewToken.title = New Token +dialog.NewToken.type = Type: +dialog.NewToken.visible = Visible: +dialog.NewToken.show = Show this dialog +dialog.NewToken.tokenPropertyType = Token Property +dialog.NewToken.statSheet = Stat Sheet +dialog.NewToken.statSheetLocation = Stat Sheet Location + +prefs.language.override.tooltip = Select a language for the MapTool interface. + +prefs.jvm.advanced.enableAssertions.tooltip = Enables Java language assertions in the MapTool code. +prefs.jvm.advanced.direct3d.tooltip = Disable the use of Direct3D pipeline for problem video cards/drivers. +prefs.jvm.advanced.opengl.tooltip = Enable the OpenGL pipeline. +prefs.jvm.advanced.initAWTbeforeJFX.tooltip = Initialize AWT before JavaFx. This is for issues specific to the MacOS. + +prefs.jvm.xmx.tooltip = Set the maximum memory (heap size) that MapTool is allowed to use. Input a number followed by either a single letter M or G.
Examples: 4G is 4 Gigabytes, 4096M is 4096 Megabytes and is the same as 4G. +prefs.jvm.xms.tooltip = Set the initial and minimum memory setting for MapTool. Must be less than or equal to max heap size.
Input a number followed by either a single letter M or G. +prefs.jvm.xss.tooltip = Set the stack size for MapTool program threads. Values between 4M and 12M are recommended.
Values too large will cause problems. + +roll.description = Roll and broadcast the result to all connected players. +roll.general.unknown = Unknown roll: "{0}". Use #d#+#. +# {0} is the players name, {1} is the roll +roll.string = {0} rolls: {1} + +rollgm.description = Roll and broadcast the result to all GMs. +# {0} is the players name, {1} is the roll +rollgm.gm.string = {0} rolls to you: {1} +# {0} is the roll +rollgm.self.string = You roll to the GMs: {0} + +rollme.description = Roll and show the result only to me. +# {0} is the roll +rollme.string = You roll to yourself: {0} + +rollsecret.description = Roll and broadcast the result to only the GMs and hide the result even from yourself. +# {0} is the sender {1} is the roll +rollsecret.gm.string = {0} rolls secretly to you: {1} +# When the GM does "/rollsecret". {0} is the roll. Easier to use "/self"? +rollsecret.gmself.string = You roll secretly: {0} +rollsecret.self.string = You roll secretly to the GMs. + +# {0} is the error message +savealiases.couldNotSave = Could not save alias file: {0} +savealiases.created = MapTool Aliases - created +savealiases.description = Save all current aliases to a file. See "/loadaliases" to load them back in. +savealiases.dialogTitle = Save Aliases +savealiases.saved = Aliases Saved. + +# {0} is the error message +savetokenstates.couldNotSave = Could not save token states file: {0} +savetokenstates.description = Save the current set of token states to a file. +savetokenstates.dialogTitle = Save Token States +# {0} is the number of token states saved. +savetokenstates.saved = There were {0,number} token states saved. + +say.description = Broadcast a message to all connected players. + +self.description = Send a message only to yourself. + +settokenproperty.description = Set the property of a token. +settokenproperty.param = You must specify a token name and an expression, or select token(s) and supply an expression. +settokenproperty.unknownTokens = Unable to determine which tokens to set the property of. + +settokenstate.description = Set a state value on a token. +# {0} is the token name, {1} is the state name +settokenstate.marked = Token "{0}" now has {1} set. +settokenstate.param = A token state name and token name, or a selected token and state name are required. +settokenstate.unknownState = Unknown state name "{0}". +settokenstate.unknownTokens = Unable to determine which tokens to set the state of. +settokenstate.unmarked = Token "{0}" now has {1} reset. + +# Texture Noise +texturenoise.description = Change the noise applied to textures (only works on background tile textures at the moment). +texturenoise.currentValsOn = Current Values, alpha = {0}, seed = {1}. +texturenoise.currentValsOff = Noise is currently off. +texturenoise.usage = To change use /texturenoise alpha [seed] or /texturenoise on | off. + +# Version slash command +slashversion.description = Display the MapTool Version in the chat window. +slashversion.message = MapTool Version {0}. + +# About slash command +slashabout.description = Display the about dialog. + +# Slash Command errors +slash.mustBeGM = You must be a GM to use "/{0}". + +tmacro.description = Run the given macro on the currently selected tokens. + +togm.description = Send to GMs exclusively. +# {0} is the name of the sender, what to say is appended internally to +# close off HTML tags. +togm.saysToGM = {0} says to the GMs: +# {0} is what to say +togm.self = You say to the GMs: {0} + +token.popup.menu.always.visible = Visible over FoW +token.popup.menu.autoresize = Auto Resize... +token.popup.menu.expose = Expose +token.popup.menu.expose.currentonly = Only currently visible +token.popup.menu.expose.currentonly.accel = shift O +token.popup.menu.expose.lastpath = Last path +token.popup.menu.expose.lastpath.accel = P +token.popup.menu.expose.visible = Visible area +token.popup.menu.expose.visible.accel = I +token.popup.menu.fow = FOW Views +token.popup.menu.fow.clearselected = Clear Selected''s Exposed Area +token.popup.menu.fow.expose = Expose +token.popup.menu.fow.global = Add From Global Exposed Area +token.popup.menu.fow.party = Add From Group''s Exposed Area +token.popup.menu.fow.tokens = Token's FOW Views +token.popup.menu.fow.tokens.view = {0}''s Exposed Area +token.popup.menu.showHandout = Show Handout +token.popup.menu.facing.set = Set Facing +token.popup.menu.facing.clear = Clear Facing +token.popup.menu.lights.clear = Clear Lights Only +token.popup.menu.lights.clearAll = Clear All +token.popup.menu.auras.clear = Clear Auras Only +token.popup.menu.auras.clearGM = Clear GM Auras Only +token.popup.menu.auras.clearOwner = Clear Owner Auras Only +token.popup.menu.snap = Snap to grid +token.popup.menu.visible = Visible to players +token.popup.menu.impersonate = Impersonate +token.popup.menu.move = Move +token.popup.menu.move.path = Show Path +token.popup.menu.move.revertlast = Revert Last Move +token.popup.menu.export.libTokenAddon = Export Library Token as Addon... +token.popup.menu.edit = Edit ... +token.popup.menu.delete = Delete +token.popup.menu.flip = Flip +token.popup.menu.flip.horizontal = Horizontal +token.popup.menu.flip.vertical = Vertical +token.popup.menu.flip.isometric = Isometric Plane +token.popup.menu.change = Change to +token.popup.menu.arrange = Arrange +token.popup.menu.zorder.front = Bring to Front +token.popup.menu.zorder.back = Send to Back +token.popup.menu.save = Save ... +token.popup.menu.size = Size +token.popup.menu.size.free = Free Size +token.popup.menu.size.native = Native Size +token.popup.menu.size.reset = Reset +token.popup.menu.edit.toomany.tooltip = Only one token can be edited at a time. +token.popup.menu.edit.notallowed.tooltip = The GM is currently locking access to the Token Editor. + +# Token Content Menu +# +# Note the use of the two single quotes. See the URL at the top of the +# file for an explanation. (Essentially, a single quote in the output +# requires two single quotes in the message string.) +token.popup.menu.halo = Halo +token.popup.menu.vision.overlay = Vision Overlay +token.properties.button.transferVblFromMap.copy.text = Copy VBL From Map +token.properties.button.transferVblFromMap.move.text = Move VBL From Map +token.properties.button.transferVblToMap.copy.text = Copy VBL To Map +token.properties.button.transferVblToMap.move.text = Move VBL To Map + +tokenspeech.description = Say the given speech on the currently selected tokens. + +tool.LineCellTemplate.tooltip = Draw a line template centered on a grid cell. +# We use LClick to mean "left-click" and RClick to mean "right-click". +# We use MClick to mean "middle mouse button click". +# We use LDrag to mean "left-click-and-drag" and ditto for RDrag. +# We use MWheel to mean "mouse wheel". +# We add "Shift" or "Ctrl" in front to mean that keystroke. +tool.blasttemplate.instructions = LClick: set starting cell, second LClick sets radius and direction; Ctrl: move origin point +tool.blasttemplate.tooltip = Draw a blast template. +#tool.boardtool.instructions=Reposition Background Image +tool.boardtool.tooltip = Reposition background map image +tool.bursttemplate.instructions = LClick: set center cell, second LClick sets radius; Ctrl: move origin point +tool.bursttemplate.tooltip = Draw a burst template. +tool.cone.instructions = LClick: set initial point, second LClick sets radius and direction; Ctrl: move origin point +tool.cone.tooltip = Draw a cone template. +tool.crosstopology.instructions = LClick: set initial/final point; Shift LClick: erase cross; Ctrl snaps to grid +tool.crosstopology.tooltip = Draw a cross VBL +tool.deletedrawing.instructions=LClick: Select drawings Double-Click: Delete selected drawings. +tool.deletedrawing.tooltip=Delete drawing tool +tool.diamond.tooltip = Draw a diamond. +tool.diamondexpose.tooltip = Expose/Hide a diamond on the Fog of War. +tool.facing.instructions = Unused +tool.facing.tooltip = Set the token facing. +tool.filltopology.tooltip = Fill in closed areas of VBL. +tool.freehand.instructions = LDrag: draw freehand line, Shift+LDrag: erase freehand line, Alt (hold): Snap to cell center +tool.freehand.tooltip = Draw freehand lines. +tool.freehandexpose.instructions = LClick: lay initial/final point to expose, RClick (while drawing): set intermediate point, Shift+LClick (initial): hide area +tool.freehandexpose.tooltip = Expose/Hide a freehand shape on the Fog of War. +tool.gridtool.instructions = Arrows: move grid offset, Shift+Arrows: change grid size, LDrag: Move grid, MWheel: scale grid +tool.gridtool.tooltip = Show/Hide the map grid. +tool.label.dialogtitle = Edit Label +tool.label.instructions = LClick: create a new label, RDrag: move map, MWheel: zoom +tool.label.tooltip = Add text label to map. +tool.line.instructions = LClick: lay initial/final point, RClick (while drawing): set intermediate point, Shift+LClick (initial): erase line, Alt (hold): Snap to cell center +tool.line.tooltip = Draw straight lines. +tool.linetemplate.instructions = LClick: set initial point, second LClick determines path, third LClick sets length; Ctrl: move last point set +tool.linetemplate.tooltip = Draw a line template. +tool.measure.instructions = LDrag: measure cell distance, RDrag: move map, MWheel: zoom, MClick and Spacebar: Toggle waypoint +tool.measure.tooltip = Measure distance along path. +tool.oval.instructions = LClick: set initial/final point, Shift+LClick: start erase oval; Alt: origin is centerpoint +tool.oval.tooltip = Draw an oval. +tool.ovalexpose.instructions = LClick: set initial/final point to expose, Shift+LClick: hide area; Alt: origin is centerpoint +tool.ovalexpose.tooltip = Expose/Hide an oval on the Fog of War. +tool.ovaltopology.instructions = LClick: set initial/final point, Shift+LClick: start erase oval +tool.ovaltopology.tooltip = Draw an oval VBL. +tool.ovaltopologyhollow.tooltip = Draw a hollow oval VBL. +tool.pointer.instructions = LClick: select, LDrag: move selected, RClick: menu, RDrag: move map, MWheel: zoom, MClick and Spacebar: Toggle waypoint, Shift+MouseOver: no statsheet +tool.pointer.tooltip = Pointer tool +tool.poly.instructions = LClick: lay initial/final point, RClick (while drawing): set intermediate point, RDrag: move map, Shift+LClick (initial): Erase poly area +tool.poly.tooltip = Draw closed polygon. +tool.polyexpose.instructions = LClick: lay initial/final point to expose, RClick (while drawing): set intermediate point, RDrag: move map, Shift+LClick (initial): hide area +tool.polyexpose.tooltip = Expose/Hide a polygon on the Fog of War. +tool.polylinetopo.tooltip = Draw poly line VBL. +tool.polytopo.tooltip = Draw closed polygon VBL. +tool.radiusCellTemplate.tooltip = Draw a radius template centered on a grid cell. +tool.radiustemplate.instructions = LClick: set initial point, second LClick sets radius; Ctrl: move origin point +tool.radiustemplate.tooltip = Draw a radius template. +tool.rect.instructions = LClick: set initial/final point, Shift+LClick: erase rectangle; Ctrl: snap-to-grid, Alt: origin is centerpoint +tool.rect.tooltip = Draw a rectangle. +tool.rectexpose.instructions = LClick: set initial/final point to expose; Shift+LClick: hide rectangle; Alt: origin is centerpoint +tool.rectexpose.tooltip = Expose/Hide a rectangle on the Fog of War. +tool.recttopology.instructions = LClick: set initial/final point, Shift+LClick: erase rectangle; Ctrl: snap-to-grid +tool.recttopology.tooltip = Draw a rectangular VBL. +tool.recttopologyhollow.tooltip = Draw a hollow rectangular VBL. +tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. +tool.isorectangletopology.instructions = LClick: set initial/final point, Shift+LClick: erase isometric rectangle; Ctrl: snap-to-grid +tool.stamp.tooltip = Stamp tool +tool.walltemplate.instructions = LClick: set starting cell, move mouse in direction of wall, second LClick to finish wall; Ctrl: move origin point +tool.walltemplate.tooltip = Draw a wall template. +tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. +tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. +tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.drawing.tooltip = Drawing Tools +tools.fog.tooltip = Fog of War Tools +tools.interaction.tooltip = Interaction Tools +tools.mute.tooltip = Mute system sounds and audio streams +tools.unmute.tooltip = Unmute system sounds and audio streams +tools.hidetoolbar.tooltip = Hide the toolbar +tools.unhidetoolbar.tooltip = Unhide the toolbar +tools.template.tooltip = Template Tools +tools.token.fow.all.tooltip = Show FoW for All Tokens you explicitly own or are owned by all. +tools.token.fow.gm.tooltip = Show FoW for Tokens you explicitly own.
IF you are a GM, you will also see any tokens that have no ownership set. +tools.token.fow.npc.tooltip = Show FoW for NPC Tokens you explicitly own or are owned by all. +tools.token.fow.pc.tooltip = Show FoW for PC Tokens you explicitly own or are owned by all. +tools.topo.tooltip = Vision Blocking Layer (VBL) Tools +tools.zoneselector.tooltip = Select Map +tools.initiative.tooltip = Initiative Tools + +undefinedmacro.unknownCommand = Unknown command: "{0}". Try /help for a list of commands. + + + +startup.config.unableToWrite = Unable to write to configuration file. +Preferences.startup.label.info = Startup Preferences Information +startup.preferences.info = \ + {0} \ + JVM Memory Settings\ +

    \ +
  • \ + Maximum Heap Size: The maximum amount of memory MapTool can use\ +
      \ +
    • This should include G for gig, e.g. 8G
    • \ +
    \ +
  • \ +
  • \ + Minimum Heap Size: The minimum amount of memory MapTool will use\ +
      \ +
    • This should include G for gig, e.g. 4G
    • \ +
    \ +
  • \ +
  • \ + Thread Stack Size: The amount of memory MapTool will for its stack, increase this if you get stack errors when running \ + macros.\ +
      \ +
    • This should include M for Meg, e.g. 8M
    • \ +
    • warning setting this higher than 16M may cause issues
    • \ +
    \ +
  • \ +
\ + Language Override\ +
    \ +
  • Language: The language to use for MapTool

  • \ +
\ + Additional Options\ +
    \ +
  • Data Directory: The directory where MapTool data will be stored
  • \ +
\ + Advanced Options\ +
    \ +
  • Disable Direct3d pipeline: Try disabling this if you are experiencing graphical glitches on Windows Systems
  • \ +
  • Disable OpenGL pipeline: Try disabling this if you are experiencing graphical glitches on non Windows Systems
  • \ +
  • Initialize AWT before JavaFx: Only check this if you are experiencing problems with windows and dialogs not appearing
  • \ +
\ + + +startup.preferences.info.manualCopy =

Activating Startup Preferences

\ + MapTool is unable to copy the configuration file to the startup directory.
\ + In order for them to take effect you will need to edit the {0} and restart MapTool \ + after saving your changes.
+ + +userTerm.GM = GM +userTerm.Player = Player +# Note the capitalization on the second one. Some languages might use +# different capitalization so both are included here... +# +# Note that these are not used universally, but as code is modified they +# will be added. These should not be used by the programmer when user +# input is involved, for example in a dropdown box or similar. That's +# because the program is likely hard-coded to look at the text instead +# of localizing it. As we move forward, we'll write code so that it +# displays one thing but uses a separate value internally. That allows +# you to display whatever you want to the user and still have hard-coded +# values in the program (because it makes the program significantly +# easier to write and faster at runtime). +userTerm.player = player + +visionType.DAY = Day +visionType.NIGHT = Night +visionType.OFF = Off + +lightingStyle.ENVIRONMENTAL = Environmental +lightingStyle.OVERTOP = Overtop + +mapSortType.GMNAME = True Name +mapSortType.DISPLAYNAME = Display Name + + +webapp.serverAlreadyRunning = The webapp server is already running. +webapp.serverStarted = Webapp server has been started
Connect to \ + http://{0}:{1}/{2} on your browser/phone/tablet.

\ + The experimental Server App is deprecated and will be removed in an \ + upcoming version.

If you currently make use of this feature please \ + visit discord channel
to let us know how you are using it so we \ + can include this in our plans for its replacement

Discord: \ + https://discord.gg/hKChMAmn32

+ +whisper.command = Whisper +whisper.description = Send a message to a specific player. +whisper.enterText = enter text here +whisper.noName = Must supply a player name. +# {0} is the name, {1} is the message +whisper.string = {0} whispers: {1} +whisper.toSelf = Talking to yourself again? +whisper.you.string = You whisper to {0}: {1} + +whisperreply.description = Reply to the last player to whisper to you. +whisperreply.noTarget = You do not have anyone to reply to. + +zone.player_view = Player View +zone.map_not_visible = Map not visible to players + + + +# Player Database Dialog +playerDB.dialog.player = Player +playerDB.dialog.role = Role +playerDB.dialog.add = Add +playerDB.dialog.authType = Authentication Type +playerDB.dialog.blocked = Blocked +playerDB.dialog.connected = Connected +playerDB.dialog.title = Player Password Database +playerDB.dialog.title.edit = Edit Player +playerDB.dialog.title.new = New Player +playerDB.dialog.password = Password +playerDB.dialog.passwordGenerate = Generate New Password +playerDB.dialog.publicKey = Public Key +playerDB.dialog.edit = Edit... +playerDB.dialog.delete = Delete +playerDB.dialog.deleteConfirm = Are you sure you want to delete {0}? +playerDB.dialog.error.missingName = Missing Player Name +playerDB.dialog.error.passwordMissing = Missing Password +playerDB.dialog.error.passwordTooShort = Password is too short +playerDB.dialog.error.invalidPublicKey = Invalid Public Key +playerDB.dialog.error.emptyBlockReason = Blocked reason can not be empty +playerDB.dialog.error.playerExists = Player already exists +playerDB.dialog.error.savingChanges = Error saving database changes + + +# Text to display instead of the password +playerDB.dialog.encodedPassword = -- Encoded Password -- + +WebRTC.toggleUseWebRTC = Use WebRTC (experimental) +WebRTC.toggleUseWebRTC.tooltip = Use WebRTC as connection method, this may help
\ + with connection issues where portforwarding doesn't work
\ + both client and server must have the same setting.
\ + This functionality is still experimental.
\ + Requires an RPTools net Alias to be set + +dialog.button.ok = Ok +dialog.button.cancel = Cancel + + + +# Add-On Library support +library.error.invalidDefinition = Invalid library definition. +library.error.emptyName = Name can not be empty for add-on library. +library.error.emptyVersion = Version can''t be empty for add-on library {0}. +library.dialog.import.title = Import Add-On Library. +library.import.ioError = IO Error importing Drop In Library. +library.import.error = Error importing Drop In Library {0}. +library.import.error.notGM = Only GM can import a Drop in Library. +library.imported = Library {0} imported. +library.error.libtoken.no.access = Allow URI Access is not allowed for {0}. +library.error.addOn.no.access = Allow URI Access is not allowed for {0} add-on library. +library.error.libtoken.missing = Lib:Token can no longer be found. +library.error.addOnLibraryExists = Add-On Library with namespace {0} already exists. Do you want to replace it? +library.error.addOn.notText = Can''t convert asset of type {0} to text. +library.error.addOn.noConfigFile = library.json file not found in {0}. +library.property.value.notSpecified = Not Specified +# {0} is the name of the event, {1} is the name of the library, {2} is the exception message +library.error.errorParsingVotableEvent = Continuing after error parsing vote from event {0} @ {1}, error {2}. +# {0} is the name of the event, {1} is the name of the library, {2} is the exception message +library.error.errorRunningEvent = Continuing after error running event {0} @ {1}, error {2}. +library.error.notFound = Library with namespace {0} does not exist. +library.error.noEventHandler = Library with namespace {1} does not contains an event handler for {0}. +library.error.retrievingEventHandler = Error retrieving event handlers for event {0}. +library.error.addOn.sheet = Error adding stat sheet {1}, namespace {0} +library.export.information = This will extract the Lib:Token to the specified directory \ + as the format required for an add-on library.
Most functionality will work without modifications \ + but you will probably still need to make some modifications. +library.export.done = Exported {0} to {1} as add-on library. It's likely you \ + will need to make modifications to the add on library to make it work. +library.export.error.overwrite = Directory {0} is not empty, please select a different directory. +library.export.errorReadingDirectory = Unable to read directory {0}. +library.export.errorWriting = Error writing file {0} for add-on library. +library.dialog.button.add = Add +library.dialog.button.close = Close +library.dialog.button.details = Details +library.dialog.title = Add-On libraries +library.dialog.library.label = Libraries +library.dialog.development.label = Development +library.dialog.addon.name = Add-On Name +library.dialog.addon.version = Version +library.dialog.addon.namespace = Namespace +library.dialog.addon.shortDescription = Short Description +library.dialog.addon.description = Description +library.dialog.addon.readMeFile = View Read Me File +library.dialog.addon.authors = Authors +library.dialog.addon.license = License +library.dialog.addon.licenseFile = View License File +library.dialog.addon.giturl = Git URL +library.dialog.addon.website = Website +library.dialog.table.remove = Remove Library +library.dialog.table.removeData = Remove Library and Data +library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? +library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? +library.dialog.copy.title = The copied CSS is for testing \ + purposes only.
Within your add-on use
lib://net.rptools.maptool/css/mt-stat-sheet.css \ + or
lib://net.rptools.maptool/css/mt-theme.css +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord + +# Game Data +data.error.cantConvertTo = Can''t convert {0} to {1}. +data.error.alreadyExists = Data Property {0} already exists. +data.error.undefined = Data Property {0} is undefined. +data.error.namespaceDoesNotExist = Data Namespace {0} does not exist for type {1}. +data.error.namespaceAlreadyExists= Data Namespace {0} already exists for type {1}. +data.error.sendingUpdate = Error sending game data update. +data.error.receivingUpdate = Error receiving game data update. +data.error.importGameData = Error importing game data. +data.error.clearingNamespace = Error clearing data namespace {0} from type {1}. +data.error.removingData = Error data data from {0} namespace {1} from type {2}. +Label.icontheme=Icon theme +Preferences.label.icontheme.tooltip=The theme aplication icons use. +Label.theme.macroeditor=Macro editor theme +TEXT_TYPE=Text type +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map +EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map +Label.label=Label: + +# StatSheet +token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet +token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties b/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties new file mode 100644 index 0000000000..09270fc578 --- /dev/null +++ b/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties @@ -0,0 +1,2825 @@ + +#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/) +# This software copyright by various authors including the RPTools.net +# development team, and licensed under the LGPL Version 3 or, at your +# option, any later version. +# +# Portions of this software were originally covered under the Apache +# Software License, Version 1.1 or Version 2.0. +# +# See the file LICENSE elsewhere in this distribution for license details. +#_____________________________________________________________________ +# +# This is the English translation file for MapTool 1.3. If you are +# translating MapTool to another language and leave out a translation +# for any key that appears here (the "key" is the text before the "=") +# then the values in this file will be used. +# +# Please submit all translations using the UTF-8 encoding! If you MUST +# use a different encoding, please document it INSIDE your translation +# file. I use an automated technique to detect the encoding and convert +# the file to the Unicode format that Java needs. (For those who are +# interested, it involves the "native2ascii" program which is part of +# the Java Software Development Kit.) +# +# Some of the keys used in this file are not consistent. :( For example, +# the NewMap menu option has the key "action.newMap" but the QuickMap +# menu option is "menu.QuickMap". IMO this should be fixed, but MapTool +# 1.4 will likely have a completely different (i.e. consistent) set of +# keys, so we're not going to bother for 1.3. +# +# In all cases in this file, any accelerator keystroke will automatically +# have the 'menuShortcut' key added to it. For Windows this is the Ctrl +# key, on the Mac it's the Command (Cmd) key. Other platforms may have yet +# other keys. +# +# IMPORTANT: Do not add the platform-dependent menu modifier key to this +# file! If you add "ctrl", for example, the modifier will be ignored +# on Windows but will require Mac users to use Cmd-Ctrl-C for a copy +# operation. This is an ugly situation and we should find some way to +# define a menuShortcutKey (such as "menu") and then be able to use +# that in our definition strings. I expect that MapTool 1.4 will have +# a user interface for changing these keystrokes so perhaps it's all +# moot anyway. +# +# Note that the accelerator keys are not case-sensitive. So if you +# specify "F" as the accelerator, that means lowercase "F". If you +# want an uppercase "F", add the word "shift": "shift F" or "shift f". +# There are a lot of examples of this throughout the file. +# +# Check the javadoc for the 'MessageFormat' class for more details on +# the formatting of text in this file, as you'll see below (basically +# anything with braces): +# http://download.oracle.com/javase/7/docs/api/java/text/MessageFormat.html +# Localization contributed by David Herman ("aku" on forums.rptools.net) +ActivityMonitorPanel.colorDefinition = Green:Sending, Red:Receiving + +AppHomeDiskSpaceStatusBar.toolTip = Current free space in users home directory. + +AssetCacheStatusBar.toolTip = Current size of Asset cache directory, Double-Click to clear this cache. + +AssetViewerDialog.leftDragMove = Left button drag to move +AssetViewerDialog.rightDragResize = Right button drag to resize + +AutoSaveManager.failed = Autosave failed: +AutoSaveManager.failed_badState = Autosave failed:\nBad application state?! Please report this! +AutoSaveManager.status.autoSaveComplete = Autosave complete. Elapsed time (ms): {0,number} +AutoSaveManager.status.autoSaving = Autosaving campaign... +AutoSaveManager.status.lockFailed = Autosave skipped. Background operation in progress. + +CampaignProperties.error.initLightSources = Cannot initialize light sources. +CampaignProperties.error.noGenericLight = Can''t get light source "Generic : 5"?! + +ChatAutoSave.status.chatAutosave = Autosaving chat log... + +Color.aqua = aqua +Color.black = black +Color.blue = blue +Color.cyan = cyan +Color.darkgray = dark gray +Color.fuchsia = fuchsia +Color.gray = gray +Color.gray25 = 25% gray +Color.gray50 = 50% gray +Color.gray75 = 75% gray +Color.green = green +Color.lightgray = light gray +Color.lime = lime +Color.magenta = magenta +Color.maroon = maroon +Color.navy = navy +color.olive = olive +Color.orange = orange +Color.pink = pink +Color.purple = purple +Color.red = red +Color.silver = silver +Color.teal = teal +Color.white = white +Color.yellow = yellow +Color.none = None +Color.custom = Custom +Color.default = Default + +Button.ok = OK +Button.cancel = Cancel +Button.refresh = Refresh +Button.rescan = Rescan +Button.revert = Revert +Button.close = Close +Button.import = Import +Button.export = Export +Button.delete = Delete +Button.add = Add +Button.new = New +Button.browse = Browse +Button.update = Update +Button.apply = APPLY +Button.accept = Accept +Button.up = Move Up +Button.down = Move Down +Button.background = Background +Button.map = Map +Button.fog = Fog +Button.clear = Clear +Button.clearall = Clear All +Button.yes = Yes +Button.no = No +Button.install = Install +Button.runmacro = RUN MACRO +Button.hide = Hide + +Label.lights = Vision: +Label.name = Name: +Label.gmname = GM Name: +Label.speechName = Speech Bubble Name: +Label.optional = Optional +Label.options = Options +Label.maps = Maps +Label.objects = Objects +Label.token = Token +Label.tokens = Tokens +Label.backgrounds = Backgrounds +Label.macroeditor = Macro Editor +Label.styletheme = Style Theme +Label.currentTheme = Current Theme +Label.filterTheme = Theme Filter +Label.useThemeForChat = Use Theme Colours for Chat Window +Label.facing = Facing +Label.accessibility = Accessibility +Label.sounds = Sounds +Label.auth = Authentication +Label.version = MapTool Version: +Label.startup = Startup +Label.themes = Themes +Label.application = Application +Label.preferences = Preferences +Label.save = Save +Label.minute = min +Label.performance = Performance +Label.client = Client +Label.macropanels = Macro Panels +Label.upnp = UPnP +Label.macropermissions = Macro Permissions +Label.path = Path: +Label.url = URL +Label.url2 = URL: +Label.library = RPTools Library +Label.progress = Progress +Label.about = About +Label.dimensions = Dimensions: +Label.layer = Layer: +Label.grid = Grid +Label.tile = Tile +Label.ready = Ready +Label.saved = Saved +Label.filesystem = Filesystem ... +Label.filesystem2 = Filesystem +Label.roll = Roll: +Label.table.image = Table Image +Label.blankdefault = (Leave blank for default) +Label.range = Range +Label.image = Image +Label.value = Value +Label.image.choose = Choose Image +Label.table.import = Import Table +Label.table.export = Export Table +Label.preview = Preview +Label.foreground = Foreground: +Label.showbackground = Show Background: +Label.layers = Layers: +Label.view.current = Current View +Label.host = Host: +Label.location = Location: +Label.advanced = Advanced +Label.view = View: +Label.board = Board +Label.visibility = Visibility +Label.pathfilename = Path/Filename: +Label.allowURIAccess = Allow URI Access + +CampaignPropertyDialog.error.parenthesis = Missing right parenthesis ")" in the following property: {0} + +ColorPicker.tooltip.gridSnap = Snap to Grid +ColorPicker.tooltip.lineType = Line Type +ColorPicker.tooltip.eraser = Eraser +ColorPicker.tooltip.penWidth = Pen Width +ColorPicker.tooltip.opacity = Opacity + +ConnectToServerDialog.msg.headingServer = Server Name +ConnectToServerDialog.msg.headingVersion = Version +ConnectToServerDialog.msg.title = Connect to Server +# This next string will use the results of looking up 'menu.file' for {0} and the lookup of 'action.showConnectionInfo' for {1}. +ConnectToServerDialog.warning.doNotUseExternalAddress = It is unlikely that using your own external IP address will work.

Use your local address or localhost.

To see the current values, use the {1} option of the {0} menu.


Attempt connection anyway? +ConnectToServerDialog.username = Username: +ConnectToServerDialog.password = Password +ConnectToServerDialog.usePublicKey = Connect using public key +ConnectToServerDialog.role = Role: +ConnectToServerDialog.server.name = Server Name: +ConnectToServerDialog.server.local = Local Servers: +ConnectToServerDialog.server.address = Address: +ConnectToServerDialog.server.port = Port: +ConnectToServerDialog.tab.lan = LAN +ConnectToServerDialog.tab.direct = Direct + +ConnectionInfoDialog.title = Server Info +ConnectionInfoDialog.address.local = Local Address: +ConnectionInfoDialog.address.external = External Address: +ConnectionInfoDialog.port = Port: +ConnectionInfoDialog.discovering = Discovering... + +ConnectionStatusPanel.notConnected = Not connected +ConnectionStatusPanel.runningServer = Running a Server +ConnectionStatusPanel.playersLoadedZone = {0} out of {1} players have loaded their zone +ConnectionStatusPanel.serverConnected = Connected to Server + +CoordinateStatusBar.mapCoordinates = Map Coordinates + +DrawPanelPopupMenu.menu.group = Group Drawings +DrawPanelPopupMenu.menu.ungroup = Ungroup +DrawPanelPopupMenu.menu.merge = Merge Drawings +DrawPanelPopupMenu.menu.getProperties = Get Properties +DrawPanelPopupMenu.menu.setProperties = Set Properties +DrawPanelPopupMenu.menu.setName = Set Name +DrawPanelPopupMenu.menu.getId = Get Drawing ID +DrawPanelPopupMenu.menu.pathVbl = Path to VBL +DrawPanelPopupMenu.menu.shapeVbl = Shape to VBL +DrawPanelPopupMenu.menu.vbl.add = Add to VBL +DrawPanelPopupMenu.menu.vbl.remove = Remove from VBL +DrawPanelPopupMenu.dialog.name.title = Set Name +DrawPanelPopupMenu.dialog.name.msg = Enter a name: + +EditLookupTablePanel.error.badRange = Table "{0}" contains bad range "{1}" on row {2,number}. +EditLookupTablePanel.error.invalidSize = Table "{0}" must have at least one row. +EditLookupTablePanel.error.noName = Table must have a name. +EditLookupTablePanel.error.sameName = Table name "{0}" duplicates existing table. +EditLookupTablePanel.tooltip.allowLookup = Selecting this box allows players to execute a lookup against this table (i.e. double-click the table, use /table, or macro functions). +EditLookupTablePanel.tooltip.visible = Selecting this box allows players to see this table in their Tables panel. +EditLookupTablePanel.create.tooltip = Create a new lookup table. +EditLookupTablePanel.edit.tooltip = Edit selected table. +EditLookupTablePanel.delete.tooltip = Delete table. +EditLookupTablePanel.duplicate.tooltip = Duplicate selected table. +EditLookupTablePanel.showplayer = Show Table to Players +EditLookupTablePanel.lookup = Allow Lookup by Players + +EditTokenDialog.label.label = Label: +EditTokenDialog.tab.notes = Notes +EditTokenDialog.label.gmnotes = GM Notes +EditTokenDialog.menu.notes.sendChat = Send to Chat +EditTokenDialog.menu.notes.sendEmit = Send as Emit +EditTokenDialog.label.shape = Shape: +EditTokenDialog.label.snaptogrid = Snap To Grid: +EditTokenDialog.label.size = Size: +EditTokenDialog.label.visible = Visible to players: +EditTokenDialog.label.properties = Properties: +EditTokenDialog.label.visible.owner = Visible to Owners Only: +EditTokenDialog.label.sight.has = Has Sight: +EditTokenDialog.label.terrain.mod = Terrain Modifier: +EditTokenDialog.label.terrain.mod.tooltip= Adjust the cost of movement other tokens will may to move over or through this token. Default multiplier of 1 equals no change (1 * 1 = 1). +EditTokenDialog.label.image = Image Table: +EditTokenDialog.label.opacity = Token Opacity: +EditTokenDialog.label.opacity.tooltip = Change the opacity of the token. +EditTokenDialog.label.opacity.100 = 100% +EditTokenDialog.label.terrain.ignore = Ignore Terrain: +EditTokenDialog.label.terrain.ignore.tooltip= Select any terrain modifier types this token should ignore. +EditTokenDialog.label.statSheet = Stat Sheet +EditTokenDialog.label.defaultStatSheet = Default Stat Sheet +EditTokenDialog.combo.terrain.mod = Set whether the cell cost should be added or multiplied. Use negative numbers to subtract and decimal values to divide costs. +EditTokenDialog.border.title.layout = Layout +EditTokenDialog.border.title.portrait = Portrait +EditTokenDialog.border.title.handout = Handout +EditTokenDialog.border.title.charsheet = Charsheet +EditTokenDialog.status.layout.instructions = Mouse Wheel to zoom; double-LClick to reset position and zoom +EditTokenDialog.label.allplayers = All Players +EditTokenDialog.tab.properties = Properties +EditTokenDialog.tab.vbl = Topology +EditTokenDialog.tab.state = State +EditTokenDialog.tab.speech = Speech +EditTokenDialog.tab.ownership = Ownership +EditTokenDialog.tab.config = Config +EditTokenDialog.tab.hero = Hero Lab +EditTokenDialog.tab.libToken = Lib:Token properties +EditTokenDialog.button.vbl = Generate Token Topology +EditTokenDialog.button.vbl.tooltip = This will create VBL/MBL based on non-transparent pixels. +EditTokenDialog.button.vbl.clear = Clear Token Topology +EditTokenDialog.button.vbl.clear.tooltip = Clear VBL/MBL from token. +EditTokenDialog.button.vbl.tomap = Move Topology To Map +EditTokenDialog.button.vbl.frommap = Move Topology From Map +EditTokenDialog.button.vbl.preview = VBL Preview +EditTokenDialog.option.vbl.erase = Erase Source Topology on Move +EditTokenDialog.option.vbl.erase.tooltip = Move the VBL/MBL vs Copy it. +EditTokenDialog.label.vbl.visiblity = Token Visibility +EditTokenDialog.label.vbl.tolerance = Visibility Tolerance +EditTokenDialog.label.vbl.preview = Hide Token Image Preview +EditTokenDialog.label.vbl.preview.tooltip= Do not generate a preview of the VBL/MBL in this window. +EditTokenDialog.label.vbl.sensitivity = Colour Sensitivity +EditTokenDialog.label.vbl.sensitivity.tooltip = Adjust the sensitivity to the colour match that will be used to generate VBL, values 0-255 with 0 being an exact colour match. +EditTokenDialog.label.vbl.invert = Inverse Topology Colour Selection +EditTokenDialog.label.vbl.invert.tooltip = Generate VBL/MBL where the colour does not match on the token when checked. +EditTokenDialog.label.vbl.level = Level +EditTokenDialog.label.vbl.method = Method +EditTokenDialog.label.vbl.optimize = Topology Optimization +EditTokenDialog.drop.vbl.optimize.tooltip= Advanced Use: Choose the algorithm used to decimate curves in the generated polygon.

The default is generally the best but unique polygons may benifit from one of the other selected algorithms. +EditTokenDialog.label.vbl.over = Is Visible over FoW +EditTokenDialog.label.vbl.over.tooltip = Always show this token over FoW when in sight of another token. Useful for doors, statues, columns, roofs, etc. +EditTokenDialog.label.vbl.color = Colour Selection +EditTokenDialog.label.vbl.toggle = Pick a colour from the image to match against when generating token VBL/MBL. +EditTokenDialog.label.vbl.well = Manually pick a colour to match against when generating token VBL/MBL. +EditTokenDialog.border.title.vbl.preview = Topology Preview +EditTokenDialog.status.vbl.instructions = Mouse Wheel to zoom; double-LClick to reset position and zoom +EditTokenDialog.label.hero.summary = Summary: +EditTokenDialog.label.hero.portfolio = Portfolio: +EditTokenDialog.label.hero.last = Last Modified: +EditTokenDialog.button.hero.setAsTokenPortrait = Set as Token Portrait +EditTokenDialog.button.hero.setAsTokenImage = Set as Token Image +EditTokenDialog.button.hero.setAsTokenHandout = Set as Token Handout +EditTokenDialog.label.hero.isAlly = Ally? +EditTokenDialog.label.hero.statBlockSearch = Expression: +EditTokenDialog.button.hero.statBlockSearch.tooltip = Search the statblock using the expression provided. +EditTokenDialog.label.hero.statBlockSearch.tooltip = Enter raw text, a regular expression or an xPath expression to search the statblock for. +EditTokenDialog.action.hero.statBlockRTextScroll = Find +EditTokenDialog.tab.hero.images = Images +EditTokenDialog.tab.hero.text = TEXT +EditTokenDialog.tab.hero.xml = XML +EditTokenDialog.tab.hero.html = HTML +EditTokenDialog.spinner.tolerance.tooltip= Sets the tolerance for the optimization, a value of 0 disables optimization and values > 0 reduce the number of polygon points for better performance. +EditTokenDialog.vbl.explanation.tooltip = Controls how many of the tokens regions must be seen before showing over FoW, range is 1-9 regions.

The image is sliced into an even 3 x 3 grid for a total of 9 regions. The tolerance controls how many of these "regions" must be "seen" by another token before it's image is revealed.

For a very large roof, because of vision distance, you may want to use a value of 1.
Where as for a smaller token like a statue, you may not want to show the image until more of it is visable and use a value of 3 or 4. +EditTokenDialog.confirm.clearSpeech = Are you sure you want to clear all speech for this token? +EditTokenDialog.confirm.vbl.autoGenerate = Are you sure you want to reset all VBL/MBL \n and automatically generate VBL/MBL for this token? +EditTokenDialog.confirm.vbl.clearVBL = Are you sure you want to clear all VBL/MBL for this token? +# These "generic" entries are currently not used; they're supposed to be +# overridden with specific entries in the code. So if they show up, +# it's a software bug. ;-) +EditTokenDialog.msg.generic.colKey = Key (Bug!) +EditTokenDialog.msg.generic.colValue = Value (Bug!) +EditTokenDialog.msg.speech.colID = ID +EditTokenDialog.msg.speech.colSpeechText = Speech Text +EditTokenDialog.msg.title = Edit Token +EditTokenDialog.msg.wrap = Wrap +EditTokenDialog.vbl.label.originalPointCount = Original Point Count +EditTokenDialog.vbl.label.optimizedPointCount = Optimized Point Count +EditTokenDialog.vbl.label.working = Working... +EditTokenDialog.checkbox.state.hide = Hide +EditTokenDialog.button.hero.refresh.tooltip.on = Refresh data from Hero Lab
Changes detected! +EditTokenDialog.button.hero.refresh.tooltip.off = Refresh data from Hero Lab
No changes detected... +EditTokenDialog.libTokenURI.error.notLibToken = {0} is not a valid name for a lib:Token. +EditTokenDialog.libTokenURI.error.reserved = lib:Tokens can not be named {0} if you want to enable URI access. + +MapPropertiesDialog.label.playerMapAlias = Display Name: +MapPropertiesDialog.label.playerMapAlias.tooltip = This is how players will see the map identified. Must be unique within campaign. +MapPropertiesDialog.label.Name.tooltip = This is how the map is referred to in macros and is only visible to the GM. +MapPropertiesDialog.label.cell.type = Cell Type: +MapPropertiesDialog.label.cell.dist = Distance per cell: +MapPropertiesDialog.label.cell.pixels = Pixels per Cell: +MapPropertiesDialog.label.cell.ai = AI Cell Rounding: +MapPropertiesDialog.label.vision.dist = Vision Distance: +MapPropertiesDialog.label.lights.tooltip = Can be Off, Day or Night. Can be changed after the map is created. +MapPropertiesDialog.image.nogrid = No Grid +MapPropertiesDialog.label.cell.ai.tooltip = This controls how the AI will round the distance per cell after terrain modifiers have been applied. The default is no rounding, which may leave the cell cost as a fraction and/or not in even multiples of cell units. +MapPropertiesDialog.label.image = Select Map Image +MapPropertiesDialog.label.background = Choose Background +MapPropertiesDialog.label.fog = Choose Fog +MapPropertiesDialog.label.lightingStyle = Lighting style: +MapPropertiesDialog.label.lightingStyle.tooltip = Controls how lights will be rendered. The default is "Overtop", which renders lights as a translucent overlay on top of the map (useful for black & white maps and similar). "Environmental" renders lights as though they illuminate the map itself (useful for full-colour artwork maps). + +AddResourcesDialog.label.localdirectory = Local Directory +AddResourcesDialog.label.example = (e.g. c:\\data\\cmpgn_images) +AddResourcesDialog.label.none = None + +AdjustBoardDialog.title = Adjust Board Position +AdjustBoardDialog.snapto = Snap to: +AdjustBoardDialog.none.tooltip = No snap. +AdjustBoardDialog.grid.tooltip = Snap to the token grid. +AdjustBoardDialog.tile.tooltip = Snap to the repeating background texture. + +GridControlPanel.size = Grid Size +GridControlPanel.size.second = 2nd Size +GridControlPanel.offset.x = Offset X +GridControlPanel.offset.y = Offset Y +GridControlPanel.colour = Colour +GridControlPanel.secondColour = 2nd Colour + +GridlessGrid.error.notLoaded = Could not load gridless grid footprints. + + + +# Handshake messages +Handshake.msg.duplicateName = Someone is already using that player name. Please choose another name and try again. +Handshake.msg.wrongPassword = You entered the wrong password. Please try again. +Handshake.msg.unknownPlayer = Player {0} is unknown. +Handshake.msg.wrongVersion = The versions used do not match. You are trying to connect a client running version {0} to a server running version {1}.
Please update your client to the correct version. +Handshake.msg.failedLogin = Failed login attempt from {0}, errors decoding handshake follow. +Handshake.msg.failedLoginDecode = Failed decoding handshake with password. +Handshake.msg.encodeInitFail = Failed to initialize encoding for handshake. +Handshake.msg.badChallengeResponse = Bad Handshake challenge response by client for player {0}. +Handshake.msg.errorValidating = Error validating handshake. +Handshake.msg.unableToConnectPublicKey = Unable to connect using public key. +Handshake.msg.invalidHandshake = Unable to connect due to Invalid Handshake. +Handshake.msg.playerBlocked = Player is blocked: {0}. +Handshake.msg.incorrectPassword = Incorrect Password during handshake. +Handshake.msg.incorrectPublicKey = Incorrect public key used during handshake. +Handshake.msg.deniedEasyConnect = Easy connect request denied. +Handshake.msg.gmDeniedRequest = GM has denied your request to connect. +Handshake.msg.playerAlreadyConnected = That player name is already connected. + +Update.title = Update Available +Update.msg1 = A new version of MapTool is available! +Update.msg2 = Would you like to download {0}? +Update.button = Skip this Version +Update.chkbox = Never check for updates again! + +ExportCampaign.desc = Export campaign to a previous version + +ExportScreenshot.view.current.tooltip = What you see is what you get. +ExportScreenshot.view.asselected = As Selected +ExportScreenshot.view.asselected.tooltip = Pick which layers to include in the screenshot. +ExportScreenshot.view.entiremap = Entire Map +ExportScreenshot.view.entiremap.tooltip = Entire map, respects visibility and fog. +ExportScreenshot.view.fog.tooltip = Entire Map: Same as enabling fog on the Map menu. Entire Map As Layers: If checked, a separate file will be exported with the current fog mask. +ExportScreenshot.view.gm.tooltip = Everything the GM sees. +ExportScreenshot.view.player.tooltip = Only what a Player can see. +ExportScreenshot.view.layer.tooltip = Include this layer. +ExportScreenshot.view.board.tooltip = The tiling background and/or the image used in "New Map". +ExportScreenshot.view.layer.vbl.tooltip = Saves Visibility Blocking Layer (VBL) as a monochrome image. +ExportScreenshot.ftp.path.note = NOTE: path must already exist +ExportScreenshot.ftp.host.example = (ex: myhost.com) +ExportScreenshot.ftp.username.example = (ex: pbpuser) +ExportScreenshot.ftp.path.example = (ex: path/to/my/images/map.png) +ExportScreenshot.method.label = Rendering Method: +ExportScreenshot.method.buffered = Buffered Image +ExportScreenshot.method.buffered.tooltip = Renders the image into a single bitmap then saves that to the chosen location. Can use a lot of memory, and may fail if the image is too large. +ExportScreenshot.method.iw = Image Writer +ExportScreenshot.method.iw.tooltip = Renders the image incrementally as it is needed by the file output formatting code. Uses less memory. Extremely large files can take a long time. The UI will not update during the file output, so the program may be unresponsive for several minutes while the file is saved. +ExportScreenshot.method.bg = Background Thread +ExportScreenshot.method.bg.tooltip = NOT IMPLEMENTED! Uses the Image Writer technique in a background thread so that the UI can be updated with the progress. + + +ImageCacheStatusBar.toolTip = Current size of Image thumbs cache directory, Double-Click to clear this cache. + +# {0} is the table name to be deleted. +LookupTablePanel.confirm.delete = Delete table "{0}"? +LookupTablePanel.confirm.export = Export table "{0}"? +LookupTablePanel.confirm.import = Import table "{0}"? +LookupTablePanel.confirm.overwrite = Overwrite table "{0}"? +LookupTablePanel.error.loadFailed = Could not load table. +LookupTablePanel.error.saveFailed = Could not save table "{0}". +LookupTablePanel.info.saved = Table saved as "{0}". +LookupTablePanel.msg.titleEdit = Edit Table +LookupTablePanel.msg.titleNew = New Table + +# Unfortunately, the Details button has not been localized yet. :( +MapToolEventQueue.details = Click the Details... button to see more information.
Please copy/paste the contents to a forum post when reporting errors. +MapToolEventQueue.stackOverflow = A stack overflow has occurred.\n\nThis is commonly because a macro being used has exceeded the stack space specified when MapTool was executed.\n\nPlease specify a larger stack size for MapTool and run again. +MapToolEventQueue.stackOverflow.title = Error: Stack Overflow +MapToolEventQueue.unexpectedError = An unexpected error has occurred. +MapToolEventQueue.warning.title = Warning + +MemoryStatusBar.tooltip = Used Memory: {0}M, Total Memory: {1}M, Maximum Memory:{2}M + +PaintChooser.title = Choose Paint + +PersistenceUtil.error.campaignPropertiesLegacy = This campaign properties file is not a legacy format file readable by this version of MapTool. +PersistenceUtil.error.campaignPropertiesVersion = This campaign properties file is not readable by this version of MapTool. +PersistenceUtil.error.campaignPropertiesRead = Error while reading campaign properties data from file. +PersistenceUtil.warn.campaignProperties.importWrongFileType = File is not a MapTool campaign properties file. File is {0}. + +PersistenceUtil.error.campaignRead = Error while reading campaign file. +PersistenceUtil.error.campaignVersion = This campaign file is not readable by this version of MapTool.
We will attempt to load using the legacy format... +# The keys ending with "Read" are for reporting IOExceptions. +# The ones ending with "Version" are for reporting ConversionExceptions (from XStream). +PersistenceUtil.error.macroRead = Error while reading macro button data from file. +PersistenceUtil.error.macroVersion = This macro button file is not readable by this version of MapTool. +PersistenceUtil.error.macrosetVersion = This macroset file is not readable by this version of MapTool. +PersistenceUtil.error.mapRead = Error while reading map data from file. +PersistenceUtil.error.mapVersion = This map file is not readable by this version of MapTool. +PersistenceUtil.error.tableRead = Error while reading table data from file. +PersistenceUtil.error.tableVersion = This table file is not readable by this version of MapTool. +PersistenceUtil.warn.campaignNotLoaded = Cannot determine campaign file format; not loaded. +PersistenceUtil.warn.campaignWrongFileType = File is not a MapTool campaign file. File is {0}. +PersistenceUtil.warn.importWrongFileType = File is not a MapTool map file. File is {0}. +PersistenceUtil.warn.macroWrongFileType = File is not a MapTool macro file. File is {0}. +PersistenceUtil.warn.macroSet = a Macro Set +PersistenceUtil.warn.macrosetWrongFileType = File is not a MapTool macro set file. File is {0}. + +Preferences.tab.developer = Developer +Preferences.tab.developer.warning = These options are not meant for normal use. If you aren't developing or debugging MapTool, don't enable them! +Preferences.developer.info.developerOptionsInUse = The following developer options are enabled: +Preferences.developer.autoSaveMeasuredInSeconds.label = Measure auto-save time in seconds +Preferences.developer.autoSaveMeasuredInSeconds.tooltip = When enabled, increases the frequency of auto-saves by reinterpreting the number as measuring seconds instead of minutes. +Preferences.developer.showPartitionDrawableBoundaries.label = Show spatial partitions when rendering drawings +Preferences.developer.showPartitionDrawableBoundaries.tooltip = When enabled, draws a boundary around each spatial partition that is used in drawing rendering. +Preferences.developer.showAiDebugging.label = Enable AI debugging +Preferences.developer.showAiDebugging.tooltip = When enabled, adds labels containing the f, g, and h costs calculated by A* during pathfinding, as well as the moves blocked by VBL. +Preferences.developer.ignoreGridShapeCache.label = Ignore grid shape cache +Preferences.developer.ignoreGridShapeCache.tooltip = When enabled, the grid's shape is recalculated every time it is needed. +Preferences.developer.info.developerOptionsInUsePost = If this is not intended, go to {0} > {1} > {2} tab and disable the options there. +Preferences.tab.interactions = Interactions +Preferences.label.maps.fow = New maps have Fog of War +Preferences.label.maps.fow.tooltip = Fog of War can be enabled or disabled on individual maps. +Preferences.label.maps.visible = New maps visible to players +Preferences.label.maps.visible.tooltip = Individual maps may or may not be visible to players. +Preferences.label.maps.grid = New Map Grid Type +Preferences.label.maps.grid.tooltip = The grid type for new maps. Cannot be changed once the map has been created. +Preferences.combo.maps.grid.square = Square +Preferences.combo.maps.grid.hexHori = Horizontal Hex +Preferences.combo.maps.grid.hexVert = Vertical Hex +Preferences.combo.maps.grid.isometric = Isometric +Preferences.label.maps.grid.new = New Map Grid Size +Preferences.label.maps.grid.new.tooltip = Number of map pixels that represents one unit of distance. +Preferences.label.maps.units = New Map Units Per Cell +Preferences.label.maps.units.tooltip = The size of a grid cell in game-system units. +Preferences.label.maps.vision = New Map Vision Distance +Preferences.label.maps.vision.tooltip = The distance at which MapTool should stop calculating sight lines. +Preferences.label.maps.light = New Map Vision +Preferences.label.maps.light.tooltip = The type of vision selected in a new map. +Preferences.label.maps.metric = Movement metric +Preferences.label.maps.metric.tooltip = Determines how MapTool handles movement on the selected grid type. +Preferences.label.maps.sortType = Sorting Method +Preferences.label.maps.sortType.tooltip = Determines if the maps are sorted by Name or Display Name +Preferences.label.objects.snap = Start Snap to Grid +Preferences.label.objects.snap.tooltip = Whether images dropped on the Object layer have snap-to-grid turned on by default. +Preferences.label.objects.free = Start Freesize +Preferences.label.objects.free.tooltip = If enabled, new objects will be shown at their native resolution with a resizing handle attached. +Preferences.label.background.snap.tooltip = Whether images dropped on the Background layer have snap-to-grid turned on by default. +Preferences.label.background.free.tooltip = If enabled, new background images will be shown at their native resolution with a resizing handle attached. +Preferences.label.tokens.snap.tooltip = Whether tokens have snap-to-grid turned on by default. +Preferences.label.tokens.free.tooltip = Whether new tokens will be shown at their native resolution. +Preferences.label.tokens.visible = New tokens visible to players +Preferences.label.tokens.visible.tooltip = Whether tokens dropped by the GM are immediately visible to players. (Note that token owners can always see their tokens.) +Preferences.label.tokens.delete = Warn when tokens are deleted +Preferences.label.tokens.delete.tooltip = There is no "undo" for token deletion. You probably want this enabled. +Preferences.label.tokens.duplicate = Duplicate Token Numbering +Preferences.label.tokens.duplicate.tooltip = When a token is pasted or dropped onto a map, how should duplicate names be resolved. +Preferences.combo.tokens.duplicate.increment = Increment +Preferences.combo.tokens.duplicate.random = Random +Preferences.label.tokens.numbering = Show Numbering on +Preferences.combo.tokens.numbering.name = Name +Preferences.combo.tokens.numbering.gm = GM Name +Preferences.combo.tokens.numbering.both = Both +Preferences.label.tokens.naming = New Token Naming +Preferences.label.tokens.naming.tooltip = Determines how new tokens are initially named. +Preferences.combo.tokens.naming.filename = Use Filename +# {0} is the localized version of "Creature" (See: Token.name.creature) +Preferences.combo.tokens.naming.creature = Use "{0}" +Preferences.label.tokens.dialog = Show Dialog on New Token +Preferences.label.tokens.dialog.tooltip = Determines whether the New Token dialog appears when a token is dropped onto the map. +Preferences.label.tokens.statsheet = Statsheet Portrait Size +Preferences.label.tokens.statsheet.tooltip = Size of the image that appears next to the statsheet on mouseover. Set to zero to disable portraits. +Preferences.label.tokens.portrait.mouse = Show Portrait on mouseover +Preferences.label.tokens.portrait.mouse.tooltip = Whether to show the portrait when the mouse hovers over a Token. +Preferences.label.tokens.statsheet.mouse = Show statsheet on mouseover +Preferences.label.tokens.statsheet.mouse.tooltip = Whether to show the statsheet when the mouse hovers over a Token. +Preferences.label.tokens.statsheet.shift = Stat sheet requires Shift key +Preferences.label.tokens.statsheet.shift.tooltip = The stat sheet will only show when the mouse hovers over a Token if the Shift key is also held down. Otherwise, Shift key will hide stat sheet on mouse hovers. +Preferences.label.tokens.arrow = Force Token Facing Arrow +Preferences.label.tokens.arrow.tooltip = Forces the display of the token facing arrow for Top Down tokens and tokens with image tables. +Preferences.label.tokens.drag.snap = Snap Token while dragging +Preferences.label.tokens.drag.snap.tooltip = Token image snaps to movement path while dragging. +Preferences.label.tokens.drag.hide = Hide Mouse Pointer while dragging +Preferences.label.tokens.drag.hide.tooltip = When dragging tokens the mouse pointer will be hidden. +Preferences.label.chat.avatar = Show Avatar per line +Preferences.label.chat.avatar.tooltip = Causes an icon of the impersonated token to appear at the beginning of each chat message. +Preferences.label.chat.smilies = Insert Smilies +Preferences.label.chat.smilies.tooltip = Certain strings of text are treated as smilies and replaced with images. A popup panel of smilies appears to the right of the chat input box. +Preferences.label.chat.rolls = Use ToolTips for Inline Rolls +Preferences.label.chat.rolls.tooltip = Die rolls are normally expanded and included in the chat window output. This options changes them into tooltips, although the result is still shown normally. +Preferences.checkbox.chat.rolls.tooltip = Enabled: [ ] acts like [t: ]
Disabled: [ ] acts like [h: ] +Preferences.label.chat.type.duration = Typing Notification Duration Seconds +Preferences.label.chat.type.duration.tooltip = Time before typing notifications disappear, in seconds. +Preferences.label.chat.type.color = Typing Notification Colour +Preferences.label.chat.type.color.tooltip = Colour of the text for typing notifications. +Preferences.label.chat.type.background = Typing Notification Background +Preferences.label.chat.type.background.tooltip = If enabled, shows a background frame underneath the typing notification. +Preferences.label.chat.trusted.background = Trusted Prefix Background +Preferences.label.chat.trusted.background.tooltip = Text generated by trusted macros is forced to a particular background colour. +Preferences.label.chat.trusted.foreground = Trusted Prefix Foreground +Preferences.label.chat.trusted.foreground.tooltip = Text generated by trusted macros is forced to a particular foreground colour. +Preferences.label.macroeditor.tooltip = Theme of the macro editor. +Preferences.label.facing.edge = On Edges +Preferences.label.facing.edge.tooltip = Causes token facing rotation to snap to edges of the grid cell. +Preferences.label.facing.vertices = On Vertices +Preferences.label.facing.vertices.tooltip = Causes token facing rotation to snap to the vertices of the grid cell. +Preferences.label.access.delay = ToolTip Initial Delay +Preferences.label.access.delay.tooltip = The initial delay (in milliseconds) before a tooltip is displayed. +Preferences.label.access.delay.dismiss = ToolTip Dismiss Delay +Preferences.label.access.delay.dismiss.tooltip = The amount of time (in milliseconds) the tooltip will remain before being removed. +Preferences.label.access.size = Chat Font Size +Preferences.label.access.size.tooltip = Point size for all chat window text (both input and output). +Preferences.label.sound.system = Play system sounds +Preferences.label.sound.system.tooltip = Turn this off to prevent all sounds from within MapTool. Needed for some Java implementations as too many sounds queued up can crash the JVM. +Preferences.label.sound.stream = Play clips and streams +Preferences.label.sound.stream.tooltip = Turn this off to prevent audio clips and streams from playing. +Preferences.label.sound.focus = Only when window not focused +Preferences.label.sound.focus.tooltip = Only turn off sounds when the window is not focused. +Preferences.label.sound.syrinscape = Turn on Syrinscape Integration +Preferences.label.sound.syrinscape.tooltip = Allow MapTool to launch Syrinscape via 3rd party integration URI. This will take affect on next launch of MapTool. +Preferences.label.auth.publicKey = Client Public Key +Preferences.label.auth.publicKey.tooltip = Key used for authentication with servers using public/private key authentication. +Preferences.label.auth.copyKey = Copy Public Key +Preferences.label.auth.regenKey = Regenerate Key +Preferences.label.language.tooltip = Select Language for User Interface. +Preferences.label.language.override = Language Override +Preferences.label.options = Additional Options +Preferences.label.options.directory = Data Directory +Preferences.label.options.directory.tooltip = Override default data directory. Default is .maptool under user directory. +Preferences.label.advanced = Advanced Options +Preferences.label.advanced.assert = Enable assertions +Preferences.label.advanced.direct3d = Disable Direct3d Pipeline +Preferences.label.advanced.opengl = Enable OpenGL Pipeline +Preferences.label.advanced.javafx = Intialize AWT before JavaFX +Preferences.label.jvm = JVM Memory Settings +Preferences.label.jvm.heap = Maximum heap size (-Xmx) +Preferences.label.jvm.heap.tooltip = -Xmx size in bytes Sets the maximum size to which the Java heap can grow. +Preferences.label.jvm.min = Initial & minimum heap size (-Xms) +Preferences.label.jvm.min.tooltip = Oracle recommends setting the minimum heap size (-Xms) equal to the maximum heap size (-Xmx) to minimize garbage collections. +Preferences.label.jvm.stack = Thread stack size (-Xss) +Preferences.label.jvm.stack.tooltip = Thread stacks are memory areas allocated for each Java thread for their internal use. This is where the thread stores its local execution state. +Preferences.label.autosave = Campaign autosave every +Preferences.label.autosave.tooltip = Autosaved campaigns are in ${appHome}/autosave. Autosaving a campaign is memory-intensive. Be sure to take that into account. Set to 0 to disable. +Preferences.label.save.reminder = Save reminder on close +Preferences.label.save.reminder.tooltip = Whether a prompt appears before MapTool closes. +Preferences.label.autosave.chat = Time between chat log autosaves +Preferences.label.autosave.chat.tooltip = The chat log will be autosaved at this interval (in minutes) using the filename pattern below. Set to 0 to disable. +Preferences.label.autosave.chat.filename = Autosave chat log filename +Preferences.label.autosave.chat.filename.tooltip = Specify a filename. Without a directory name is relative to ${appHome}/autosave. +Preferences.label.directory.sync = File Sync Directory +Preferences.label.directory.sync.tooltip = Specify the path to your cloud sync directy, eg Google Drive, Dropbox, One Drive, etc. This will be used to determine the relative path external files such as Hero Lab portfolios. +Preferences.label.directory.sync.set = Click the eclipses to the right to set the directory. +Preferences.label.map = Map Visuals +Preferences.label.halo.width = Halo line width +Preferences.label.halo.width.tooltip = The width of the single-colour halo around individual tokens. +Preferences.label.halo.color = Use halo colour for vision +Preferences.label.halo.color.tooltip = If enabled, the area visible to a token will be coloured the same as the halo. +Preferences.label.halo.opacity = Halo opacity +Preferences.label.halo.opacity.tooltip = Measures how opaque the halo vision overlay is drawn (0-255). +Preferences.label.aura.opacity = Aura opacity +Preferences.label.aura.opacity.tooltip = Measures how opaque the aura overlay is drawn (0-255). +Preferences.label.lumens.opacity = Lumens overlay opacity +Preferences.label.lumens.opacity.tooltip = Measures how opaque the lumens overlay is drawn (0-255). +Preferences.label.lumens.borderThickness = Lumens overlay border thickness +Preferences.label.lumens.borderThickness.tooltip = How thick to draw the border between lumens regions. Set to 0 for no border. +Preferences.label.lumens.startEnabled = Show lumens overlay by default +Preferences.label.lumens.startEnabled.tooltip = Toggle on to show the lumens overlay whenever MapTool is started. +Preferences.label.lights.startEnabled = Show environmental lights by default +Preferences.label.lights.startEnabled.tooltip = Toggle on to show the environmental lights whenever MapTool is started. +Preferences.label.light.opacity = Light opacity +Preferences.label.light.opacity.tooltip = Measures how opaque the light overlay is drawn (0-255). Has no effect on maps with environmental lighting. +Preferences.label.fog.opacity = Fog opacity +Preferences.label.fog.opacity.tooltip = Measures how opaque the "soft fog" overlay is drawn (0-255). +Preferences.label.fog.mapvisibilitywarning = Hide 'Map not visible to players' Warning +Preferences.label.fog.mapvisibilitywarning.tooltip= Hide warning from players telling that map is not visible. +Preferences.label.fog.autoexpose = Auto-expose fog on token movement (personal server) +Preferences.label.fog.autoexpose.tooltip = If enabled, the fog of war is automatically exposed as a token moves on maps with a grid. Gridless maps cannot auto-expose fog. When running a server, this setting is ignored in favor of the settings in the 'Start Server' dialog. +Preferences.label.performance.fillselection = Fill selection box +Preferences.label.performance.fillselection.tooltip = If enabled, a shaded area is used when dragging the mouse to select multiple tokens. +Preferences.label.performance.cap = Frame Rate Cap +Preferences.label.performance.cap.tooltip = Frame rate cap for map renderer in FPS. +Preferences.label.performance.render = Image Scaling Quality +Preferences.label.performance.render.tooltip = Quality of scaled images. +Preferences.combo.render.low = Low (Fastest) +Preferences.combo.render.pixel = Pixel Art +Preferences.combo.render.medium = Medium +Preferences.combo.render.high = High (Slowest) +Preferences.label.initiative.defaults = Campaign Defaults +Preferences.label.initiative.hidenpc = Hide NPCs from players on new maps +Preferences.label.initiative.hidenpc.tooltip = If enabled, NPCs will not appear in the players views of the Initiative panel. +Preferences.label.initiative.owner = Give Owners Permission in new campaigns +Preferences.label.initiative.owner.tooltip = Owner Permission allows players to perform certain actions on their tokens in the Initiative panel. +Preferences.label.initiative.lock = Lock Player Movement in new campaigns +Preferences.label.initiative.lock.tooltip = When enabled, players will only be able to move their token when that token has initiative. +Preferences.label.initiative.msg = Show Initiative Gain Message +Preferences.label.initiative.msg.tooltip = When enabled, a message is sent to chat when a token gains initiative. +Preferences.label.client.fitview = Fit GM view +Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? +Preferences.label.client.default.username = Default Username +Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory +Preferences.client.webEndPoint.port = Internal Web Server End Point Port +Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) +Preferences.client.default.username.value = Anonymous User +Preferences.label.macros.edit = Default: Allow players to edit macros +Preferences.label.macros.edit.tooltip = Player-editable macros cannot call trusted functions. When developing a framework, this should be disabled. +Preferences.label.upnp.timeout = Discovery Timeout +Preferences.label.upnp.timeout.tooltip = Timeout period in milliseconds to wait when looking for UPnP gateways. +Preferences.label.macros.permissions = Enable External Macro Access +Preferences.label.macros.permissions.tooltip = Enable macros to call functions that can access your drive and http services. The following functions will be enabled: getRequest, postRequest, exportData, getEnvironmentVariable. +Preferences.label.chat.macrolinks = Suppress ToolTips for MacroLinks +Preferences.label.chat.macrolinks.tooltip = MacroLinks show normally tooltips that state informations about the link target. This is a anti cheating device. This options let you disable this tooltips for aesthetic reasons. +Preference.checkbox.chat.macrolinks.tooltip = Enabled: do not show tooltips for macroLink
Disabled (default): show tooltips for macroLinks +PreferencesDialog.themeChangeWarning = Changing the theme requires a restart of MapTool to take effect. +PreferencesDialog.themeChangeWarningTitle = Theme Change. +Preferences.combo.themes.filter.all = All +Preferences.combo.themes.filter.dark = Dark +Preferences.combo.themes.filter.light = Light + +ServerDialog.error.port = You must enter a numeric port. +ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535. +ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?! Web server bug? +ServerDialog.error.server = You must enter a server name or IP address. +ServerDialog.error.serverNotFound = Server "{0}" not found. +ServerDialog.error.username = A username must be provided. +ServerDialog.error.noConnectPassword = You must enter a password to connect to a server. +ServerDialog.error.passwordMissing = Both Player and GM Password must be provided. +ServerDialog.error.playerPasswordMissing = Player Password must be provided. +ServerDialog.error.gmPasswordMissing = GM Password must be provided. +ServerDialog.error.passwordMustDiffer = Player and GM Password can not be the same. +ServerDialog.error.serverAlreadyExists = A server with the same name already exists. + +# The connection test has been disabled so these are not currently used. +ServerDialog.msg.test1 = Setting Up For Connection Test... +ServerDialog.msg.test2 = Performing connection test. Success is usually quick; failure often takes longer... +ServerDialog.msg.test3 = Success! I successfully connected to your computer from the Internet. +# Yes, I know these are similar. But I wanted *some* difference so the +# programmer can easily locate specific areas of the code. +ServerDialog.msg.test4 = Could not see your computer from the Internet.

It could be a port forwarding issue. Visit the RPTools forum (Tools -> MapTool -> HOWTO) to find the Networking FAQ. +ServerDialog.msg.test5 = Unable to see your computer from the Internet.

It could be a port forwarding issue. Visit the RPTools forum (Tools -> MapTool -> HOWTO) to find the Networking FAQ. +ServerDialog.msg.test6 = Communication error during test... +ServerDialog.msg.test7 = Unknown or unexpected exception during test. +ServerDialog.msg.title = Start Server +ServerDialog.label.usePasswordFile = Use MapTool Password file. +ServerDialog.tooltip.usePasswordFile = Use MapTool Password file for player and GM passwords. +ServerDialog.label.useEasyConnect = Use MapTool Easy Connect. +ServerDialog.tooltip.useEasyConnect = Use MapTool Easy Connect to simplify public key authentication. +ServerDialog.label.usepnp = Use UPnP +ServerDialog.option.hidemapselectui = Hide the map select UI from players +ServerDialog.option.hidemapselectui.tooltip = Hides the top right map select UI so that a custom one may be used or players are unable to change maps. +ServerDialog.option.disablePlayerLibrary = Hide Players' Library +ServerDialog.option.disablePlayerLibrary.tooltip = Prevents players from importing tokens from their libraries. +ServerDialog.tooltip.useupnp = Attempt to map ports automatically. Most people should try this option first, and forward ports manually only if UPnP does not work. If you have set up port forwarding, leave this option unchecked. +ServerDialog.label.alias = RPTools.net Alias: +ServerDialog.tooltip.alias = Allows players to find this server by name. If not provided,
\ + players will need your external address to use Direct Connect.
\ + must be specified if using WebRTC. +ServerDialog.label.gmpassword = GM Password: +ServerDialog.label.password = Player Password: +ServerDialog.label.metric = Movement metric +ServerDialog.label.metric.tooltip = Determines how MapTool handles movement on the selected grid type. +ServerDialog.option.ownership = Strict token ownership +ServerDialog.option.ownership.tooltip = Only the owner of a particular token may perform any actions on it. +ServerDialog.option.reveal.gm = GM reveals vision On Movement for Unowned Tokens +ServerDialog.option.reveal.gm.tooltip = If a token has no ownership, FoW will not be revealed on movement unless this is selected. +ServerDialog.option.reveal.player = Players can reveal vision +ServerDialog.option.reveal.move = Auto Reveal On Movement +ServerDialog.option.reveal.move.tooltip = Allows tokens to automatically reveal FoW at the end of movement. +ServerDialog.option.vision.individual = Use Individual Views +ServerDialog.option.vision.individual.tooltip = Players do not share vision. +ServerDialog.option.fow.individual = Use Individual FOW +ServerDialog.option.fow.individual.tooltip = Each token has it's own FOW. +ServerDialog.option.impersonate = Allow Players to Impersonate any token +ServerDialog.option.impersonate.tooltip = Gives players the ability to impersonate any character as if they had GM status. +ServerDialog.option.macros = Players Receive Campaign Macros +ServerDialog.option.macros.tooltip = The campaign panel macros will be available for players to use (but not edit). +ServerDialog.option.rolls = Use ToolTips for [] Rolls +ServerDialog.option.rolls.tooltip = Tool Tips will be used for [ ] rolls where no format options are specified. +ServerDialog.button.networkinghelp = Networking Help +ServerDialog.generatePassword = Generate Password + + +CampaignPropertiesDialog.tab.token = Token Properties +CampaignPropertiesDialog.tab.repo = Repositories +CampaignPropertiesDialog.tab.sight = Sight +CampaignPropertiesDialog.tab.light = Light +CampaignPropertiesDialog.tab.states = States +CampaignPropertiesDialog.tab.bars = Bars +CampaignPropertiesDialog.button.import = Import predefined +campaignPropertiesDialog.newTokenTypeName = Enter the name for the new token type +campaignPropertiesDialog.newTokenTypeTitle = New Token Type +campaignPropertiesDialog.newTokenTypeDefaultName = New Token Type {0} +campaignPropertiesDialog.newTokenPropertyDefaultName = New Prop {0} +campaignPropertiesDialog.tokenTypeNameChangeWarning = Changing the token type name will update all tokens with this type which could take a while. +campaignPropertiesDialog.tokenTypeNameChangeTitle = Token Type Name Change +campaignPropertiesDialog.tokenTypeNameDeleteTitle = Delete Token Type {0} +campaignPropertiesDialog.tokenTypeNameDeleteMessage =Change existing Tokens to: +campaignPropertiesDialog.tokenTypeNameRename = Renaming Token Types... +campaignProperties.macroEditDialog.default.title = Default value for Property +campaignPropertiesTable.column.name = Name +campaignPropertiesTable.column.shortName = Short Name +campaignPropertiesTable.column.displayName = Display Name +campaignPropertiesTable.column.onStatSheet = Stat Sheet +campaignPropertiesTable.column.gmStatSheet = GM +campaignPropertiesTable.column.ownerStatSheet = Owner +campaignPropertiesTable.column.defaultValue = Default + +# Bar propertyType +CampaignPropertiesDialog.combo.bars.type.twoImages = Two Images +CampaignPropertiesDialog.combo.bars.type.singleImage = Single Image +CampaignPropertiesDialog.combo.bars.type.multipleImages = Multiple Images +CampaignPropertiesDialog.combo.bars.type.solid = Solid +CampaignPropertiesDialog.combo.bars.type.twoTone = Two Tone +# Bar side +CampaignPropertiesDialog.combo.bars.side.top = Top +CampaignPropertiesDialog.combo.bars.type.bottom = Bottom +CampaignPropertiesDialog.combo.bars.type.left = Left +CampaignPropertiesDialog.combo.bars.type.right = Right +# State propertyType +CampaignPropertiesDialog.combo.states.type.image = Image +CampaignPropertiesDialog.combo.states.type.cornerImage = Corner Image +CampaignPropertiesDialog.combo.states.type.gridImage = Grid Image +CampaignPropertiesDialog.combo.states.type.dot = Dot +CampaignPropertiesDialog.combo.states.type.gridDot = Grid Dot +CampaignPropertiesDialog.combo.states.type.circle = Circle +CampaignPropertiesDialog.combo.states.type.shaded = Shaded +CampaignPropertiesDialog.combo.states.type.x = X +CampaignPropertiesDialog.combo.states.type.cross = Cross +CampaignPropertiesDialog.combo.states.type.diamond = Diamond +CampaignPropertiesDialog.combo.states.type.gridDiamond = Grid Diamond +# "Yield" here refers to the shape of the traffic sign (an inverted triangle) +CampaignPropertiesDialog.combo.states.type.yield = Yield +CampaignPropertiesDialog.combo.states.type.gridYield = Grid Yield +CampaignPropertiesDialog.combo.states.type.triangle = Triangle +CampaignPropertiesDialog.combo.states.type.gridTriangle = Grid Triangle +CampaignPropertiesDialog.combo.states.type.gridSquare = Grid Square +# Positions +position.corner.topLeft = Top Left +position.corner.topRight = Top Right +position.corner.bottomLeft = Bottom Left +position.corner.bottomRight = Bottom Right +position.side.left = Left +position.side.right = Right +position.side.top = Top +position.side.bottom = Bottom + + +CampaignPropertiesDialog.label.sight = \ + Format:\ +

Name : options
\ +

Each sight type can have zero or more options, use spaces between each option. Having zero options implies using \ + defaults for all values (e.g. Normal vision).

\ +

Options:

\ +
\ +
shape
shape may be circle, square, hex, grid or cone
\ +
distance=y
Distance is the range at which this vision type ends. Can be a decimal value. Ex: distance=10
\ +
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ +
arc=y
When used with the cone shape, it signifies how large a field of vision the token has. Can be an interger value. Ex: arc=120
\ +
offset=y
When used with the cone shape, it signifies how much offset the cone begins from the center of the tokens facing. Can be an integer value. Ex: offset=120
\ +
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value. Ex: x2
\ +
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\ +

Can have an optional #rrggbb hex colour component appended to it as per typical CSS rules.

\ +

Can also have an optional +x lumens value. Lumens defaults to 100, meaning it will see through any darkness with a lumens value from -1 to -99. See discussion of lumens on the Light tab for more info.

\ +

Ex: r60#bb0000+120

\ +
\ + +CampaignPropertiesDialog.label.light = \ +Format: \ +
Group name
\ +----------
\ +name: type shape OPTIONS scale range#rrggbb+x
\ +

Define groups of light types with a line of text to indicate the group \ +name followed by one or more name definitions. End a group with a \ +blank line. All text is case-insensitive. Lines that start with a "-" are \ +considered comments and are ignored. The group name becomes an entry on \ +the token's popup menu under the Light Sources element, and \ +individual light source definitions become sub-entries. Group names are \ +displayed in sorted order, and the sub-entries are alphabetically sorted \ +as well.

\ +
\ +
name
A user-visible name for light definition.
\ +
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\ +
shape
An optional shape for the light emanation. Can be circle (default), \ + square, cone (cones also have arc=angle and \ + offset=y fields) or grid (for systems like Pathfinder if \ + you want to see exactly which grid cells are affected by a Light/Aura). Shapes \ + apply from the point they are included in the definition until the end of the \ + definition or until another shape is specified. This means multiple light shapes \ + can be created under a single name and turned on or off as a unit.
\ +
scale
An optional keyword that adds the token's footprint (size) to the range so the light/aura starts at token's edge vs the token's center.
\ +
range

A distance measured in map units (defined when the map is created). Units are \ + measured from the centerpoint of the grid cell, hence the extra 2 ½ feet \ + added in the below example to make neat squares.

\ +

Can have an optional #rrggbb hex colour component appended to it as per \ + typical CSS rules.

\ +

Can have an optional +x lumens value, with x equaling an integer \ + (-x can instead be used to provide a negative lumens value). If not \ + provided, the value will default to 100. If set to a negative number, the \ + light will instead act as darkness and subtract it's area from the FoW. \ + Lights are processed in order of their absolute value of lumens. eg. Darkness \ + with lumens=-20 will cover over any light with lumens <= 20 and any light \ + with lumens >= 21 will expose through any darkness with a lumens value of \ + -1 to -20.

\ +

*Note: Personal Lights defined in Sight have a default lumens \ + value of 100. So a typical sight defined for Darkvision will see through \ + any lights with a lumens value of -1 through -99. To overcome Darkvision, use \ + lumens values <= -100.

\ +
OPTIONS
The only valid options are GM and OWNER and they apply only to auras (see below).
\ +
\ +

Example:

\ +
\
+Sample Lights - 5' square grid 
\ +----
\ +Candle - 5 : 7.5 12.5#000000
\ +Lamp - 15 : 17.5 32.5#000000
\ +Torch - 20 : 22.5 42.5#000000
\ +Lantern, bullseye - 60 : cone arc=60 62.5 122.5#000000
\ +Lantern, bullseye (leaks light) - 60 : cone arc=60 62.5 122.5#000000 circle 2.5#000000
\ +Daylight Spell - 60 : 62.5+50 122.5#000000+50
\ +Nightvision goggles - 40 : cone arc=30 42.5#00e000+30
\ +
\ +Magical Darkness
\ +----
\ +Deeper Darkness - 60: circle 62.5-130
\ +Darkness - 20 (CL2): circle 22.5-20
\ +Darkness - 20 (CL4): circle 22.5-40
\ +
\ +
\ +

Auras:

\ +

To create an aura, put the keyword aura at the beginning of the \ +definition. Auras radiate a coloured area and interact with the vision \ +blocking layer (i.e. are blocked by VBL), but do not actually cast any \ +visible light and therefore do not expose any fog-of-war. GM-only auras \ +are only visible by clients logged into the server as GM. They remain \ +visible even when the map is in Show As Player mode. Owner-only \ +auras are only visible to the player(s) who owns the token they are \ +attached to and are always visible to the GM. See examples, below.

\ +

In the following example, the GM-only auras are red, the owner-only \ +auras are green, and the player auras are blue. You can of course define \ +your own colours.

\ +
\
+Sample Auras - 5" square grid
\ +----
\ +Aura red 5 : aura square GM 2.5#ff0000
\ +Aura red 10 : aura GM 7.5#ff0000
\ +Aura Owner Also 5 : aura square owner 2.5#00ff00
\ +Aura Owner Also 10 : aura owner 7.5#00ff00
\ +Aura Player Also 5 : aura square 2.5#0000ff
\ +Aura Player Also 10 : aura 7.5#0000ff
\ +
\ +

The first line creates a square GM-only aura in red that is 5-feet across. \ +The second creates a round GM-only aura in red with a 15-foot diameter. \ +Lines three and four do the same thing, but with a green aura that is only \ +visible to players who own the token with the aura attached to it. Lines \ +five and six are visible to all players and are in blue.

\ + +CampaignPropertiesDialog.label.title = Campaign Properties +CampaignPropertiesDialog.label.group = Group: +CampaignPropertiesDialog.label.image = Image: +CampaignPropertiesDialog.label.images = Images: +CampaignPropertiesDialog.label.show = Show To: +CampaignPropertiesDialog.label.corner = Corner: +CampaignPropertiesDialog.label.preview = Preview: +CampaignPropertiesDialog.label.side = Side: +CampaignPropertiesDialog.label.bar = Bar Colour: +CampaignPropertiesDialog.label.background = Background: +CampaignPropertiesDialog.label.thick = Thickness: +CampaignPropertiesDialog.label.opacity = Opacity: +CampaignPropertiesDialog.label.inc = Increments: +CampaignPropertiesDialog.label.mouse = Mouseover: +CampaignPropertiesDialog.label.order = Order: +CampaignPropertiesDialog.label.order.tooltip = Position in the list of states, change to move up or down the list. +CampaignPropertiesDialog.label.else = Everybody Else +CampaginPropertiesDialog.label.owner = Owner + +TextureChooserPanel.title = Texture + +TokenPropertiesPanel.label.list = List the token properties for this token type below, one property per line: +TokenPropertiesPanel.label.type = Token Type +TokenPropertiesPanel.label.statSheet = Stat Sheet +TokenPropertiesPanel.button.statSheetProps = Stat Sheet Properties +TokenPropertiesPanel.button.setAsDefault = Set as Default +TokenPropertiesPanel.defaultPropertyType = Default Property Type + + +# Token terrain modifier operations +Token.TerrainModifierOperation.NONE = None +Token.TerrainModifierOperation.MULTIPLY = Multiply +Token.TerrainModifierOperation.ADD = Add +Token.TerrainModifierOperation.BLOCK = Block +Token.TerrainModifierOperation.FREE = Free + +# Token shapes +Token.TokenShape.TOP_DOWN = Top Down +Token.TokenShape.CIRCLE = Circle +Token.TokenShape.SQUARE = Square +Token.TokenShape.FIGURE = Figure + +Token.Type.PC = PC +Token.Type.NPC = NPC + +# Token sizes, from smallest to largest +TokenFootprint.name.fine = Fine +TokenFootprint.name.diminutive = Diminutive +TokenFootprint.name.tiny = Tiny +TokenFootprint.name.small = Small +TokenFootprint.name.medium = Medium +TokenFootprint.name.large = Large +TokenFootprint.name.huge = Huge +# Humongous is only used on hex grids, comes after huge +TokenFootprint.name.humongous = Humongous +# The following are only used on square grids, come after huge +TokenFootprint.name.gargantuan = Gargantuan +TokenFootprint.name.colossal = Colossal + +# Token VBL Optimization methods +TokenVBL.JTS_SimplifyMethodType.DOUGLAS_PEUCKER_SIMPLIFIER = Douglas Peucker +TokenVBL.JTS_SimplifyMethodType.TOPOLOGY_PRESERVING_SIMPLIFIER = Topology Preserving +TokenVBL.JTS_SimplifyMethodType.VW_SIMPLIFIER = VW Simplifier +TokenVBL.JTS_SimplifyMethodType.NONE = No Optimization + +TransferProgressDialog.title = Assets in Transit +TransferProgressDialog.desc = These are images that are currently being retrieved from the server or a repository. + +SquareGrid.error.pathhighlightingNotLoaded = Could not load path highlighting image. +SquareGrid.error.squareGridNotLoaded = Could not load square grid footprints. + +Token.dropped.byPlayer = Tokens dropped onto map "{0}" by player {1} +# This is the name given to new tokens if the New Token Naming preference +# is set to "Use "Creature"" +Token.name.creature = Creature +Token.error.unableToPaste = Failed to paste token(s) with duplicate name(s): {0} +Token.error.unableToRename = Cannot rename token to "{0}" as there is already another token with this name on the map.
Only the GM can create multiple tokens with the same name! + +ToolbarPanel.manualFogActivated = Modifying the fog-of-war manually without a server running affects only the global exposed area (i.e. the entire map), even
if one or more tokens are selected. If you want your changes to apply to individual tokens, start a MapTool server with
Individual Fog enabled (you can leave the Alias field empty to make an anonymous server, if you wish).

This warning will not appear again for this campaign. + +TransferableHelper.error.ioException = I/O error during drag/drop operation. +TransferableHelper.error.unrecognizedAsset = Could not retrieve drag/drop asset. +TransferableHelper.error.unsupportedFlavorException = Unsupported data type during drag/drop operation. +TransferableHelper.error.urlFlavor = Cannot read URL_FLAVOR. +TransferableHelper.warning.badObject = Unable to obtain data from dropped object.
Likely causes are an empty object due to a network error (such as proxy settings or missing authentication)
or possibly an incompatible object was dropped (such as an invalid file type). +TransferableHelper.warning.tokensAddedAndExcluded = Added {0,number} tokens. There were {1,number} tokens that could not be added
because they were missing names or images. + +VisionDialog.error.EmptyDistance = Distance Text Field is empty, enter a distance. +VisionDialog.error.numericDistanceOnly = Distance must be numeric. +# These are for a first cut at a true vision UI but the code is +# currently not accessible by the user. +VisionDialog.msg.title = Vision + +# Movement metrics +WalkerMetric.NO_DIAGONALS = No Diagonals +# "Manhattan" refers to Manhattan Distance (See: https://en.wikipedia.org/wiki/Taxicab_geometry) +WalkerMetric.MANHATTAN = Manhattan +WalkerMetric.ONE_TWO_ONE = One-Two-One +WalkerMetric.ONE_ONE_ONE = One-One-One + +# AI cell rounding options +Zone.AStarRoundingOptions.NONE = None +Zone.AStarRoundingOptions.CELL_UNIT = Cell Unit +Zone.AStarRoundingOptions.INTEGER = Integer + +# This message appears when a campaign is loaded and MapTool is scanning +# the maps and optimizing their memory footprint by collapsing +# drawables, if possible. +Zone.status.optimizing = Optimizing map: "{0}" + +ZoomStatusBar.tooltip = Zoom level + +action.addDefaultTables = Add Default Tables... +action.addDefaultTables.description = Adds several dice image and card tables to the campaign. +action.addIconSelector = Add Resource to &Library... +action.addIconSelector.description = Opens a dialog to add local and remote content to your Resource Library. +action.addOnLibraries = Add On Libraries... +action.adjustBoard = Adjust Map Board... +action.adjustBoard.description = Open dialog to adjust the position of the embedded map image. +action.adjustGrid = &Adjust Grid... +action.adjustGrid.accel = shift A +action.adjustGrid.description = Open dialog to adjust the grid settings. +action.autohideNewIcons = Autohide New Tokens +action.autohideNewIcons.description = New tokens start invisible to players. +action.autohideNewMaps = Autohide New Maps +action.autohideNewMaps.description = New maps start invisible to players. +# Other actions which are not necessarily on the top menu but may +# appear on a context (i.e. right-click) menu or be connected to +# an editable field on a dialog. NOTE: MapTool 1.3 does not properly +# localize dialog labels yet! Only one or two dialogs have the +# necessary code for localization. +action.bootConnectedPlayer = Boot... +action.campaignProperties = Campaign Properties... +action.campaignProperties.description = Opens dialog for setting Campaign Properties. +action.cancelCommand = Not used (action.cancelCommand) +action.clearDrawing = Clear All Drawings +action.clearDrawing.accel = shift D +action.clearDrawing.description = Clear will clear all drawings from the active layer and clear all drawing undo history. +action.clientConnect = Connect to Server... +action.clientConnect.description = Connect as a client to a server. +action.clientDisconnect = Disconnect from Server... +action.clientDisconnect.description = Disconnect from or shutdown the server. +action.collectPerformanceData = Collect Performance Data +action.collectPerformanceData.description = Opens a floating panel that reports various performance statistics. +action.commandPanel = Command Panel +# These next two are used internally but never appear on a menu item. +# In order to prevent I18N from warning that they don't exist these +# lines have been added. +action.commitCommand = Not used (action.commitCommand) +action.copyTokens = Copy +action.copyTokens.accel = C +action.copyTokens.description = Copy selected tokens to an internal clipboard. +action.copyZone = Copy... +action.copyZone.description = Make a copy of the current map. +action.cutTokens = Cut +action.cutTokens.accel = X +action.cutTokens.description = Cut selected tokens to an internal clipboard. +action.debug.duplicateLastIcon = Duplicate Last Icon (debug) +action.editMap = Edit Map... +action.editMap.description = Open a dialog to edit settings for the current map. +# Is this accelerator a bad choice on OSX? The Mac uses Cmd-W to mean +# "close focused window"... Even if we answer "yes", should we change this? +# I hate to start putting os-specific settings into the properties file. :( +# Unless we add the "os.name" field as a prefix to all properties +# as a way to override what's here. For example, adding a property named +# mac os x.action.enabledFogOfWar.accel=f +# to indicate a platform-specific change to the accelerator...? +# With MapTool 1.4 expected to allow users to define their own accelerators +# this probably doesn't matter much. +action.enableFogOfWar = Fog-of-&War +action.enableFogOfWar.accel = W +action.enableFogOfWar.description = Enable the fog of war for the current map. +action.enforceNotification = Enforce Typing Notifications +action.enforceNotification.description = Enforce Typing Notifications. +action.enforceView = &Center Players on Current View +action.enforceView.accel = F +action.enforceView.description = Causes all clients to zoom to your current view. +action.enforceZone = &Enforce Players to Current Map +action.enforceZone.accel = E +action.enforceZone.description = Causes all clients to change to the map you are on. +action.error.noMapBoard = There is no map image. Use "Edit Map..." to add one. +# Not used on the Mac, as the application menu will have 'Quit' added to +# it instead and Meta-Q set as the accelerator. Kind of ugly that it is +# hard-coded in the application, but that's OSX for you. ;-) +action.exit = E&xit +action.exit.description = Exit out of MapTool. +action.exportCampaignAs = Campaign As... +action.exportCampaignAs.description = Export current campaign to a version compatible with older MapTool releases. +action.exportScreenShot = Screenshot +action.exportScreenShot.title = Export Screenshot +action.exportScreenShot.accel = shift S +action.exportScreenShot.description = Export an image of the current map. Use Export Screenshot As first. +action.exportScreenShotAs = Screenshot As... +action.exportScreenShotAs.description = Opens a dialog to export an image of the current map. +action.fullscreen = Fullscreen Mode +action.fullscreen.accel = alt ENTER +action.fullscreen.description = Change to full screen mode hiding everything else but the map view. +action.toggleFullScreenTools = Enable tools in full screen mode. +action.toggleFullScreenTools.accel = alt T +action.gatherDebugInfo = Gather Debug Information... +action.gatherDebugInfoWait = Gathering information, please wait... +action.gatherDebugInfo.description = Collects information about your system to aid in troubleshooting or reporting bugs. +action.gridSize = Grid &Line Width +# These are url menu actions. Each item consists of three keys. The first key is +# action.url.## which contains the displayed string. The second key is +# action.url.##.description which contains the url to load when the action is +# executed. The last key is action.url.##.icon which contains the image embedded +# inside the MapTool JAR file which appears on the menu item. +action.helpurl.01 = Documentation +action.helpurl.01.description = https://www.rptools.net/toolbox/maptool/ +action.helpurl.02 = Tutorials +action.helpurl.02.description = https://www.rptools.net/tutorials/ +action.helpurl.03 = Forums +action.helpurl.03.description = http://forums.rptools.net/ +action.helpurl.04 = Networking Setup (forum thread) +action.helpurl.04.description = http://forums.rptools.net/viewtopic.php?f=22&t=3370 +action.helpurl.05 = Macro Scripting +action.helpurl.05.description=https://wiki.rptools.info/index.php/Main_Page +action.helpurl.06 = Frameworks +action.helpurl.06.description = https\://wiki.rptools.info/index.php/Frameworks +action.hideMap = &Player Visible +action.hideMap.accel = H +action.hideMap.description = Toggle visibility of map for the players. +action.linkPlayerView = Center Players on Current View (Continuous) +action.linkPlayerView.accel = shift F +action.linkPlayerView.description = Causes all clients to continuously track your view. +action.loadCampaign = &Open Campaign... +action.playerDatabase = Player Database +action.loadCampaign.accel = O +action.loadCampaign.description = Load a previously saved campaign. +action.loadMap = &Import Map... +action.loadMap.description = Load a previously saved map. +action.loadMap.warning1 = This is an experimental feature. Save your campaign before using this feature (you are a GM logged in remotely). +action.loadMap.warning2 = Help opens a browser to the forum thread discussion and aborts this import. +action.loadMap.warning3 = Yes acknowledges the issues and proceeds to import the map. +action.loadMap.warning4 = No closes this panel and aborts the import. +action.import.dungeondraft = Import Universal VTT... +action.import.dungeondraft.dialog.title = Import Universal VTT File +action.loadSaveDialog = DEBUG LOAD/SAVE +action.loadSaveDialog.accel = F5 +action.macro.addNewToSelected = Add New to Selected +action.macro.clearGroup = Clear Group... +action.macro.clearPanel = Clear Panel... +action.macro.delete = Delete... +action.macro.deleteFromCommon = Delete from Common... +action.macro.duplicate = Duplicate +action.macro.duplicateOnSelected = Duplicate Macro on Selected +action.macro.edit = Edit... +action.macro.export = Export... +action.macro.exportCommon = Export Common Macro... +action.macro.exportCommonSet = Export Common Macro Set... +action.macro.exportSet = Export Macro Set... +action.macro.exportGroup = Export Macro Group... +action.macro.import = Import... +action.macro.importSet = Import Macro Set... +action.macro.importSetToSelected = Import Macro Set to Selected... +action.macro.importToSelected = Import Macro to Selected... +action.macro.new = Add New Macro +action.macro.renameGroup = Rename Macro Group... +action.macro.reset = Reset +action.macro.runForEachSelected = Run for Each Selected +action.macroEditor.gotoLine = &Go to Line... +action.macroEditor.gotoLine.accel = L +action.macroEditor.searchFind = &Find... +action.macroEditor.searchFind.accel = F +action.macroEditor.searchReplace = &Replace... +action.macroEditor.searchReplace.accel = H +action.macroEditor.showFindSearchBar = Show Find Search Bar +action.macroEditor.showFindSearchBar.accel = shift F +action.macroEditor.showReplaceSearchBar = Show Replace Search Bar +action.macroEditor.showReplaceSearchBar.accel = shift H +# File Menu +action.newCampaign = &New Campaign +action.newCampaign.description = Discards current campaign and creates a new campaign with a single Grasslands map. +# Map Menu +action.newMap = New Map... +action.newMap.accel = N +action.newMap.description = Opens a dialog to add a new map to the current campaign. +action.newToken = New Token... +action.newUnboundedMap = New Tiled Map... +action.newUnboundedMap.accel = shift n +action.openLogConsole = Open Log Console +action.openLogConsole.title = Log Console +action.openLogConsole.description = Opens the Log Console to display the log output. +action.pasteTokens = Paste +action.pasteTokens.accel = V +action.pasteTokens.description = Paste internal clipboard to the current mouse location. +action.preferences = Preferences... +action.preferences.description = Opens Preferences dialog. +action.redoDrawing = Redo Drawing +action.redoDrawing.accel = R +action.redoDrawing.description = Redo the most recent drawing in the undo history. +action.refresh = Refresh +action.refresh.accel = F5 +action.removeAssetRoot = Remove... +action.removeZone = Delete... +action.removeZone.description = Delete the current map from the campaign. +action.renameMap = Rename... +action.renameMap.description = Rename the current map. +action.rescanNode = Rescan... +action.restoreDefaultImages = Restore &Default Images... +action.restoreDefaultImages.description = Restores the default tokens, textures, dice and other images to the Resource Library. +action.restoreFogOfWar = Restore Fog-of-&War +action.restoreFogOfWar.accel = shift R +action.restoreFogOfWar.description = Restore the fog of war for the current map (erase all revealed FoW). +action.revealFogAtWaypoints.description = Reveal Fog-of-War only at start and end points, as well as set way points. +action.revealFogAtWaypoints = FoW: Expose only at way points +action.revealFogAtWaypoints.accel = shift W +action.runMacro = &Run Macro +action.runMacro.accel = typed / +action.runMacro.description = Makes the chat window active and begins the line with a slash(/). +action.saveCampaign = &Save Campaign +action.saveCampaign.accel = S +action.saveCampaign.description = Save all resources (maps, tokens, tables, etc) in a single file. +action.saveCampaignAs = Save Campaign &As... +action.saveCampaignAs.accel = A +action.saveCampaignAs.description = Save all resources (maps, tokens, tables, etc) in a single file. +action.saveMapAs = &Export Map... +action.saveMapAs.description = Save a map to an external file. +action.saveMessageHistory = Save Chat Log &History... +action.saveMessageHistory.description = Save the contents of your chat log, including whispers. +# Tool +action.sendChat = C&hat +action.sendChat.accel = ENTER +action.chat.color.tooltip = Set the colour of your speech text +action.chat.scrolllock.tooltip = Scroll lock +action.chat.showhide.tooltip = Show/hide typing notification +#action.addIconSelector.accel=ctrl shift i +action.serverStart = Start Server... +action.serverStart.description = Start a server so that other MapTool clients can connect to you. +action.setZoneGridColor = Set Grid Colour... +# Help +action.showAboutDialog = &About... +action.showAboutDialog.description = Show information about MapTool. +action.showConnectionInfo = &Connection Information... +action.showConnectionInfo.description = Opens window displaying the Local and External IP addresses of your connection as well as the Port being used. +action.showCoordinates = Show &Coordinates +action.showCoordinates.description = Display row/column coordinates. For square grids only. +action.showGrid = Show &Grid +action.showGrid.accel = G +action.showGrid.description = Toggles display of the grid on and off. +action.showLightRadius = Show Token &Lights +action.showLightRadius.accel = L +action.showLightRadius.description = Causes light overlays to be enabled for all tokens that have a light source. +action.showLightSources = Show Light Sources +action.showLightSources.accel = K +action.showLightSources.description = Displays a light bulb icon on all tokens with a Light Source. GM Only +# Currently unused but the code is in place which searches for this key, so... +action.showMapSelector = &MiniMap +action.showMapSelector.accel = M +action.showMovementMeasures = Show Movement &Distances +action.showMovementMeasures.accel = D +action.showTextLabels = Show Text Labels +action.showMovementMeasures.description = Show the distance traveled by a token while dragging it. +action.showNames = Show &Token Names +action.showNames.accel = T +action.showNames.description = Displays names below tokens.
Visible NPC: White on Blue
Visible PC: Black on Grey
Not Visible: White on Dark Grey. +action.showPlayerView = Show As Player +action.showPlayerView.accel = shift P +action.showPlayerView.description = Causes your view to (mostly) show what a player would see. +action.toggleDoubleWide = &Straight Line Width Doubled +action.toggleDoubleWide.description = When selected the line template will draw straight lines at double width. +action.showLumensOverlay = Show Lumens Overlay +action.showLumensOverlay.description = Render the lumens levels on top of the map. +action.showLights = Show Lights +action.showLights.description = Draw lights onto the map as part of the environment. + +action.toggleDrawMeasurements = Display Drawing &Distances +action.toggleDrawMeasurements.description = When selected the drawing tools will display distances during drawing. +action.toggleMovementLock = &Lock Player Movement +action.toggleMovementLock.accel = shift L +action.toggleMovementLock.description = Locks movement for player-owned tokens. +action.toggleTokenEditorLock = Lock Player Token Editor +action.toggleTokenEditorLock.description = Locks access to the Token Editor. +action.toggleNewZonesHaveFOW = New Maps have Fog of War +action.toggleTokensStartSnapToGrid = Tokens Start Snap to Grid +# Edit Menu +action.undoDrawing = Undo Drawing +action.undoDrawing.accel = Z +action.undoDrawing.description = Removes the last drawing placing it in the undo history. +action.useAlphaFog = Toggle Translucent Fog +action.zoom100 = Zoom 1:1 +action.zoom100.accel = typed + +# View +action.zoomIn = Zoom &In +action.zoomIn.accel = typed = +action.zoomLock = Lock Zoom +action.zoomOut = Zoom &Out +action.zoomOut.accel = typed - + +addtokenstate.added = Token state "{0}" was added +# Slash command info +addtokenstate.description = Add a new token state that can be set on tokens. +addtokenstate.exists = A token state with the name "{0}" already exists. +addtokenstate.invalidColor = An invalid colour "{0}" was passed as a parameter. Valid values are hex or integer numbers or the name of a common colour (black, blue, cyan, darkgray, gray, green, lightgray, magenta, orange, pink, red, white, yellow). +addtokenstate.invalidCorner = An invalid corner name "{0}" was passed as a parameter. Valid values are nw, ne, sw, se. +addtokenstate.invalidNumber = An invalid number "{0}" was passed as a parameter. +addtokenstate.noOverlyType = There is no overlay type with the name "{0}". Valid types are "dot, circle, shade, X, cross, diamond, yield or triangle". +addtokenstate.param = A token state name and overlay name are required. + +admin.exportCampaignRepo = Campaign Repository File... +admin.exportCampaignRepo.description = Export a campaign repository file. +admin.updateCampaignRepo = Update Campaign Repository... + +alias.added = Alias "{0}" added. +alias.commandHeader = Command +alias.descriptionHeader = Description +alias.description = Create an alias. +alias.header = Alias +alias.removed = Alias "{0}" removed. +alias.notFound = Alias "{0}" not found. +alias.campaign.title = Campaign Aliases +alias.client.title = Client Aliases +alias.addon.title = Aliases defined by {0} ({1}) Add-On . + + +changecolor.description = Change your chat text colour via macros. Colour must be in hexadecimal format. Example: /cc #ff0099 + +clear.description = Clear the message panel. + +clearaliases.description = Clear all aliases. +clearaliases.prompt = Clear all aliases? + + + +component.areaGroup.macro.commonMacros = Common Macros +component.areaGroup.macro.noMacros = No Macros +component.dialogTitle.macro.macroID = Macro ID +component.label.macro.allowPlayerEdits = Allow Players to Edit Macro +component.label.macro.applyToSelected = Apply to Selected Tokens +component.label.macro.autoExecute = Auto Execute +component.label.macro.buttonColor = Button Colour +component.label.macro.command = Command +component.label.macro.compareApplyToSelected = Use Apply to Selected Tokens +component.label.macro.compareUseAutoExecute = Use Auto Execute +component.label.macro.compareUseCommand = Use Command +component.label.macro.compareUseGroup = Use Group +component.label.macro.compareUseIncludeLabel = Use Include Label +component.label.macro.compareUseSortPrefix = Use Sort Prefix +component.label.macro.displayHotKey = Display Hot Key? +component.label.macro.fontColor = Font Colour +component.label.macro.fontSize = Font Size +component.label.macro.group = Group +component.label.macro.hotKey = Hot Key +component.label.macro.includeLabel = Include Label +component.label.macro.label = Label +component.label.macro.macroCommonality = Macro Commonality +component.label.macro.maxWidth = Max Width +component.label.macro.minWidth = Min Width +component.label.macro.sortPrefix = Sort Prefix +component.label.macro.toolTip = Tooltip +component.tab.macro.details = Details +component.tab.macro.editor = Editor +component.tab.macro.options = Options +component.tooltip.macro.allowPlayerEdits = Select this to allow players to edit this macro. +component.tooltip.macro.applyToSelected = Check here to run this macro against the currently selected tokens. Uncheck to run this macro outside of the context of any selected tokens. If this macro references one or more token properties, it should be checked. +component.tooltip.macro.autoExecute = Check to run the macro as soon as its button is pressed. Uncheck to impersonate (if applicable) and prepare the macro command in the command box. +#TODO: Write tooltip for this. +component.tooltip.macro.buttonColor = Select the colour of the face of this macro's button. +component.tooltip.macro.compareUseApplyToSelected = Check here to consider this macro's Use Apply to Selected Tokens state when determining its commonality with other macros. +component.tooltip.macro.compareUseAutoExecute = Check here to consider this macro's Auto Execute state when determining its commonality with other macros. +component.tooltip.macro.compareUseCommand = Check here to consider this macro's Command when determining its commonality with other macros. +component.tooltip.macro.compareUseGroup = Check here to consider this macro's Group when determining its commonality with other macros. +component.tooltip.macro.compareUseIncludeLabel = Check here to consider this macro's Include Label state when determining its commonality with other macros. +component.tooltip.macro.compareUseSortPrefix = Check here to consider this macro's Sort Prefix when determining its commonality with other macros. +component.tooltip.macro.displayHotKey = Display or Hide the Hot Key on the macro button. +component.tooltip.macro.fontColor = Select the colour in which the label for this macro's button will appear in the macro button panels. +component.tooltip.macro.fontSize = Selected the size of the font in which the label for this macro's button will appear in the macro button panels. +component.tooltip.macro.group = This is the group in the macro button panel in which this macro will appear. If the group does not already exist, it will be created. +component.tooltip.macro.hotKey = This sets a hot key for this macro. These hot keys are common across all macro panels. +component.tooltip.macro.includeLabel = Check here to include the macro's label with the macro output in chat. Uncheck to only have the macro output appear in chat. +# These really should use the ".description" style that is used by the menu +# selections, above. We'll convert these to new names later on and when +# we do, we'll convert all translation files at the same time. +component.tooltip.macro.label = This is the name that will appear on the macro button. +component.tooltip.macro.maxWidth = Specify the maximum width this macro button should fill in a macro button panel. If the label for the macro button exceeds this width, the label will be cut off. Leaving this field blank will let the button auto-fit to the label length. +component.tooltip.macro.minWidth = Specify the minimum width this macro button should fill in a macro button panel. If the label for the macro button exceeds this width, the button will grow to accommodate it. Leaving this filed blank will allow the button to shrink to auto-fit smaller labels. +component.tooltip.macro.sortPrefix = This determines the order within its group that this macro will appear. +component.tooltip.macro.tooltip = Enter a tool tip for the macro button to display here. +component.msg.macro.textfound = Text found; occurrences marked: {0} +component.msg.macro.occurrences = Occurrences marked: {0} +component.msg.macro.notfound = Text not found + +# The IP address in these next two messages comes from the results of the ConnectionInfoDialog contacting the RPTools Registry and asking for it. +# It's obviously possible that this will fail. In those cases the string returned will be "Unknown". The first line is for the confirmation dialog and the +# other two appear as output in the chat window. +confirm.info.heartbeat.registryFailure = Connection refresh to the MapTool registry failed.

The registry server will purge records periodically, making it difficult for future clients to connect.
If this persists, you will need to provide clients with your contact information directly (IP address "{0}" and port {1}). +confirm.macro.allowPlayerEdits = Are you sure you wish to allow players to edit any macro common to this one?

Select "Yes" to continue with the change. Select "No" to revert. +confirm.macro.checkComparisons = Do you want to check comparison criteria for each common macro before adding it to the export list?

If you select "No", MapTool will not prompt you if any of a particular macro's commonality criteria are deselected. A macro with deselected macro criteria may be exported with missing information. For example, if a macro with "Command" comparison deselected is added to the export list, that macro will be exported without a command. +confirm.macro.clearGroup = You are about to clear the {0} macro group. Are you sure you want to continue? +confirm.macro.clearPanel = You are about to clear the {0} macro panel. Are you sure you want to continue? +confirm.macro.commonSelectionLocation = within the common selection macros +# The only parameter for *most* translation strings is the +# player's name (as it appears in the Connection panel). Some +# strings, particularly the ones dealing with macro messages, have +# multiple parameters. It's usually pretty obvious what propertyType of +# value is being used as a parameter, but some messages have a comment +# directly above them to clarify, if appropriate. +# +# Valid patterns used to express parameters are: +# {num} replace the parameter with a string +# {num,propertyType,size} +# propertyType can be 'time' or 'date' (for java.util.Date objects), +# 'number' to indicate a numeric propertyType, +# and size can be +# 'short', 'int', or 'long' for numeric arguments of the same propertyType. +# +# Check the javadoc for the 'MessageFormat' class for more details on the +# formatting of values in this file (the time and date ones are particularly +# tricky, but thankfully aren't used much in MapTool). The URL is in the +# comments at the top of this file. +# General confirmation-propertyType messages +confirm.macro.delete = You are about to delete the {0} macro.

Do you wish to continue? +confirm.macro.disallowPlayerEdits = Are you sure you wish to prevent players from editing any macro common to this one?

Select "Yes" to continue with the change. Select "No" to revert. +confirm.macro.exportInto = You are about to export the {0} macro.

Do you wish to continue? +confirm.macro.exportOverwrite = You are about to overwrite an existing macro file.

Do you wish to continue? +confirm.macro.exportSetInto = You are about to export the current macro set.

Do you wish to continue? +confirm.macro.exportSetOverwrite = You are about to overwrite an existing macro set file.

Do you wish to continue? +confirm.macro.failComparison = Macro {0} has the following comparison criteria deselected:

    {1}

Do you wish to add this macro to the export list?

Selecting "Yes" will result in the macro being exported without the information listed. +confirm.macro.import = The import macro {0} appears to match a macro that already exists {1}. Do you wish to import the macro again?

Select "Yes" to import the macro anyway. Select "No" to cancel import of the macro.

If you believe the macros are not the same, select "No" and verify the commonality criteria of the existing macro on the "Options" tab of its edit dialog. +# {0} is the name of the frame that contains the macro: Global, Campaign, etc. +confirm.macro.panelLocation = within the {0} panel +confirm.macro.reset = You are about to reset all fields of the {0} macro.

Do you wish to continue? +# {0} is the token's Name field +confirm.macro.tokenLocation = on {0} + +defaultTool.barMenu = Bar +defaultTool.ownerMenu = Owner +defaultTool.stateAction.AFK = Away From Keyboard +defaultTool.stateAction.AFK.accel = typed Pause +defaultTool.stateAction.StableHP = Stabilized +defaultTool.stateAction.clear = Clear State +# My campaign has the following states. Putting their descriptions +# here is decidedly obscure. :) There should be fields on the Campaign +# Properties' States tab for this instead. Although it's questionable +# whether user-defined states need to be translated anyway! +# AFK Dead Fly Other4 Song +# Bless Deafened Haste Paralyzed StableHP +# Blind Disabled Hidden Poisoned Staggered +# Bloody25 Dying Incapacitated Prayer Stunned +# Bloody50 EnergyDrained Levitate PrayerFOE Turned +# Bloody75 Enraged Marked Prone Unconscious +# Bloody100 Entangled Other Shield Update +# Confused Fatigued Other2 Sickened +# Dazed Fear Other3 Slowed +defaultTool.stateAction.light = Light... +defaultTool.stateMenu = &State +defaultTool.visionMenu = Vision + +dialog.addresource.downloading = Downloading List ... +dialog.addresource.errorDownloading = Error downloading list. +dialog.addresource.warn.badpath = Invalid path +dialog.addresource.warn.couldnotload = Error while downloading library +dialog.addresource.warn.directoryrequired = Must be a directory +dialog.addresource.warn.filenotfound = Could not find resource "{0}" +dialog.addresource.warn.invalidurl = Invalid URL: {0} +dialog.addresource.warn.musthavename = Must supply a name for the library +dialog.addresource.warn.mustselectone = Must select at least one library to download +dialog.addresource.error.malformedurl = Artpack URL {0} is malformed. Please check your installation. +dialog.addresource.warn.badresourceid = Bad resource identifier: {0}. Report error to MapTool team. +dialog.campaignExport.notes.version.1.4.0.0 = Exporting to this version will strip out any drawables and any campaign settings for Lumens.
Tokens with VBL will loose this functionality as well as any Always Visible values.
Merged Drawings will still be present but their label in Draw Explorer will not show as normal.

Note: Macros will remain unchanged, so any reference to newer functionality not available in this version will cause normal errors when ran. +dialog.campaignExport.notes.version.1.4.0.1 = Exporting to this version will strip out any campaign settings for Lumens.
Tokens with VBL will loose this functionality as well as any Always Visible values.
Merged Drawings will still be present but their label in Draw Explorer will not show as normal.

Note: Macros will remain unchanged, so any reference to newer functionality not available in this version will cause normal errors when ran. +dialog.campaignExport.notes.version.1.4.1..1.5.0 = Exporting to this version will make sure the former format of the content.xml inside the campaign file is kept and the unitsPerCell value for zones/maps is an integer (vs. double in the newer versions). +dialog.campaignExport.notes.version.1.5.1 = Exporting to this version will make sure the former format of the content.xml inside the campaign file is kept. +dialog.campaignexport.error.invalidversion = Unable to export, an invalid version number was detected. +dialog.colorChooser.title = Choose Colour +dialog.copyZone.msg = New map name: +# {0} is the current map name +dialog.copyZone.initial = Copy of {0} +dialog.resizeStamp.title = Automatically Resize Stamp +dialog.resizeStamp.checkbox.horizontal.anchor = Adjust Horizontal Anchor? +dialog.resizeStamp.checkbox.vertical.anchor = Adjust Vertical Anchor? +dialog.resizeStamp.label.height = Height: +dialog.resizeStamp.label.height.selected = Number of Vertical Cells Selected: +dialog.resizeStamp.label.px = px +dialog.resizeStamp.label.stampDimensions = Stamp Dimensions +dialog.resizeStamp.label.width = Width: +dialog.resizeStamp.label.width.selected = Number of Horizontal Cells Selected: +dialog.resizeStamp.toolTip = Adjust the Anchor point so when snapping to grid, the grid aligns. Useful when the left edge of the stamp has a partial cell. +dialog.screenshot.error.failedExportingImage = Failed to export image. +dialog.screenshot.error.failedImageGeneration = Failed to generate image. +dialog.screenshot.error.invalidDialogSettings = Invalid dialog settings... Please report bug! +dialog.screenshot.error.mustSelectView = Must select a view. +dialog.screenshot.error.negativeFogExtents = Error computing fog extents... Please send campaign for debugging. +dialog.screenshot.error.noArea = Screenshot has no area. +dialog.screenshot.layer.button.uiImplementationError = Enums in class do not match Abeille form variables. Please report bug. +dialog.screenshot.msg.GeneratingScreenshot = Generating screenshot. +dialog.screenshot.msg.screenshotSaved = Screenshot saved +dialog.screenshot.msg.screenshotSaving = Screenshot saving +dialog.screenshot.msg.screenshotStreaming = Screenshot streaming +dialog.screenshot.radio.button.uiImplementationError = Enums in class do not match Abeille form variables. Please report bug. +dialog.stampTool.error.badSelection = Please create a larger selection area. +dialog.stampTool.error.noSelection = Please select an area that starts and stops over the token. +dialog.mapProperties.title = Map Properties +dialog.importedMapProperties.title = Imported Map Properties + +dungeondraft.import.unknownFormat = Unrecognized format value in Universal VTT file: {0}. +dungeondraft.import.missingFormatField = No format specifier found. Invalid file format. +dungeondraft.import.ioError = IO Error importing map. +dungeondraft.import.missingResolution = Resolution field missing in import file. +dungeondraft.import.missingPixelsPerGrid = Pixels per grid field missing in import file. +dungeondraft.import.image = Image field missing in import file. +dungeondraft.import.lightsIgnored = Some lights where ignored as X,Y co-ordinates where missing. + + +emit.description = Broadcast text to all connected players without indicating who sent it (GM only command). + +emote.description = Broadcast an emote to all connected players. + +emoteplural.description = Broadcast plural emote to all connected players. + +experiments.description = Start experimental features. +# Experimental features +experiments.listTitle = Experimental Features (use at own risk). + +# Filename extension descriptions +# (These should be more consistent. Maybe in 1.4. Sigh.) +file.ext.cmpgn = MapTool Campaign +file.ext.mtmacro = MapTool Macro +file.ext.mtmacset = MapTool Macro Set +file.ext.mtprops = MapTool Campaign Properties +file.ext.mttable = MapTool Table +file.ext.rpmap = MapTool Map +file.ext.rptok = MapTool Token +file.ext.dungeondraft = Universal VTT Map (.dd2vtt, .df2vtt, .uvtt) +file.ext.addOnLib = Maptool Add-On Library + +goto.description = Goto location or token. /goto X,Y or /goto tokenname. + +help.description = Display list of available commands. +help.header.aliases = Aliases +# Next three are for the titles generated in the table of commands in /help +help.header.command = Slash Command +help.header.description = Description + +impersonate.description = Speak as if you were something/one else. +impersonate.mustOwn = Only {0}''s owners can impersonate or run macros on it. + +initPanel.addAll = Add All +initPanel.addPCs = Add PCs +initPanel.center = Center On Map +initPanel.clearInitState = Clear Initiative +initPanel.displayMessage = {0} has received initiative. +initPanel.enterState = Enter the initiative for {0}: +initPanel.enterStateMany = Enter the initiative for the selected tokens: +initPanel.initStateSecondLine = Initiative on Line 2 +initPanel.makeCurrent = Make Current +initPanel.moveDown = Move Down +initPanel.moveUp = Move Up +initPanel.next = Next +initPanel.next.description = Move the initiative to the next token. +initPanel.prev = Previous +initPanel.prev.description = Move the initiative to the previous token. +initPanel.remove = Remove Token +initPanel.removeAll = Remove All +# Initiative Panel +initPanel.round = Round: +initPanel.round.description = Reset the Round counter and clear current initiative. +initPanel.setInitState = Set Initiative... +initPanel.showInitStates = Show Initiative +initPanel.showTokenStates = Show Token States +initPanel.showTokens = Show Tokens +initPanel.sort = Sort +initPanel.sort.description = Sort the list by initiative values. Uses Descending order by default, with any non-numeric values coming after any numbers, and any blank values coming last. +initPanel.toggleHideNPCs = Hide NPCs +initPanel.toggleHideNPCs.description = When enabled, players will not see any NPC tokens in this list. +initPanel.toggleHold = Toggle Hold +initPanel.toggleHold.description = Toggle Hold for selected token. +initPanel.toggleMovementLock = Lock Movement +initPanel.toggleMovementLock.description = When enabled, only the token with initiative can be moved (unless by GMs). +initPanel.toggleOwnerPermissions = Owner Permissions +initPanel.toggleOwnerPermissions.description = Allow players with token ownership to add/remove their tokens, and use the Next button when it is their turn. +initPanel.toggleReverseSort = Use Reverse Sort Order +initPanel.toggleReverseSort.description = Use the Reverse (Ascending) Order when Sorting from this menu. +initPanel.togglePanelButtonsDisabled = Disable Panel Buttons +initPanel.togglePanelButtonsDisabled.description = Disable the Next/Previous buttons on the Initiative Panel. Useful to prevent mistakes when managing initiative through other macros. +initPanel.buttonsAreDisabled = Panel buttons have been disabled by GM. + +# Initiative menu on the token popup. +initiative.menu = Initiative +initiative.menu.add = Add +initiative.menu.addToInitiative = Add To Initiative +initiative.menu.clearState = Clear Initiative +initiative.menu.enterState = Set the initiative for selected tokens: +initiative.menu.hold = Hold +initiative.menu.remove = Remove +initiative.menu.resume = Resume +initiative.menu.setState = Set Initiative... + + +layer.token = Token +layer.gm = Hidden +layer.object = Object +layer.background = Background + +lightDialog.cancel = &Cancel +lightDialog.off = O&ff +lightDialog.ok = &OK + +lineParser.atTokenNotFound = Macro not found: "{0}@token". +lineParser.badOptionFound = Bad option found! Options String = "{0}", Roll String = "{1}". +# {0} is the roll options string. +lineParser.badRollOpt = Bad Roll option "{0}". +lineParser.countNonNeg = Count option requires a non negative number, got {0}. +# {0} = token name or gm name. +# Notice there are no double quotes around {0}. +lineParser.dialogTitle = Input Value for {0}. +lineParser.dialogTitleNoToken = Input Value. +lineParser.dialogValueFor = Value For "{0}" +lineParser.duplicateLibTokens = Duplicate "{0}" tokens found. +lineParser.emptyTokenName = Cannot assign a blank or empty string to the variable token.name +lineParser.errorBodyRoll = Error in body of roll. +# {0} = the error, {1} = the expression +lineParser.errorExecutingExpression = {0} error executing expression {1}. +# {0} = the option (e.g. FOR, COUNT), {1} = error message. +# Notice that {1} doesn't have quotes around it. +lineParser.errorProcessingOpt = Error processing "{0}" option: {1}. +lineParser.errorStmtBody = Statement Body +lineParser.errorStmtBodyFirst200 = Statement Body (first 200 characters) +lineParser.errorStmtOpts = Statement options (if any) +lineParser.forNoZeroStep = Step size for FOR loop cannot be zero. +lineParser.forVarMissing = FOR: variable missing. +lineParser.foreachVarMissing = FOREACH: variable missing. +lineParser.ifError = Error in roll for IF option. +lineParser.invalidCondition = Invalid condition in {0}({1}) roll option. +lineParser.invalidExpr = Invalid expression: {0}. +lineParser.invalidIfCond = Invalid IF condition: {0}, evaluates to: {1}. +lineParser.invalidMacroLoc = Must specify a location for the macro "{0}" to be run from. +lineParser.invalidWhile = Invalid condition in WHILE({0}) roll option. +lineParser.libUnableToExec = Unable to execute macro from "{0}": not visible to player. +lineParser.cantAssignToConstant = Constant "{0}" is not a valid assignment target. +# MapToolLineParser errors +# Note that many of the errors detected by the line parser will include +# single and/or double quotes. That means we don't want to add any here +# unless we are absolutely sure that they should always be printed and +# will be useful to the user. Don't change these without testing... +lineParser.maxRecursion = Maximum recurse limit reached. +lineParser.nonDefLoopSep = To specify a non-default loop separator, you must use the format "FOR(var,start,end,step,separator)" +lineParser.notALibToken = Macros from other tokens are only available if the token name starts with "Lib:". +lineParser.notValidNumber = "{0}" is not a valid number. +lineParser.notValidVariableName = "{0}" is not a valid variable name. +# Map Tool Variable Resolver +lineParser.onlyGMCanGet = Only GM can get "{0}". +lineParser.onlyGMCanSet = Only GM can set "{0}". +lineParser.optBadParam = Roll option "{0}": bad option parameters {1}. +lineParser.optRequiresParam = Roll option "{0}" requires a list of no more than {1} parameters in parentheses. +lineParser.optReservedName = Roll option "{0}": "{1}" is a reserved name. +lineParser.optWrongParam = Roll option "{0}" must have between {1} and {2} parameters; found {3}: parameter list = "{4}" +lineParser.rollOptionComma = Roll option list can't end with a comma. +lineParser.switchError = Error in roll for SWITCH option. +lineParser.switchNoMatch = SWITCH option found no match for "{0}". +lineParser.tooManyLoops = Too many loop iterations (possible infinite loop?) +lineParser.unknownCampaignMacro = Unknown campaign macro "{0}". +lineParser.unknownGlobalMacro = Unknown global macro "{0}". +lineParser.unknownLibToken = Unknown library token "{0}". +lineParser.unknownMacro = Unknown macro "{0}". +lineParser.unknownOptionName = Unknown option name "{0}". +lineParser.unresolvedValue = Unresolved value "{0}". + +# Notice that the error messages don't have double quotes around them... +# +# {0} is the file name +loadaliases.cantFindFile = Could not find alias file: "{0}" +# {0} is the error message +loadaliases.couldNotLoad = Could not load alias file: {0} +loadaliases.description = Load a file that contains aliases, one per line, with a : between the name and the value (just as if you were typing it in). +loadaliases.dialogTitle = Load Aliases +loadaliases.ignoring = Ignoring alias "{0}" +loadaliases.loading = Loading aliases: + +# {0} is the file name +loadtokenstates.cantFindFile = Could not find token states file: "{0}" +# {0} is the error message +loadtokenstates.couldNotLoad = Could not load token states file: {0} +loadtokenstates.description = Load all of the token states from a file. +loadtokenstates.dialogTitle = Load Token States +# {0} is the number of states loaded +# Note that this numeric value is declared as such. This is to provide +# for localization support, i.e. in English adding a comma in the thousands +# position and a period for the decimal separator (it's a whole number though, +# so there will never be a decimal point). +loadtokenstates.loaded = There were {0,number} token states loaded. + +lookuptable.couldNotPerform = Could not do table lookup: "{0}" +lookuptable.description = Run a table lookup. Usage: /tbl [value to lookup, can be a dice roll] +lookuptable.specifyTable = Must specify a table + +macro.function.LookupTableFunctions.invalidSize = Invalid image size in function "{0}". +macro.function.LookupTableFunctions.noImage = No Image available in function "{0}" for table "{1}". +# LookupTableFunctions +macro.function.LookupTableFunctions.unknownTable = Unknown table name "{1}" in function "{0}". +macro.function.MacroFunctions.missingCommand = "{0}": Missing command. +macro.function.MacroFunctions.missingLabel = "{0}": Missing label. +macro.function.MacroFunctions.noPerm = "{0}": You do not have permissions to edit macro button at index {1} on token {2}. +macro.function.MacroFunctions.noPermOther = "{0}": You do not have permissions to edit macro button {1} at index {2} on token {3}. +macro.function.MacroFunctions.noPermMove = "{0}": You do not have permissions to move macro button {1} at index {2}. +macro.function.MacroFunctions.noPermCommand = "{0}": You do not have permissions to change the command of macro button at index {1} on token {2}. +macro.function.MacroFunctions.noPermEditable = "{0}": You do not have permissions to change the player editable status of macro button at index {1} on token {2}. +macro.function.MacroFunctions.outOfRange = "{0}": Macro at index {1} does not exist for token {2}. +macro.function.TokenInit.notOnList = The token is not in the initiative list. +# TokenInitFunctions +macro.function.TokenInit.notOnListSet = The token is not in the initiative list so no value can be set. +# abort Function +# Note that I'm leaving off the double quotes on this one. I think it +# will look better that way. +macro.function.abortFunction.messge = {0} function called. +# addAllToInitiativeFunction +macro.function.addAllToInitiativeFunction.mustBeGM = Only the GM has the permission to execute the "{0}" function. +# MacroArgsFunctions +macro.function.args.incorrectParam = Function "{0}" must be called with exactly 1 numeric parameter. +macro.function.args.outOfRange = Argument index {1} out of range (max of {2}) in function "{0}". +# assert Function +# {0} is the error message specified when calling assert() for message. +# Note that I'm leaving off the double quotes on this one, too. I think it +# will look better that way. +macro.function.assert.message = Macro-defined error: {0} +macro.function.assert.mustBeString = Second argument to "{0}": "{1}" must be of type String. +macro.function.defineFunction.functionDefined = "{0}" function defined. +# DefineMacroFunctions +macro.function.defineFunction.notEnoughParam = Not enough parameters for "defineFunction". +# FindTokenFunctions +macro.function.findTokenFunctions.offsetArray = Offset array for Area must contain JSON object with (x,y) coordinates in function "{0}". +macro.function.findTokenFunctions.unknownEnum = Program error: unknown enum "{1}" in switch block in function "{0}". +macro.function.general.accessDenied = Access is denied for the "{0}" function. Enable access via Preferences option. +macro.function.general.argumentKeyTypeA = Argument key "{1}" to function "{0}" must be a JSON Array. +macro.function.general.argumentKeyTypeD = Argument key "{1}" to function "{0}" must be an number. +macro.function.general.argumentKeyTypeG = Argument key "{1}" to function "{0}" must be a GUID. +macro.function.general.argumentKeyTypeI = Argument key "{1}" to function "{0}" must be an integer. +macro.function.general.argumentTypeA = Argument number {1} to function "{0}" must be a JSON Array. +macro.function.general.argumentTypeI = Argument number {1} "{2}" to function "{0}" must be an integer. +macro.function.general.argumentTypeInvalid = Argument number {1} invalid argument type for function "{0}". +macro.function.general.argumentTypeJ = Argument number {1} to function "{0}" must be a JSON Array or Object. +macro.function.general.argumentTypeN = Argument number {1} "{2}" to function "{0}" must be a number. +macro.function.general.argumentTypeO = Argument number {1} to function "{0}" must be a JSON Object. +macro.function.general.argumentTypeS = Argument number {1} to function "{0}" must be a string. +# {0} = function name, {1} = argument number, {2} = content of argument {1} +macro.function.general.argumentTypeT = Argument number {1} to function "{0}" must be a Token id or name. +macro.function.general.noImpersonated = Error executing "{0}": there is no impersonated token. +# Externalized strings for Macro Functions errors +# +# Unless otherwise specified {0} is the name of the function that was called +# +# General messages used in several functions. +# You'll see {1} and {2} used as numbers, below. Technically they +# should actually be {1,number} and {2,number}. However, there's no +# reason to localize these values as they will always be whole numbers +# so the decimal separator is not needed, and they will always be small +# enough that no thousands separator will be needed either. So leaving +# off the ",number" means they'll be treated as strings and simply +# output as-is. Which is fine. :) +macro.function.general.reservedJS = {0} is a reserved function in the js. prefix. +macro.function.general.noPermJS = You do not have permission to use the "{0}" namespace. +macro.function.general.noPerm = You do not have permission to call the "{0}" function. +macro.function.general.noPermOther = You do not have permission to access another token in the "{0}" function. +macro.function.general.notEnoughParam = Function "{0}" requires at least {1} parameters; {2} were provided. +macro.function.general.onlyGM = Only the GM can call the "{0}" function. +macro.function.general.tooManyParam = Function "{0}" requires no more than {1} parameters; {2} were provided. +macro.function.general.unknownFunction = Unknown function name "{0}". +macro.function.general.unknownToken = Error executing "{0}": the token name or id "{1}" is unknown. +macro.function.general.unknownPropertyType = Error executing "{0}": the property type "{1}" is unknown. +macro.function.general.unknownProperty = Error executing "{0}": the property "{1}" is unknown for type "{2}". +macro.function.general.unknownTokenOnMap = Error executing "{0}": the token name or id "{1}" is unknown on map "{2}". +macro.function.general.wrongNumParam = Function "{0}" requires exactly {1} parameters; {2} were provided. +macro.function.general.listCannotBeEmpty = {0}: string list at argument {1} cannot be empty +# Token Distance functions +# I.e. ONE_TWO_ONE or ONE_ONE_ONE +macro.function.getDistance.invalidMetric = Invalid metric type "{0}". +#getInfo function {0} is the value that was passed in +macro.function.getInfo.invalidArg = Invalid value "{0}" for getInfo(). +# InitiativeRoundFunctions +macro.function.getInitiativeRound.mustBeGM = Only the GM can set the round. +# ExecFunction +macro.function.execFunction.incorrectName = Error executing "{0}": the function name "{1}" is unknown. +# Token Halo functions {0} is the colour +macro.function.haloFunctions.invalidColor = Invalid halo colour "{0}". +macro.function.herolab.null = HeroLab data does not exist for this token. +macro.function.herolab.xpath.invalid = Provided XPath expression "{0}" was invalid or did not point to a text or attribute node. +# Initiative functions general errors +macro.function.initiative.gmOnly = Only the GM can perform "{0}". +macro.function.initiative.gmOrOwner = Only the GM or owner can perform "{0}". +macro.function.initiative.noImpersonated = Error executing initiative function: there is no impersonated token. +macro.function.initiative.oneParam = Must call "{0}" with one parameter. +macro.function.initiative.unknownToken = Unknown token id "{0}" on map "{1}". +macro.function.input.illegalArgumentType = Illegal argument type "{0}", expecting "{1}". +macro.function.parse.enum.illegalArgumentType = Error executing "{0}": Illegal argument type "{1}", expecting one of "{2}". +# {0} = the option key, {1} = the option value, {2} = the option propertyType, {3} = the option specifier +macro.function.input.invalidOptionType = The option "{0}={1}" is invalid for input type "{2}" in specifier "{3}". +#input function +macro.function.input.invalidSpecifier = Empty variable name in the specifier string "{0}". +macro.function.input.invalidTAB = To use inputType of TAB in input(), the first entry must have the TAB type. +macro.function.input.invalidType = Invalid input type "{0}" in the specifier string "{1}". +macro.function.json.append.onlyArray = You can only append to the end of JSON Arrays. +macro.function.json.arrayMustContainObjects = Fields specified for json.sort but not all items in array are JSON objects; found "{0}". +macro.function.json.arrayCannotBeEmpty = {0}: JSON Array at argument {1} cannot be empty +macro.function.json.getInvalidEndIndex = Invalid end index "{1}" for array (size of {2}) in function "{0}". +macro.function.json.getInvalidStartIndex = Invalid start index "{1}" for array (size of {2}) in function "{0}". +macro.function.json.matchingArrayOrRoll = The 3rd argument must be a string containing a roll or a JSON array the same size as the 2nd argument. +macro.function.json.notAllContainKey = Not all objects contain field "{0}" in json.sort. +macro.function.json.arrayArgMustBeNumber = Argument number {2} to {1} must be a number for JSON Arrays. +macro.function.json.indentMustBeNumeric = Indentation value passed to {0} must be numeric +# General JSON macro function errors +macro.function.json.onlyArray = Got {0} but "{1}" only accepts JSON Arrays. +macro.function.json.onlyJSON = Got {0} but "{1}" only accepts JSON Arrays or Objects. +macro.function.json.onlyObject = Got {0} but "{1}" only accepts JSON Objects. +macro.function.json.setNoMatchingValue = No matching value for key in "{0}". +macro.function.json.unknownType = Unknown JSON type "{0}" in function "{1}". +macro.function.json.path = Error with function "{0}": {1} +macro.function.macroLink.arguments = Arguments +# Informational messages for Macro functions. +macro.function.macroLink.autoExecToolTip = Auto Execute Macro Link +# {0} is the error message +macro.function.macroLink.errorRunning = Error Running Macro Link: "{0}" +macro.function.macroLink.executeOn = Execute On +macro.function.macroLink.impersonated = Impersonated Tokens +# MacroLinkFunctions +macro.function.macroLink.missingName = Missing macro name in function "{0}". +macro.function.macroLink.selected = Selected Tokens +macro.function.macroLink.unknown = Unknown +macro.function.map.none = {0}: function requires a current map, but none is present. +# {0} is the function name +macro.function.map.notFound = {0}: indicated map in first parameter not found. +macro.function.map.invalidAsset = {0}: "{1}" is not a valid asset ID or URL +# {0} is the function name +macro.function.moveTokenMap.alreadyThere = Can not use "{0}" to move tokens to a map that they are already on! +# {0} is the token name/id, {1} is the map it's moved to. +macro.function.moveTokenMap.movedToken = Moved Token "{0}" to map "{1}" from map "{2}". +# moveTokenToMap/moveTokenFromMap, {0} is the function name, {1} is the +# map name or token id +macro.function.moveTokenMap.unknownMap = Can not find map "{1}" in function "{0}". +macro.function.moveTokenMap.unknownToken = Can not find token "{1}" in function "{0}". +# number function +macro.function.number.invalid = Invalid number format "{1}" in "{0}". +# RESTful Function Errors +macro.function.rest.error.response = Unable to process function "{0}", HTTP Status Code: {1} +macro.function.rest.error.unknown = Unable to process function "{0}", An Exception has occurred: {1} +macro.function.rest.syrinscape.error = Unable to launch Syrinscape. Check that Syrinscape is installed and a proper URI was passed. +# [token():...] roll option +macro.function.roll.noPerm = You do not have enough permissions to run the [token(...): ...] roll command. +macro.function.stateImage.notImage = State "{1}" is not an image state in function "{0}". +# StateImageFunction {1} is the state name +macro.function.stateImage.unknownState = Unknown state "{1}" in function "{0}". +macro.function.barImage.notImage = Bar "{1}" is not an (multi-)image bar in function "{0}". +# BarImageFunction {1} is the state name +macro.function.barImage.unknownBar = Unknown bar "{1}" in function "{0}". +macro.function.strLst.incorrectParam = "{0}" requires between {1} and {2} parameters. +# String List +macro.function.strLst.incorrectParamExact = "{0}" requires exactly {1} parameters. +# {0} = function name, {1} = argument number, {2} = expected propertyType, +# {3} = value user passed, {4} = propertyType of the value user passed. +macro.function.strLst.incorrectParamType = Argument number {1} to function "{0}" must be type "{2}", but was passed "{3}" of type "{4}". +macro.function.strPropFromVar.wrongArgs = strPropFromVars second parameter "{0}" is invalid. +macro.function.sound.illegalargument = Error executing "{0}", parameter "{1}" is invalid: {2} +macro.function.sound.mediaexception = Error executing "{0}" with media "{1}" +macro.function.syrinscape.inactive = This client has not enabled Syrinscape integration in preference. +# TokenLightFunctions +macro.function.tokenLight.unknownLightType = Unknown light type "{1}" in function "{0}". +# name setting functions +macro.function.tokenName.emptyTokenNameForbidden = Error executing "{0}": the token name cannot be empty. +# TokenPropertyFunctions +macro.function.tokenProperty.invalidSize = Invalid token size "{1}" in function "{0}". +macro.function.tokenProperty.unknownLayer = Unknown layer "{1}" in function "{0}". +macro.function.tokenProperty.unknownLibToken = Unknown Lib: token "{1}" in function "{0}". +macro.function.tokenProperty.unknownPropType = Unknown property type "{1}" in function "{0}". +# CopyTokenFunctions +macro.function.tokenCopy.oxymoronicParameters = In "{0}": Parameters "delta" and "relativeto" can't be used at the same time. ("delta" parameter is deprecated as of 1.9.0). Visit https://wiki.rptools.info/index.php/copyToken +macro.function.tokenCopy.noCurrentToken = No current token found. Try using switchToken() or impersonate one. See https://wiki.rptools.info/index.php/Current_Token +macro.function.tokenCopy.unrecognizedRelativeValue = In "{0}": "relativeto" value within 4th parameter (json properties) not recognized. Visit https://wiki.rptools.info/index.php/copyToken +macro.function.tokenCopy.invalidPropertyType = The property type {0} does not exist in the campaign properties. +# TokenStateFunctions +macro.function.tokenStateFunctions.unknownState = Unknown state "{0}". +# TokenBarFunction +macro.function.tokenBarFunction.unknownBar = Error with function "{0}": unknown bar "{1}". +# String Property +# {0} = value the user passed. +macro.function.varsFromstrProp.wrongArgs = varsFromStrProp called with 3 arguments, but second argument "{0}" was not one of NONE, SUFFIXED, or UNSUFFIXED. +macro.function.tokenCopyDelete.noName = No name specified for token. +macro.function.tokenCopyDelete.noImage = No image specified for token. + +macro.function.markdown.unknownType = Unknown Markdown type {0}. + +macro.function.html5.invalidURI = Invalid URI {0}. +macro.function.html5.unknownType = Unknown HTML5 Container specified. +macro.function.jsevalURI.invalidURI = Can not access JavaScript from URI {0}. + +macro.setAllowsURIAccess.notLibToken = {0} is not a valid lib:token name, URI access can only be set on lib:tokens. +macro.setAllowsURIAccess.reservedPrefix = Can not set URI access on lib:tokens starting with {0} +macro.setAllowsURIAccess.reserved = Can not set URI access on lib:token named {0} +# Macro Link +macroLink.error.running = Error running macro link. +macroLink.error.tooltip.bad.href = Invalid or missing HREF + +macromanager.alias.indexNotFound = (error: "{0}" is not found) +# {0} is the command, {1} is the exception +macromanager.couldNotExecute = Could not execute the command: "{0}", exception = {1} +# {0} is the command +macromanager.tooManyResolves = Too many resolves running "{0}"; perhaps an infinite loop? +macromanager.ambiguous = Command {0} is ambiguous, please specify the namespace as well, matching options are: + +menu.QuickMap = Quick Map +menu.edit = &Edit +menu.export = Export +menu.file = &File +menu.help = &Help +menu.map = &Map +menu.overlay = &Overlays +menu.recent = &Recent Campaigns +menu.tools = &Tool +menu.view = &View +#action.enableVision=Use Vision +#action.enableVision.description=Use the Vision Blocking Layer on this map +menu.vision = Vision +menu.window = &Window +menu.zoom = &Zoom + + +dragdrop.unsupportedType = MapTool does not support adding this file type to the campaign. + + +msg.button.close = Close +msg.commandPanel.hasEnteredText = {0} has entered text. +# Command Panel; {0} is the player name +msg.commandPanel.liveTyping = {0} is typing... +msg.commandPanel.cheater.self = Cheater. You have been reported. +# {0} is the player name, {1} is their input +msg.commandPanel.cheater.gm = {0} was caught cheating: {1} +msg.commandPanel.div = Unexpected </div> tag without matching <div>. +msg.confirm.aboutToBeginFTP = About to begin FTP process of {0,number} file(s)... +msg.confirm.bootPlayer = Are you sure you want to boot {0}? +msg.confirm.campaignExported = Campaign exported. +msg.confirm.clearAllDrawings = This will clear all drawings on layer {0} and completely empty the undo queue for ALL layers.
This cannot be undone. Are you sure? +msg.confirm.deleteDraw = Are you sure you want to delete the selected drawings? +msg.confirm.deleteDraw.removed = This will no longer ask for permission when deleting drawing. If you want to turn this back on look in Preferences. +msg.confirm.deleteToken = Are you sure you want to delete the selected tokens? +msg.confirm.deleteToken.removed = This will no longer ask for permission when deleting tokens. If you want to turn this back on look in Preferences. +msg.confirm.disconnecting = You will be disconnected. Are you sure you want to exit? +msg.confirm.fileExists = Overwrite existing file? +msg.confirm.hostingDisconnect = You are hosting a server. Disconnecting will disconnect all connected clients.
Are you sure? +msg.confirm.jvm.options = Some Java JVM startup options for MapTool may have changed.
You will need to restart MapTool before these will take affect.

Invalid settings could prevent MapTool from starting, are you sure you wish to save these settings? +msg.confirm.legacySave = You are saving in an old format -- you may lose some information by doing this. Continue? +msg.confirm.loseChanges = Changes to your campaign will be lost. Continue? +msg.confirm.newCampaign = Discard current campaign? +msg.confirm.webServerStartTitle = Start Experimental Web App? +msg.confirm.webServerStart =
\ + If you did not start the server press cancel\ +

The experimental Server App is deprecated and will be removed \ + in an upcoming version.

If you currently make use of this feature please \ + visit discord channel to let us know how you are using it so we can \ + include this in our plans for its replacement

\ +

(link will appear in chat after server has started)

+ +msg.confirm.newerVersion = You are attempting to load a campaign created by MapTool {1}.
There may be loading errors because you are running version {0}.

Are you sure? +msg.confirm.overwriteExistingCampaign = That file already exists. Overwrite? +# Notice in this message how {0} is used twice? The first one is a +# Date object interpreted as a time, and the second one is a Date object +# interpreted as a date. +msg.confirm.recoverAutosave = An autosave file created at {0,time} on {0,date} exists.
Would you like to retrieve it? +msg.confirm.removeFacings = Are you sure you want to delete the facing of the selected tokens? +msg.confirm.removeZone = Removing a map cannot be undone.
Are you sure? +msg.confirm.renameMap = Rename "{0}"? +msg.confirm.restoreFoW = Map contains exposed areas of fog.
Do you want to reset all of the fog? +msg.confirm.saveCampaign = Would you like to save your campaign before you exit? +msg.error.alreadyRegistered = That ID is already in use -- server not registered. +msg.error.alreadyRunningServer = You are already running a server. +msg.error.browser.cannotStart = Browser could not be started.
{0} +msg.error.browser.notFound = System browser could not be identified.
Please specify your system browser in the {0} environment variable. +msg.error.cantAdjustGridInfMaps = Cannot adjust grid on infinite maps. +msg.error.cantApplyMacroToSelected = Commonality of this macro is not based on the command field. The macro cannot be applied to the entire selection set. +msg.error.cantBootGM = You can't boot another GM. +msg.error.cantBootSelf = You can't boot yourself. Disconnect the server via the File menu. +msg.error.credits = Unable to load credits or version. +msg.error.creatingBackupManager = Error creating BackupManager. +msg.error.dialog.js.id = Error executing "{0}": the Javascript identifier "{1}" is invalid. +msg.error.dialog.js.name = Error executing "{0}": the {1} named {2} does not exist or cannot run Javascript. +msg.error.dialog.js.type = Error executing "{0}": the html type "{1}" is invalid. +msg.error.errorResolvingCacheDir = Error resolving cache dir for id {0}, error = {1} +msg.error.frame.reservedName = {0} is a reserved name and can not be used by macros. +# token naming errors +msg.error.emptyTokenName = The token name cannot be blank. +msg.error.evaluatingExpr = Error evaluating expression: {0} +msg.error.failedAddingDefaultImages = Could not restore default images. +msg.error.failedAddingDefaultTables = Could not restore default tables. +msg.error.failedCannotRegisterServer = Unable to register your server. +msg.error.failedConnect = Could not connect to server. +msg.error.fetchingRegistryInformation = Error fetching server information from registry. +msg.error.initializeCrypto = Failed to initialize Cryptology library. +msg.error.initializePlayerDatabase = Failed to initialize Player Database. +msg.error.failedExportingCampaignRepo = Could not export campaign repository file. +msg.error.failedExportingImage = Could not export image. +msg.error.failedLoadCampaign = Could not load campaign. +msg.error.failedLoadCampaign_Timeout = Could not load campaign; timeout waiting for autosave to complete. +msg.error.failedLoadMap = Could not load map. +msg.error.failedLoadCampaignLock = Could not load campaign while background task is active. Try again later. +msg.error.failedSaveCampaignLock = Could not save campaign while background task is active. Try again later. +msg.error.failedSaveCampaign = Could not save campaign. +msg.error.failedSaveCampaignOOM = Out of memory while saving campaign!

Try creating a new/empty map and perform the save with that map active. +msg.error.failedSaveCampaignPreview = Could not save the campaign preview image. +msg.error.failedSaveMap = Could not save map. +msg.error.failedSavingNewVersion = Could not save the new version. +msg.error.fileAlreadyExists = File {0} already exists. +msg.error.directoryNotWriteable = Directory {0} is not writeable. +# When the user attempts to save the chat log and we fail, it's an Error. +# When we try to autosave the chat log and fail, it's a Warning. +# It's all about the semantics, baby. ;-) +msg.error.failedSavingMessageHistory = Could not save message history. +msg.error.failedScreenCapture = Could not get screen capture. +msg.error.failedStartPersonalServer = Could not restart personal server. +msg.error.failedToBoot = Boot attempt failed: player not found. +msg.error.failedUpdatingCampaignRepo = Could not update campaign repository; I/O error. +msg.error.inaccessibleRepo = Repository not available: "{0}". +msg.error.host.inaccessibleRepo = The following repositories are not available: \n{0}\nTo change or remove an invalid repo, go to Campaign Properties and edit the Repositories list. +msg.error.fileNotFound = File Not found. +msg.error.fogexpose = Must be a GM to change the fog of war. +msg.error.gmRequired = Only GMs can do that. +msg.error.invalidLocalhost = "localhost" is not a valid address?! Check your /etc/hosts file. +msg.error.renderingStatSheet = Error while trying to render stat sheet. +msg.error.encryptionSetup = Unable to initialize encryption library. +# JVM Related +msg.error.jvm.options = "{0}" is an invalid memory setting.

Be sure to enter a valid Java JVM value that includes a memory size that ends in K, M, or G.
e.g. 4M, 6G, 2048M, 1024K, etc.

Warning: An improper setting could prevent MapTool from starting. +msg.error.lafSetup = Exception during look and feel setup. +msg.error.cantLoadThemeTitle = Unable to load theme +msg.error.cantLoadTheme = Unable to load theme {0}, using default theme. +msg.error.cantSaveTheme = Unable to save theme details. +msg.error.layoutInitial = Could not load the initial layout. +msg.error.layoutParse = Error parsing the layout file. +msg.error.loadingIconImage = Could not load icon image. +msg.error.loadingQuickMaps = Error loading quickmaps. +msg.error.copyingStartupConfig = Error copying Startup Configuration file. +msg.error.copyingStartupConfig.unixLike = Can not copy configuration file, see Preferences -> Startup for details. +msg.error.macro.buttonGroupDnDFail = Drag & Drop problem +msg.error.macro.buttonPropsAreNull = Button properties are null. +msg.error.macro.buttonNullToken = Macro {0} cannot be saved; token {1} no longer valid. +msg.error.macro.exportFail = Macro could not be exported:

{0} +msg.error.macro.exportSetFail = Macro set could not be exported:

{0} +msg.error.macro.importFail = Macro could not be imported:

{0} +msg.error.macro.importSetFail = Macro set could not be imported:

{0} +msg.error.mtprops.light.arc = Light:line {0,number}:unrecognizable arc "{1}" +msg.error.mtprops.light.definition = Error(s) in Light definitions. Correct error(s) or select Cancel on the Campaign Properties dialog. +msg.error.mtprops.light.distance = Light:line {0,number}:unrecognizable distance "{1}" +msg.error.mtprops.light.gmOrOwner = Light:line {0,number}:GM and OWNER can only be specified for auras. +msg.error.mtprops.light.ioexception = Error reading Light definition from string -- shouldn't happen! +msg.error.mtprops.light.lumens = Light:line {0,number}:unrecognizable lumens "{1}" +msg.error.mtprops.light.zerolumens = Light:line {0,number}: lumens must not be zero +msg.error.mtprops.properties.duplicate = Property name in "{0}" duplicates the one in "{1}". +msg.error.mtprops.properties.duplicateComment = The line "{0}" appears to be a comment, but duplicates "{1}" and must be unique to prevent this warning. +msg.error.mtprops.properties.ending = You will be placed back into edit mode. +msg.error.mtprops.properties.title = The following errors occurred: +msg.error.mtprops.sight.arc = Sight:line {0,number}:unrecognizable arc "{1}" +msg.error.mtprops.sight.definition = Error(s) in Sight definitions. Correct error(s) or select Cancel on the Campaign Properties dialog. +msg.error.mtprops.sight.distance = Sight:line {0,number}:unrecognizable distance "{1}" +msg.error.mtprops.sight.ioexception = Error reading Sight definition from string -- shouldn't happen! +msg.error.mtprops.sight.zerolumens = Sight:line {0,number}: lumens must not be zero + +# For parsing anything in the Campaign Properties dialog. Each tab +# should have its own subcategory underneath "msg.error.mtprops" +# Notice how {0} has the ",number" suffix to denote that a numeric +# value is being used by the program; that tells the program how to +# display the result (i.e. this value should be a localized number). +msg.error.mtprops.sight.multiplier = Sight:line {0,number}:unrecognizable multiplier "{1}" +msg.error.mtprops.sight.offset = Sight:line {0,number}:unrecognizable offset "{1}" +msg.error.mtprops.sight.range = Sight:line {0,number}:unrecognizable range "{1}" +msg.error.mtprops.sight.lumensWithoutLight = Sight:line {0,number}:Cannot use field lumens without range for personal light +msg.error.mtprops.sight.unknownField = Sight:line {0,number}:unknown field name "{1}" +msg.error.mustDisconnectFirst = You are connected to a server. Please disconnect. +msg.error.mustSelectAssetGroupFirst = Select an asset group first. +msg.error.mustSelectPlayerFirst = Select a player first. +msg.error.mustSelectRootGroup = Must select a root group. +msg.error.noTokensSelected = No Tokens Selected. +msg.error.playerNotConnected = Player "{0}" is not connected. +msg.error.server.disconnected = Server has disconnected. +msg.error.server.cantrestart = Could not restart personal server. +msg.error.server.upnp.noigd = UPnP Error - No Internet Gateway Devices found.

This means that your router either does not have UPnP enabled, or is incompatible with the version of UPnP used by MapTool.
Your server will still start, but you will need to manually configure port forwarding to allow connections from the outside Internet.

For more details and assistance, please see the Networking Setup guide from the Help menu. +msg.error.tableAccessProhibited = The GM has disallowed player use of table. +msg.error.tableDoesNotExist = No such table. +msg.error.tableUnknown = Unknown table. +msg.error.toolCannotInstantiate = Could not instantiate tool class: {0} +msg.error.toolConstructorFailed = Failed in constructor of tool: {0} +msg.error.toolNeedPublicConstructor = Constructor must be public for tool: {0} +msg.error.toolNeedValidConstructor = Class must have a public constructor with a Toolbox argument for tool: {0} +msg.error.trace = Error trace : {0} +msg.error.udf.tooltip.loading = Error retrieving description for "{0}": {1} +msg.error.udf.tooltip.missingTarget = Error retrieving description for "{0}": target not found. +msg.error.unableToCreateClientIdFile = Can''t create the client id file. +msg.error.unableToCreateDataDir = Can''t create the data directory "{0}". Try manually specifying the data directory by setting the environment variable "MAPTOOL_DATADIR". Search our forums for that name if you need help. +msg.error.unableToReadClientIdFile = Can''t read the client id file. +msg.error.unknownHost = Unknown host. +msg.error.unknownJavaVersion = Cannot determine Java version?! Will attempt to continue anyway... +msg.error.unusableDataDir = Can''t use the data directory "{0}" because it contains potentially dangerous characters. Try manually specifying the data directory by setting the environment variable "MAPTOOL_DATADIR". Search our forums for that name if you need help. +msg.error.unusableDir = Directory "{0}" contains potentially dangerous characters and will not be used. +msg.error.versionFile = Can't find version file: {0} +msg.error.unableToGetThemeList = Error fetching theme list. +msg.error.wrongJavaVersion = You are running MapTool using a version of Java too old to be 100% compatible with some of the third-party libraries used.
If you continue to use MapTool, you may experience unexpected crashes do to this incompatibility. Do you want to continue? + +msg.error.cantStartWebEndPoint = Unable to start the webserver end point, please change the port + +# Errors when dealing with the passwords file +# for missingPasswordsField the "passwords" text should not be translated as its the field name in the file +msg.error.playerNotInDatabase = The specified player {0} does not exist in the database. +msg.error.passFile.missingPasswordsField = Missing "passwords" field in the +msg.error.passFile.errorInJson = Error reading passsword file, invalid JSON. +msg.error.passFile.errorReadingFile = Error reading password file. +msg.error.passFile.errorCopyingBackup = Error while backing up current password file. +msg.error.passFile.errorWritingFile = Error while writing password file. +msg.error.passFile.cantDisablePlayer = Player Database does not support disabling players. +msg.error.passFile.cantSetPlayTimes = Player Database does not support setting play times. +msg.error.passFile.playerExists = {0} already exists. +msg.error.passFile.publicKeyNotFound = Public key not found. +msg.error.passFile.publicKeyWriteFailed = Failed to write public key file {0}. +msg.error.playerDB.errorAdding = Error while trying to add {0} to the player database. +msg.error.playerDB.cantAddPlayer = Can't add player {0} to a database which doesn't support adding players. +msg.error.playerDB.cantAddPlayerPublicKey = Can't add player {0} to a database with public key as its unsupported. +msg.error.playerDB.errorAddingPlayer = Error adding player {0}. +msg.error.playerDB.cantUpdatePlayer = Can't update player {0} for a database that does't support updating. +msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. +msg.error.playerDB.cantRemovePlayer = Can't remove player {0} to a database which doesn't support removing players. +msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. +msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can't load built-in library {0}. + + +msg.info.action.disableFoW = FoW disabled. +msg.info.action.disableRevealFogAtWaypoints = FoW will now expose at all cell points along the path. +msg.info.action.enableFoW = FoW enabled. +msg.info.action.enableRevealFogAtWaypoints = FoW will now only expose at designated waypoints. +msg.info.action.FoWDisabled = FoW is disabled. +msg.info.campaignLoading = Loading Campaign +msg.info.campaignSaved = Campaign Saved. +msg.info.campaignSaving = Saving Campaign +msg.info.connecting = Connecting +msg.info.disconnected = You have disconnected. +msg.info.heartbeat.registryFailure = Connection refresh to the MapTool registry failed (total of {2} failures so far). The registry server will purge records periodically, making it difficult for future clients to connect. If this persists, you will need to provide clients with the server information directly (IP address "{0}" and port {1}). +msg.info.heartbeat.registrySuccess = Connection refresh to the MapTool registry succeeded (after {0} past failures). As long as success is maintained, you will not see this message again. +msg.info.macro.exportCancel = Macro export canceled. +msg.info.macro.exportSuccess = Macro exported successfully. +msg.info.mapLoading = Loading Map +msg.info.mapSaved = Map Saved. +msg.info.noCampaignPreview = No campaign preview available. +msg.info.playerBooted = {0} has been disconnected. +msg.info.playerConnected = {0} has connected. +msg.info.playerDisconnected = {0} is disconnected. +msg.info.restoreLayout = Restore layout +msg.info.restoreLayout.description = Restore the MapTool user interface to the default layout. +msg.info.screenshotSaved = Saved screenshot. +msg.info.screenshotSaving = Saving screenshot... +msg.info.server.forumNFAQ_URL = http://forums.rptools.net/viewtopic.php?f=22&t=3370 +msg.info.server.networkingHelp = Hosting a MapTool server involves proper network setup.
Do you want to visit the forum post that describes this process? +msg.info.showTransferWindow = Show Transfer Window +msg.info.showTransferWindow.description = Open a window showing the pending asset transfers. +msg.info.startServer = Server started; please wait for map to refresh. +msg.info.startWebEndWebPoint = Starting web end point on port {0}. +msg.info.stopWebEndWebPoint = Stopping web end point. +# Some of these don't have the "..." appended to them because the +# code adds that, if appropriate, based on the situation. +msg.info.versionFile = CAN'T FIND VERSION FILE +msg.info.assetsDisabled = The GM has disabled insertion of player assets. + + +msg.title.exportMacro = Export Macro +msg.title.exportMacroSet = Export Macro Set +msg.title.exportProperties = Export Properties +msg.title.importMacro = Import Macro +msg.title.importMacroSet = Import Macro Set +msg.title.importProperties = Import Properties +msg.title.loadAssetTree = Load Asset Tree +msg.title.loadCampaign = Load Campaign +msg.autosave.wait = Waiting up to {0} seconds for autosave to finish... +# I'm trying to add some consistency to the property names. So... +# "msg.title.*" are strings used as the titles of dialogs and frames +# created by the application. +msg.title.loadMap = Load Map +msg.title.messageDialog.cancel = &Cancel +msg.title.messageDialog.continue = Continue +msg.title.messageDialog.dontAskAgain = Yes, and &don't ask me again +msg.title.messageDialog.no = &No +msg.title.messageDialog.ok = &Ok +# Just adding in some choices for s +msg.title.messageDialog.yes = &Yes +msg.title.messageDialogConfirm = Confirmation +msg.title.messageDialogError = Error +msg.title.messageDialogFeedback = Feedback +msg.title.messageDialogInfo = Information +msg.title.messageDialogWarning = Warning +msg.title.saveCampaign = Save Campaign +msg.title.saveMessageHistory = Save Message History +msg.warn.failedAutoSavingMessageHistory = Could not autosave message history. +msg.warning.macro.playerChangesNotAllowed = The GM has not allowed players to change this macro. +msg.warning.macro.willNotExport = The macro "{0}" will not be exported. Either it has been flagged by the GM as not player editable or you do not have ownership privileges over the source. +msg.warning.prerelease.only = Warning {0} is for pre-release testing only and may not be available in the actual release. +msg.warning.loadCampaignFromInstallDir = Saving to the installation directory is not supported. After loading you will need to save to a different location. +msg.warning.saveCampaignToInstallDir = Saving to the installation directory is not supported, please choose a different location to save to. +msg.warning.exportRepoToInstallDir = Exporting Repository to the installation directory is not supported, please choose a different location to save to. +msg.warning.saveTokenToInstallDir = Saving Tokens to the installation directory is not supported, please choose a different location to save to. +msg.warning.saveMapToInstallDir = Saving Maps to the installation directory is not supported, please choose a different location to save to. +msg.warning.saveTableToInstallDir = Saving Tables to the installation directory is not supported, please choose a different location to save to. +msg.warning.savePropToInstallDir = Saving Campaign Properties to the installation directory is not supported, please choose a different location to save to. +msg.warning.saveMacrosToInstallDir = Saving Macros to the installation directory is not supported, please choose a different location to save to. + +msg.error.serverOnly = Function {0} can only be used on the server. + +msg.asset.error.invalidAsset = An invalid asset has been selected. If you get this message please report it on the MapTool forums or Discord server. + +ooc.description = Out-Of-Character chat + +panel.Asset.ImageModel.checkbox.extractRenderedPages = Render Pages +panel.Asset.ImageModel.checkbox.tooltip.extractRenderedPages = Extract each page from PDF to a single image. +panel.Asset.ImageModel.checkbox.searchSubDir1 = Search subdirectories? +panel.Asset.ImageModel.checkbox.searchSubDir2 = results +panel.Asset.ImageModel.slider.toolTip = Slide to adjust the thumbnail preview size... +panel.Asset.Mouseover.dimensions = Dimensions: {0} x {1} +panel.Asset.Mouseover.type = Type: {0} +panel.Asset.Mouseover.size = Size: {0} + +panel.Campaign = Campaign +panel.Campaign.description = Dockable window for Campaign macros. +panel.Gm = GM +panel.Gm.description = Dockable window for GM-visible macros +panel.Chat = Chat +panel.Chat.description = Dockable chat window. +panel.Connections = Connections +connections.tab.connected = Connected +connections.tab.pending = Pending +connections.playerIsInZone = {0} is in zone {1}. +connections.playerIsLoadingZone = {0} is loading zone {1}. +pendingConnection.label.playerName = Name +pendingConnection.label.pin = PIN +pendingConnection.column.title = Players attempting to connect +pendingConnection.sendPublicKey.title = Sending Public Key to Server +pendingConnection.sendPublicKey = Sending public key to server, let the GM know \ + your PIN is {0} so they can approve your connection. +panel.Connections.description = Dockable window showing connected clients. +panel.DrawExplorer = Draw Explorer +panel.DrawExplorer.description = Dockable window for managing drawings. +panel.DrawExplorer.LineSegment.Line = points({0}) pen width({1}) +panel.DrawExplorer.ShapeDrawable.Area = width({0}) height({1}) +panel.DrawExplorer.ShapeDrawable.Float = width({0}) height({1}) +panel.DrawExplorer.ShapeDrawable.Polygon = width({0}) height({1}) +panel.DrawExplorer.ShapeDrawable.Rectangle = width({0}) height({1}) +panel.DrawExplorer.Template.BlastTemplate = Blast ({0}) +panel.DrawExplorer.Template.BurstTemplate = Burst ({0}) +panel.DrawExplorer.Template.ConeTemplate = Cone ({0}) +panel.DrawExplorer.Template.LineTemplate = Line ({0}) +panel.DrawExplorer.Template.LineCellTemplate = Line ({0}) +panel.DrawExplorer.Template.RadiusTemplate = Radius ({0}) +panel.DrawExplorer.Template.RadiusCellTemplate = Radius ({0}) +panel.DrawExplorer.Template.WallTemplate = Wall ({0}) +# "Group" is a noun +panel.DrawExplorer.group = Group +panel.DrawExplorer.opacity = opacity({0}%) +# Prefix added when a drawing was done with the eraser +panel.DrawExplorer.eraser = CUT: {0} +# DrawExplorer panel +panel.DrawExplorer.Unknown.Shape = Unknown Shape +panel.Global = Global +panel.Global.description = Dockable window showing macros stored on the local computer. +panel.Impersonate = Impersonate +panel.Impersonate.description = Dockable window showing the macros stored on the currently impersonated token. +panel.Impersonate.button.impersonateSelected = Impersonate Selected +panel.Impersonate.identity = Speaking as: {0} +panel.Initiative = Initiative +panel.Initiative.description = Dockable window for managing combat initiative. +panel.Library = Library +panel.Library.description = Dockable window to access assets in your Resource Library. +panel.MapExplorer = Map Explorer +panel.MapExplorer.description = Dockable window showing the tokens and other assets on the current map. +panel.MapExplorer.View.BACKGROUND = Background +panel.MapExplorer.View.CLIPBOARD = Clipboard +panel.MapExplorer.View.GM = Hidden +panel.MapExplorer.View.GROUPS = Groups +panel.MapExplorer.View.LIGHT_SOURCES = Light Sources +panel.MapExplorer.View.OBJECTS = Objects +panel.MapExplorer.View.PLAYERS = Players +panel.MapExplorer.View.TOKENS = Tokens +panel.NewGroupName = New Group Name +panel.Selected = Selected +panel.Selected.description = Dockable window showing the macros on the currently selected token(s). +panel.Selected.tooltip.deslectAll = Deselect all tokens +panel.Selected.tooltip.next = Select next token +panel.Selected.tooltip.previous = Select previous token +panel.Selected.tooltip.revertToPrevious = Revert to previous selection +panel.Selected.tooltip.selectAll = Select all tokens on the map +panel.Tables = Tables +panel.Tables.description = Dockable window for managing the tables in the current campaign. + +dialog.NewToken.title = New Token +dialog.NewToken.type = Type: +dialog.NewToken.visible = Visible: +dialog.NewToken.show = Show this dialog +dialog.NewToken.tokenPropertyType = Token Property +dialog.NewToken.statSheet = Stat Sheet +dialog.NewToken.statSheetLocation = Stat Sheet Location + +prefs.language.override.tooltip = Select a language for the MapTool interface. + +prefs.jvm.advanced.enableAssertions.tooltip = Enables Java language assertions in the MapTool code. +prefs.jvm.advanced.direct3d.tooltip = Disable the use of Direct3D pipeline for problem video cards/drivers. +prefs.jvm.advanced.opengl.tooltip = Enable the OpenGL pipeline. +prefs.jvm.advanced.initAWTbeforeJFX.tooltip = Initialize AWT before JavaFx. This is for issues specific to the MacOS. + +prefs.jvm.xmx.tooltip = Set the maximum memory (heap size) that MapTool is allowed to use. Input a number followed by either a single letter M or G.
Examples: 4G is 4 Gigabytes, 4096M is 4096 Megabytes and is the same as 4G. +prefs.jvm.xms.tooltip = Set the initial and minimum memory setting for MapTool. Must be less than or equal to max heap size.
Input a number followed by either a single letter M or G. +prefs.jvm.xss.tooltip = Set the stack size for MapTool program threads. Values between 4M and 12M are recommended.
Values too large will cause problems. + +roll.description = Roll and broadcast the result to all connected players. +roll.general.unknown = Unknown roll: "{0}". Use #d#+#. +# {0} is the players name, {1} is the roll +roll.string = {0} rolls: {1} + +rollgm.description = Roll and broadcast the result to all GMs. +# {0} is the players name, {1} is the roll +rollgm.gm.string = {0} rolls to you: {1} +# {0} is the roll +rollgm.self.string = You roll to the GMs: {0} + +rollme.description = Roll and show the result only to me. +# {0} is the roll +rollme.string = You roll to yourself: {0} + +rollsecret.description = Roll and broadcast the result to only the GMs and hide the result even from yourself. +# {0} is the sender {1} is the roll +rollsecret.gm.string = {0} rolls secretly to you: {1} +# When the GM does "/rollsecret". {0} is the roll. Easier to use "/self"? +rollsecret.gmself.string = You roll secretly: {0} +rollsecret.self.string = You roll secretly to the GMs. + +# {0} is the error message +savealiases.couldNotSave = Could not save alias file: {0} +savealiases.created = MapTool Aliases - created +savealiases.description = Save all current aliases to a file. See "/loadaliases" to load them back in. +savealiases.dialogTitle = Save Aliases +savealiases.saved = Aliases Saved. + +# {0} is the error message +savetokenstates.couldNotSave = Could not save token states file: {0} +savetokenstates.description = Save the current set of token states to a file. +savetokenstates.dialogTitle = Save Token States +# {0} is the number of token states saved. +savetokenstates.saved = There were {0,number} token states saved. + +say.description = Broadcast a message to all connected players. + +self.description = Send a message only to yourself. + +settokenproperty.description = Set the property of a token. +settokenproperty.param = You must specify a token name and an expression, or select token(s) and supply an expression. +settokenproperty.unknownTokens = Unable to determine which tokens to set the property of. + +settokenstate.description = Set a state value on a token. +# {0} is the token name, {1} is the state name +settokenstate.marked = Token "{0}" now has {1} set. +settokenstate.param = A token state name and token name, or a selected token and state name are required. +settokenstate.unknownState = Unknown state name "{0}". +settokenstate.unknownTokens = Unable to determine which tokens to set the state of. +settokenstate.unmarked = Token "{0}" now has {1} reset. + +# Texture Noise +texturenoise.description = Change the noise applied to textures (only works on background tile textures at the moment). +texturenoise.currentValsOn = Current Values, alpha = {0}, seed = {1}. +texturenoise.currentValsOff = Noise is currently off. +texturenoise.usage = To change use /texturenoise alpha [seed] or /texturenoise on | off. + +# Version slash command +slashversion.description = Display the MapTool Version in the chat window. +slashversion.message = MapTool Version {0}. + +# About slash command +slashabout.description = Display the about dialog. + +# Slash Command errors +slash.mustBeGM = You must be a GM to use "/{0}". + +tmacro.description = Run the given macro on the currently selected tokens. + +togm.description = Send to GMs exclusively. +# {0} is the name of the sender, what to say is appended internally to +# close off HTML tags. +togm.saysToGM = {0} says to the GMs: +# {0} is what to say +togm.self = You say to the GMs: {0} + +token.popup.menu.always.visible = Visible over FoW +token.popup.menu.autoresize = Auto Resize... +token.popup.menu.expose = Expose +token.popup.menu.expose.currentonly = Only currently visible +token.popup.menu.expose.currentonly.accel = shift O +token.popup.menu.expose.lastpath = Last path +token.popup.menu.expose.lastpath.accel = P +token.popup.menu.expose.visible = Visible area +token.popup.menu.expose.visible.accel = I +token.popup.menu.fow = FOW Views +token.popup.menu.fow.clearselected = Clear Selected''s Exposed Area +token.popup.menu.fow.expose = Expose +token.popup.menu.fow.global = Add From Global Exposed Area +token.popup.menu.fow.party = Add From Group''s Exposed Area +token.popup.menu.fow.tokens = Token's FOW Views +token.popup.menu.fow.tokens.view = {0}''s Exposed Area +token.popup.menu.showHandout = Show Handout +token.popup.menu.facing.set = Set Facing +token.popup.menu.facing.clear = Clear Facing +token.popup.menu.lights.clear = Clear Lights Only +token.popup.menu.lights.clearAll = Clear All +token.popup.menu.auras.clear = Clear Auras Only +token.popup.menu.auras.clearGM = Clear GM Auras Only +token.popup.menu.auras.clearOwner = Clear Owner Auras Only +token.popup.menu.snap = Snap to grid +token.popup.menu.visible = Visible to players +token.popup.menu.impersonate = Impersonate +token.popup.menu.move = Move +token.popup.menu.move.path = Show Path +token.popup.menu.move.revertlast = Revert Last Move +token.popup.menu.export.libTokenAddon = Export Library Token as Addon... +token.popup.menu.edit = Edit ... +token.popup.menu.delete = Delete +token.popup.menu.flip = Flip +token.popup.menu.flip.horizontal = Horizontal +token.popup.menu.flip.vertical = Vertical +token.popup.menu.flip.isometric = Isometric Plane +token.popup.menu.change = Change to +token.popup.menu.arrange = Arrange +token.popup.menu.zorder.front = Bring to Front +token.popup.menu.zorder.back = Send to Back +token.popup.menu.save = Save ... +token.popup.menu.size = Size +token.popup.menu.size.free = Free Size +token.popup.menu.size.native = Native Size +token.popup.menu.size.reset = Reset +token.popup.menu.edit.toomany.tooltip = Only one token can be edited at a time. +token.popup.menu.edit.notallowed.tooltip = The GM is currently locking access to the Token Editor. + +# Token Content Menu +# +# Note the use of the two single quotes. See the URL at the top of the +# file for an explanation. (Essentially, a single quote in the output +# requires two single quotes in the message string.) +token.popup.menu.halo = Halo +token.popup.menu.vision.overlay = Vision Overlay +token.properties.button.transferVblFromMap.copy.text = Copy VBL From Map +token.properties.button.transferVblFromMap.move.text = Move VBL From Map +token.properties.button.transferVblToMap.copy.text = Copy VBL To Map +token.properties.button.transferVblToMap.move.text = Move VBL To Map + +tokenspeech.description = Say the given speech on the currently selected tokens. + +tool.LineCellTemplate.tooltip = Draw a line template centered on a grid cell. +# We use LClick to mean "left-click" and RClick to mean "right-click". +# We use MClick to mean "middle mouse button click". +# We use LDrag to mean "left-click-and-drag" and ditto for RDrag. +# We use MWheel to mean "mouse wheel". +# We add "Shift" or "Ctrl" in front to mean that keystroke. +tool.blasttemplate.instructions = LClick: set starting cell, second LClick sets radius and direction; Ctrl: move origin point +tool.blasttemplate.tooltip = Draw a blast template. +#tool.boardtool.instructions=Reposition Background Image +tool.boardtool.tooltip = Reposition background map image +tool.bursttemplate.instructions = LClick: set center cell, second LClick sets radius; Ctrl: move origin point +tool.bursttemplate.tooltip = Draw a burst template. +tool.cone.instructions = LClick: set initial point, second LClick sets radius and direction; Ctrl: move origin point +tool.cone.tooltip = Draw a cone template. +tool.crosstopology.instructions = LClick: set initial/final point; Shift LClick: erase cross; Ctrl snaps to grid +tool.crosstopology.tooltip = Draw a cross VBL +tool.deletedrawing.instructions=LClick: Select drawings Double-Click: Delete selected drawings. +tool.deletedrawing.tooltip=Delete drawing tool +tool.diamond.tooltip = Draw a diamond. +tool.diamondexpose.tooltip = Expose/Hide a diamond on the Fog of War. +tool.facing.instructions = Unused +tool.facing.tooltip = Set the token facing. +tool.filltopology.tooltip = Fill in closed areas of VBL. +tool.freehand.instructions = LDrag: draw freehand line, Shift+LDrag: erase freehand line, Alt (hold): Snap to cell center +tool.freehand.tooltip = Draw freehand lines. +tool.freehandexpose.instructions = LClick: lay initial/final point to expose, RClick (while drawing): set intermediate point, Shift+LClick (initial): hide area +tool.freehandexpose.tooltip = Expose/Hide a freehand shape on the Fog of War. +tool.gridtool.instructions = Arrows: move grid offset, Shift+Arrows: change grid size, LDrag: Move grid, MWheel: scale grid +tool.gridtool.tooltip = Show/Hide the map grid. +tool.label.dialogtitle = Edit Label +tool.label.instructions = LClick: create a new label, RDrag: move map, MWheel: zoom +tool.label.tooltip = Add text label to map. +tool.line.instructions = LClick: lay initial/final point, RClick (while drawing): set intermediate point, Shift+LClick (initial): erase line, Alt (hold): Snap to cell center +tool.line.tooltip = Draw straight lines. +tool.linetemplate.instructions = LClick: set initial point, second LClick determines path, third LClick sets length; Ctrl: move last point set +tool.linetemplate.tooltip = Draw a line template. +tool.measure.instructions = LDrag: measure cell distance, RDrag: move map, MWheel: zoom, MClick and Spacebar: Toggle waypoint +tool.measure.tooltip = Measure distance along path. +tool.oval.instructions = LClick: set initial/final point, Shift+LClick: start erase oval; Alt: origin is centerpoint +tool.oval.tooltip = Draw an oval. +tool.ovalexpose.instructions = LClick: set initial/final point to expose, Shift+LClick: hide area; Alt: origin is centerpoint +tool.ovalexpose.tooltip = Expose/Hide an oval on the Fog of War. +tool.ovaltopology.instructions = LClick: set initial/final point, Shift+LClick: start erase oval +tool.ovaltopology.tooltip = Draw an oval VBL. +tool.ovaltopologyhollow.tooltip = Draw a hollow oval VBL. +tool.pointer.instructions = LClick: select, LDrag: move selected, RClick: menu, RDrag: move map, MWheel: zoom, MClick and Spacebar: Toggle waypoint, Shift+MouseOver: no statsheet +tool.pointer.tooltip = Pointer tool +tool.poly.instructions = LClick: lay initial/final point, RClick (while drawing): set intermediate point, RDrag: move map, Shift+LClick (initial): Erase poly area +tool.poly.tooltip = Draw closed polygon. +tool.polyexpose.instructions = LClick: lay initial/final point to expose, RClick (while drawing): set intermediate point, RDrag: move map, Shift+LClick (initial): hide area +tool.polyexpose.tooltip = Expose/Hide a polygon on the Fog of War. +tool.polylinetopo.tooltip = Draw poly line VBL. +tool.polytopo.tooltip = Draw closed polygon VBL. +tool.radiusCellTemplate.tooltip = Draw a radius template centered on a grid cell. +tool.radiustemplate.instructions = LClick: set initial point, second LClick sets radius; Ctrl: move origin point +tool.radiustemplate.tooltip = Draw a radius template. +tool.rect.instructions = LClick: set initial/final point, Shift+LClick: erase rectangle; Ctrl: snap-to-grid, Alt: origin is centerpoint +tool.rect.tooltip = Draw a rectangle. +tool.rectexpose.instructions = LClick: set initial/final point to expose; Shift+LClick: hide rectangle; Alt: origin is centerpoint +tool.rectexpose.tooltip = Expose/Hide a rectangle on the Fog of War. +tool.recttopology.instructions = LClick: set initial/final point, Shift+LClick: erase rectangle; Ctrl: snap-to-grid +tool.recttopology.tooltip = Draw a rectangular VBL. +tool.recttopologyhollow.tooltip = Draw a hollow rectangular VBL. +tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. +tool.isorectangletopology.instructions = LClick: set initial/final point, Shift+LClick: erase isometric rectangle; Ctrl: snap-to-grid +tool.stamp.tooltip = Stamp tool +tool.walltemplate.instructions = LClick: set starting cell, move mouse in direction of wall, second LClick to finish wall; Ctrl: move origin point +tool.walltemplate.tooltip = Draw a wall template. +tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. +tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. +tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.drawing.tooltip = Drawing Tools +tools.fog.tooltip = Fog of War Tools +tools.interaction.tooltip = Interaction Tools +tools.mute.tooltip = Mute system sounds and audio streams +tools.unmute.tooltip = Unmute system sounds and audio streams +tools.hidetoolbar.tooltip = Hide the toolbar +tools.unhidetoolbar.tooltip = Unhide the toolbar +tools.template.tooltip = Template Tools +tools.token.fow.all.tooltip = Show FoW for All Tokens you explicitly own or are owned by all. +tools.token.fow.gm.tooltip = Show FoW for Tokens you explicitly own.
IF you are a GM, you will also see any tokens that have no ownership set. +tools.token.fow.npc.tooltip = Show FoW for NPC Tokens you explicitly own or are owned by all. +tools.token.fow.pc.tooltip = Show FoW for PC Tokens you explicitly own or are owned by all. +tools.topo.tooltip = Vision Blocking Layer (VBL) Tools +tools.zoneselector.tooltip = Select Map +tools.initiative.tooltip = Initiative Tools + +undefinedmacro.unknownCommand = Unknown command: "{0}". Try /help for a list of commands. + + + +startup.config.unableToWrite = Unable to write to configuration file. +Preferences.startup.label.info = Startup Preferences Information +startup.preferences.info = \ + {0} \ + JVM Memory Settings\ +

    \ +
  • \ + Maximum Heap Size: The maximum amount of memory MapTool can use\ +
      \ +
    • This should include G for gig, e.g. 8G
    • \ +
    \ +
  • \ +
  • \ + Minimum Heap Size: The minimum amount of memory MapTool will use\ +
      \ +
    • This should include G for gig, e.g. 4G
    • \ +
    \ +
  • \ +
  • \ + Thread Stack Size: The amount of memory MapTool will for its stack, increase this if you get stack errors when running \ + macros.\ +
      \ +
    • This should include M for Meg, e.g. 8M
    • \ +
    • warning setting this higher than 16M may cause issues
    • \ +
    \ +
  • \ +
\ + Language Override\ +
    \ +
  • Language: The language to use for MapTool

  • \ +
\ + Additional Options\ +
    \ +
  • Data Directory: The directory where MapTool data will be stored
  • \ +
\ + Advanced Options\ +
    \ +
  • Disable Direct3d pipeline: Try disabling this if you are experiencing graphical glitches on Windows Systems
  • \ +
  • Disable OpenGL pipeline: Try disabling this if you are experiencing graphical glitches on non Windows Systems
  • \ +
  • Initialize AWT before JavaFx: Only check this if you are experiencing problems with windows and dialogs not appearing
  • \ +
\ + + +startup.preferences.info.manualCopy =

Activating Startup Preferences

\ + MapTool is unable to copy the configuration file to the startup directory.
\ + In order for them to take effect you will need to edit the {0} and restart MapTool \ + after saving your changes.
+ + +userTerm.GM = GM +userTerm.Player = Player +# Note the capitalization on the second one. Some languages might use +# different capitalization so both are included here... +# +# Note that these are not used universally, but as code is modified they +# will be added. These should not be used by the programmer when user +# input is involved, for example in a dropdown box or similar. That's +# because the program is likely hard-coded to look at the text instead +# of localizing it. As we move forward, we'll write code so that it +# displays one thing but uses a separate value internally. That allows +# you to display whatever you want to the user and still have hard-coded +# values in the program (because it makes the program significantly +# easier to write and faster at runtime). +userTerm.player = player + +visionType.DAY = Day +visionType.NIGHT = Night +visionType.OFF = Off + +lightingStyle.ENVIRONMENTAL = Environmental +lightingStyle.OVERTOP = Overtop + +mapSortType.GMNAME = True Name +mapSortType.DISPLAYNAME = Display Name + + +webapp.serverAlreadyRunning = The webapp server is already running. +webapp.serverStarted = Webapp server has been started
Connect to \ + http://{0}:{1}/{2} on your browser/phone/tablet.

\ + The experimental Server App is deprecated and will be removed in an \ + upcoming version.

If you currently make use of this feature please \ + visit discord channel
to let us know how you are using it so we \ + can include this in our plans for its replacement

Discord: \ + https://discord.gg/hKChMAmn32

+ +whisper.command = Whisper +whisper.description = Send a message to a specific player. +whisper.enterText = enter text here +whisper.noName = Must supply a player name. +# {0} is the name, {1} is the message +whisper.string = {0} whispers: {1} +whisper.toSelf = Talking to yourself again? +whisper.you.string = You whisper to {0}: {1} + +whisperreply.description = Reply to the last player to whisper to you. +whisperreply.noTarget = You do not have anyone to reply to. + +zone.player_view = Player View +zone.map_not_visible = Map not visible to players + + + +# Player Database Dialog +playerDB.dialog.player = Player +playerDB.dialog.role = Role +playerDB.dialog.add = Add +playerDB.dialog.authType = Authentication Type +playerDB.dialog.blocked = Blocked +playerDB.dialog.connected = Connected +playerDB.dialog.title = Player Password Database +playerDB.dialog.title.edit = Edit Player +playerDB.dialog.title.new = New Player +playerDB.dialog.password = Password +playerDB.dialog.passwordGenerate = Generate New Password +playerDB.dialog.publicKey = Public Key +playerDB.dialog.edit = Edit... +playerDB.dialog.delete = Delete +playerDB.dialog.deleteConfirm = Are you sure you want to delete {0}? +playerDB.dialog.error.missingName = Missing Player Name +playerDB.dialog.error.passwordMissing = Missing Password +playerDB.dialog.error.passwordTooShort = Password is too short +playerDB.dialog.error.invalidPublicKey = Invalid Public Key +playerDB.dialog.error.emptyBlockReason = Blocked reason can not be empty +playerDB.dialog.error.playerExists = Player already exists +playerDB.dialog.error.savingChanges = Error saving database changes + + +# Text to display instead of the password +playerDB.dialog.encodedPassword = -- Encoded Password -- + +WebRTC.toggleUseWebRTC = Use WebRTC (experimental) +WebRTC.toggleUseWebRTC.tooltip = Use WebRTC as connection method, this may help
\ + with connection issues where portforwarding doesn't work
\ + both client and server must have the same setting.
\ + This functionality is still experimental.
\ + Requires an RPTools net Alias to be set + +dialog.button.ok = Ok +dialog.button.cancel = Cancel + + + +# Add-On Library support +library.error.invalidDefinition = Invalid library definition. +library.error.emptyName = Name can not be empty for add-on library. +library.error.emptyVersion = Version can''t be empty for add-on library {0}. +library.dialog.import.title = Import Add-On Library. +library.import.ioError = IO Error importing Drop In Library. +library.import.error = Error importing Drop In Library {0}. +library.import.error.notGM = Only GM can import a Drop in Library. +library.imported = Library {0} imported. +library.error.libtoken.no.access = Allow URI Access is not allowed for {0}. +library.error.addOn.no.access = Allow URI Access is not allowed for {0} add-on library. +library.error.libtoken.missing = Lib:Token can no longer be found. +library.error.addOnLibraryExists = Add-On Library with namespace {0} already exists. Do you want to replace it? +library.error.addOn.notText = Can''t convert asset of type {0} to text. +library.error.addOn.noConfigFile = library.json file not found in {0}. +library.property.value.notSpecified = Not Specified +# {0} is the name of the event, {1} is the name of the library, {2} is the exception message +library.error.errorParsingVotableEvent = Continuing after error parsing vote from event {0} @ {1}, error {2}. +# {0} is the name of the event, {1} is the name of the library, {2} is the exception message +library.error.errorRunningEvent = Continuing after error running event {0} @ {1}, error {2}. +library.error.notFound = Library with namespace {0} does not exist. +library.error.noEventHandler = Library with namespace {1} does not contains an event handler for {0}. +library.error.retrievingEventHandler = Error retrieving event handlers for event {0}. +library.error.addOn.sheet = Error adding stat sheet {1}, namespace {0} +library.export.information = This will extract the Lib:Token to the specified directory \ + as the format required for an add-on library.
Most functionality will work without modifications \ + but you will probably still need to make some modifications. +library.export.done = Exported {0} to {1} as add-on library. It's likely you \ + will need to make modifications to the add on library to make it work. +library.export.error.overwrite = Directory {0} is not empty, please select a different directory. +library.export.errorReadingDirectory = Unable to read directory {0}. +library.export.errorWriting = Error writing file {0} for add-on library. +library.dialog.button.add = Add +library.dialog.button.close = Close +library.dialog.button.details = Details +library.dialog.title = Add-On libraries +library.dialog.library.label = Libraries +library.dialog.development.label = Development +library.dialog.addon.name = Add-On Name +library.dialog.addon.version = Version +library.dialog.addon.namespace = Namespace +library.dialog.addon.shortDescription = Short Description +library.dialog.addon.description = Description +library.dialog.addon.readMeFile = View Read Me File +library.dialog.addon.authors = Authors +library.dialog.addon.license = License +library.dialog.addon.licenseFile = View License File +library.dialog.addon.giturl = Git URL +library.dialog.addon.website = Website +library.dialog.table.remove = Remove Library +library.dialog.table.removeData = Remove Library and Data +library.dialog.delete.confirm = Are you sure you want to remove add-on library {0}? +library.dialog.deleteData.confirm = Are you sure you want to remove add-on library {0} and all its data? +library.dialog.copy.title = The copied CSS is for testing \ + purposes only.
Within your add-on use
lib://net.rptools.maptool/css/mt-stat-sheet.css \ + or
lib://net.rptools.maptool/css/mt-theme.css +library.dialog.copyMTThemeCSS = Copy CSS Theme to clipbaord +library.dialog.copyMTStatSheetTheme = Copy Stat Sheet Theme to clipbaord + +# Game Data +data.error.cantConvertTo = Can''t convert {0} to {1}. +data.error.alreadyExists = Data Property {0} already exists. +data.error.undefined = Data Property {0} is undefined. +data.error.namespaceDoesNotExist = Data Namespace {0} does not exist for type {1}. +data.error.namespaceAlreadyExists= Data Namespace {0} already exists for type {1}. +data.error.sendingUpdate = Error sending game data update. +data.error.receivingUpdate = Error receiving game data update. +data.error.importGameData = Error importing game data. +data.error.clearingNamespace = Error clearing data namespace {0} from type {1}. +data.error.removingData = Error data data from {0} namespace {1} from type {2}. +Label.icontheme=Icon theme +Preferences.label.icontheme.tooltip=The theme aplication icons use. +Label.theme.macroeditor=Macro editor theme +TEXT_TYPE=Text type +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map +EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map +Label.label=Label: + +# StatSheet +token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet +token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_es.properties b/src/main/resources/net/rptools/maptool/language/i18n_es.properties index af2e5bda54..617fb51168 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_es.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_es.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Fit GM view Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? Preferences.label.client.default.username = Default Username Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonymous User @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Opción Count requiere un número no negat # Notice there are no double quotes around {0}. lineParser.dialogTitle = Ingresar valor para {0}. lineParser.dialogTitleNoToken = Ingresar valor. -lineParser.dialogValueFor = Valor para +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Se encontraron fichas "{0}" duplicadas. lineParser.emptyTokenName = No es posible asignar una cadena vacía a la variable token.name lineParser.errorBodyRoll = Error en el cuerpo de la tirada. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = FoW disabled. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = LClick\: set initial/final point; Shift LClic tool.crosstopology.tooltip = Draw a cross VBL tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = Dibuja un diamante. -tool.diamondexpose.tooltip = Exponer/Ocultar un diamante en la Niebla de Guerra +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = No usado tool.facing.tooltip = Asignar el frente de la ficha. tool.filltopology.tooltip = Rellenar áreas cerradas de CBV. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Exponer/Ocultar un rectángulo en la Niebla d tool.recttopology.instructions = ClicIz\: punto inicial/final; Mayus+ClicIz\: borrar rectángulo; Ctrl\: ajustado a la rejilla tool.recttopology.tooltip = Trazar una CBV rectangular. tool.recttopologyhollow.tooltip = Trazar una CBV rectangular vacía. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Herramienta objetos @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = ClicIz\: celda inicial, mueve el puntero en l tool.walltemplate.tooltip = Trazar una plantilla de muro. tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Herramientas de Trazos tools.fog.tooltip = Herramientas de Niebla de Guerra tools.interaction.tooltip = Herramientas de interacción @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_fr.properties b/src/main/resources/net/rptools/maptool/language/i18n_fr.properties index b416585804..f0c226e601 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_fr.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_fr.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Ajuster à la vue GM Preferences.label.client.fitview.tooltip = En forçant les joueurs à la vue du MJ, doit-on zoomer la carte du joueur de telle sorte que son écran affiche au moins le même contenu que l'écran du MJ? Preferences.label.client.default.username = Default Username Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonymous User @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Une option de comptage requiert un nombre # Notice there are no double quotes around {0}. lineParser.dialogTitle = Entrer une valeur pour {0}. lineParser.dialogTitleNoToken = Entrer la valeur. -lineParser.dialogValueFor = Valeur pour +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Trouve {0} pions dupliqués. lineParser.emptyTokenName = Impossible d'affecter une chaine de caractère vide à la variable token.name lineParser.errorBodyRoll = Erreur dans le corps du tirage de dé. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = FoW désactivé. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = Clic Gauche \: définit le point initial/fina tool.crosstopology.tooltip = Dessiner un VBL croisé tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = Dessinez un diamant. -tool.diamondexpose.tooltip = Révèle/cache un diamant dans le brouillard de guerre +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Non utilisé tool.facing.tooltip = Définit l'orientation du pion tool.filltopology.tooltip = Remplit des régions fermées de CBV (VBL) @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Révèle/cache un rectangle dans le brouillar tool.recttopology.instructions = Clic Gauche \: définit le point initial/final; Maj Clic Gauche \: efface le rectangle tool.recttopology.tooltip = Dessiner une CBV (VBL) en rectangle plein tool.recttopologyhollow.tooltip = Dessiner une CBV (VBL) en rectangle creux -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Outil tampon @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = Clic Gauche \: définit la case de départ, D tool.walltemplate.tooltip = Dessiner un gabarit de mur tools.ai_selector.tooltip = Les pions navigueront autour de MBL, VBL (si sélectionné), et prendront en compte les modificateurs de terrain. tools.ignore_vbl_on_move.tooltip = Les pions navigueront dans VBL si sélectionné, sinon ils se déplaceront librement dans le VBL. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Outils de dessin tools.fog.tooltip = Outils de Brouillard de Guerre tools.interaction.tooltip = Outils d'interaction @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_it.properties b/src/main/resources/net/rptools/maptool/language/i18n_it.properties index c3ed211386..8987d974ac 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_it.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_it.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Adatta vista GM Preferences.label.client.fitview.tooltip = Quando si forzano i giocatori alla vista del GM, la mappa del giocatore dovrebbe essere ingrandita in modo che lo schermo mostri almeno lo stesso contenuto dello schermo del GM? Preferences.label.client.default.username = Nome Utente Predefinito Preferences.label.client.default.username.tooltip = Il nome utente predefinito che appare nella barra degli strumenti di MapTool. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Porta End Point Web Server Interno Preferences.client.webEndPoint.port.tooltip = Porta End Point Web Server (Solo MapTool Interno) Preferences.client.default.username.value = Utente Anonimo @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = L''opzione Count richiede un numero non ne # Notice there are no double quotes around {0}. lineParser.dialogTitle = Inserisce un valore per {0}. lineParser.dialogTitleNoToken = Inserisce un valore. -lineParser.dialogValueFor = Valore per +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Token "{0}" duplicati trovati. lineParser.emptyTokenName = Impossibile assegnare una stringa vuota alla variabile token.name. lineParser.errorBodyRoll = Errore nel corpo del tiro. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Errore nell''aggiornare il gioca msg.error.playerDB.cantRemovePlayer = Impossibile rimuovere il giocatore {0} in un database che non supporta la rimozione dei giocatori. msg.error.playerDB.noSuchPlayer = Il giocatore {0} non esiste nel database dei giocatori attivi. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = FoW disabilitata. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = ClickSx\: imposta il punto iniziale/finale da tool.crosstopology.tooltip = Disegna un VBL a croce. tool.deletedrawing.instructions=ClickSx\: Seleziona disegni Doppio click\: Cancella i disegni selezionati. tool.deletedrawing.tooltip=Strumento elimina disegno -tool.diamond.tooltip = Disegna un diamante. -tool.diamondexpose.tooltip = Rivela/Nascondi un diamante di Fog of War. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Muovi il mouse per modificare l'orientamento del token; ClickSx per impostarlo. tool.facing.tooltip = Imposta l'orientamento del token. tool.filltopology.tooltip = Riempi nelle aree chiuse del VBL. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Rivela/Nascondi un rettangolo di Fog of War. tool.recttopology.instructions = ClickSx\: imposta il punto iniziale/finale; Shift+ClickSx\: cancella il rettangolo; Ctrl ancora alla griglia. tool.recttopology.tooltip = Disegna un VBL rettangolare. tool.recttopologyhollow.tooltip = Disegna un VBL rettangolare vuoto. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Timbro @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = ClickSx\: imposta la cella iniziale, muovi il tool.walltemplate.tooltip = Disegna un Muro. tools.ai_selector.tooltip = I token si sposteranno intorno a MBL, VBL (se selezionato) e terranno di conto dei token con modificatori di terreno. tools.ignore_vbl_on_move.tooltip = I token eviteranno il VBL se selezionato, altrimenti si muoveranno liberamente nel VBL. -tools.topology_mode_selection.vbl.tooltip = Disegna VBL Parete. -tools.topology_mode_selection.hill_vbl.tooltip = Disegna VBL Collina. -tools.topology_mode_selection.pit_vbl.tooltip = Disegna VBL Fossato. -tools.topology_mode_selection.mbl.tooltip = Disegna VBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Disegno tools.fog.tooltip = Fog of War tools.interaction.tooltip = Interazione @@ -2624,10 +2627,10 @@ Label.icontheme=Tema icone Preferences.label.icontheme.tooltip=Tema usato dalle icone dell'applicazione. Label.theme.macroeditor=Tema editor macro TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_ja.properties b/src/main/resources/net/rptools/maptool/language/i18n_ja.properties index fb1d7e8052..b66dc43d7c 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_ja.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_ja.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = GM表示に合わせる Preferences.label.client.fitview.tooltip = プレイヤーにGM表示を強制する場合、GMの画面に表示されている内容が全て見えるようにプレイヤーの地図表示の拡大率を調整する。 Preferences.label.client.default.username = ユーザー名の初期値 Preferences.label.client.default.username.tooltip = MapToolのツールバーに表示されるユーザー名の初期値。 +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = 内部WEBサーバーの終端ポート番号 Preferences.client.webEndPoint.port.tooltip = WEBサーバー終端ポート番号(MapTool内部のみ) Preferences.client.default.username.value = 匿名のユーザー @@ -1243,14 +1244,14 @@ admin.updateCampaignRepo = キャンペーン用配信素材置き場を更新.. alias.added = エイリアス『{0}』を追加しました。 alias.commandHeader = コマンド -alias.descriptionHeader = Description +alias.descriptionHeader = 説明 alias.description = エイリアスを作成します。 alias.header = エイリアス alias.removed = エイリアス『{0}』を取り除きました。 -alias.notFound = Alias "{0}" not found. -alias.campaign.title = Campaign Aliases -alias.client.title = Client Aliases -alias.addon.title = Aliases defined by {0} ({1}) Add-On . +alias.notFound = エイリアス『{0}』が見つかりません。 +alias.campaign.title = キャンペーン用エイリアス +alias.client.title = クライアント用エイリアス +alias.addon.title = 拡張『{0}』({1})によって定義されたエイリアス changecolor.description = 文字色を変更するには、マクロを介してチャット欄でテキストの色を入力します。 色は16進形式(カラーコード)で指定する必要があります。 例\: /cc \#ff0099 @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = カウントオプションは0以上の # Notice there are no double quotes around {0}. lineParser.dialogTitle = {0} の値を入力してください。 lineParser.dialogTitleNoToken = 値を入力 -lineParser.dialogValueFor = 値: +lineParser.dialogValueFor = 『{0}』の値 lineParser.duplicateLibTokens = トークン『{0}』が重複しています。 lineParser.emptyTokenName = 変数 token.name に空の値をを割りてることはできません。 lineParser.errorBodyRoll = ロールの本文でエラーが発生。 @@ -1833,7 +1834,7 @@ macromanager.alias.indexNotFound = (エラー:{0} が見つかりません macromanager.couldNotExecute = コマンド『{0}』を実行できません。例外:{1} # {0} is the command macromanager.tooManyResolves = {0} の実行中に解決すべきものが多すぎます。無限ループになっていませんか? -macromanager.ambiguous = Command {0} is ambiguous, please specify the namespace as well, matching options are\: +macromanager.ambiguous = コマンド {0} は曖昧です。名前空間を指定してください。適合するオプションは次の通りです: menu.QuickMap = 即席地図 menu.edit = 編集(&E) @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = プレイヤー {0} の更新時 msg.error.playerDB.cantRemovePlayer = プレイヤーの削除に対応していないデータベース上でプレイヤー {0} の削除を行う事はできません。 msg.error.playerDB.noSuchPlayer = プレイヤー {0} は有効なデータベース内に存在しません。 msg.error.parsing.handlebars = ハンドルバーテンプレート『{0}』の解析中にエラーが発生しました。 +msg.error.library.builtin.path = 組込ライブラリーのパスを読み込むことができませんでした。 +msg.error.library.builtin.load = 組込ライブラリー {0} を読み込むことができませんでした。 msg.info.action.disableFoW = 不明領域は無効です。 @@ -2117,14 +2120,14 @@ msg.warn.failedAutoSavingMessageHistory = メッセージ履歴を自動 msg.warning.macro.playerChangesNotAllowed = このマクロを変更することは、GMに禁止されています。 msg.warning.macro.willNotExport = マクロ『{0}』は書き出されませんでした。GMによりプレイヤーが編集することを禁止されているか、元のアイテムの所有権がないかのどちらかです。 msg.warning.prerelease.only = {0} の警告はリリース前テスト用のもので、実際のリリース時には無効化される予定です。 -msg.warning.loadCampaignFromInstallDir = Saving to the installation directory is not supported. After loading you will need to save to a different location. -msg.warning.saveCampaignToInstallDir = Saving to the installation directory is not supported, please choose a different location to save to. -msg.warning.exportRepoToInstallDir = Exporting Repository to the installation directory is not supported, please choose a different location to save to. -msg.warning.saveTokenToInstallDir = Saving Tokens to the installation directory is not supported, please choose a different location to save to. -msg.warning.saveMapToInstallDir = Saving Maps to the installation directory is not supported, please choose a different location to save to. -msg.warning.saveTableToInstallDir = Saving Tables to the installation directory is not supported, please choose a different location to save to. -msg.warning.savePropToInstallDir = Saving Campaign Properties to the installation directory is not supported, please choose a different location to save to. -msg.warning.saveMacrosToInstallDir = Saving Macros to the installation directory is not supported, please choose a different location to save to. +msg.warning.loadCampaignFromInstallDir = インストールディレクトリーへの保存はサポートされていません。読込後に別の場所に保存する必要があります。 +msg.warning.saveCampaignToInstallDir = インストールディレクトリーへの保存はサポートされていません。別の保存先を選択してください。 +msg.warning.exportRepoToInstallDir = リポジトリ書出をインストールディレクトリーに対して行うことはサポートされていません。別の保存先を選択してください。 +msg.warning.saveTokenToInstallDir = トークンの保存をインストールディレクトリーに対して行うことはサポートされていません。別の保存先を選択してください。 +msg.warning.saveMapToInstallDir = 地図の保存をインストールディレクトリーに対して行うことはサポートされていません。別の保存先を選択してください。 +msg.warning.saveTableToInstallDir = ロール表の保存をインストールディレクトリーに対して行うことはサポートされていません。別の保存先を選択してください。 +msg.warning.savePropToInstallDir = キャンペーン設定の保存をインストールディレクトリーに対して行うことはサポートされていません。別の保存先を選択してください。 +msg.warning.saveMacrosToInstallDir = マクロの保存をインストールディレクトリーに対して行うことはサポートされていません。別の保存先を選択してください。 msg.error.serverOnly = 関数 {0} はサーバー上でのみ使用することが出来ます。 @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = 左クリック:開始/終了点を指定 tool.crosstopology.tooltip = 十字遮光レイヤーを描画 tool.deletedrawing.instructions=左クリック:描画を選択/ダブルクリック:選択した描画を削除する。 tool.deletedrawing.tooltip=描画ツールを削除 -tool.diamond.tooltip = 長方形を描画 -tool.diamondexpose.tooltip = 不明領域を長方形状に公開する/隠す。 +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = 未使用 tool.facing.tooltip = トークン方向を設定する。 tool.filltopology.tooltip = 閉じた遮光レイヤーの範囲を塗りつぶす @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = 不明領域を長方形状に公開する/ tool.recttopology.instructions = 左クリック:開始点/終点を指定、シフト+左クリック:長方形を消去、CTRL:マス目に吸着 tool.recttopology.tooltip = 長方形の遮光レイヤーを描画 tool.recttopologyhollow.tooltip = 枠状の長方形遮光レイヤーを描画 -tool.isorectangletopology.tooltip = 等角図の長方形遮光レイヤーを描画する +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = 空洞の等角図長方形遮光レイヤーを描画する。 tool.isorectangletopology.instructions = 左クリック:開始点/終点を指定、シフト+左クリック:等角図長方形を消去、CTRL:マス目に吸着 tool.stamp.tooltip = スタンプツール @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = 左クリック:開始するマス目を選 tool.walltemplate.tooltip = 壁(wall)テンプレートを描画 tools.ai_selector.tooltip = トークンは、障壁レイヤーと遮光レイヤー(選択した場合)を回り込み、地形修正が設定されたトークンの影響を考慮して誘導されるようになります。 tools.ignore_vbl_on_move.tooltip = トークンは遮光レイヤーを回り込むように設定されていれば遮光レイヤーを回り込み、そうでない場合は遮光レイヤー内を自由に動くように誘導されます。 -tools.topology_mode_selection.vbl.tooltip = 壁型遮光レイヤーを描画する。 -tools.topology_mode_selection.hill_vbl.tooltip = 丘型遮光レイヤーを描画する。 -tools.topology_mode_selection.pit_vbl.tooltip = 縦穴遮光レイヤーを描画する。 -tools.topology_mode_selection.mbl.tooltip = 障壁レイヤーを描画する。 +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = 描画ツール tools.fog.tooltip = 不明領域ツール tools.interaction.tooltip = 操作ツール @@ -2624,10 +2627,10 @@ Label.icontheme=アイコンテーマ Preferences.label.icontheme.tooltip=使用するアプリケーションアイコンのテーマ。 Label.theme.macroeditor=マクロエディターのテーマ TEXT_TYPE=テキスト種別 -EditTokenDialog.button.movevbltoggle.tooltip=移動または複製時に壁遮光レイヤーを含む -EditTokenDialog.button.movembltoggle.tooltip=移動または複製時に障壁レイヤーを含む -EditTokenDialog.button.movehbltoggle.tooltip=移動または複製時に丘遮光レイヤーを含む -EditTokenDialog.button.movepbltoggle.tooltip=移動または複製時に穴遮光レイヤーを含む +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=選択した障壁レイヤーを地図から移動または複製する EditTokenDialog.button.movetomap.tooltip=選択した障壁レイヤーを地図へ移動または複製する Label.label=ラベル: @@ -2635,3 +2638,15 @@ Label.label=ラベル: # StatSheet token.statSheet.legacyStatSheetDescription = 旧来(1.14より前)データシート token.statSheet.useDefault = 特性値種別の初期データシート + +# Advanced Dice Rolls +advanced.roll.parserError = ダイスロール文字列にエラー {0}行 {1}桁 『{2}』。 +advanced.roll.unknownDiceType = 未知のダイスロール種別 {0}。 +advanced.roll.unknownVariable = 未知の変数 {0}。 +advanced.roll.variableNotNumber = 変数 {0} は数値ではありません。 +advanced.roll.unknownProperty = 未知の特性値 {0}。 +advanced.roll.propertyNotNumber = 特性値 {0} は数値ではありません。 +advanced.roll.noTokenInContext = コンテキストにトークンがありません。 +advanced.roll.inputNotNumber = 入力 {0} は数値ではありません。 +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_nl.properties b/src/main/resources/net/rptools/maptool/language/i18n_nl.properties index 9721885532..2fb46056a1 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_nl.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_nl.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Fit GM view Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? Preferences.label.client.default.username = Default Username Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonymous User @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = De count optie vereist een niet negatief n # Notice there are no double quotes around {0}. lineParser.dialogTitle = Invoer waarde voor {0}. lineParser.dialogTitleNoToken = Invoerwaarde. -lineParser.dialogValueFor = Waarde voor +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Dupliceer "{0}" gevonden tokens. lineParser.emptyTokenName = Kan geen lege tekenreeks toewijzen aan de variabele token.name lineParser.errorBodyRoll = Fout in de 'body' van de macro. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = FoW uitgeschakeld. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = LKlik\: stel begin/eindpunt in, Shift LKlik\: tool.crosstopology.tooltip = Teken een VBL kruis tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = Teken een diamant. -tool.diamondexpose.tooltip = Een diamant onthullen/verbergen op de FoW. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Ongebruikt tool.facing.tooltip = Stel het token kijkrichting in. tool.filltopology.tooltip = Vul gesloten gebied in van VBL. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Onthul/Verberg een rechthoek uit de FoW. tool.recttopology.instructions = LKlik\: stel eerste/laatste punt in, Shift+LKlik\: wis rechthoek; Ctrl\: uitlijnen op raster in tool.recttopology.tooltip = Teken een rechthoekige VBL. tool.recttopologyhollow.tooltip = Teken een holle rechthoekige VBL. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Stempel gereedschap @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = LKlik\: stel eerste cel in, beweeg de muis in tool.walltemplate.tooltip = Teken een muur sjabloon. tools.ai_selector.tooltip = Tokens zullen navigeren rond MBL, VBL (indien geselecteerd) en rekening houden met tokens met terrein modifiers. tools.ignore_vbl_on_move.tooltip = Indien geselecteerd zullen Tokens om de VBL heen navigeren, anders zullen ze vrij door de VBL bewegen. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Tekenhulpmiddelen tools.fog.tooltip = Fog of War Gereedschap tools.interaction.tooltip = Interactie Gereedschap @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_pl.properties b/src/main/resources/net/rptools/maptool/language/i18n_pl.properties index c9db72307d..5fd7120ee3 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_pl.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_pl.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Dopasuj widok GM Preferences.label.client.fitview.tooltip = Podczas wymuszania widoku GM'a określa, czy mapa gracza powinna być powiększona tak, aby ich ekran pokazywał co najmniej taką samą zawartość jak ekran GMa. Preferences.label.client.default.username = Domyślna nazwa użytkownika Preferences.label.client.default.username.tooltip = Domyślna nazwa użytkownika, która pojawia się na pasku narzędzi MapTool. +Preferences.label.installDir = Ścieżka instalacji Preferences.client.webEndPoint.port = Wewnętrzny port punktu końcowego serwera sieci Web Preferences.client.webEndPoint.port.tooltip = Port punktu końcowego serwera sieci Web (Tylko Wewnętrzne MapTool) Preferences.client.default.username.value = Anonimowy użytkownik @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Opcja liczenia wymaga liczby nieujemnej, a # Notice there are no double quotes around {0}. lineParser.dialogTitle = Wprowadź wartość dla {0}. lineParser.dialogTitleNoToken = Wprowadź wartość. -lineParser.dialogValueFor = Wartość dla +lineParser.dialogValueFor = Wartość dla "{0}" lineParser.duplicateLibTokens = Znaleziono duplikaty żetonów „{0}”. lineParser.emptyTokenName = Nie można przypisać pustego ciągu do zmiennej token.name lineParser.errorBodyRoll = Błąd w treści rzutu. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Błąd podczas aktualizacji grac msg.error.playerDB.cantRemovePlayer = Nie można usunąć gracza {0} do bazy danych, która nie obsługuje usuwania graczy. msg.error.playerDB.noSuchPlayer = Gracz {0} nie istnieje w bazie danych aktywnych graczy. msg.error.parsing.handlebars = Błąd przetwarzania szablonu paska obsługi {0}. +msg.error.library.builtin.path = Nie można odczytać wbudowanej ścieżki biblioteki. +msg.error.library.builtin.load = Nie można załadować wbudowanej biblioteki {0}. msg.info.action.disableFoW = Mgła wojny wyłączona. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = L-klik\: pkt pocz./końcowy; Shift+L-klik wym tool.crosstopology.tooltip = Rysuje X WBW. tool.deletedrawing.instructions=LClick\: Wybierz rysunki Dwukrotne kliknięcie\: Usuń wybrane rysunki. tool.deletedrawing.tooltip=Usuń narzędzie rysowania -tool.diamond.tooltip = Rysuje równoległobok. -tool.diamondexpose.tooltip = Odkryj/Ukryj równoległobok w Mgle Wojny. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Nieużywane tool.facing.tooltip = Ustaw zwrot żetonu. tool.filltopology.tooltip = Wypełnij zamknięte obszary WBW. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Odkryj/Ukryj prostokąt w Mgle Wojny. tool.recttopology.instructions = L-klik\: pkt pocz./końcowy; Shift+L-klik\: usuwa prostokąt; Ctrl\: przyciąga do siatki tool.recttopology.tooltip = Rysuje czworokątną WBW. tool.recttopologyhollow.tooltip = Rysuje pustą czworokątną WBW. -tool.isorectangletopology.tooltip = Narysuj prostokąt izometryczny VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Narysuj pusty prostokąt izometryczny VBL. tool.isorectangletopology.instructions = LClick\: ustawianie punktu początkowego/końcowego, Shift+LClick\: usuwanie prostokąta izometrycznego; Ctrl\: przyciąganie do siatki tool.stamp.tooltip = Narzędzie do stempla @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = L-klik\: pole początkowe, ruch myszą ustawi tool.walltemplate.tooltip = Draw a wall template tools.ai_selector.tooltip = Żetony będą omijać WBR, WBW (jeśli włączone) i brać pod uwagę żetony z modyfikatorami terenu. tools.ignore_vbl_on_move.tooltip = Włączone\: żetony będą omijać WBW. Wyłączone\: będą przechodzić przez WBW. -tools.topology_mode_selection.vbl.tooltip = Narysuj ścianę VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Narysuj wzgórze VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Narysuj dołek VBL. -tools.topology_mode_selection.mbl.tooltip = Narysuj MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Narzędzia rysowania tools.fog.tooltip = Narzędzia Mgły Wojny tools.interaction.tooltip = Narzędzia interakcji @@ -2624,10 +2627,10 @@ Label.icontheme=Zestaw ikon Preferences.label.icontheme.tooltip=Używane ikony aplikacji motywu. Label.theme.macroeditor=Motyw edytora makro TEXT_TYPE=Typ tekstu -EditTokenDialog.button.movevbltoggle.tooltip=Dołącz warstwę blokującą ściany (VBL) podczas przenoszenia lub kopiowania. -EditTokenDialog.button.movembltoggle.tooltip=Dołącz warstwę blokowania (MBL) podczas przenoszenia lub kopiowania -EditTokenDialog.button.movehbltoggle.tooltip=Dołącz warstwę blokowania wierszy (HillVBL) podczas przenoszenia lub kopiowania -EditTokenDialog.button.movepbltoggle.tooltip=Dołącz warstwę blokowania Pit (PitVBL) podczas przenoszenia lub kopiowania +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Przenieś lub skopiuj wybraną warstwę blokowania z mapy EditTokenDialog.button.movetomap.tooltip=Przenieś lub skopiuj wybraną warstwę blokowania do mapy Label.label=Etykieta\: @@ -2635,3 +2638,15 @@ Label.label=Etykieta\: # StatSheet token.statSheet.legacyStatSheetDescription = Wcześniejsze (przed 1.14) arkusze statystyk token.statSheet.useDefault = Domyślny arkusz danych statystycznych dla typu właściwości + +# Advanced Dice Rolls +advanced.roll.parserError = Błąd rzutu kostką wiersz {0} kolumna {1} "{2}". +advanced.roll.unknownDiceType = Nieznany typ rzutu kostką {0}. +advanced.roll.unknownVariable = Nieznana zmienna {0}. +advanced.roll.variableNotNumber = Zmienna {0} nie jest liczbą. +advanced.roll.unknownProperty = Nieznana właściwość {0}. +advanced.roll.propertyNotNumber = Właściwość {0} nie jest liczbą. +advanced.roll.noTokenInContext = Brak tokena w kontekście. +advanced.roll.inputNotNumber = Dane wejściowe {0} nie są liczbami. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_pt.properties b/src/main/resources/net/rptools/maptool/language/i18n_pt.properties index 4f1542dad5..213f5023f6 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_pt.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_pt.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Fit GM view Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? Preferences.label.client.default.username = Nome Padrão do Usuário Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Usuário Anônimo @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Count option requires a non negative numbe # Notice there are no double quotes around {0}. lineParser.dialogTitle = Input Value for {0}. lineParser.dialogTitleNoToken = Input Value. -lineParser.dialogValueFor = Value For +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Duplicate "{0}" tokens found. lineParser.emptyTokenName = Cannot assign a blank or empty string to the variable token.name lineParser.errorBodyRoll = Error in body of roll. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = FoW desabilitado. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = LClick\: set initial/final point; Shift LClic tool.crosstopology.tooltip = Draw a cross VBL tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Excluir o desenho -tool.diamond.tooltip = Desenha um diamante. -tool.diamondexpose.tooltip = Expor/Esconder o diamante no Fog of War. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Não Utilizado tool.facing.tooltip = Defina a direção da face do token. tool.filltopology.tooltip = Fill in closed areas of VBL. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Expor/Esconder um retângulo no Fog of War. tool.recttopology.instructions = Clique esquerdo do mouse\: define ponto inicial/final, Shift + Clique esquerdo\: apaga retângulo; Ctrl\: alinha à grade tool.recttopology.tooltip = Desenhe um VBL retangular. tool.recttopologyhollow.tooltip = Desenhe um VBL retangular oco. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Stamp tool @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = LClick\: set starting cell, move mouse in dir tool.walltemplate.tooltip = Desenhe um modelo de parede. tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Ferramentas de desenho tools.fog.tooltip = Ferramentas do Nevoeiro de Guerra tools.interaction.tooltip = Ferramentas de Interação @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_ru.properties b/src/main/resources/net/rptools/maptool/language/i18n_ru.properties index fe1d9849ab..5971f72e63 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_ru.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_ru.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Fit GM view Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? Preferences.label.client.default.username = Default Username Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonymous User @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Опция для Count не должна # Notice there are no double quotes around {0}. lineParser.dialogTitle = Введите значение для {0}. lineParser.dialogTitleNoToken = Значение для Ввода -lineParser.dialogValueFor = Значение Для +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Обнаружено дублирование {0} фишек. lineParser.emptyTokenName = Невозможно присвоить пустую строку переменной token.name lineParser.errorBodyRoll = Ошибка в теле вывода. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = Туман войны отключен. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = Лев.Мышь\: установить нач tool.crosstopology.tooltip = Draw a cross VBL tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = Рисовать прямоугольник -tool.diamondexpose.tooltip = Показать/Скрыть прямоугольник на Тумане Войны +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Не используется tool.facing.tooltip = Установить направление токена. tool.filltopology.tooltip = Заполнение в замкнутых областях (СБВ) @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Показать/Скрыть прямоуг tool.recttopology.instructions = Лев.Мышь\: установить начальную/конечную точку; Shift Лев.Мышь\: стереть прямоугольник; Ctrl привязывает к сетке tool.recttopology.tooltip = Рисовать прямоугольник СБВ. tool.recttopologyhollow.tooltip = Рисовать полый прямоугольник СБВ. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Инструмент штампа @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = Лев.Мышь\: установить нач tool.walltemplate.tooltip = Рисовать шаблон стены (wall) tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Инструменты рисования tools.fog.tooltip = Инструменты Тумана Войны tools.interaction.tooltip = Инструменты Взаимодействия @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_sv.properties b/src/main/resources/net/rptools/maptool/language/i18n_sv.properties index f0c1288090..9dbf60ff62 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_sv.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_sv.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Passa GM-vy Preferences.label.client.fitview.tooltip = När du tvingar spelare så de ser det spelledaren ser, ska spelarens karta zoomas så att deras skärm visar minst samma innehåll som spelledar-skärmen? Preferences.label.client.default.username = Default Username Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonymous User @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Räknealternativ kräver ett icke-negativt # Notice there are no double quotes around {0}. lineParser.dialogTitle = Inmatningsvärde för {0}. lineParser.dialogTitleNoToken = Inmatningsvärde. -lineParser.dialogValueFor = Värde för +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Spelpjäsduplikat "{0}" hittades. lineParser.emptyTokenName = Kan inte tilldela en blank eller tom sträng till variabeln token.name lineParser.errorBodyRoll = Fel i rollens kropp. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = FoW disabled. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = LClick\: set initial/final point; Shift LClic tool.crosstopology.tooltip = Draw a cross VBL tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = Rita isometrisk ruta. -tool.diamondexpose.tooltip = Expose/Hide a diamond on the Fog of War. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Oanvänd tool.facing.tooltip = Set the token facing. tool.filltopology.tooltip = Fill in closed areas of VBL. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Visa/dölj en rektangel av krigsdimman. tool.recttopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase rectangle; Ctrl\: snap-to-grid tool.recttopology.tooltip = Draw a rectangular VBL. tool.recttopologyhollow.tooltip = Draw a hollow rectangular VBL. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Stamp tool @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = LClick\: set starting cell, move mouse in dir tool.walltemplate.tooltip = Rita en väggmall. tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Ritverktyg tools.fog.tooltip = Fog of War-verktyg tools.interaction.tooltip = Interaktionsverktyg @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_uk.properties b/src/main/resources/net/rptools/maptool/language/i18n_uk.properties index 10ac7b0714..543727c05f 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_uk.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_uk.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = Fit GM view Preferences.label.client.fitview.tooltip = When forcing players to the GM's view, should the player's map be zoomed such that their screen shows at least the same content as the GM's screen? Preferences.label.client.default.username = Default Username Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = Anonymous User @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = Count option requires a non negative numbe # Notice there are no double quotes around {0}. lineParser.dialogTitle = Input Value for {0}. lineParser.dialogTitleNoToken = Input Value. -lineParser.dialogValueFor = Value For +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = Duplicate "{0}" tokens found. lineParser.emptyTokenName = Cannot assign a blank or empty string to the variable token.name lineParser.errorBodyRoll = Error in body of roll. @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = FoW disabled. @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = LClick\: set initial/final point; Shift LClic tool.crosstopology.tooltip = Draw a cross VBL tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = Draw a diamond. -tool.diamondexpose.tooltip = Expose/Hide a diamond on the Fog of War. +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = Unused tool.facing.tooltip = Set the token facing. tool.filltopology.tooltip = Fill in closed areas of VBL. @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = Expose/Hide a rectangle on the Fog of War. tool.recttopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase rectangle; Ctrl\: snap-to-grid tool.recttopology.tooltip = Draw a rectangular VBL. tool.recttopologyhollow.tooltip = Draw a hollow rectangular VBL. -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = Stamp tool @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = LClick\: set starting cell, move mouse in dir tool.walltemplate.tooltip = Draw a wall template. tools.ai_selector.tooltip = Tokens will navigate around MBL, VBL (if selected), and account for tokens with terrain modifiers. tools.ignore_vbl_on_move.tooltip = Tokens will navigate around VBL if selected, otherwise they will freely move into VBL. -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = Drawing Tools tools.fog.tooltip = Fog of War Tools tools.interaction.tooltip = Interaction Tools @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/main/resources/net/rptools/maptool/language/i18n_zh.properties b/src/main/resources/net/rptools/maptool/language/i18n_zh.properties index 51e8411878..eaf689bab3 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_zh.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_zh.properties @@ -691,6 +691,7 @@ Preferences.label.client.fitview = 适应GM视图 Preferences.label.client.fitview.tooltip = 当使用“强制玩家显示GM视图”时,玩家地图是否缩放至与GM屏幕相同。 Preferences.label.client.default.username = 默认用户名 Preferences.label.client.default.username.tooltip = The default username that appears in the MapTool toolbar. +Preferences.label.installDir = Installation Directory Preferences.client.webEndPoint.port = Internal Web Server End Point Port Preferences.client.webEndPoint.port.tooltip = Web Server End Point Port (Internal MapTool Only) Preferences.client.default.username.value = 匿名用户 @@ -1545,7 +1546,7 @@ lineParser.countNonNeg = 计数选项需要非负数,但得到了 # Notice there are no double quotes around {0}. lineParser.dialogTitle = 请为 {0} 输入值 lineParser.dialogTitleNoToken = 输入值 -lineParser.dialogValueFor = 赋值 +lineParser.dialogValueFor = Value For "{0}" lineParser.duplicateLibTokens = 发现指示物"{0}"重复。 lineParser.emptyTokenName = 无法将变量token.name设为空或空字符串。 lineParser.errorBodyRoll = 投骰正文错误。 @@ -2047,6 +2048,8 @@ msg.error.playerDB.errorUpdatingPlayer = Error updating player {0}. msg.error.playerDB.cantRemovePlayer = Can''t remove player {0} to a database which doesn''t support removing players. msg.error.playerDB.noSuchPlayer = Player {0} does not exist in active player database. msg.error.parsing.handlebars = Error parsing handlebars template {0}. +msg.error.library.builtin.path = Can't read built-in library path. +msg.error.library.builtin.load = Can''t load built-in library {0}. msg.info.action.disableFoW = 战争迷雾已禁用。 @@ -2388,8 +2391,8 @@ tool.crosstopology.instructions = 单击左键:设置起始/终结点,Shift tool.crosstopology.tooltip = 绘制十字VBL tool.deletedrawing.instructions=LClick\: Select drawings Double-Click\: Delete selected drawings. tool.deletedrawing.tooltip=Delete drawing tool -tool.diamond.tooltip = 绘制菱形 -tool.diamondexpose.tooltip = 显示/隐藏战争迷雾中的一块菱形区域 +tool.isorectangle.tooltip = Draw an isometric rectangle. +tool.isorectangleexpose.tooltip = Expose/Hide an isometric rectangle on the Fog of War. tool.facing.instructions = 设置指示物朝向 tool.facing.tooltip = 设置指示物朝向 tool.filltopology.tooltip = 自动填充封闭型拓扑区域 @@ -2433,7 +2436,7 @@ tool.rectexpose.tooltip = 显示/隐藏战争迷雾中的一块矩形 tool.recttopology.instructions = 单击左键:设置起始/终结点;Shift+左键:清除矩形区域 tool.recttopology.tooltip = 绘制矩形拓扑 tool.recttopologyhollow.tooltip = 绘制空心矩形拓扑 -tool.isorectangletopology.tooltip = Draw a isometric rectangle VBL. +tool.isorectangletopology.tooltip = Draw an isometric rectangle VBL. tool.isorectangletopologyhollow.tooltip = Draw a hollow isometric rectangle VBL. tool.isorectangletopology.instructions = LClick\: set initial/final point, Shift+LClick\: erase isometric rectangle; Ctrl\: snap-to-grid tool.stamp.tooltip = 图章工具 @@ -2441,10 +2444,10 @@ tool.walltemplate.instructions = 单击左键:设置起始格,移动鼠标 tool.walltemplate.tooltip = 绘制墙模板 tools.ai_selector.tooltip = 指示物将环绕MBL,VBL (如果选定),并对指示物应用地形修正。 tools.ignore_vbl_on_move.tooltip = 已选指示物将会环绕VBL,否则它们将能够自由移入VBL。 -tools.topology_mode_selection.vbl.tooltip = Draw Wall VBL. -tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill VBL. -tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit VBL. -tools.topology_mode_selection.mbl.tooltip = Draw MBL. +tools.topology_mode_selection.vbl.tooltip = Draw Wall Vision Blocking Layer (Wall VBL). +tools.topology_mode_selection.hill_vbl.tooltip = Draw Hill Vision Blocking Layer (Hill VBL). +tools.topology_mode_selection.pit_vbl.tooltip = Draw Pit Vision Blocking Layer (Pit VBL). +tools.topology_mode_selection.mbl.tooltip = Draw Movement Blocking Layer (MBL). tools.drawing.tooltip = 绘图工具 tools.fog.tooltip = 战争迷雾工具 tools.interaction.tooltip = 交互工具 @@ -2624,10 +2627,10 @@ Label.icontheme=Icon theme Preferences.label.icontheme.tooltip=The theme aplication icons use. Label.theme.macroeditor=Macro editor theme TEXT_TYPE=Text type -EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Blocking Layer (VBL) during move or copy -EditTokenDialog.button.movembltoggle.tooltip=Include Move Blocking Layer (MBL) during move or copy -EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Blocking Layer (HillVBL) during move or copy -EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Blocking Layer (PitVBL) during move or copy +EditTokenDialog.button.movevbltoggle.tooltip=Include Wall Vision Blocking Layer (Wall VBL) during move or copy +EditTokenDialog.button.movembltoggle.tooltip=Include Movement Blocking Layer (MBL) during move or copy +EditTokenDialog.button.movehbltoggle.tooltip=Include Hill Vision Blocking Layer (Hill VBL) during move or copy +EditTokenDialog.button.movepbltoggle.tooltip=Include Pit Vision Blocking Layer (Pit VBL) during move or copy EditTokenDialog.button.movefrommap.tooltip=Move or Copy selected blocking layer from Map EditTokenDialog.button.movetomap.tooltip=Move or Copy selected blocking layer to Map Label.label=Label\: @@ -2635,3 +2638,15 @@ Label.label=Label\: # StatSheet token.statSheet.legacyStatSheetDescription = Legacy (pre 1.14) Stat Sheet token.statSheet.useDefault = Default Stat Sheet for Property Type + +# Advanced Dice Rolls +advanced.roll.parserError = Dice Roll String Error line {0} column {1} "{2}". +advanced.roll.unknownDiceType = Unknown Dice Roll Type {0}. +advanced.roll.unknownVariable = Unknown Variable {0}. +advanced.roll.variableNotNumber = Variable {0} is not a number. +advanced.roll.unknownProperty = Unknown Property {0}. +advanced.roll.propertyNotNumber = Property {0} is not a number. +advanced.roll.noTokenInContext = No token in context. +advanced.roll.inputNotNumber = Input {0} is not a number. +Preferences.label.tokens.stack.hide=Hide Token stack indicator +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden \ No newline at end of file diff --git a/src/test/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoCompleteTest.java b/src/test/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoCompleteTest.java index 3030020c39..d542a3dbc2 100644 --- a/src/test/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoCompleteTest.java +++ b/src/test/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoCompleteTest.java @@ -16,7 +16,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.net.URL; import java.util.List; +import net.rptools.lib.net.RPTURLStreamHandlerFactory; +import net.rptools.maptool.model.library.url.LibraryURLStreamHandler; import org.fife.ui.autocomplete.BasicCompletion; import org.fife.ui.autocomplete.Completion; import org.fife.ui.autocomplete.DefaultCompletionProvider; @@ -26,6 +29,15 @@ class MapToolScriptAutoCompleteTest { @Test void tagsAreStrippedFromAShortDesc() { + /* + * Protocol handlers, we need to register lib: protocol handler so that the UDF auto-complete + * doesn't pause with a dialog box containing an error message during tests as now tests + * wont run without any add-on loaded + */ + RPTURLStreamHandlerFactory factory = new RPTURLStreamHandlerFactory(); + factory.registerProtocol("lib", new LibraryURLStreamHandler()); + URL.setURLStreamHandlerFactory(factory); + MapToolScriptAutoComplete mapToolScriptAutoComplete = new MapToolScriptAutoComplete(); DefaultCompletionProvider completionProvider = (DefaultCompletionProvider) mapToolScriptAutoComplete.get();