Skip to content

Commit

Permalink
Add mapname parameter to getTokens and getTokenNames
Browse files Browse the repository at this point in the history
- Add optional mapname parameters (defaults to current map)
- Add error message for incorrect number of parameters for FindToken functions
- Close #867
  • Loading branch information
Merudo committed Oct 30, 2019
1 parent 2466403 commit 57a7b53
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public boolean matchToken(Token t) {
private FindTokenFunctions() {
super(
0,
2,
3,
"findToken",
"currentToken",
"getTokenName",
Expand Down Expand Up @@ -257,55 +257,53 @@ public Object childEvaluate(Parser parser, String functionName, List<Object> par
}
}
if (functionName.equals("findToken")) {
if (parameters.size() < 1) {
throw new ParserException(
I18N.getText(
"macro.function.general.notEnoughParam", functionName, 1, parameters.size()));
}
FunctionUtil.checkNumberParam(functionName, parameters, 1, 2);
String mapName = parameters.size() > 1 ? parameters.get(1).toString() : null;
return findTokenId(parameters.get(0).toString(), mapName);
}
String delim = ",";
FindType findType;
String findArgs = null;
ZoneRenderer zoneRenderer = MapTool.getFrame().getCurrentZoneRenderer();
if (functionName.equals("currentToken")) {
FunctionUtil.checkNumberParam(functionName, parameters, 0, 0);
findType = FindType.CURRENT;
} else if (functionName.startsWith("getSelected")) {
FunctionUtil.checkNumberParam(functionName, parameters, 0, 1);
findType = FindType.SELECTED;
delim = !parameters.isEmpty() ? parameters.get(0).toString() : delim;
} else if (functionName.startsWith("getImpersonated")) {
FunctionUtil.checkNumberParam(functionName, parameters, 0, 0);
findType = FindType.IMPERSONATED;
} else if (functionName.startsWith("getPC")) {
FunctionUtil.checkNumberParam(functionName, parameters, 0, 1);
findType = FindType.PC;
delim = !parameters.isEmpty() ? parameters.get(0).toString() : delim;
} else if (functionName.startsWith("getNPC")) {
FunctionUtil.checkNumberParam(functionName, parameters, 0, 1);
findType = FindType.NPC;
delim = !parameters.isEmpty() ? parameters.get(0).toString() : delim;
} else if (functionName.startsWith("getToken")) {
FunctionUtil.checkNumberParam(functionName, parameters, 0, 3);
findType = FindType.ALL;
delim = !parameters.isEmpty() ? parameters.get(0).toString() : delim;
zoneRenderer = FunctionUtil.getZoneRendererFromParam(functionName, parameters, 2);
} else if (functionName.startsWith("getExposedToken")) {
FunctionUtil.checkNumberParam(functionName, parameters, 0, 1);
findType = FindType.EXPOSED;
delim = !parameters.isEmpty() ? parameters.get(0).toString() : delim;
} else if (functionName.startsWith("getWithState")) {
if (parameters.size() < 1) {
throw new ParserException(
I18N.getText(
"macro.function.general.notEnoughParam", functionName, 1, parameters.size()));
}
FunctionUtil.checkNumberParam(functionName, parameters, 1, 2);
findType = FindType.STATE;
findArgs = parameters.get(0).toString();
delim = parameters.size() > 1 ? parameters.get(1).toString() : delim;
} else if (functionName.startsWith("getOwned")) {
if (parameters.size() < 1) {
throw new ParserException(
I18N.getText(
"macro.function.general.notEnoughParam", functionName, 1, parameters.size()));
}
FunctionUtil.checkNumberParam(functionName, parameters, 1, 2);
findType = FindType.OWNED;
findArgs = parameters.get(0).toString();
delim = parameters.size() > 1 ? parameters.get(1).toString() : delim;
} else if (functionName.startsWith("getVisibleToken")) {
FunctionUtil.checkNumberParam(functionName, parameters, 0, 1);
findType = FindType.VISIBLE;
delim = parameters.size() > 0 ? parameters.get(0).toString() : delim;
} else {
Expand All @@ -319,9 +317,9 @@ public Object childEvaluate(Parser parser, String functionName, List<Object> par

// Special case of getToken,getTokenNames where a JSON object supplies arguments
if (findType == FindType.ALL && parameters.size() > 1) {
return getTokenList(parser, nameOnly, delim, parameters.get(1).toString());
return getTokenList(parser, nameOnly, delim, parameters.get(1).toString(), zoneRenderer);
}
return getTokens(parser, findType, nameOnly, delim, findArgs);
return getTokens(parser, findType, nameOnly, delim, findArgs, zoneRenderer);
}

/**
Expand All @@ -332,10 +330,12 @@ public Object childEvaluate(Parser parser, String functionName, List<Object> par
* @param nameOnly whether to return only token names (<code>false</code> = token GUIDs)
* @param delim either <code>json</code> or a string delimiter between output entries
* @param jsonString incoming JSON data structure to filter results
* @param zoneRenderer the zone renderer of the map where the tokens are
* @return list of filtered tokens
* @throws ParserException
*/
private Object getTokenList(Parser parser, boolean nameOnly, String delim, String jsonString)
private Object getTokenList(
Parser parser, boolean nameOnly, String delim, String jsonString, ZoneRenderer zoneRenderer)
throws ParserException {
JSONObject jobj = JSONObject.fromObject(jsonString);

Expand All @@ -355,7 +355,7 @@ private Object getTokenList(Parser parser, boolean nameOnly, String delim, Strin
layers.add(o.toString());
}
}
Zone zone = MapTool.getFrame().getCurrentZoneRenderer().getZone();
Zone zone = zoneRenderer.getZone();
allTokens = zone.getTokensFiltered(new LayerFilter(layers));
List<Token> tokenList = new ArrayList<Token>(allTokens.size());
tokenList.addAll(allTokens);
Expand All @@ -377,7 +377,8 @@ private Object getTokenList(Parser parser, boolean nameOnly, String delim, Strin
match = "setStates".equalsIgnoreCase(searchType);
// Looking for tokens that either match or don't match the states
for (Object item : states) {
tokenList = getTokenList(parser, FindType.STATE, item.toString(), match, tokenList);
tokenList =
getTokenList(parser, FindType.STATE, item.toString(), match, tokenList, zoneRenderer);
}
} else if ("range".equalsIgnoreCase(searchType)) {
// We will do this as one of the last steps as it's one of the most expensive so we want to
Expand Down Expand Up @@ -431,20 +432,27 @@ private Object getTokenList(Parser parser, boolean nameOnly, String delim, Strin
} else {
match = booleanCheck(jobj, searchType);
if ("npc".equalsIgnoreCase(searchType)) {
tokenList = getTokenList(parser, FindType.NPC, "", match, tokenList);
tokenList = getTokenList(parser, FindType.NPC, "", match, tokenList, zoneRenderer);
} else if ("pc".equalsIgnoreCase(searchType)) {
tokenList = getTokenList(parser, FindType.PC, "", match, tokenList);
tokenList = getTokenList(parser, FindType.PC, "", match, tokenList, zoneRenderer);
} else if ("selected".equalsIgnoreCase(searchType)) {
tokenList = getTokenList(parser, FindType.SELECTED, "", match, tokenList);
tokenList = getTokenList(parser, FindType.SELECTED, "", match, tokenList, zoneRenderer);
} else if ("visible".equalsIgnoreCase(searchType)) {
tokenList = getTokenList(parser, FindType.VISIBLE, "", match, tokenList);
tokenList = getTokenList(parser, FindType.VISIBLE, "", match, tokenList, zoneRenderer);
} else if ("owned".equalsIgnoreCase(searchType)) {
tokenList =
getTokenList(parser, FindType.OWNED, MapTool.getPlayer().getName(), match, tokenList);
getTokenList(
parser,
FindType.OWNED,
MapTool.getPlayer().getName(),
match,
tokenList,
zoneRenderer);
} else if ("current".equalsIgnoreCase(searchType)) {
tokenList = getTokenList(parser, FindType.CURRENT, "", match, tokenList);
tokenList = getTokenList(parser, FindType.CURRENT, "", match, tokenList, zoneRenderer);
} else if ("impersonated".equalsIgnoreCase(searchType)) {
tokenList = getTokenList(parser, FindType.IMPERSONATED, "", match, tokenList);
tokenList =
getTokenList(parser, FindType.IMPERSONATED, "", match, tokenList, zoneRenderer);
}
}
}
Expand All @@ -462,8 +470,7 @@ private Object getTokenList(Parser parser, boolean nameOnly, String delim, Strin
}
} else {
GUID guid = MapTool.getFrame().getCommandPanel().getIdentityGUID();
if (guid != null)
token = MapTool.getFrame().getCurrentZoneRenderer().getZone().getToken(guid);
if (guid != null) token = zone.getToken(guid);
else token = findToken(MapTool.getFrame().getCommandPanel().getIdentity(), null);
if (token == null) {
throw new ParserException(
Expand Down Expand Up @@ -511,8 +518,7 @@ private Object getTokenList(Parser parser, boolean nameOnly, String delim, Strin
}
} else {
GUID guid = MapTool.getFrame().getCommandPanel().getIdentityGUID();
if (guid != null)
token = MapTool.getFrame().getCurrentZoneRenderer().getZone().getToken(guid);
if (guid != null) token = zone.getToken(guid);
else token = findToken(MapTool.getFrame().getCommandPanel().getIdentity(), null);
if (token == null) {
throw new ParserException(
Expand Down Expand Up @@ -597,15 +603,20 @@ private boolean booleanCheck(JSONObject jobj, String searchType) {
* @param findArgs additional argument for the search
* @param match should the property match? true: only include matches, false: exclude matches
* @param originalList the list of tokens to search from
* @param zoneRenderer the zone render of the map where the tokens are
* @return tokenList satisfying the requirement
*/
private List<Token> getTokenList(
Parser parser, FindType findType, String findArgs, boolean match, List<Token> originalList)
Parser parser,
FindType findType,
String findArgs,
boolean match,
List<Token> originalList,
ZoneRenderer zoneRenderer)
throws ParserException {
List<Token> tokenList = new LinkedList<Token>();
if (originalList.size() == 0) return tokenList;

ZoneRenderer zoneRenderer = MapTool.getFrame().getCurrentZoneRenderer();
Zone zone = zoneRenderer.getZone();
switch (findType) {
case ALL:
Expand All @@ -629,7 +640,7 @@ private List<Token> getTokenList(
case IMPERSONATED:
Token t;
GUID guid = MapTool.getFrame().getCommandPanel().getIdentityGUID();
if (guid != null) t = MapTool.getFrame().getCurrentZoneRenderer().getZone().getToken(guid);
if (guid != null) t = zone.getToken(guid);
else t = zone.resolveToken(MapTool.getFrame().getCommandPanel().getIdentity());
if (t != null) {
tokenList = getTokensFiltered(Collections.singletonList(t), originalList, match);
Expand Down Expand Up @@ -680,22 +691,29 @@ private static List<Token> getTokensFiltered(
}

/**
* Gets the names or ids of the tokens on the current map.
* Gets the names or ids of the tokens on a map.
*
* @param parser The parser that called the function.
* @param findType The type of tokens to find.
* @param nameOnly If a list of names is wanted.
* @param delim The delimiter to use for lists, or "json" for a json array.
* @param findArgs Any arguments for the find function
* @param zoneRenderer the zone renderer of the map
* @return a string list that contains the ids or names of the tokens.
* @throws ParserException if this code adds a new enum but doesn't properly handle it
*/
private String getTokens(
Parser parser, FindType findType, boolean nameOnly, String delim, String findArgs)
Parser parser,
FindType findType,
boolean nameOnly,
String delim,
String findArgs,
ZoneRenderer zoneRenderer)
throws ParserException {
ArrayList<String> values = new ArrayList<String>();
Zone zone = MapTool.getFrame().getCurrentZoneRenderer().getZone();
List<Token> tokens = getTokenList(parser, findType, findArgs, true, zone.getAllTokens());
Zone zone = zoneRenderer.getZone();
List<Token> tokens =
getTokenList(parser, findType, findArgs, true, zone.getAllTokens(), zoneRenderer);

if (tokens != null && !tokens.isEmpty()) {
for (Token token : tokens) {
Expand Down Expand Up @@ -728,6 +746,7 @@ private String findTokenId(String identifier, String zoneName) {
* Finds the specified token.
*
* @param identifier the name of the token.
* @param zoneName the name of the zone.
* @return the token.
*/
public static Token findToken(String identifier, String zoneName) {
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/net/rptools/maptool/util/FunctionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import net.rptools.maptool.client.MapToolVariableResolver;
import net.rptools.maptool.client.functions.FindTokenFunctions;
import net.rptools.maptool.client.functions.JSONMacroFunctions;
import net.rptools.maptool.client.ui.zone.ZoneRenderer;
import net.rptools.maptool.language.I18N;
import net.rptools.maptool.model.Token;
import net.rptools.parser.ParserException;
Expand Down Expand Up @@ -124,6 +125,34 @@ public static Token getTokenFromParam(
return token;
}

/**
* Gets the ZoneRender from the specified index or returns the current ZoneRender. This method
* will check the list size before trying to retrieve the token so it is safe to use for functions
* that have the map as a optional argument.
*
* @param functionName the function name (used for generating exception messages).
* @param param the parameters for the function
* @param indexMap the index to find the map name at. If -1, use current map instead.
* @return the ZoneRenderer.
* @throws ParserException if the map cannot be found
*/
public static ZoneRenderer getZoneRendererFromParam(
String functionName, List<Object> param, int indexMap) throws ParserException {

String map = indexMap >= 0 && param.size() > indexMap ? param.get(indexMap).toString() : null;

ZoneRenderer zoneRenderer;
if (map == null) {
zoneRenderer = MapTool.getFrame().getCurrentZoneRenderer();
} else {
zoneRenderer = MapTool.getFrame().getZoneRenderer(map);
if (zoneRenderer == null) {
throw new ParserException(I18N.getText(KEY_UNKNOWN_MAP, functionName, map));
}
}
return zoneRenderer;
}

/**
* Return the BigDecimal value of a parameter. Throws a <code>ParserException</code> if the
* parameter can't be converted to BigDecimal.
Expand Down

0 comments on commit 57a7b53

Please sign in to comment.