diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index 98f1ea7a..5cb5fdfa 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -482,36 +482,30 @@ TRACE_HAS_TRACES=§ehas Traces TRACE_IDLE_SINGLE=§esingle TRACE_IDLE_AUTO_IGNITE=§eauto TRACE_MESSAGE_AUTO_IDLE_IGNITE = §aAuto-Tracer ignite started -TRACE_MESSAGE_AUTO_DELETE_INVALID = §cAuto delete cannot be used currently -TRACE_MESSAGE_AUTO_DELETE_ALWAYS = §7Last Shot will §ealways §7be deleted -TRACE_MESSAGE_AUTO_DELETE_NEVER = §7Last Shot will §enever §7be deleted -TRACE_MESSAGE_AUTO_DELETE_NO_BUILD_DESTROY = §7Last Shot will be deleted if §eno build §7block was destroyed -TRACE_MESSAGE_AUTO_DELETE_BUILD_DESTROY = §7Last Shot will be deleted if §ea build §7block was destroyed -TRACE_MESSAGE_AUTO_DELETE_NO_TESTBLOCK_DESTROY = §7Last Shot will be deleted if §eno testblock §7block was destroyed -TRACE_MESSAGE_AUTO_DELETE_TESTBLOCK_DESTROY = §7Last Shot will be deleted if §ea testlblock §7block was destroyed TRACE_MESSAGE_START = §aTNT-Tracer started -TRACE_MESSAGE_SINGLE = §aSingle-Tracer started TRACE_MESSAGE_STOP = §cTNT-Tracer stopped TRACE_MESSAGE_DELETE = §cAll TNT-positions deleted +TRACE_MESSAGE_DELETE_SPECIFIC=§cTrace TNT-positions deleted TRACE_MESSAGE_SHOW = §aAll TNT-positions shown TRACE_MESSAGE_HIDE = §cAll TNT-positions hidden -TRACE_MESSAGE_DISALLOWED = §cYou are not allowed to use the TNT-Tracer here -TRACE_MESSAGE_SHOW_AT = §aTNT-positions shown with {0} at {1} -TRACE_MESSAGE_SHOW_FROM = §aAll TNT-positions shown with {0} from {1} -TRACE_MESSAGE_SHOW_FROM_TO = §aAll TNT-positions shown with {0} from {1} to {2} +TRACE_MESSAGE_SHOW_AT=§aTNT-positions shown at {1} +TRACE_MESSAGE_SHOW_FROM=§aAll TNT-positions shown from {1} +TRACE_MESSAGE_SHOW_FROM_TO=§aAll TNT-positions shown from {1} to {2} TRACE_MESSAGE_SHOW_TO_SMALLER = §cTo must be bigger then from TRACE_COMMAND_HELP_START = §8/§etrace start §8- §7Starts recording of all TNT-positions -TRACE_COMMAND_HELP_SINGLE = §8/§etrace single §8- §7Starts a single recording of all TNT-positions TRACE_COMMAND_HELP_STOP = §8/§etrace stop §8- §7Stops the TNT-Tracer TRACE_COMMAND_HELP_AUTO = §8/§etrace toggleauto §8- §7Automatic start of recording -TRACE_COMMAND_HELP_AUTO_REMOVE = §8/§etrace autoremove §8<§eParameter§8> §8- §7Remove last Trace Record automatically TRACE_COMMAND_HELP_SHOW = §8/§etrace show §8<§eParameter§8> - §7Shows all TNT-positions -TRACE_COMMAND_HELP_SHOW_AT = §8/§etrace show §8(§etime§8|§7fuse§8) §7at §8<§eTIME§8> - §7Shows all Trace Positions at §8<§eTIME§8> -TRACE_COMMAND_HELP_SHOW_FROM = §8/§etrace show §8(§etime§8|§7fuse§8) §7from §8<§eFROM§8> - §7Shows all Trace Positions from §8<§eFROM§8> -TRACE_COMMAND_HELP_SHOW_FROM_TO = §8/§etrace show §8(§etime§8|§7fuse§8) §7from §8<§eFROM§8> §7to §8<§eTO§8> - §7Shows all Trace Positions from §8<§eFROM§8> to §8<§eTO§8> +TRACE_COMMAND_HELP_SHOW_AT=§8/§etrace show §7at §8<§eTIME§8> - §7Shows all Trace Positions at §8<§eTIME§8> +TRACE_COMMAND_HELP_SHOW_AT_WITH=§8/§etrace show §7at §8<§eTIME§8> §7with §8<§eParameter§8> - §7Shows all Trace Positions at §8<§eTIME§8> +TRACE_COMMAND_HELP_SHOW_FROM=§8/§etrace show §7from §8<§eFROM§8> - §7Shows all Trace Positions from §8<§eFROM§8> +TRACE_COMMAND_HELP_SHOW_FROM_WITH=§8/§etrace show §7from §8<§eFROM§8> §7with §8<§eParameter§8> - §7Shows all Trace Positions from §8<§eFROM§8> +TRACE_COMMAND_HELP_SHOW_FROM_TO=§8/§etrace show §7from §8<§eFROM§8> §7to §8<§eTO§8> - §7Shows all Trace Positions from §8<§eFROM§8> to §8<§eTO§8> +TRACE_COMMAND_HELP_SHOW_FROM_TO_WITH=§8/§etrace show §7from §8<§eFROM§8> §7to §8<§eTO§8> §7with §8<§eParameter§8> - §7Shows all Trace Positions from §8<§eFROM§8> to §8<§eTO§8> TRACE_COMMAND_HELP_HIDE = §8/§etrace hide §8- §7Hides all TNT-positions -TRACE_COMMAND_HELP_DELETE = §8/§etrace delete §8- §7Deletes all TNT-positions +TRACE_COMMAND_HELP_DELETE=§8/§etrace delete §8[§eTrace§8] §8- §7Deletes all TNT-positions or a Trace +TRACE_COMMAND_HELP_ISOLATE=§8/§etrace isolate §8[§eTrace§8] §8[§eTNT§8] §8- §7Isolates specific TNTs from the Trace TRACE_GUI_ITEM_NAME = §eTracer TRACE_GUI_ITEM_LORE = §7Status§8: {0} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlagHolder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/PlayerTraceShowData.java similarity index 74% rename from BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlagHolder.java rename to BauSystem_Main/src/de/steamwar/bausystem/features/tracer/PlayerTraceShowData.java index a79d969b..8ec215c4 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlagHolder.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/PlayerTraceShowData.java @@ -17,15 +17,25 @@ * along with this program. If not, see . */ -package de.steamwar.bausystem.features.tracer.rendering; +package de.steamwar.bausystem.features.tracer; + +import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; +import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; +import lombok.Getter; +import lombok.Setter; import java.util.*; -public class ViewFlagHolder { +public class PlayerTraceShowData { + + @Getter + @Setter + private BundleFilter bundleFilter; private Map, ViewFlag> viewFlags = new HashMap<>(); - public ViewFlagHolder(ViewFlag... viewFlags) { + public PlayerTraceShowData(BundleFilter bundleFilter, ViewFlag... viewFlags) { + this.bundleFilter = bundleFilter; for (ViewFlag viewFlag : viewFlags) { this.viewFlags.put(viewFlag.getClass(), viewFlag); } @@ -51,10 +61,18 @@ public class ViewFlagHolder { return flagList; } + public boolean hasNoViewFlags() { + return viewFlags.isEmpty(); + } + public boolean hasViewFlag(Class clazz) { return viewFlags.containsKey(clazz); } + public boolean hasViewFlagOnly(Class clazz) { + return viewFlags.containsKey(clazz) && viewFlags.size() == 1; + } + public T getViewFlag(Class clazz) { return (T) viewFlags.get(clazz); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java index 68049eb7..01c597a0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java @@ -23,15 +23,14 @@ import de.steamwar.bausystem.features.tpslimit.TPSUtils; import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; import de.steamwar.bausystem.features.tracer.rendering.TraceEntity; import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; -import de.steamwar.bausystem.features.tracer.rendering.ViewFlagHolder; -import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag; -import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.IsolateFlag; import de.steamwar.bausystem.region.Region; +import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import lombok.Getter; import org.bukkit.entity.Player; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; public class Trace { // TODO: Add UUID for file saving and so on! @@ -54,11 +53,13 @@ public class Trace { // TODO: Add UUID for file saving and so on! private List records = new ArrayList<>(); /** - * ID that should be asigned to the next record of a unique tnt + * ID that should be assigned to the next record of a unique tnt */ @Getter private int nextOpenRecordId = -1; + private final Map entityServerMap = new HashMap<>(); + /** * List of all used ids */ @@ -70,21 +71,6 @@ public class Trace { // TODO: Add UUID for file saving and so on! .collect(Collectors.toList()); } - /** - * A map of players -> REntityServers for rendering traces to a player - */ - private final Map serverMap = new HashMap<>(); - - /** - * A map saving the bundle filters for rendered traces, for life rendering - */ - private final Map bundleFilterMap = new HashMap<>(); - - /** - * A map saving the view flags for rendered traces, for life rendering - */ - private final Map viewFlagMap = new HashMap<>(); - public Trace(Region region) { this.region = region; } @@ -101,15 +87,17 @@ public class Trace { // TODO: Add UUID for file saving and so on! /** * Adds the given records and updates potential trace renderings */ - protected void addAll(List records) { + protected void addAll(List records, Function getter) { this.records.addAll(records); - - for (Player player : serverMap.keySet()) { - REntityServer server = serverMap.get(player); - BundleFilter bundleFilter = bundleFilterMap.getOrDefault(player, BundleFilter.DEFAULT); - ViewFlagHolder viewFlagHolder = viewFlagMap.computeIfAbsent(player, ignored -> new ViewFlagHolder()); - - render(server, records, viewFlagHolder, bundleFilter); + Iterator keySetIterator = entityServerMap.keySet().iterator(); + while (keySetIterator.hasNext()) { + Player player = keySetIterator.next(); + PlayerTraceShowData playerTraceShowData = getter.apply(player); + if (playerTraceShowData == null) { + keySetIterator.remove(); + continue; + } + render(getRecords(), entityServerMap.get(player), playerTraceShowData); } } @@ -130,7 +118,7 @@ public class Trace { // TODO: Add UUID for file saving and so on! public Set> getHistories() { Set> histories = new HashSet<>(); - for (TNTRecord record : records) { + for (TNTRecord record : getRecords()) { histories.add(record.getHistory()); } @@ -140,43 +128,31 @@ public class Trace { // TODO: Add UUID for file saving and so on! /** * Renders this traces * - * @param player The player the trace is rendered to - * @param viewFlagHolder Flags modefieing the rendering - * @param bundleFilter Filter to determin bundeling of records + * @param player The player the trace is rendered to + * @param playerTraceShowData The showData for modifying the rendering */ - public void render(Player player, ViewFlagHolder viewFlagHolder, BundleFilter bundleFilter) { - if (serverMap.containsKey(player)) { - REntityServer server = serverMap.get(player); - server.close(); - - serverMap.remove(player); - viewFlagMap.remove(player); - bundleFilterMap.remove(player); + public void render(Player player, PlayerTraceShowData playerTraceShowData) { + REntityServer entityServer = entityServerMap.get(player); + if (entityServer != null) { + entityServer.getEntities().forEach(REntity::die); + } else { + entityServer = new REntityServer(); + entityServerMap.put(player, entityServer); } - - viewFlagMap.put(player, viewFlagHolder); - bundleFilterMap.put(player, bundleFilter); - - REntityServer server = new REntityServer(); - server.addPlayer(player); - serverMap.put(player, server); - - render(server, records, viewFlagHolder, bundleFilter); + render(getRecords(), entityServer, playerTraceShowData); } /** * Internal methode to render records to a REntityServer * - * @param server Server to render to - * @param records Records to render - * @param viewFlagHolder Flags modefieing the rendering - * @param bundleFilter Filter to determin bundeling of records + * @param records Records to render + * @param playerTraceShowData The showData for modifying the rendering */ - private void render(REntityServer server, List records, ViewFlagHolder viewFlagHolder, BundleFilter bundleFilter) { + private void render(List records, REntityServer entityServer, PlayerTraceShowData playerTraceShowData) { if (records.isEmpty()) return; List workingRecords = records; - Set flagList = viewFlagHolder.getEffectiveViewFlags(); + Set flagList = playerTraceShowData.getEffectiveViewFlags(); //Apply filters for (ViewFlag flag : flagList) { @@ -184,28 +160,27 @@ public class Trace { // TODO: Add UUID for file saving and so on! } //Bundle records at unique positions - List> bundles = bundleRecords(workingRecords, bundleFilter); + List> bundles = bundleRecords(workingRecords, playerTraceShowData.getBundleFilter()); //Render bundled records List entities = new LinkedList<>(); for (List bundle : bundles) { - entities.add(new TraceEntity(server, bundle.get(0).getLocation(), bundle.get(0).isExplosion(), bundle)); + entities.add(new TraceEntity(entityServer, bundle.get(0).getLocation(), bundle.get(0).isExplosion(), bundle)); } //Apply modifiers for (ViewFlag flag : flagList) { - flag.modify(server, entities); + flag.modify(entityServer, entities); } - - server.setCallback(((player, rEntity, entityAction) -> { + entityServer.setCallback((player, rEntity, entityAction) -> { for (TraceEntity entity : entities) { if (rEntity.equals(entity)) { entity.printIntoChat(player); return; } } - })); + }); } /** @@ -243,48 +218,6 @@ public class Trace { // TODO: Add UUID for file saving and so on! return bundles; } - - /** - * Modifies the render for the given player, to only show tnts at the given time interval - * - * @param player - * @param from start of time interval - * @param to end of time interval - */ - public void renderAt(Player player, int from, int to) { - ViewFlagHolder viewFlags = viewFlagMap.computeIfAbsent(player, p -> new ViewFlagHolder()); - if (viewFlags.hasViewFlag(AtFlag.class)) { - viewFlags.getViewFlag(AtFlag.class).update(from, to); - } else { - viewFlags.addViewFlag(new AtFlag(from, to)); - } - render(player, viewFlags, BundleFilter.STRICT); - } - - /** - * Toggles the isolated render for the given records and player - * - * @param player the player the trace is shown to - * @param records the record for which isolation is toggled - */ - public void isolate(Player player, TNTRecord... records) { - IsolateFlag isolateFlag; - ViewFlagHolder viewFlags = viewFlagMap.get(player); - if (viewFlags != null && viewFlags.hasViewFlag(IsolateFlag.class)) { - isolateFlag = viewFlags.getViewFlag(IsolateFlag.class); - } else { - viewFlags = new ViewFlagHolder(); - isolateFlag = new IsolateFlag(); - viewFlags.addViewFlag(isolateFlag); - } - - for (TNTRecord record : records) { - isolateFlag.toggleId(record.getTntId()); - } - - render(player, viewFlags, BundleFilter.STRICT); - } - /** * Makes the first passed player follow the trace render of the second passed player * @@ -292,11 +225,7 @@ public class Trace { // TODO: Add UUID for file saving and so on! * @param toFollow */ public void follow(Player player, Player toFollow) { - for (REntityServer server : serverMap.values()) { - server.removePlayer(player); - } - - serverMap.get(toFollow).addPlayer(player); + throw new UnsupportedOperationException(); } /** @@ -305,13 +234,7 @@ public class Trace { // TODO: Add UUID for file saving and so on! * @param player */ public void unfollow(Player player) { - for (REntityServer server : serverMap.values()) { - server.removePlayer(player); - } - - if (serverMap.get(player) != null) { - serverMap.get(player).addPlayer(player); - } + throw new UnsupportedOperationException(); } /** @@ -320,12 +243,8 @@ public class Trace { // TODO: Add UUID for file saving and so on! * @param player */ public void hide(Player player) { - REntityServer server = serverMap.get(player); - if (server == null) return; - - bundleFilterMap.remove(player); - viewFlagMap.remove(player); - server.close(); + REntityServer entityServer = entityServerMap.remove(player); + if (entityServer != null) entityServer.close(); } @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java index 8dbc9583..854deaed 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java @@ -22,7 +22,7 @@ package de.steamwar.bausystem.features.tracer; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; -import de.steamwar.bausystem.features.tracer.rendering.ViewFlagHolder; +import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag; import de.steamwar.bausystem.region.Region; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; @@ -43,6 +43,7 @@ public class TraceCommand extends SWCommand { @LinkedInstance public TraceRecorder traceRecorder; + @LinkedInstance public TraceManager manager; @@ -64,44 +65,87 @@ public class TraceCommand extends SWCommand { BauSystem.MESSAGE.send("TRACE_MESSAGE_STOP", player); } - @Register(value = "auto", description = "TRACE_COMMAND_HELP_SHOW") + @Register(value = "auto", description = "TRACE_COMMAND_HELP_AUTO") public void auto(@Validator Player player) { Region region = Region.getRegion(player.getLocation()); traceRecorder.toggleAutoTrace(region); + // TODO: Add Auto toggle Message! } @Register(value = "show", description = "TRACE_COMMAND_HELP_SHOW") - public void show(@Validator Player player, @OptionalValue("STRICT") BundleFilter filter, ViewFlag... flags) { - manager.show(player, new ViewFlagHolder(flags), filter); + public void show(@Validator Player player, @OptionalValue("STRICT") BundleFilter bundleFilter, ViewFlag... flags) { + showInternal(player, 0, Integer.MAX_VALUE, bundleFilter, flags); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW", player); } - @Register(value = "hide", description = "TRACE_COMMAND_HELP_SHOW") + @Register(value = {"show", "at"}, description = "TRACE_COMMAND_HELP_SHOW_AT_WITH") + public void showAt(@Validator Player player, @Min(intValue = 0) int time, @StaticValue("with") String with, @OptionalValue("STRICT") BundleFilter bundleFilter, @ArrayLength(min = 1) ViewFlag... flags) { + showInternal(player, time, time, bundleFilter, flags); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_AT", player, time); + } + + @Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_WITH") + public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("with") String with, @OptionalValue("STRICT") BundleFilter bundleFilter, @ArrayLength(min = 1) ViewFlag... flags) { + showInternal(player, from, Integer.MAX_VALUE, bundleFilter, flags); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM", player, from); + } + + @Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO_WITH") + public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString, int to, @StaticValue("with") String with, @OptionalValue("STRICT") BundleFilter bundleFilter, @ArrayLength(min = 1) ViewFlag... flags) { + if (to < from) { + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_TO_SMALLER", player); + return; + } + showInternal(player, from, to, bundleFilter, flags); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM_TO", player, from, to); + } + + private void showInternal(Player player, int from, int to, BundleFilter bundleFilter, ViewFlag... flags) { + PlayerTraceShowData playerTraceShowData = new PlayerTraceShowData(bundleFilter, flags); + playerTraceShowData.addViewFlag(new AtFlag(from, to)); + manager.show(player, playerTraceShowData); + } + + @Register(value = {"show", "at"}, description = "TRACE_COMMAND_HELP_SHOW_AT") + public void showAt(@Validator Player player, @Min(intValue = 0) int time) { + manager.renderAt(player, time, time); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_AT", player, time); + } + + @Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM") + public void showFrom(@Validator Player player, @Min(intValue = 0) int from) { + manager.renderAt(player, from, Integer.MAX_VALUE); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM", player, from); + } + + @Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO") + public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString, int to) { + manager.renderAt(player, from, to); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM_TO", player, from, to); + } + + @Register(value = "hide", description = "TRACE_COMMAND_HELP_HIDE") public void hide(@Validator Player player) { manager.hide(player); BauSystem.MESSAGE.send("TRACE_MESSAGE_HIDE", player); } - @Register(value = "delete", description = "TRACE_COMMAND_HELP_SHOW") + @Register(value = "delete", description = "TRACE_COMMAND_HELP_DELETE") public void delete(@Validator Player player) { manager.clear(); + BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE", player); } - @Register(value = "delete", description = "TRACE_COMMAND_HELP_SHOW") - public void delete(@Validator Player player, int id) { - manager.remove(id); + @Register(value = "delete") + public void delete(@Validator Player player, Trace trace) { + // TODO: Reimplement manager.remove(trace); + BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE_SPECIFIC", player); } - @Register(value = "isolate", description = "TRACE_COMMAND_HELP_SHOW") + @Register(value = "isolate", description = "TRACE_COMMAND_HELP_ISOLATE") public void isolate(@Validator Player player, Trace trace, @ErrorMessage("TRACE_RECORD_ID_INVALID") TNTRecord... records) { - trace.isolate(player, records); - } - - @Register(value = "at", description = "TRACE_COMMAND_HELP_SHOW") - public void at(@Validator Player player, int start, int end) { - for (Trace trace : manager.getAll()) { - trace.renderAt(player, start, end); - } + manager.isolate(player, records); + // TODO: Add Message! } @Register(value = "share", description = "TRACE_COMMAND_HELP_SHOW") @@ -111,6 +155,7 @@ public class TraceCommand extends SWCommand { @Register(value = "follow", description = "TRACE_COMMAND_HELP_SHOW") public void follow(@Validator Player player, Player toFollow) { + // TODO: Implement for (Trace trace : manager.getAll()) { trace.follow(player, toFollow); } @@ -118,6 +163,7 @@ public class TraceCommand extends SWCommand { @Register(value = "unfollow", description = "TRACE_COMMAND_HELP_SHOW") public void unfollow(@Validator Player player) { + // TODO: Implement for (Trace trace : manager.getAll()) { trace.unfollow(player); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java index 47819a75..1e693207 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java @@ -20,7 +20,8 @@ package de.steamwar.bausystem.features.tracer; import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; -import de.steamwar.bausystem.features.tracer.rendering.ViewFlagHolder; +import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag; +import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.IsolateFlag; import de.steamwar.bausystem.region.Region; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; @@ -37,15 +38,7 @@ public class TraceManager implements Listener { private final Map> tracesByRegion = new HashMap<>(); - /** - * A map saving the view flags used by Players - */ - private final Map viewFlagMap = new HashMap<>(); - - /** - * A map saving the bundle filter used by Players - */ - private final Map bundleFilterMap = new HashMap<>(); + private final Map> showDataPerRegionPerPlayer = new HashMap<>(); /** * Utility variable to keep track of the next open trace id; @@ -59,15 +52,21 @@ public class TraceManager implements Listener { * @return id of the created trace */ protected int add(Trace trace) { - for (Player player : viewFlagMap.keySet()) { - trace.render(player, viewFlagMap.get(player), bundleFilterMap.get(player)); - } + showDataPerRegionPerPlayer.getOrDefault(trace.getRegion(), Collections.emptyMap()).forEach((player, playerTraceShowData) -> { + trace.render(player, playerTraceShowData); + }); traces.put(nextOpenId, trace); tracesByRegion.computeIfAbsent(trace.getRegion(), region -> new HashMap<>()).put(nextOpenId, trace); nextOpenId++; return nextOpenId; } + protected void addAll(Trace trace, List tntRecords) { + trace.addAll(tntRecords, player -> { + return showDataPerRegionPerPlayer.getOrDefault(trace.getRegion(), Collections.emptyMap()).get(player); + }); + } + /** * Removes the trace with the given id * @@ -76,13 +75,11 @@ public class TraceManager implements Listener { public boolean remove(int id) { if (id >= nextOpenId) return false; if (traces.get(id) == null) return false; - for (Player player : viewFlagMap.keySet()) { - traces.get(id).hide(player); - } Trace trace = traces.remove(id); - if (trace != null) { - tracesByRegion.get(trace.getRegion()).remove(id); - } + showDataPerRegionPerPlayer.get(trace.getRegion()).forEach((player, playerTraceShowData) -> { + trace.hide(player); + }); + tracesByRegion.get(trace.getRegion()).remove(id); return true; } @@ -90,11 +87,15 @@ public class TraceManager implements Listener { * Clears all traces */ public void clear() { - for (Player player : viewFlagMap.keySet()) { - for (Trace trace : traces.values()) { - trace.hide(player); - } - } + showDataPerRegionPerPlayer.values() + .stream() + .flatMap(map -> map.entrySet().stream()) + .map(Map.Entry::getKey) + .forEach(player -> { + traces.values().forEach(trace -> { + trace.hide(player); + }); + }); traces.clear(); tracesByRegion.clear(); nextOpenId = 0; @@ -117,10 +118,7 @@ public class TraceManager implements Listener { * @return the trace with given id or null if no trace with id is found */ public Optional get(int index) { - if (index < traces.size()) { - return Optional.of(traces.get(index)); - } - return Optional.empty(); + return Optional.ofNullable(traces.get(index)); } /** @@ -140,32 +138,87 @@ public class TraceManager implements Listener { } /** - * Toggles trace show on for player + * Shows traces for the player of the current Region * * @param player - * @param viewFlagHolder - * @param bundleFilter + * @param playerTraceShowData */ - public void show(Player player, ViewFlagHolder viewFlagHolder, BundleFilter bundleFilter) { - viewFlagMap.put(player, viewFlagHolder); - bundleFilterMap.put(player, bundleFilter); - - for (Trace trace : traces.values()) { - trace.render(player, viewFlagHolder, bundleFilter); - } + public void show(Player player, PlayerTraceShowData playerTraceShowData) { + Region region = Region.getRegion(player.getLocation()); + showDataPerRegionPerPlayer.computeIfAbsent(region, ignored -> new HashMap<>()).put(player, playerTraceShowData); + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.render(player, playerTraceShowData); + }); } /** - * Toggles trace show of for player + * Hides traces for the player of the current Region * * @param player */ public void hide(Player player) { - for (Trace trace : traces.values()) { + Region region = Region.getRegion(player.getLocation()); + PlayerTraceShowData previous = showDataPerRegionPerPlayer.getOrDefault(region, Collections.emptyMap()).remove(player); + if (previous == null) return; + tracesByRegion.getOrDefault(player, Collections.emptyMap()).forEach((integer, trace) -> { trace.hide(player); + }); + } + + /** + * Modifies the render for the given player, to only show tnts at the given time interval + * + * @param player + * @param from start of time interval + * @param to end of time interval + */ + public void renderAt(Player player, int from, int to) { + Region region = Region.getRegion(player.getLocation()); + PlayerTraceShowData playerTraceShowData = showDataPerRegionPerPlayer.computeIfAbsent(region, ignored -> new HashMap<>()).computeIfAbsent(player, ignored -> new PlayerTraceShowData(BundleFilter.STRICT)); + + AtFlag atFlag = playerTraceShowData.getViewFlag(AtFlag.class); + if (atFlag == null) { + atFlag = new AtFlag(from, to); + playerTraceShowData.addViewFlag(atFlag); + } else { + atFlag.update(from, to); } - viewFlagMap.remove(player); - bundleFilterMap.remove(player); + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.render(player, playerTraceShowData); + }); + } + + /** + * Toggles the isolated render for the given records and player + * + * @param player the player the trace is shown to + * @param records the record for which isolation is toggled + */ + public void isolate(Player player, TNTRecord... records) { + Region region = Region.getRegion(player.getLocation()); + PlayerTraceShowData playerTraceShowData = showDataPerRegionPerPlayer.computeIfAbsent(region, ignored -> new HashMap<>()).computeIfAbsent(player, ignored -> new PlayerTraceShowData(BundleFilter.STRICT)); + + IsolateFlag isolateFlag; + if (playerTraceShowData.hasViewFlagOnly(IsolateFlag.class)) { + isolateFlag = playerTraceShowData.getViewFlag(IsolateFlag.class); + } else if (playerTraceShowData.hasNoViewFlags()) { + isolateFlag = new IsolateFlag(); + playerTraceShowData.addViewFlag(isolateFlag); + } else { + playerTraceShowData = new PlayerTraceShowData(BundleFilter.STRICT); + isolateFlag = new IsolateFlag(); + playerTraceShowData.addViewFlag(isolateFlag); + showDataPerRegionPerPlayer.get(region).put(player, playerTraceShowData); + } + + for (TNTRecord record : records) { + isolateFlag.toggleId(record.getTntId()); + } + + PlayerTraceShowData finalPlayerTraceShowData = playerTraceShowData; + tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { + trace.render(player, finalPlayerTraceShowData); + }); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java index 58f719bf..da31507a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java @@ -159,8 +159,10 @@ public class TraceRecorder implements Listener { for (TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) { record(tnt, trace, Collections.emptyList()); } - trace.addAll(recordsToAddMap.get(trace)); - recordsToAddMap.get(trace).clear(); + + List tntRecords = recordsToAddMap.get(trace); + manager.addAll(trace, tntRecords); + tntRecords.clear(); } }