From 9ea88a933b8faeff6f3f4c4ee42cebc07edc5b59 Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Fri, 14 Jun 2024 20:11:17 +0930 Subject: [PATCH 1/9] Basic Excluding of Token/Map VBL Doesn't work, but almost does. --- .../client/functions/Topology_Functions.java | 108 +++++++++++++++++- .../maptool/client/ui/zone/ZoneView.java | 69 +++++++++-- .../java/net/rptools/maptool/model/Token.java | 81 ++++++++++++- src/main/proto/data_transfer_objects.proto | 2 + 4 files changed, 247 insertions(+), 13 deletions(-) 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 c25326b9a0..d01dca4299 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 @@ -163,7 +163,14 @@ private Topology_Functions() { "transferHillVBL", "transferPitVBL", "transferCoverVBL", - "transferMBL"); + "transferMBL", + "setTokenVBLImmunity", + "addTokenVBLImmunity", + "removeTokenVBLImmunity", + "getTokenVBLImmunity", + "setMapVBLImmunity", + "toggleMapVBLImmunity", + "getMapVBLImmunity"); } public static Topology_Functions getInstance() { @@ -214,6 +221,15 @@ public Object childEvaluate( || functionName.equalsIgnoreCase("transferCoverVBL") || functionName.equalsIgnoreCase("transferMBL")) { childEvaluateTransferTopology(resolver, functionName, parameters); + } else if (functionName.equalsIgnoreCase("setTokenVBLImmunity") + || functionName.equalsIgnoreCase("addTokenVBLImmunity") + || functionName.equalsIgnoreCase("removeTokenVBLImmunity") + || functionName.equalsIgnoreCase("setMapVBLImmunity") + || functionName.equalsIgnoreCase("toggleMapVBLImmunity")) { + childEvaluateSetTopologyImmunity(resolver, functionName, parameters); + } else if (functionName.equalsIgnoreCase("getTokenVBLImmunity") + || functionName.equalsIgnoreCase("getMapVBLImmunity")) { + return childEvaluateGetTopologyImmunity(resolver, functionName, parameters).toString(); } else { throw new ParserException( I18N.getText("macro.function.general.unknownFunction", functionName)); @@ -610,6 +626,96 @@ private void childEvaluateTransferTopology( } } + public void childEvaluateSetTopologyImmunity( + VariableResolver resolver, String functionName, List parameters) + throws ParserException { + + if (parameters.size() > 3) { + throw new ParserException( + I18N.getText("macro.function.general.tooManyParam", functionName, 1, parameters.size())); + } + + if (parameters.isEmpty()) { + throw new ParserException( + I18N.getText( + "macro.function.general.notEnoughParam", functionName, 1, parameters.size())); + } + + if (!MapTool.getParser().isMacroTrusted()) { + throw new ParserException(I18N.getText("macro.function.general.noPerm", functionName)); + } + + Token token = FindTokenFunctions.findToken(parameters.get(0).toString(), null); + if (token == null) { + throw new ParserException( + I18N.getText( + "macro.function.general.unknownToken", functionName, parameters.get(0).toString())); + } + + if (functionName.equalsIgnoreCase("setTokenVBLImmunity")) { + // Need to make it an array + // token.setTokenVBLImmunity(parameters.get(1).toString()); + } else if (functionName.equalsIgnoreCase("addTokenVBLImmunity")) { + token.addTokenVBLImmunity(parameters.get(1).toString()); + } else if (functionName.equalsIgnoreCase("removeTokenVBLImmunity")) { + token.removeTokenVBLImmunity(parameters.get(1).toString()); + } else if (functionName.equalsIgnoreCase("setMapVBLImmunity")) { + token.setMapVBLImmunity( + parameters.get(1).toString(), BigDecimal.ONE.equals(parameters.get(2))); + } else if (functionName.equalsIgnoreCase("toggleMapVBLImmunity")) { + token.toggleMapVBLImmunity(parameters.get(1).toString()); + } + } + + public JsonArray childEvaluateGetTopologyImmunity( + VariableResolver resolver, String functionName, List parameters) + throws ParserException { + + if (parameters.size() > 3) { + throw new ParserException( + I18N.getText("macro.function.general.tooManyParam", functionName, 1, parameters.size())); + } + + if (parameters.isEmpty()) { + throw new ParserException( + I18N.getText( + "macro.function.general.notEnoughParam", functionName, 1, parameters.size())); + } + + if (!MapTool.getParser().isMacroTrusted()) { + throw new ParserException(I18N.getText("macro.function.general.noPerm", functionName)); + } + + Token token = FindTokenFunctions.findToken(parameters.get(0).toString(), null); + if (token == null) { + throw new ParserException( + I18N.getText( + "macro.function.general.unknownToken", functionName, parameters.get(0).toString())); + } + + JsonArray returnValue = new JsonArray(); + + if (functionName.equalsIgnoreCase("getTokenVBLImmunity")) { + token + .getTokenVBLImmunity() + .forEach( + (value) -> { + returnValue.add(value); + }); + } else if (functionName.equalsIgnoreCase("getMapVBLImmunity")) { + token + .getMapVBLImmunity() + .forEach( + (key, value) -> { + if (value) { + returnValue.add(key); + } + }); + } + + return returnValue; + } + /** * Auto generate topology using token topology optimzation options * 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 afc56902f6..e9bcd3f1d3 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 @@ -239,17 +239,26 @@ public boolean isUsingVision() { * @param topologyType The type of topology tree to get. * @return the area of the topology. */ - public synchronized Area getTopology(Zone.TopologyType topologyType) { + public synchronized Area getTopology( + Zone.TopologyType topologyType, + Set excludeTypes, + Set excludeTokens) { var topology = topologyAreas.get(topologyType); if (topology == null) { log.debug("ZoneView topology area for {} is null, generating...", topologyType.name()); - topology = new Area(zone.getTopology(topologyType)); + if (excludeTypes.contains(topologyType)) { + topology = new Area(); + } else { + topology = new Area(zone.getTopology(topologyType)); + } List topologyTokens = MapTool.getFrame().getCurrentZoneRenderer().getZone().getTokensWithTopology(topologyType); for (Token topologyToken : topologyTokens) { - topology.add(topologyToken.getTransformedTopology(topologyType)); + if (!excludeTokens.contains(topologyToken.getId().toString())) { + topology.add(topologyToken.getTransformedTopology(topologyType)); + } } topologyAreas.put(topologyType, topology); @@ -258,6 +267,10 @@ public synchronized Area getTopology(Zone.TopologyType topologyType) { return topology; } + public synchronized Area getTopology(Zone.TopologyType topologyType) { + return getTopology(topologyType, new HashSet(), new HashSet()); + } + /** * Get the topology tree of the requested type. * @@ -270,21 +283,32 @@ public synchronized Area getTopology(Zone.TopologyType topologyType) { * @param topologyType The type of topology tree to get. * @return the AreaTree (topology tree). */ - private synchronized AreaTree getTopologyTree(Zone.TopologyType topologyType) { + private synchronized AreaTree getTopologyTree( + Zone.TopologyType topologyType, + Set excludeTypes, + Set excludeTokens) { var topologyTree = topologyTrees.get(topologyType); - if (topologyTree == null) { + if (topologyTree == null + || (!excludeTypes.isEmpty() && excludeTypes.contains(topologyType)) + || !excludeTokens.isEmpty()) { log.debug("ZoneView topology tree for {} is null, generating...", topologyType.name()); - var topology = getTopology(topologyType); + var topology = getTopology(topologyType, excludeTypes, excludeTokens); topologyTree = new AreaTree(topology); - topologyTrees.put(topologyType, topologyTree); + if (excludeTypes.isEmpty() && excludeTokens.isEmpty()) { + topologyTrees.put(topologyType, topologyTree); + } } return topologyTree; } + private synchronized AreaTree getTopologyTree(Zone.TopologyType topologyType) { + return getTopologyTree(topologyType, new HashSet(), new HashSet()); + } + private IlluminationModel getIlluminationModel(IlluminationKey illuminationKey) { final var illuminationModel = illuminationModels.computeIfAbsent(illuminationKey, key -> new IlluminationModel()); @@ -590,14 +614,37 @@ private Area getTokenVisibleArea(@Nonnull Token token) { Point p = FogUtil.calculateVisionCenter(token, zone); Area visibleArea = sight.getVisionShape(token, zone); visibleArea.transform(AffineTransform.getTranslateInstance(p.x, p.y)); + Set excludeTypes = new HashSet(); + token + .getMapVBLImmunity() + .forEach( + (key, value) -> { + if (value) { + switch (key) { + case "wall": + excludeTypes.add(Zone.TopologyType.WALL_VBL); + break; + case "hill": + excludeTypes.add(Zone.TopologyType.HILL_VBL); + break; + case "pit": + excludeTypes.add(Zone.TopologyType.PIT_VBL); + break; + case "cover": + excludeTypes.add(Zone.TopologyType.COVER_VBL); + break; + } + } + }); + Set excludeTokens = token.getTokenVBLImmunity(); tokenVisibleArea = FogUtil.calculateVisibility( p, visibleArea, - getTopologyTree(Zone.TopologyType.WALL_VBL), - getTopologyTree(Zone.TopologyType.HILL_VBL), - getTopologyTree(Zone.TopologyType.PIT_VBL), - getTopologyTree(Zone.TopologyType.COVER_VBL)); + getTopologyTree(Zone.TopologyType.WALL_VBL, excludeTypes, excludeTokens), + getTopologyTree(Zone.TopologyType.HILL_VBL, excludeTypes, excludeTokens), + getTopologyTree(Zone.TopologyType.PIT_VBL, excludeTypes, excludeTokens), + getTopologyTree(Zone.TopologyType.COVER_VBL, excludeTypes, excludeTokens)); tokenVisibleAreaCache.put(token.getId(), tokenVisibleArea); } diff --git a/src/main/java/net/rptools/maptool/model/Token.java b/src/main/java/net/rptools/maptool/model/Token.java index 59d5a3baca..504a6e38ef 100644 --- a/src/main/java/net/rptools/maptool/model/Token.java +++ b/src/main/java/net/rptools/maptool/model/Token.java @@ -220,7 +220,12 @@ public enum Update { flipY, flipIso, setSpeechName, - removeFacing + removeFacing, + setTokenVBLImmunity, + addTokenVBLImmunity, + removeTokenVBLImmunity, + toggleMapVBLImmunity, + setMapVBLImmunity } public static final Comparator NAME_COMPARATOR = @@ -271,6 +276,10 @@ public enum Update { private Area coverVbl; private Area mbl; + private Map mapVBLImmunity = new HashMap<>(); + + private Set tokenVBLImmunity = new HashSet<>(); + private String name = ""; private Set ownerList = new HashSet<>(); @@ -2176,6 +2185,46 @@ public void setSizeScale(double scale) { sizeScale = scale; } + public void setTokenVBLImmunity(Set immunityData) { + tokenVBLImmunity = immunityData; + } + + public void addTokenVBLImmunity(String tokenID) { + tokenVBLImmunity.add(tokenID); + } + + public void removeTokenVBLImmunity(String tokenID) { + tokenVBLImmunity.remove(tokenID); + } + + public Set getTokenVBLImmunity() { + return tokenVBLImmunity; + } + + public void setMapVBLImmunity(String key, Boolean value) { + mapVBLImmunity.put(key, value); + } + + public HashMap getMapVBLImmunity() { + if (!mapVBLImmunity.containsKey("wall")) { + mapVBLImmunity.put("wall", false); + } + if (!mapVBLImmunity.containsKey("hill")) { + mapVBLImmunity.put("hill", false); + } + if (!mapVBLImmunity.containsKey("pit")) { + mapVBLImmunity.put("pit", false); + } + if (!mapVBLImmunity.containsKey("cover")) { + mapVBLImmunity.put("cover", false); + } + return new HashMap(mapVBLImmunity); + } + + public void toggleMapVBLImmunity(String key) { + mapVBLImmunity.put(key, !mapVBLImmunity.get(key)); + } + /** * Convert the token into a hash map. This is used to ship all of the properties for the token to * other apps that do need access to the Token class. @@ -2865,6 +2914,21 @@ public void updateProperty(Zone zone, Update update, List case flipIso: setFlippedIso(!isFlippedIso()); break; + case setTokenVBLImmunity: + // setTokenVBLImmunity(parameters.get(1).getStringValue()); + break; + case addTokenVBLImmunity: + addTokenVBLImmunity(parameters.get(1).getStringValue()); + break; + case removeTokenVBLImmunity: + removeTokenVBLImmunity(parameters.get(1).getStringValue()); + break; + case setMapVBLImmunity: + setMapVBLImmunity(parameters.get(1).getStringValue(), parameters.get(2).getBoolValue()); + break; + case toggleMapVBLImmunity: + toggleMapVBLImmunity(parameters.get(1).getStringValue()); + break; } if (lightChanged) { getZoneRenderer().flushLight(); // flush lights if it changed @@ -2960,6 +3024,17 @@ public static Token fromDto(TokenDto dto) { token.notesType = dto.getNotesType(); token.gmNotesType = dto.getGmNotesType(); + dto.getTokenVblImmunityList() + .forEach( + (value) -> { + token.tokenVBLImmunity.add(value); + }); + dto.getMapVblImmunityMap() + .forEach( + (key, value) -> { + token.setMapVBLImmunity(key, value); + }); + dto.getStateMap() .forEach( (key, stateDto) -> { @@ -3117,6 +3192,10 @@ public TokenDto toDto() { if (statSheet != null) { dto.setStatSheetProperties(StatSheetProperties.toDto(statSheet)); } + + dto.putAllMapVblImmunity(getMapVBLImmunity()); + dto.addAllTokenVblImmunity(getTokenVBLImmunity()); + return dto.build(); } diff --git a/src/main/proto/data_transfer_objects.proto b/src/main/proto/data_transfer_objects.proto index 4b7b41d973..8ccfa442e1 100644 --- a/src/main/proto/data_transfer_objects.proto +++ b/src/main/proto/data_transfer_objects.proto @@ -364,6 +364,8 @@ message TokenDto { string notes_type = 68; string gm_notes_type = 69; StatSheetPropertiesDto stat_sheet_properties = 70; + map map_vbl_immunity = 72; + repeated string token_vbl_immunity = 73; } message PathDto { From c94367ea6157fe00b8d3ba21e2e03e923e4f32b1 Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Sat, 15 Jun 2024 10:37:15 +0930 Subject: [PATCH 2/9] Now working, except for cached vision setTokenVBLImmunity Macro also doesn't work yet. --- .../java/net/rptools/maptool/client/ui/zone/ZoneView.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 e9bcd3f1d3..9d6f26fc58 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 @@ -245,7 +245,9 @@ public synchronized Area getTopology( Set excludeTokens) { var topology = topologyAreas.get(topologyType); - if (topology == null) { + if (topology == null + || (!excludeTypes.isEmpty() && excludeTypes.contains(topologyType)) + || !excludeTokens.isEmpty()) { log.debug("ZoneView topology area for {} is null, generating...", topologyType.name()); if (excludeTypes.contains(topologyType)) { @@ -261,7 +263,9 @@ public synchronized Area getTopology( } } - topologyAreas.put(topologyType, topology); + if (excludeTypes.isEmpty() && excludeTokens.isEmpty()) { + topologyAreas.put(topologyType, topology); + } } return topology; From 50a264d6c5ac5114c27cbb41bbb9a964d1f1484e Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:51:26 +0930 Subject: [PATCH 3/9] Some missing parts completed --- .../client/functions/Topology_Functions.java | 15 ++++++++++++--- .../java/net/rptools/maptool/model/Token.java | 5 +++++ 2 files changed, 17 insertions(+), 3 deletions(-) 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 d01dca4299..418567db8e 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 @@ -26,6 +26,7 @@ import java.awt.geom.PathIterator; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.function.BiConsumer; import net.rptools.maptool.client.MapTool; @@ -225,7 +226,8 @@ public Object childEvaluate( || functionName.equalsIgnoreCase("addTokenVBLImmunity") || functionName.equalsIgnoreCase("removeTokenVBLImmunity") || functionName.equalsIgnoreCase("setMapVBLImmunity") - || functionName.equalsIgnoreCase("toggleMapVBLImmunity")) { + || functionName.equalsIgnoreCase("toggleMapVBLImmunity") + || functionName.equalsIgnoreCase("clearTokenVBLImmunity")) { childEvaluateSetTopologyImmunity(resolver, functionName, parameters); } else if (functionName.equalsIgnoreCase("getTokenVBLImmunity") || functionName.equalsIgnoreCase("getMapVBLImmunity")) { @@ -653,8 +655,13 @@ public void childEvaluateSetTopologyImmunity( } if (functionName.equalsIgnoreCase("setTokenVBLImmunity")) { - // Need to make it an array - // token.setTokenVBLImmunity(parameters.get(1).toString()); + JsonArray setList = + net.rptools.maptool.util.FunctionUtil.paramAsJsonArray(functionName, parameters, 1); + HashSet newSet = new HashSet(); + for (JsonElement entry : setList) { + newSet.add(entry.getAsString()); + } + token.setTokenVBLImmunity(newSet); } else if (functionName.equalsIgnoreCase("addTokenVBLImmunity")) { token.addTokenVBLImmunity(parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("removeTokenVBLImmunity")) { @@ -664,6 +671,8 @@ public void childEvaluateSetTopologyImmunity( parameters.get(1).toString(), BigDecimal.ONE.equals(parameters.get(2))); } else if (functionName.equalsIgnoreCase("toggleMapVBLImmunity")) { token.toggleMapVBLImmunity(parameters.get(1).toString()); + } else if (functionName.equalsIgnoreCase("clearTokenVBLImmunity")) { + token.clearTokenVBLImmunity(); } } diff --git a/src/main/java/net/rptools/maptool/model/Token.java b/src/main/java/net/rptools/maptool/model/Token.java index 504a6e38ef..0e57b08cbd 100644 --- a/src/main/java/net/rptools/maptool/model/Token.java +++ b/src/main/java/net/rptools/maptool/model/Token.java @@ -2189,6 +2189,10 @@ public void setTokenVBLImmunity(Set immunityData) { tokenVBLImmunity = immunityData; } + public void clearTokenVBLImmunity() { + tokenVBLImmunity.clear(); + } + public void addTokenVBLImmunity(String tokenID) { tokenVBLImmunity.add(tokenID); } @@ -2915,6 +2919,7 @@ public void updateProperty(Zone zone, Update update, List setFlippedIso(!isFlippedIso()); break; case setTokenVBLImmunity: + // unknown caller, unknown usage // setTokenVBLImmunity(parameters.get(1).getStringValue()); break; case addTokenVBLImmunity: From f496a64ed4d5a9170d561ec75f1854dc6f4048e2 Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Mon, 23 Sep 2024 19:08:31 +0930 Subject: [PATCH 4/9] Maybe finished VBL Immunity. --- .../client/functions/Topology_Functions.java | 22 ++++++++++++++++++- .../java/net/rptools/maptool/model/Token.java | 18 +++++++++------ src/main/proto/data_transfer_objects.proto | 6 +++++ 3 files changed, 38 insertions(+), 8 deletions(-) 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 418567db8e..b253dde6ae 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 @@ -171,7 +171,8 @@ private Topology_Functions() { "getTokenVBLImmunity", "setMapVBLImmunity", "toggleMapVBLImmunity", - "getMapVBLImmunity"); + "getMapVBLImmunity", + "clearTokenVBLImmunity"); } public static Topology_Functions getInstance() { @@ -662,17 +663,36 @@ public void childEvaluateSetTopologyImmunity( newSet.add(entry.getAsString()); } token.setTokenVBLImmunity(newSet); + MapTool.serverCommand() + .updateTokenProperty( + token, Token.Update.setTokenVBLImmunity, newSet.toString().replaceAll("^\\[|]$", "")); } else if (functionName.equalsIgnoreCase("addTokenVBLImmunity")) { token.addTokenVBLImmunity(parameters.get(1).toString()); + MapTool.serverCommand() + .updateTokenProperty( + token, Token.Update.addTokenVBLImmunity, parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("removeTokenVBLImmunity")) { token.removeTokenVBLImmunity(parameters.get(1).toString()); + MapTool.serverCommand() + .updateTokenProperty( + token, Token.Update.removeTokenVBLImmunity, parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("setMapVBLImmunity")) { token.setMapVBLImmunity( parameters.get(1).toString(), BigDecimal.ONE.equals(parameters.get(2))); + MapTool.serverCommand() + .updateTokenProperty( + token, + Token.Update.setMapVBLImmunity, + parameters.get(1).toString(), + BigDecimal.ONE.equals(parameters.get(2))); } else if (functionName.equalsIgnoreCase("toggleMapVBLImmunity")) { token.toggleMapVBLImmunity(parameters.get(1).toString()); + MapTool.serverCommand() + .updateTokenProperty( + token, Token.Update.toggleMapVBLImmunity, parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("clearTokenVBLImmunity")) { token.clearTokenVBLImmunity(); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.clearTokenVBLImmunity); } } diff --git a/src/main/java/net/rptools/maptool/model/Token.java b/src/main/java/net/rptools/maptool/model/Token.java index 0e57b08cbd..21fd10876f 100644 --- a/src/main/java/net/rptools/maptool/model/Token.java +++ b/src/main/java/net/rptools/maptool/model/Token.java @@ -225,7 +225,8 @@ public enum Update { addTokenVBLImmunity, removeTokenVBLImmunity, toggleMapVBLImmunity, - setMapVBLImmunity + setMapVBLImmunity, + clearTokenVBLImmunity } public static final Comparator NAME_COMPARATOR = @@ -2919,20 +2920,23 @@ public void updateProperty(Zone zone, Update update, List setFlippedIso(!isFlippedIso()); break; case setTokenVBLImmunity: - // unknown caller, unknown usage - // setTokenVBLImmunity(parameters.get(1).getStringValue()); + setTokenVBLImmunity( + new HashSet(List.of(parameters.get(0).getStringValue().split(", ")))); break; case addTokenVBLImmunity: - addTokenVBLImmunity(parameters.get(1).getStringValue()); + addTokenVBLImmunity(parameters.get(0).getStringValue()); break; case removeTokenVBLImmunity: - removeTokenVBLImmunity(parameters.get(1).getStringValue()); + removeTokenVBLImmunity(parameters.get(0).getStringValue()); break; case setMapVBLImmunity: - setMapVBLImmunity(parameters.get(1).getStringValue(), parameters.get(2).getBoolValue()); + setMapVBLImmunity(parameters.get(0).getStringValue(), parameters.get(1).getBoolValue()); break; case toggleMapVBLImmunity: - toggleMapVBLImmunity(parameters.get(1).getStringValue()); + toggleMapVBLImmunity(parameters.get(0).getStringValue()); + break; + case clearTokenVBLImmunity: + clearTokenVBLImmunity(); break; } if (lightChanged) { diff --git a/src/main/proto/data_transfer_objects.proto b/src/main/proto/data_transfer_objects.proto index 426f15ecd9..cb47a263ff 100644 --- a/src/main/proto/data_transfer_objects.proto +++ b/src/main/proto/data_transfer_objects.proto @@ -658,6 +658,12 @@ enum TokenUpdateDto { flipIso = 55; setSpeechName = 56; removeFacing = 57; + setTokenVBLImmunity = 58; + addTokenVBLImmunity = 59; + removeTokenVBLImmunity = 60; + setMapVBLImmunity = 61; + toggleMapVBLImmunity = 62; + clearTokenVBLImmunity = 63; } message AssetTransferHeaderDto { From 9e91a9fc31cfb9273784075bf6adbb9852c54eea Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Wed, 25 Sep 2024 18:36:55 +0930 Subject: [PATCH 5/9] Mediocre Token Edit GUI --- .../ui/token/dialog/edit/EditTokenDialog.java | 131 ++++++++++++++ .../dialog/edit/TokenPropertiesDialog.form | 160 +++++++++++++++++- .../rptools/maptool/language/i18n.properties | 9 +- 3 files changed, 296 insertions(+), 4 deletions(-) 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 a5887838ea..96adaa762f 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 @@ -120,6 +120,9 @@ public class EditTokenDialog extends AbeillePanel { // private final Toolbox toolbox = new Toolbox(); private HeroLabData heroLabData; + + private Set tokenVBLImmunity; + private Set availableTokens = new HashSet(); private AutoGenerateTopologySwingWorker autoGenerateTopologySwingWorker = new AutoGenerateTopologySwingWorker(false, Color.BLACK); @@ -495,6 +498,13 @@ public void bind(final Token token) { }; getVisibleCheckBox().addActionListener(tokenVisibleActionListener); + // Init VBL Immunity Tab + if (MapTool.getPlayer().isGM()) { + initVBLImmunityTab(token); + } else { + getVBLImmunityTab().setEnabled(false); + } + // Character Sheets // controller = null; // String form = @@ -898,6 +908,13 @@ public boolean commit() { token.setHeroLabData(heroLabData); + // Update VBL Immunity + token.setMapVBLImmunity("wall", getWallVBLImmunityCB().isSelected()); + token.setMapVBLImmunity("hill", getHillVBLImmunityCB().isSelected()); + token.setMapVBLImmunity("pit", getPitVBLImmunityCB().isSelected()); + token.setMapVBLImmunity("cover", getCoverVBLImmunityCB().isSelected()); + token.setTokenVBLImmunity(tokenVBLImmunity); + // URI Access token.setAllowURIAccess(getAllowURLAccess().isEnabled() && getAllowURLAccess().isSelected()); // OTHER @@ -1087,6 +1104,42 @@ public JToggleButton getMblToggle() { return (JToggleButton) getComponent("mblToggle"); } + public JTabbedPane getVBLImmunityTab() { + return (JTabbedPane) getComponent("vblImmunityTab"); + } + + public JCheckBox getWallVBLImmunityCB() { + return (JCheckBox) getComponent("wallImmunityCB"); + } + + public JCheckBox getCoverVBLImmunityCB() { + return (JCheckBox) getComponent("coverImmunityCB"); + } + + public JCheckBox getHillVBLImmunityCB() { + return (JCheckBox) getComponent("hillImmunityCB"); + } + + public JCheckBox getPitVBLImmunityCB() { + return (JCheckBox) getComponent("pitImmunityCB"); + } + + public JList getTokenVBLImmunityList() { + return (JList) getComponent("tokenVBLImmunityList"); + } + + public JList getAvailableTokenList() { + return (JList) getComponent("availableTokenList"); + } + + public JButton getAddTokenVBLImmunityButton() { + return (JButton) getComponent("addTokenVBLImmunityButton"); + } + + public JButton getRemoveTokenVBLImmunityButton() { + return (JButton) getComponent("removeTokenVBLImmunityButton"); + } + public JButton getAutoGenerateTopologyButton() { return (JButton) getComponent("autoGenerateVblButton"); } @@ -1732,6 +1785,84 @@ public void keyPressed(KeyEvent e) { }); } + public void initVBLImmunityTab(Token thisToken) { + + ((JCheckBox) getWallVBLImmunityCB()).setSelected(thisToken.getMapVBLImmunity().get("wall")); + ((JCheckBox) getCoverVBLImmunityCB()).setSelected(thisToken.getMapVBLImmunity().get("cover")); + ((JCheckBox) getHillVBLImmunityCB()).setSelected(thisToken.getMapVBLImmunity().get("hill")); + ((JCheckBox) getPitVBLImmunityCB()).setSelected(thisToken.getMapVBLImmunity().get("pit")); + + tokenVBLImmunity = thisToken.getTokenVBLImmunity(); + Object[] tokenVBLImmunitiesID = tokenVBLImmunity.toArray(); + ArrayList activeListEntries = new ArrayList<>(); + ArrayList inActiveListEntries = new ArrayList<>(); + var mapZone = MapTool.getFrame().getCurrentZoneRenderer().getZone(); + + JList tokenVBLImmunityList = new JList(new DefaultListModel()); + JList availableTokenList = new JList(new DefaultListModel()); + + List tokenList = mapZone.getAllTokens(); + for (Token v : tokenList) { + if (!tokenVBLImmunity.contains(v.getId().toString()) && v.getId() != thisToken.getId()) { + availableTokens.add(v.getId().toString()); + String newEntry = v.getName(); + if (v.getGMName() != null) { + newEntry += " (" + v.getGMName() + ")"; + } + inActiveListEntries.add(newEntry); + ((DefaultListModel) availableTokenList.getModel()).addElement(newEntry); + } + } + + for (var r = 0; r < tokenVBLImmunitiesID.length; r++) { + String v = (String) tokenVBLImmunitiesID[r]; + Token t = mapZone.getToken(GUID.valueOf(v)); + String newEntry = t.getName(); + if (MapTool.getPlayer().isGM() && t.getGMName() != null) { + newEntry += " (" + t.getGMName() + ")"; + } + activeListEntries.add(newEntry); + ((DefaultListModel) tokenVBLImmunityList.getModel()).addElement(newEntry); + } + + tokenVBLImmunityList.setName("tokenVBLImmunityList"); + availableTokenList.setName("availableTokenList"); + tokenVBLImmunityList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + availableTokenList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + tokenVBLImmunityList.setLayoutOrientation(JList.VERTICAL); + availableTokenList.setLayoutOrientation(JList.VERTICAL); + + getAddTokenVBLImmunityButton() + .addActionListener( + e -> { + int removeIndex = getAvailableTokenList().getSelectedIndex(); + Object selectedObject = getAvailableTokenList().getSelectedValue(); + if (removeIndex > -1) { + tokenVBLImmunity.add((String) availableTokens.toArray()[removeIndex]); + availableTokens.remove(availableTokens.toArray()[removeIndex]); + ((DefaultListModel) getAvailableTokenList().getModel()).remove(removeIndex); + ((DefaultListModel) getTokenVBLImmunityList().getModel()) + .addElement(selectedObject); + } + }); + + getRemoveTokenVBLImmunityButton() + .addActionListener( + e -> { + int removeIndex = getTokenVBLImmunityList().getSelectedIndex(); + Object selectedObject = getTokenVBLImmunityList().getSelectedValue(); + if (removeIndex > -1) { + availableTokens.add((String) tokenVBLImmunity.toArray()[removeIndex]); + tokenVBLImmunity.remove(tokenVBLImmunity.toArray()[removeIndex]); + ((DefaultListModel) getTokenVBLImmunityList().getModel()).remove(removeIndex); + ((DefaultListModel) getAvailableTokenList().getModel()).addElement(selectedObject); + } + }); + + replaceComponent("vblImmunityActivePanel", "tokenVBLImmunityList", tokenVBLImmunityList); + replaceComponent("vblImmunityAvailablePanel", "availableTokenList", availableTokenList); + } + private static class SpeechTableModel extends KeyValueTableModel { private static final long serialVersionUID = 1601750325218502846L; 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 f1543b6b3a..1d14a825c7 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 @@ -3,7 +3,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -556,7 +556,7 @@ - + @@ -1330,6 +1330,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index 9ec4597f3c..7dd1fe6ab6 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -3018,4 +3018,11 @@ 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 +Preferences.label.tokens.stack.hide.tooltip=Token Layer stack inidicator will be hidden +EditTokenDialog.label.wallImmunity=Wall Immunity +EditTokenDialog.label.hillImmunity=Hill Immunity +EditTokenDialog.label.pitImmunity=Pit Immunity +EditTokenDialog.label.coverImmunity=Cover Immunity +EditTokenDialog.tab.vblImmunity=VBL Immunity +EditTokenDialog.label.currentImmunities=Current VBL Immunities +EditTokenDialog.label.availableTokens=Available Tokens \ No newline at end of file From 1ebb146953142730060aecdbd97b750bb7bb38b6 Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:29:06 +1030 Subject: [PATCH 6/9] Remove error --- .../client/ui/token/dialog/edit/TokenPropertiesDialog.form | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1d14a825c7..de96a90c6e 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 @@ -26,7 +26,7 @@ - + From 11bd9e1660903284589d2946751ab09161f9afcc Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Thu, 12 Dec 2024 07:57:30 +1030 Subject: [PATCH 7/9] Buildable again, ready for rework --- .../java/net/rptools/maptool/client/ui/zone/ZoneView.java | 2 +- src/main/java/net/rptools/maptool/model/Token.java | 2 +- src/main/proto/data_transfer_objects.proto | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) 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 198fd91331..6e9cd87067 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 @@ -225,7 +225,7 @@ public Area getExposedArea(PlayerView view) { public boolean isUsingVision() { return zone.getVisionType() != Zone.VisionType.OFF; } - + private IlluminationModel getIlluminationModel(IlluminationKey illuminationKey) { final var illuminationModel = illuminationModels.computeIfAbsent(illuminationKey, key -> new IlluminationModel()); diff --git a/src/main/java/net/rptools/maptool/model/Token.java b/src/main/java/net/rptools/maptool/model/Token.java index 3bb2bb6f94..4c530e4be8 100644 --- a/src/main/java/net/rptools/maptool/model/Token.java +++ b/src/main/java/net/rptools/maptool/model/Token.java @@ -281,7 +281,7 @@ public enum Update { private Area mbl; // endregion - + private Map mapVBLImmunity = new HashMap<>(); private Set tokenVBLImmunity = new HashSet<>(); diff --git a/src/main/proto/data_transfer_objects.proto b/src/main/proto/data_transfer_objects.proto index b613acb162..e6159b1b39 100644 --- a/src/main/proto/data_transfer_objects.proto +++ b/src/main/proto/data_transfer_objects.proto @@ -366,8 +366,8 @@ message TokenDto { string notes_type = 68; string gm_notes_type = 69; StatSheetPropertiesDto stat_sheet_properties = 70; - map map_vbl_immunity = 72; - repeated string token_vbl_immunity = 73; + map map_vbl_immunity = 73; + repeated string token_vbl_immunity = 74; } message PathDto { From 3b61589f191c105ca89b2a525018c48e96de06d4 Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:02:09 +1030 Subject: [PATCH 8/9] Initial Rework Complete Ugly, but fully functional --- .../client/functions/Topology_Functions.java | 47 ++++++++------ .../client/tool/drawing/TopologyTool.java | 10 +-- .../ui/token/dialog/edit/EditTokenDialog.java | 46 ++++++++++--- .../dialog/edit/TokenPropertiesDialog.form | 30 ++++++++- .../maptool/client/ui/zone/ZoneView.java | 23 ++----- .../walker/astar/AbstractAStarWalker.java | 7 +- .../java/net/rptools/maptool/model/Token.java | 64 +++++++++++-------- .../java/net/rptools/maptool/model/Zone.java | 47 ++++++++++---- src/main/proto/data_transfer_objects.proto | 7 +- 9 files changed, 188 insertions(+), 93 deletions(-) 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 e5dbbb1b85..2f405dca4e 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 @@ -169,10 +169,11 @@ private Topology_Functions() { "addTokenVBLImmunity", "removeTokenVBLImmunity", "getTokenVBLImmunity", - "setMapVBLImmunity", - "toggleMapVBLImmunity", - "getMapVBLImmunity", - "clearTokenVBLImmunity"); + "setGlobalVBLImmunity", + "toggleGlobalVBLImmunity", + "getGlobalVBLImmunity", + "clearTokenVBLImmunity", + "clearGlobalVBLImmunity"); } public static Topology_Functions getInstance() { @@ -226,12 +227,13 @@ public Object childEvaluate( } else if (functionName.equalsIgnoreCase("setTokenVBLImmunity") || functionName.equalsIgnoreCase("addTokenVBLImmunity") || functionName.equalsIgnoreCase("removeTokenVBLImmunity") - || functionName.equalsIgnoreCase("setMapVBLImmunity") - || functionName.equalsIgnoreCase("toggleMapVBLImmunity") - || functionName.equalsIgnoreCase("clearTokenVBLImmunity")) { + || functionName.equalsIgnoreCase("setGlobalVBLImmunity") + || functionName.equalsIgnoreCase("toggleGlobalVBLImmunity") + || functionName.equalsIgnoreCase("clearTokenVBLImmunity") + || functionName.equalsIgnoreCase("clearGlobalVBLImmunity")) { childEvaluateSetTopologyImmunity(resolver, functionName, parameters); } else if (functionName.equalsIgnoreCase("getTokenVBLImmunity") - || functionName.equalsIgnoreCase("getMapVBLImmunity")) { + || functionName.equalsIgnoreCase("getGlobalVBLImmunity")) { return childEvaluateGetTopologyImmunity(resolver, functionName, parameters).toString(); } else { throw new ParserException( @@ -666,37 +668,40 @@ public void childEvaluateSetTopologyImmunity( for (JsonElement entry : setList) { newSet.add(entry.getAsString()); } - token.setTokenVBLImmunity(newSet); + // token.setTokenVBLImmunity(newSet); MapTool.serverCommand() .updateTokenProperty( token, Token.Update.setTokenVBLImmunity, newSet.toString().replaceAll("^\\[|]$", "")); } else if (functionName.equalsIgnoreCase("addTokenVBLImmunity")) { - token.addTokenVBLImmunity(parameters.get(1).toString()); + // token.addTokenVBLImmunity(parameters.get(1).toString()); MapTool.serverCommand() .updateTokenProperty( token, Token.Update.addTokenVBLImmunity, parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("removeTokenVBLImmunity")) { - token.removeTokenVBLImmunity(parameters.get(1).toString()); + // token.removeTokenVBLImmunity(parameters.get(1).toString()); MapTool.serverCommand() .updateTokenProperty( token, Token.Update.removeTokenVBLImmunity, parameters.get(1).toString()); - } else if (functionName.equalsIgnoreCase("setMapVBLImmunity")) { - token.setMapVBLImmunity( - parameters.get(1).toString(), BigDecimal.ONE.equals(parameters.get(2))); + } else if (functionName.equalsIgnoreCase("setGlobalVBLImmunity")) { + // token.setGlobalVBLImmunity(parameters.get(1).toString(), + // BigDecimal.ONE.equals(parameters.get(2))); MapTool.serverCommand() .updateTokenProperty( token, - Token.Update.setMapVBLImmunity, + Token.Update.setGlobalVBLImmunity, parameters.get(1).toString(), BigDecimal.ONE.equals(parameters.get(2))); - } else if (functionName.equalsIgnoreCase("toggleMapVBLImmunity")) { - token.toggleMapVBLImmunity(parameters.get(1).toString()); + } else if (functionName.equalsIgnoreCase("toggleGlobalVBLImmunity")) { + // token.toggleGlobalVBLImmunity(parameters.get(1).toString()); MapTool.serverCommand() .updateTokenProperty( - token, Token.Update.toggleMapVBLImmunity, parameters.get(1).toString()); + token, Token.Update.toggleGlobalVBLImmunity, parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("clearTokenVBLImmunity")) { - token.clearTokenVBLImmunity(); + // token.clearTokenVBLImmunity(); MapTool.serverCommand().updateTokenProperty(token, Token.Update.clearTokenVBLImmunity); + } else if (functionName.equalsIgnoreCase("clearGlobalVBLImmunity")) { + // token.clearGlobalVBLImmunity(); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.clearGlobalVBLImmunity); } } @@ -735,9 +740,9 @@ public JsonArray childEvaluateGetTopologyImmunity( (value) -> { returnValue.add(value); }); - } else if (functionName.equalsIgnoreCase("getMapVBLImmunity")) { + } else if (functionName.equalsIgnoreCase("getGlobalVBLImmunity")) { token - .getMapVBLImmunity() + .getGlobalVBLImmunity() .forEach( (key, value) -> { if (value) { diff --git a/src/main/java/net/rptools/maptool/client/tool/drawing/TopologyTool.java b/src/main/java/net/rptools/maptool/client/tool/drawing/TopologyTool.java index ae8d537188..e525b99cdf 100644 --- a/src/main/java/net/rptools/maptool/client/tool/drawing/TopologyTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/drawing/TopologyTool.java @@ -224,15 +224,15 @@ public void paintOverlay(ZoneRenderer renderer, Graphics2D g) { g2.scale(renderer.getScale(), renderer.getScale()); g2.setColor(AppStyle.tokenMblColor); - g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.MBL, null)); + g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.MBL)); g2.setColor(AppStyle.tokenTopologyColor); - g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.WALL_VBL, null)); + g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.WALL_VBL)); g2.setColor(AppStyle.tokenHillVblColor); - g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.HILL_VBL, null)); + g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.HILL_VBL)); g2.setColor(AppStyle.tokenPitVblColor); - g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.PIT_VBL, null)); + g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.PIT_VBL)); g2.setColor(AppStyle.tokenCoverVblColor); - g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.COVER_VBL, null)); + g2.fill(zone.getTokenMaskTopology(Zone.TopologyType.COVER_VBL)); g2.setColor(AppStyle.topologyTerrainColor); g2.fill(zone.getMaskTopology(Zone.TopologyType.MBL)); 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 b0060ae941..6bc7df18ce 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 @@ -936,10 +936,17 @@ public boolean commit() { token.setHeroLabData(heroLabData); // Update VBL Immunity - token.setMapVBLImmunity("wall", getWallVBLImmunityCB().isSelected()); - token.setMapVBLImmunity("hill", getHillVBLImmunityCB().isSelected()); - token.setMapVBLImmunity("pit", getPitVBLImmunityCB().isSelected()); - token.setMapVBLImmunity("cover", getCoverVBLImmunityCB().isSelected()); + token.setGlobalVBLImmunity("WALL_VBL", getWallVBLImmunityCB().isSelected()); + token.setGlobalVBLImmunity("HILL_VBL", getHillVBLImmunityCB().isSelected()); + token.setGlobalVBLImmunity("PIT_VBL", getPitVBLImmunityCB().isSelected()); + token.setGlobalVBLImmunity("COVER_VBL", getCoverVBLImmunityCB().isSelected()); + token.setGlobalVBLImmunity("PC", getPCVBLImmunityCB().isSelected()); + token.setGlobalVBLImmunity("NPC", getNPCVBLImmunityCB().isSelected()); + + if (getSelfVBLImmunityCB().isSelected()) { + tokenVBLImmunity.add(token.getId().toString()); + } + token.setTokenVBLImmunity(tokenVBLImmunity); // URI Access @@ -1154,6 +1161,18 @@ public JCheckBox getPitVBLImmunityCB() { return (JCheckBox) getComponent("pitImmunityCB"); } + public JCheckBox getPCVBLImmunityCB() { + return (JCheckBox) getComponent("pcImmunityCB"); + } + + public JCheckBox getNPCVBLImmunityCB() { + return (JCheckBox) getComponent("npcImmunityCB"); + } + + public JCheckBox getSelfVBLImmunityCB() { + return (JCheckBox) getComponent("selfImmunityCB"); + } + public JList getTokenVBLImmunityList() { return (JList) getComponent("tokenVBLImmunityList"); } @@ -1812,12 +1831,23 @@ public void keyPressed(KeyEvent e) { public void initVBLImmunityTab(Token thisToken) { - ((JCheckBox) getWallVBLImmunityCB()).setSelected(thisToken.getMapVBLImmunity().get("wall")); - ((JCheckBox) getCoverVBLImmunityCB()).setSelected(thisToken.getMapVBLImmunity().get("cover")); - ((JCheckBox) getHillVBLImmunityCB()).setSelected(thisToken.getMapVBLImmunity().get("hill")); - ((JCheckBox) getPitVBLImmunityCB()).setSelected(thisToken.getMapVBLImmunity().get("pit")); + ((JCheckBox) getWallVBLImmunityCB()) + .setSelected(thisToken.getGlobalVBLImmunity().get("WALL_VBL")); + ((JCheckBox) getCoverVBLImmunityCB()) + .setSelected(thisToken.getGlobalVBLImmunity().get("COVER_VBL")); + ((JCheckBox) getHillVBLImmunityCB()) + .setSelected(thisToken.getGlobalVBLImmunity().get("HILL_VBL")); + ((JCheckBox) getPitVBLImmunityCB()) + .setSelected(thisToken.getGlobalVBLImmunity().get("PIT_VBL")); + ((JCheckBox) getPCVBLImmunityCB()).setSelected(thisToken.getGlobalVBLImmunity().get("PC")); + ((JCheckBox) getNPCVBLImmunityCB()).setSelected(thisToken.getGlobalVBLImmunity().get("NPC")); + ((JCheckBox) getSelfVBLImmunityCB()) + .setSelected(thisToken.getTokenVBLImmunity().contains(thisToken.getId().toString())); tokenVBLImmunity = thisToken.getTokenVBLImmunity(); + if (tokenVBLImmunity.contains(thisToken.getId().toString())) { + tokenVBLImmunity.remove(thisToken.getId().toString()); + } Object[] tokenVBLImmunitiesID = tokenVBLImmunity.toArray(); ArrayList activeListEntries = new ArrayList<>(); ArrayList inActiveListEntries = new ArrayList<>(); 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 2fcf1ff655..0886f37b23 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 @@ -1395,7 +1395,7 @@ - + @@ -1439,6 +1439,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 6e9cd87067..d100bcd8f9 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 @@ -526,30 +526,19 @@ private Area getTokenVisibleArea(@Nonnull Token token) { Point p = FogUtil.calculateVisionCenter(token, zone); Area visibleArea = sight.getVisionShape(token, zone); visibleArea.transform(AffineTransform.getTranslateInstance(p.x, p.y)); - Set excludeTypes = new HashSet(); + Set excludeTypes = new HashSet<>(); token - .getMapVBLImmunity() + .getGlobalVBLImmunity() .forEach( (key, value) -> { if (value) { - switch (key) { - case "wall": - excludeTypes.add(Zone.TopologyType.WALL_VBL); - break; - case "hill": - excludeTypes.add(Zone.TopologyType.HILL_VBL); - break; - case "pit": - excludeTypes.add(Zone.TopologyType.PIT_VBL); - break; - case "cover": - excludeTypes.add(Zone.TopologyType.COVER_VBL); - break; - } + excludeTypes.add(key); } }); Set excludeTokens = token.getTokenVBLImmunity(); - tokenVisibleArea = FogUtil.calculateVisibility(p, visibleArea, zone.prepareNodedTopologies()); + tokenVisibleArea = + FogUtil.calculateVisibility( + p, visibleArea, zone.prepareNodedTopologies(excludeTokens, excludeTypes)); tokenVisibleAreaCache.put(token.getId(), tokenVisibleArea); } diff --git a/src/main/java/net/rptools/maptool/client/walker/astar/AbstractAStarWalker.java b/src/main/java/net/rptools/maptool/client/walker/astar/AbstractAStarWalker.java index 84caf95414..981783f04d 100644 --- a/src/main/java/net/rptools/maptool/client/walker/astar/AbstractAStarWalker.java +++ b/src/main/java/net/rptools/maptool/client/walker/astar/AbstractAStarWalker.java @@ -232,10 +232,13 @@ protected List calculatePath(CellPoint start, CellPoint goal) { MapTool.getServerPolicy().getVblBlocksMove() ? EnumSet.allOf(Zone.TopologyType.class) : EnumSet.of(Zone.TopologyType.MBL); + Set excludeTokens = new HashSet<>(); + if (keyToken != null) { + excludeTokens.add(keyToken.getId().toString()); + } this.preparedTopology = new MovementBlockingTopology( - zone.getWalls(), - zone.getMasks(topologyTypes, keyToken == null ? null : keyToken.getId())); + zone.getWalls(), zone.getMasks(topologyTypes, excludeTokens, new HashSet<>())); } var view = zoneRenderer.getPlayerView(); diff --git a/src/main/java/net/rptools/maptool/model/Token.java b/src/main/java/net/rptools/maptool/model/Token.java index 4c530e4be8..a94b0d4de3 100644 --- a/src/main/java/net/rptools/maptool/model/Token.java +++ b/src/main/java/net/rptools/maptool/model/Token.java @@ -224,9 +224,10 @@ public enum Update { setTokenVBLImmunity, addTokenVBLImmunity, removeTokenVBLImmunity, - toggleMapVBLImmunity, - setMapVBLImmunity, - clearTokenVBLImmunity + toggleGlobalVBLImmunity, + setGlobalVBLImmunity, + clearTokenVBLImmunity, + clearGlobalVBLImmunity } public static final Comparator NAME_COMPARATOR = @@ -282,7 +283,7 @@ public enum Update { // endregion - private Map mapVBLImmunity = new HashMap<>(); + private Map globalVBLImmunity = new HashMap<>(); private Set tokenVBLImmunity = new HashSet<>(); @@ -2271,28 +2272,38 @@ public Set getTokenVBLImmunity() { return tokenVBLImmunity; } - public void setMapVBLImmunity(String key, Boolean value) { - mapVBLImmunity.put(key, value); + public void setGlobalVBLImmunity(String key, Boolean value) { + globalVBLImmunity.put(key, value); } - public HashMap getMapVBLImmunity() { - if (!mapVBLImmunity.containsKey("wall")) { - mapVBLImmunity.put("wall", false); + public HashMap getGlobalVBLImmunity() { + if (!globalVBLImmunity.containsKey("WALL_VBL")) { + globalVBLImmunity.put("WALL_VBL", false); } - if (!mapVBLImmunity.containsKey("hill")) { - mapVBLImmunity.put("hill", false); + if (!globalVBLImmunity.containsKey("HILL_VBL")) { + globalVBLImmunity.put("HILL_VBL", false); } - if (!mapVBLImmunity.containsKey("pit")) { - mapVBLImmunity.put("pit", false); + if (!globalVBLImmunity.containsKey("PIT_VBL")) { + globalVBLImmunity.put("PIT_VBL", false); } - if (!mapVBLImmunity.containsKey("cover")) { - mapVBLImmunity.put("cover", false); + if (!globalVBLImmunity.containsKey("COVER_VBL")) { + globalVBLImmunity.put("COVER_VBL", false); } - return new HashMap(mapVBLImmunity); + if (!globalVBLImmunity.containsKey("PC")) { + globalVBLImmunity.put("PC", false); + } + if (!globalVBLImmunity.containsKey("NPC")) { + globalVBLImmunity.put("NPC", false); + } + return new HashMap(globalVBLImmunity); } - public void toggleMapVBLImmunity(String key) { - mapVBLImmunity.put(key, !mapVBLImmunity.get(key)); + public void toggleGlobalVBLImmunity(String key) { + globalVBLImmunity.put(key, !globalVBLImmunity.get(key)); + } + + public void clearGlobalVBLImmunity() { + globalVBLImmunity.clear(); } /** @@ -2998,15 +3009,18 @@ public void updateProperty(Zone zone, Update update, List case removeTokenVBLImmunity: removeTokenVBLImmunity(parameters.get(0).getStringValue()); break; - case setMapVBLImmunity: - setMapVBLImmunity(parameters.get(0).getStringValue(), parameters.get(1).getBoolValue()); + case setGlobalVBLImmunity: + setGlobalVBLImmunity(parameters.get(0).getStringValue(), parameters.get(1).getBoolValue()); break; - case toggleMapVBLImmunity: - toggleMapVBLImmunity(parameters.get(0).getStringValue()); + case toggleGlobalVBLImmunity: + toggleGlobalVBLImmunity(parameters.get(0).getStringValue()); break; case clearTokenVBLImmunity: clearTokenVBLImmunity(); break; + case clearGlobalVBLImmunity: + clearGlobalVBLImmunity(); + break; } if (lightChanged) { getZoneRenderer().flushLight(); // flush lights if it changed @@ -3114,10 +3128,10 @@ public static Token fromDto(TokenDto dto) { (value) -> { token.tokenVBLImmunity.add(value); }); - dto.getMapVblImmunityMap() + dto.getGlobalVblImmunityMap() .forEach( (key, value) -> { - token.setMapVBLImmunity(key, value); + token.setGlobalVBLImmunity(key, value); }); dto.getStateMap() @@ -3280,7 +3294,7 @@ public TokenDto toDto() { dto.setStatSheetProperties(StatSheetProperties.toDto(statSheet)); } - dto.putAllMapVblImmunity(getMapVBLImmunity()); + dto.putAllGlobalVblImmunity(getGlobalVBLImmunity()); dto.addAllTokenVblImmunity(getTokenVBLImmunity()); return dto.build(); diff --git a/src/main/java/net/rptools/maptool/model/Zone.java b/src/main/java/net/rptools/maptool/model/Zone.java index 487195b401..9c2276599e 100644 --- a/src/main/java/net/rptools/maptool/model/Zone.java +++ b/src/main/java/net/rptools/maptool/model/Zone.java @@ -972,15 +972,20 @@ public WallTopology getWalls() { * All other tokens' topology will be included. * * @param types The type of masks to get. - * @param excluding + * @param excludeTokens set of Token IDs to exclude from mask collection + * @param excludeTypes set of mask and token types to exclude from mask collection * @return */ - public List getMasks(Set types, @Nullable GUID excluding) { + public List getMasks( + Set types, Set excludeTokens, Set excludeTypes) { var masks = new ArrayList(); for (var type : types) { - var mapArea = getMaskTopology(type); - var tokenArea = getTokenMaskTopology(type, excluding); + Area mapArea = null; + if (!excludeTypes.contains(type.toString())) { + mapArea = getMaskTopology(type); + } + var tokenArea = getTokenMaskTopology(type, excludeTokens, excludeTypes); if (mapArea != null) { tokenArea.add(mapArea); } @@ -1002,13 +1007,27 @@ public void replaceWalls(WallTopology walls) { * * @return */ - public NodedTopology prepareNodedTopologies() { - if (nodedTopology == null) { - var legacyMasks = getMasks(EnumSet.allOf(TopologyType.class), null); - nodedTopology = NodedTopology.prepare(walls, legacyMasks); + public NodedTopology prepareNodedTopologies(Set excludeTokens, Set excludeTypes) { + NodedTopology tempTopology = null; + if (nodedTopology == null || !excludeTokens.isEmpty() || !excludeTypes.isEmpty()) { + var legacyMasks = getMasks(EnumSet.allOf(TopologyType.class), excludeTokens, excludeTypes); + tempTopology = NodedTopology.prepare(walls, legacyMasks); + } + if (nodedTopology == null + && tempTopology != null + && excludeTokens.isEmpty() + && excludeTypes.isEmpty()) { + nodedTopology = tempTopology; + return nodedTopology; + } else if (tempTopology != null && (!excludeTokens.isEmpty() || !excludeTypes.isEmpty())) { + return tempTopology; + } else { + return nodedTopology; } + } - return nodedTopology; + public NodedTopology prepareNodedTopologies() { + return prepareNodedTopologies(new HashSet<>(), new HashSet<>()); } public Area getMaskTopology(TopologyType topologyType) { @@ -1061,10 +1080,12 @@ public void tokenMaskTopologyChanged(Collection types) { new MapToolEventBus().getMainEventBus().post(new MaskTopologyChanged(this)); } - public Area getTokenMaskTopology(TopologyType type, @Nullable GUID excluding) { + public Area getTokenMaskTopology( + TopologyType type, Set excludeTokens, Set excludeTypes) { var result = new Area(); for (var token : getAllTokens()) { - if (excluding != null && excluding.equals(token.getId())) { + if ((!excludeTokens.isEmpty() && excludeTokens.contains(token.getId().toString())) + || excludeTypes.contains(token.getType().toString())) { continue; } @@ -1076,6 +1097,10 @@ public Area getTokenMaskTopology(TopologyType type, @Nullable GUID excluding) { return result; } + public Area getTokenMaskTopology(TopologyType type) { + return getTokenMaskTopology(type, new HashSet<>(), new HashSet<>()); + } + /** * Fire the event TOKEN_CHANGED * diff --git a/src/main/proto/data_transfer_objects.proto b/src/main/proto/data_transfer_objects.proto index e6159b1b39..4a2d524d70 100644 --- a/src/main/proto/data_transfer_objects.proto +++ b/src/main/proto/data_transfer_objects.proto @@ -366,7 +366,7 @@ message TokenDto { string notes_type = 68; string gm_notes_type = 69; StatSheetPropertiesDto stat_sheet_properties = 70; - map map_vbl_immunity = 73; + map global_vbl_immunity = 73; repeated string token_vbl_immunity = 74; } @@ -663,9 +663,10 @@ enum TokenUpdateDto { setTokenVBLImmunity = 58; addTokenVBLImmunity = 59; removeTokenVBLImmunity = 60; - setMapVBLImmunity = 61; - toggleMapVBLImmunity = 62; + setGlobalVBLImmunity = 61; + toggleGlobalVBLImmunity = 62; clearTokenVBLImmunity = 63; + clearGlobalVBLImmunity = 64; } message AssetTransferHeaderDto { From 581a103d104571e0bec93ed32a24b0ae033f2c4d Mon Sep 17 00:00:00 2001 From: ColdAnkles <13864745+ColdAnkles@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:28:39 +1030 Subject: [PATCH 9/9] Completed Cleanup and JS Token Functions --- .../client/functions/Topology_Functions.java | 8 --- .../script/javascript/api/JSAPIToken.java | 60 +++++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) 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 2f405dca4e..0e818e78ce 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 @@ -668,23 +668,18 @@ public void childEvaluateSetTopologyImmunity( for (JsonElement entry : setList) { newSet.add(entry.getAsString()); } - // token.setTokenVBLImmunity(newSet); MapTool.serverCommand() .updateTokenProperty( token, Token.Update.setTokenVBLImmunity, newSet.toString().replaceAll("^\\[|]$", "")); } else if (functionName.equalsIgnoreCase("addTokenVBLImmunity")) { - // token.addTokenVBLImmunity(parameters.get(1).toString()); MapTool.serverCommand() .updateTokenProperty( token, Token.Update.addTokenVBLImmunity, parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("removeTokenVBLImmunity")) { - // token.removeTokenVBLImmunity(parameters.get(1).toString()); MapTool.serverCommand() .updateTokenProperty( token, Token.Update.removeTokenVBLImmunity, parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("setGlobalVBLImmunity")) { - // token.setGlobalVBLImmunity(parameters.get(1).toString(), - // BigDecimal.ONE.equals(parameters.get(2))); MapTool.serverCommand() .updateTokenProperty( token, @@ -692,15 +687,12 @@ public void childEvaluateSetTopologyImmunity( parameters.get(1).toString(), BigDecimal.ONE.equals(parameters.get(2))); } else if (functionName.equalsIgnoreCase("toggleGlobalVBLImmunity")) { - // token.toggleGlobalVBLImmunity(parameters.get(1).toString()); MapTool.serverCommand() .updateTokenProperty( token, Token.Update.toggleGlobalVBLImmunity, parameters.get(1).toString()); } else if (functionName.equalsIgnoreCase("clearTokenVBLImmunity")) { - // token.clearTokenVBLImmunity(); MapTool.serverCommand().updateTokenProperty(token, Token.Update.clearTokenVBLImmunity); } else if (functionName.equalsIgnoreCase("clearGlobalVBLImmunity")) { - // token.clearGlobalVBLImmunity(); MapTool.serverCommand().updateTokenProperty(token, Token.Update.clearGlobalVBLImmunity); } } 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 0dffe95d9f..3036217d91 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 @@ -14,6 +14,7 @@ */ package net.rptools.maptool.client.script.javascript.api; +import com.google.gson.JsonArray; import java.math.BigDecimal; import java.util.Iterator; import java.util.List; @@ -350,4 +351,63 @@ public void setNPC() { public String getType() { return this.token.getType().name(); } + + @HostAccess.Export + public String getGlobalVBLImmunity() { + JsonArray returnValue = new JsonArray(); + token + .getGlobalVBLImmunity() + .forEach( + (key, value) -> { + if (value) { + returnValue.add(key); + } + }); + return returnValue.toString(); + } + + @HostAccess.Export + public String getTokenVBLImmunity() { + JsonArray returnValue = new JsonArray(); + token + .getTokenVBLImmunity() + .forEach( + (value) -> { + returnValue.add(value); + }); + return returnValue.toString(); + } + + @HostAccess.Export + public void setGlobalVBLImmunity(String vblSelector, boolean setTo) { + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.setGlobalVBLImmunity, vblSelector, setTo); + } + + @HostAccess.Export + public void toggleGlobalVBLImmunity(String vblSelector) { + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.toggleGlobalVBLImmunity, vblSelector); + } + + @HostAccess.Export + public void addTokenVBLImmunity(String tokenID) { + MapTool.serverCommand().updateTokenProperty(token, Token.Update.addTokenVBLImmunity, tokenID); + } + + @HostAccess.Export + public void removeTokenVBLImmunity(String tokenID) { + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.removeTokenVBLImmunity, tokenID); + } + + @HostAccess.Export + public void clearTokenVBLImmunity() { + MapTool.serverCommand().updateTokenProperty(token, Token.Update.clearTokenVBLImmunity); + } + + @HostAccess.Export + public void clearGlobalVBLImmunity() { + MapTool.serverCommand().updateTokenProperty(token, Token.Update.clearGlobalVBLImmunity); + } }