diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Recorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Recorder.java index 30ff7d73..8eab6d0f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Recorder.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Recorder.java @@ -63,6 +63,11 @@ public class Recorder implements Listener { */ private final Set noExplosionRecorded = new HashSet<>(); + /** + * A map for records that have been taken in the same tick and now have to be added to the traces + */ + private final Map> recordsToAddMap = new HashMap<>(); + /** * Maps a tracked tnt entity to its entire recording history */ @@ -111,6 +116,7 @@ public class Recorder implements Listener { Trace trace = new Trace(region); noExplosionRecorded.add(trace); activeTraces.put(region, trace); + recordsToAddMap.put(trace, new ArrayList<>()); return manager.add(trace); } @@ -128,6 +134,7 @@ public class Recorder implements Listener { for(TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) historyMap.remove(tnt); + recordsToAddMap.remove(trace); trackedTNT.put(region, new ArrayList<>()); } @@ -141,7 +148,8 @@ public class Recorder implements Listener { for(TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())){ record(tnt, trace, Collections.emptyList()); } - trace.commitAdd(); + trace.addAll(recordsToAddMap.get(trace)); + recordsToAddMap.get(trace).clear(); } } @@ -152,11 +160,11 @@ public class Recorder implements Listener { */ private void record(TNTPrimed tntPrimed, Trace trace, List destroyedBlocks){ List history = historyMap.getOrDefault(tntPrimed, new ArrayList<>()); - UUID tntID; + int tntID; if(history.size() == 0){ historyMap.put(tntPrimed, history); - tntID = UUID.randomUUID(); + tntID = trace.getAndIncrementNextOpenRecordId(); } else tntID = history.get(0).getTntId(); @@ -169,7 +177,7 @@ public class Recorder implements Listener { TNTRecord record = new TNTRecord(tntID, tntPrimed, isExplosion, afterFirstExplosion, TPSUtils.currentTick.get() - trace.getStartTime(), history, destroyedBlocks); history.add(record); - trace.add(record); + recordsToAddMap.get(trace).add(record); } /** Event for TNTs beeing spawn. @@ -192,6 +200,7 @@ public class Recorder implements Listener { trackedTNT.get(region).add((TNTPrimed) event.getEntity()); tntSpawnRegion.put((TNTPrimed) event.getEntity(), region); + record((TNTPrimed) event.getEntity(), activeTraces.get(region), Collections.emptyList()); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTRecord.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTRecord.java index ee22eaeb..27aec28e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTRecord.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTRecord.java @@ -38,7 +38,7 @@ public class TNTRecord { /** * Unique number to identify records being of the same tnt */ - private final UUID tntId; + private final int tntId; /** * Whether this is a record of a tnt explosion or an entity @@ -90,7 +90,7 @@ public class TNTRecord { */ private final List history; - public TNTRecord(UUID tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart, List history, List destroyedBlocks){ + public TNTRecord(int tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart, List history, List destroyedBlocks){ this.tntId = tntId; this.explosion = explosion; this.inWater = tnt.isInWater(); @@ -107,7 +107,7 @@ public class TNTRecord { if (Region.getRegion(destroyedBlock.getLocation()).inRegion(destroyedBlock.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION)) buildDestroy = true; if (Region.getRegion(destroyedBlock.getLocation()).inRegion(destroyedBlock.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) - buildDestroy = true; + testblockDestroy = true; } destroyedBuildArea = buildDestroy; @@ -136,4 +136,15 @@ public class TNTRecord { ", velocity=" + velocity + '}'; } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof TNTRecord)) return false; + TNTRecord record = (TNTRecord) obj; + + if(record.isExplosion() != explosion) return false; + if(!record.getLocation().equals(location)) return false; + if(!record.getVelocity().equals(velocity)) return false; + return true; + } } 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 705964fc..1572c1ad 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java @@ -23,12 +23,16 @@ 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.dynamicFlags.AtFlag; +import de.steamwar.bausystem.features.tracer.rendering.dynamicFlags.IsolateFlag; import de.steamwar.bausystem.region.Region; import de.steamwar.entity.REntityServer; import lombok.Getter; import org.bukkit.entity.Player; +import java.lang.reflect.Array; import java.util.*; +import java.util.stream.Stream; public class Trace { /** @@ -50,9 +54,16 @@ public class Trace { private List records = new ArrayList<>(); /** - * Records to be added + * ID that should be asigned to the next record of a unique tnt */ - private List newRecords = new ArrayList<>(); + @Getter + private int nextOpenRecordId = -1; + + /** + * List of all used ids + */ + @Getter + private final List usedIds = new ArrayList(); /** * A map of players -> REntityServers for rendering traces to a player @@ -73,28 +84,29 @@ public class Trace { this.region = region; } - /** Methode to add a records to add staging - * - * @param records records to add + /** + * Gets and increments the next open record id + * @return next open record id */ - protected void add (TNTRecord records){ - newRecords.add(records); + protected int getAndIncrementNextOpenRecordId(){ + nextOpenRecordId++; + usedIds.add(Integer.toString(nextOpenRecordId)); + return nextOpenRecordId; } /** - * Commits the additions made to this trace and updates active renders of this trace + * Adds the given records and updates potential trace renderings */ - protected void commitAdd(){ - records.addAll(newRecords); + protected void addAll(List records){ + this.records.addAll(records); for(Player player: serverMap.keySet()){ REntityServer server = serverMap.get(player); BundleFilter bundleFilter = bundleFilterMap.get(player); ViewFlag[] viewFlags = viewFlagMap.get(player); - render(server, newRecords, viewFlags, bundleFilter); + render(server, records, viewFlags, bundleFilter); } - newRecords.clear(); } /** Internal methode to make records immutable after recording is finished @@ -105,8 +117,9 @@ public class Trace { this.records = records; } - /** + /** Gets the historys of all tnts in this trace * + * @return the historys of this trace */ public Set> getHistories() { Set> histories = new HashSet<>(); @@ -151,25 +164,30 @@ public class Trace { * @param flags Flags modefieing the rendering * @param bundleFilter Filter to determin bundeling of records */ - private void render (REntityServer server, List records, ViewFlag[] flags, BundleFilter bundleFilter){ + private void render(REntityServer server, List records, ViewFlag[] flags, BundleFilter bundleFilter){ if(records.size() == 0) return; List workingRecords = records; - List flagList = new ArrayList<>(); - - //Manage inverse flags - flagList.addAll(ViewFlag.inverseFlags); - for(ViewFlag flag: flags){ - if(flagList.contains(flag)) - flagList.remove(flag); - else - flagList.add(flag); + //Manage flags and required flags + Set flagList = new HashSet<>(Arrays.asList(flags)); + for (ViewFlag flag : flags) { + if (flag.required != null) { + flagList.addAll(Arrays.asList(flag.required)); + } } + //Manage inverse flags + ViewFlag.inverseFlags.forEach(viewFlag -> { + if (!flagList.remove(viewFlag)) { + flagList.add(viewFlag); + } + }); + //Apply filters - for(ViewFlag flag : flagList) + for(ViewFlag flag : flagList) { workingRecords = flag.filter(workingRecords); + } //Bundle records at unique positions List> bundles = bundleRecords(workingRecords, bundleFilter); @@ -177,12 +195,23 @@ public class Trace { //Render bundled records List entities = new LinkedList<>(); - for(List bundle : bundles) + for(List bundle : bundles) { entities.add(new TraceEntity(server, bundle.get(0).getLocation(), bundle.get(0).isExplosion(), bundle)); + } //Apply modifiers - for(ViewFlag flag : flags) + for(ViewFlag flag : flags) { flag.modify(server, entities); + } + + server.setCallback(((player, rEntity, entityAction) -> { + for(TraceEntity entity: entities){ + if(((TraceEntity) rEntity).equals(entity)){ + entity.printIntoChat(player); + return; + } + } + })); } /** Bundles the passed TNTRecords based on whether they are at the same location @@ -220,6 +249,94 @@ public class Trace { 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){ + ViewFlag[] viewFlags = viewFlagMap.get(player); + if(viewFlags == null) return; + + AtFlag atFlag = null; + atFlag = Stream.of(viewFlags) + .filter(AtFlag.class::isInstance) + .map(AtFlag.class::cast) + .findFirst() + .orElse(null); + + if(atFlag != null){ + atFlag.update(from, to); + } + else { + atFlag = new AtFlag(from, to); + viewFlags = Arrays.copyOf(viewFlags, viewFlags.length + 1); + viewFlags[viewFlags.length - 1] = atFlag; + } + + 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 isolationFlag = null; + + ViewFlag[] viewFlags = viewFlagMap.get(player); + if(viewFlags != null) { + isolationFlag = Stream.of(viewFlags) + .filter(IsolateFlag.class::isInstance) + .map(IsolateFlag.class::cast) + .findFirst() + .orElse(null); + } + + if (viewFlags == null || isolationFlag == null) { + viewFlags = new ViewFlag[1]; + } + if (isolationFlag == null) { + isolationFlag = new IsolateFlag(); + } + viewFlags[0] = isolationFlag; + + for(TNTRecord record: records) + isolationFlag.toggleId(record.getTntId()); + + render(player, viewFlags, BundleFilter.STRICT); + } + + /**Makes the first passed player follow the trace render of the second passed player + * + * @param player + * @param toFollow + */ + public void follow(Player player, Player toFollow){ + for(REntityServer server :serverMap.values()){ + server.removePlayer(player); + } + + serverMap.get(toFollow).addPlayer(player); + } + + /** Makes the passed player stop following any other players trace render + * + * @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); + } + } + /** Hides this trail for the given player * * @param player 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 fcbb6665..640b898b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java @@ -21,21 +21,23 @@ 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.TraceEntity; import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; +import de.steamwar.bausystem.features.tracer.rendering.dynamicFlags.IsolateFlag; import de.steamwar.bausystem.region.Region; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; +import de.steamwar.command.TypeValidator; +import de.steamwar.entity.REntityServer; import de.steamwar.linkage.Linked; import de.steamwar.linkage.LinkedInstance; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; @Linked public class TraceCommand extends SWCommand { @@ -81,14 +83,89 @@ public class TraceCommand extends SWCommand { @Register(value = "delete", description = "TRACE_COMMAND_HELP_SHOW") public void delete(Player player){ manager.clear(); - //BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE_ALL", player); } - //TODO Manage non exsistent trace @Register(value = "delete", description = "TRACE_COMMAND_HELP_SHOW") public void delete(Player player, int id){ manager.remove(id); - //BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE", player); + } + + @Register(value = "isolate", description = "TRACE_COMMAND_HELP_SHOW") + public void isolate(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(Player player, int start, int end){ + for(Trace trace: manager.getAll()){ + trace.renderAt(player, start, end); + } + } + @Register(value="share", description = "TRACE_COMMAND_HELP_SHOW") + public void share(Player player){ + //TODO Rücksprache + } + + @Register(value="follow", description = "TRACE_COMMAND_HELP_SHOW") + public void follow(Player player, Player toFollow){ + for(Trace trace: manager.getAll()){ + trace.follow(player, toFollow); + } + } + + @Register(value="unfollow", description = "TRACE_COMMAND_HELP_SHOW") + public void unfollow(Player player){ + for(Trace trace: manager.getAll()){ + trace.unfollow(player); + } + } + + @ClassMapper(value = Trace.class, local = true) + public TypeMapper traceClassMapper(){ + return new TypeMapper() { + @Override + public Trace map(CommandSender commandSender, String[] previousArguments, String s) { + int id = Integer.parseInt(s); + + Optional trace = manager.get(id); + + return trace.orElse(null); + } + + @Override + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + return manager.getAllIds().stream() + .map(id -> id.toString()) + .collect(Collectors.toList()); + } + }; + } + + @ClassMapper(value = TNTRecord.class, local = true) + public TypeMapper recordMapper() { + return new TypeMapper() { + @Override + public TNTRecord map(CommandSender commandSender, PreviousArguments previousArguments, String s) { + Trace trace = previousArguments.getFirst(Trace.class).orElse(null); + if(trace == null) return null; + + int id = Integer.parseInt(s); + + return trace.getRecords().stream() + .filter(record -> record.getTntId() == id) + .findFirst() + .orElse(null); + } + + //TODO change when new command framework update + @Override + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + Trace trace = previousArguments.getFirst(Trace.class).orElse(null); + if(trace == null) return null; + + return trace.getUsedIds(); + } + }; } @ClassMapper(value = BundleFilter.class, local = true) @@ -125,7 +202,7 @@ public class TraceCommand extends SWCommand { return flag; for(String alias: flag.aliases) - if (s.equals("--" + alias)) + if (s.equals("-" + alias)) return flag; } return null; @@ -133,8 +210,8 @@ public class TraceCommand extends SWCommand { @Override public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { return ViewFlag.flags.stream() - .map(flag -> flag.name) - .map(name -> "--" + name) + .flatMap(viewFlag -> Stream.concat(Stream.of("--" + viewFlag.name), + Arrays.stream(viewFlag.aliases).map(name -> "-" + name))) .collect(Collectors.toList()); } }; 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 786fe8e5..1ef128f5 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java @@ -63,7 +63,7 @@ public class TraceManager implements Listener { trace.render(player, viewFlagMap.get(player), bundleFilterMap.get(player)); traces.put(nextOpenId, trace); nextOpenId++; - return nextOpenId--; + return nextOpenId; } /** Removes the trace with the given id @@ -72,6 +72,7 @@ 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); traces.remove(id); @@ -119,6 +120,11 @@ public class TraceManager implements Listener { return new ArrayList<>(traces.values()); } + /** + * @return all ids of active traces + */ + public Set getAllIds(){return traces.keySet();} + /** Toggles trace show on for player * * @param player @@ -143,5 +149,5 @@ public class TraceManager implements Listener { viewFlagMap.remove(player); bundleFilterMap.remove(player); - }; + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/BundleFilter.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/BundleFilter.java index 3ce9e03e..e511c923 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/BundleFilter.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/BundleFilter.java @@ -26,7 +26,7 @@ import java.util.function.BiFunction; public enum BundleFilter { - + //TODO chagne optional to true flase null LOOSE((TNTRecord a, TNTRecord b) -> { if(a.isExplosion() != b.isExplosion()) return Optional.of(false); if(a.getLocation().distance(b.getLocation()) <= BundleFilter.pixelSize) return Optional.of(false); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java index a930ec57..ebfb6e43 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java @@ -19,12 +19,17 @@ package de.steamwar.bausystem.features.tracer.rendering; +import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.tracer.TNTRecord; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RFallingBlockEntity; import lombok.Getter; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityInteractEvent; import java.util.List; @@ -41,4 +46,25 @@ public class TraceEntity extends RFallingBlockEntity { setNoGravity(true); this.records = records; } + + public void printIntoChat(Player player){ + TNTRecord representative = records.get(0); + + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", player); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_FUSE_TIME", player, representative.getFuse()); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_X", player, representative.getLocation().getX() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", player, representative.getLocation().getY() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", player, representative.getLocation().getZ() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", player, representative.getVelocity().getX() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", player, representative.getVelocity().getY() + ""); + BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", player, representative.getVelocity().getZ() + ""); + } + + @Override + public boolean equals(Object object) { + if(!(object instanceof TraceEntity)) return false; + TraceEntity entity = (TraceEntity) object; + + return records.get(0).equals(entity.getRecords().get(0)); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java index 7798a679..c38c02a7 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java @@ -20,17 +20,16 @@ package de.steamwar.bausystem.features.tracer.rendering; import de.steamwar.bausystem.features.tracer.TNTRecord; -import de.steamwar.bausystem.features.tracer.rendering.TraceEntity; -import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RFallingBlockEntity; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.util.Vector; -import java.util.*; -import java.util.function.BiConsumer; -import java.util.function.UnaryOperator; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; public abstract class ViewFlag { @@ -44,7 +43,7 @@ public abstract class ViewFlag { */ public static final List inverseFlags = new ArrayList<>(); - public static ViewFlag EXPLOSION = new ViewFlag(true, false,"explosion") { + public static ViewFlag EXPLOSION = new ViewFlag(true, false,"explosion", "e") { @Override public List filter(List records) { return records.stream() @@ -56,7 +55,7 @@ public abstract class ViewFlag { public void modify(REntityServer server, List entities) {} }; - public static ViewFlag IGNITE = new ViewFlag(true, true, "ignite") { + public static ViewFlag IGNITE = new ViewFlag(true, true, "ignite", "i") { @Override public List filter(List records) { return records.stream() @@ -68,7 +67,7 @@ public abstract class ViewFlag { public void modify(REntityServer server, List entities) {} }; - public static ViewFlag SOURCE = new ViewFlag(true, false, "source") { + public static ViewFlag SOURCE = new ViewFlag(true, false, IGNITE, "source", "s") { @Override public List filter(List records) { return records.stream() @@ -104,10 +103,10 @@ public abstract class ViewFlag { public void modify(REntityServer server, List entities) {} }; - public static ViewFlag MICROMOTION = new ViewFlag(true, false, "micromotion") { + public static ViewFlag MICROMOTION = new ViewFlag(true, false, "micromotion", "m") { @Override public List filter(List records) { - Set seen = new HashSet<>(); + Set seen = new HashSet<>(); Set toRemove = new HashSet<>(); for(TNTRecord uniqueRecord: records){ @@ -139,37 +138,40 @@ public abstract class ViewFlag { public void modify(REntityServer server, List entities) {} }; - public static ViewFlag ADVANCED = new ViewFlag(true, false, "advanced") { + public static ViewFlag ADVANCED = new ViewFlag(true, false, "advanced", "a") { @Override public List filter(List records) {return records;} @Override public void modify(REntityServer server, List entities) { for(TraceEntity entity: entities) { - TNTRecord example = entity.getRecords().get(0); + TNTRecord current = entity.getRecords().get(0); + if(current.isExplosion()) continue; + TNTRecord next = current.getNext().orElse(null); + if (next == null) continue; - if(example.isExplosion()) continue; + Location pos = current.getLocation().clone(); + pos.setY(next.getLocation().getY()); - Location pos = example.getLocation(); + if (pos.distanceSquared(current.getLocation()) >= 1.0 / 256.0) { + RFallingBlockEntity y = new RFallingBlockEntity(server, pos, Material.WHITE_STAINED_GLASS); + y.setNoGravity(true); + } - Vector xVelocity = new Vector(example.getVelocity().getX(), 0, 0); - Vector yVelocity = new Vector(0, example.getVelocity().getY(), 0); - Vector zVelocity = new Vector(0, 0, example.getVelocity().getZ()); - - Vector firstVelocity = xVelocity.getX() >= zVelocity.getZ() ? xVelocity : zVelocity; - - pos = pos.add(yVelocity); - RFallingBlockEntity y = new RFallingBlockEntity(server, pos, Material.WHITE_STAINED_GLASS); - y.setNoGravity(true); - - pos = pos.add(firstVelocity); - RFallingBlockEntity secound = new RFallingBlockEntity(server, pos, Material.WHITE_STAINED_GLASS); - secound.setNoGravity(true); + if (current.getVelocity().getX() >= current.getVelocity().getZ()) { + pos.setX(next.getLocation().getX()); + } else { + pos.setZ(next.getLocation().getZ()); + } + if (pos.distanceSquared(next.getLocation()) >= 1.0 / 256.0) { + RFallingBlockEntity second = new RFallingBlockEntity(server, pos, Material.WHITE_STAINED_GLASS); + second.setNoGravity(true); + } } } }; - public static ViewFlag COUNT = new ViewFlag(true, false, "count") { + public static ViewFlag COUNT = new ViewFlag(true, false, "count", "c") { @Override public List filter(List records) { return records; } @@ -181,7 +183,7 @@ public abstract class ViewFlag { } }; - public static ViewFlag FUSE = new ViewFlag(true, false, "fuse") { + public static ViewFlag FUSE = new ViewFlag(true, false, "fuse", "f") { @Override public List filter(List records) { return records; } @@ -193,7 +195,7 @@ public abstract class ViewFlag { } }; - public static ViewFlag TIME = new ViewFlag(true, false, "time") { + public static ViewFlag TIME = new ViewFlag(true, false, "time", "t") { @Override public List filter(List records) { return records; } @@ -215,13 +217,25 @@ public abstract class ViewFlag { */ public final String[] aliases; - public ViewFlag(boolean isStatic, boolean isInverse, String name, String... aliases) { + /** + * A flag that is used whenever this flag is used + */ + public final ViewFlag[] required; + + public ViewFlag(boolean isStatic, boolean isInverse, String name, String... aliases) { + this(isStatic, isInverse, new ViewFlag[0], name, aliases); + } + + public ViewFlag(boolean isStatic, boolean isInverse, ViewFlag required, String name, String... aliases) { + this(isStatic, isInverse, new ViewFlag[] { required }, name, aliases); + } + + public ViewFlag(boolean isStatic, boolean isInverse, ViewFlag[] required, String name, String... aliases){ this.name = name; this.aliases = aliases; - if(isStatic) - flags.add(this); - if(isInverse) - inverseFlags.add(this); + if(isStatic) flags.add(this); + if(isInverse) inverseFlags.add(this); + this.required = required; } /** Filters the given records for a given condition diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicFlags/AtFlag.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicFlags/AtFlag.java new file mode 100644 index 00000000..cb06685a --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicFlags/AtFlag.java @@ -0,0 +1,60 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer.rendering.dynamicFlags; + +import de.steamwar.bausystem.features.tracer.TNTRecord; +import de.steamwar.bausystem.features.tracer.rendering.TraceEntity; +import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; +import de.steamwar.entity.REntityServer; + +import java.util.List; +import java.util.stream.Collectors; + +public class AtFlag extends ViewFlag { + private int start; + private int end; + + + public AtFlag(int start, int end){ + super(false, false, ViewFlag.IGNITE, null); + this.start = start; + this.end = end; + } + + /** Update this flag to represent another time interval + * + * @param start new interval start + * @param end new interval end + */ + public void update(int start, int end){ + this.start = start; + this.end = end; + } + + @Override + public List filter(List records) { + return records.stream() + .filter(record -> record.getTicksSinceStart() <= start && record.getTicksSinceStart() >= end) + .collect(Collectors.toList()); + } + + @Override + public void modify(REntityServer server, List entities) {} +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicFlags/IsolateFlag.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicFlags/IsolateFlag.java new file mode 100644 index 00000000..7832636f --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/dynamicFlags/IsolateFlag.java @@ -0,0 +1,63 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.tracer.rendering.dynamicFlags; + +import de.steamwar.bausystem.features.tracer.TNTRecord; +import de.steamwar.bausystem.features.tracer.rendering.TraceEntity; +import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; +import de.steamwar.entity.REntityServer; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class IsolateFlag extends ViewFlag { + + /** + * Tnt ids that will be isolated + */ + private final Set tntToIsolate = new HashSet<>(); + + public IsolateFlag(){ + super(false, false, ViewFlag.IGNITE, null); + } + + /** + * Toggles the given id to be or not to be rendered + * @param id + */ + public void toggleId(int id){ + if (!tntToIsolate.remove(id)) { + tntToIsolate.add(id); + } + } + + @Override + public List filter(List records) { + return records.stream() + .filter(record -> tntToIsolate.contains(record.getTntId())) + .collect(Collectors.toList()); + } + + @Override + public void modify(REntityServer server, List entities) {} +}