Trace Refactor #233
@ -63,6 +63,11 @@ public class Recorder implements Listener {
|
||||
*/
|
||||
private final Set<Trace> 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<Trace, List<TNTRecord>> 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<Block> destroyedBlocks){
|
||||
List<TNTRecord> 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<TNTRecord> history;
|
||||
|
||||
public TNTRecord(UUID tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart, List<TNTRecord> history, List<Block> destroyedBlocks){
|
||||
public TNTRecord(int tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart, List<TNTRecord> history, List<Block> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<TNTRecord> records = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Records to be added
|
||||
* ID that should be asigned to the next record of a unique tnt
|
||||
*/
|
||||
private List<TNTRecord> newRecords = new ArrayList<>();
|
||||
@Getter
|
||||
private int nextOpenRecordId = -1;
|
||||
|
||||
/**
|
||||
* List of all used ids
|
||||
*/
|
||||
@Getter
|
||||
private final List<String> 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<TNTRecord> 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<List<TNTRecord>> getHistories() {
|
||||
Set<List<TNTRecord>> 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<TNTRecord> records, ViewFlag[] flags, BundleFilter bundleFilter){
|
||||
private void render(REntityServer server, List<TNTRecord> records, ViewFlag[] flags, BundleFilter bundleFilter){
|
||||
if(records.size() == 0) return;
|
||||
|
||||
List<TNTRecord> workingRecords = records;
|
||||
|
||||
List<ViewFlag> 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<ViewFlag> 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<List<TNTRecord>> bundles = bundleRecords(workingRecords, bundleFilter);
|
||||
@ -177,14 +195,25 @@ public class Trace {
|
||||
//Render bundled records
|
||||
List<TraceEntity> entities = new LinkedList<>();
|
||||
|
||||
for(List<TNTRecord> bundle : bundles)
|
||||
for(List<TNTRecord> 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
|
||||
*
|
||||
* @param records The TNTRecords that are supposed to be bundled
|
||||
@ -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
|
||||
|
@ -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<Trace> traceClassMapper(){
|
||||
return new TypeMapper<Trace>() {
|
||||
@Override
|
||||
public Trace map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
int id = Integer.parseInt(s);
|
||||
|
||||
Optional<Trace> trace = manager.get(id);
|
||||
|
||||
return trace.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> 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<TNTRecord> recordMapper() {
|
||||
return new TypeMapper<TNTRecord>() {
|
||||
@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<String> 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<String> 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());
|
||||
}
|
||||
};
|
||||
|
@ -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<Integer> 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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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<ViewFlag> 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<TNTRecord> filter(List<TNTRecord> records) {
|
||||
return records.stream()
|
||||
@ -56,7 +55,7 @@ public abstract class ViewFlag {
|
||||
public void modify(REntityServer server, List<TraceEntity> entities) {}
|
||||
};
|
||||
|
||||
public static ViewFlag IGNITE = new ViewFlag(true, true, "ignite") {
|
||||
public static ViewFlag IGNITE = new ViewFlag(true, true, "ignite", "i") {
|
||||
@Override
|
||||
public List<TNTRecord> filter(List<TNTRecord> records) {
|
||||
return records.stream()
|
||||
@ -68,7 +67,7 @@ public abstract class ViewFlag {
|
||||
public void modify(REntityServer server, List<TraceEntity> entities) {}
|
||||
};
|
||||
|
||||
public static ViewFlag SOURCE = new ViewFlag(true, false, "source") {
|
||||
public static ViewFlag SOURCE = new ViewFlag(true, false, IGNITE, "source", "s") {
|
||||
@Override
|
||||
public List<TNTRecord> filter(List<TNTRecord> records) {
|
||||
return records.stream()
|
||||
@ -104,10 +103,10 @@ public abstract class ViewFlag {
|
||||
public void modify(REntityServer server, List<TraceEntity> entities) {}
|
||||
};
|
||||
|
||||
public static ViewFlag MICROMOTION = new ViewFlag(true, false, "micromotion") {
|
||||
public static ViewFlag MICROMOTION = new ViewFlag(true, false, "micromotion", "m") {
|
||||
@Override
|
||||
public List<TNTRecord> filter(List<TNTRecord> records) {
|
||||
Set<UUID> seen = new HashSet<>();
|
||||
Set<Integer> seen = new HashSet<>();
|
||||
Set<TNTRecord> toRemove = new HashSet<>();
|
||||
|
||||
for(TNTRecord uniqueRecord: records){
|
||||
@ -139,37 +138,40 @@ public abstract class ViewFlag {
|
||||
public void modify(REntityServer server, List<TraceEntity> entities) {}
|
||||
};
|
||||
|
||||
public static ViewFlag ADVANCED = new ViewFlag(true, false, "advanced") {
|
||||
public static ViewFlag ADVANCED = new ViewFlag(true, false, "advanced", "a") {
|
||||
@Override
|
||||
public List<TNTRecord> filter(List<TNTRecord> records) {return records;}
|
||||
|
||||
@Override
|
||||
public void modify(REntityServer server, List<TraceEntity> 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();
|
||||
|
||||
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);
|
||||
if (pos.distanceSquared(current.getLocation()) >= 1.0 / 256.0) {
|
||||
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<TNTRecord> filter(List<TNTRecord> 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<TNTRecord> filter(List<TNTRecord> 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<TNTRecord> filter(List<TNTRecord> records) { return records; }
|
||||
|
||||
@ -215,13 +217,25 @@ public abstract class ViewFlag {
|
||||
*/
|
||||
public final 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
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<TNTRecord> filter(List<TNTRecord> records) {
|
||||
return records.stream()
|
||||
.filter(record -> record.getTicksSinceStart() <= start && record.getTicksSinceStart() >= end)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modify(REntityServer server, List<TraceEntity> entities) {}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Integer> 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<TNTRecord> filter(List<TNTRecord> records) {
|
||||
return records.stream()
|
||||
.filter(record -> tntToIsolate.contains(record.getTntId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modify(REntityServer server, List<TraceEntity> entities) {}
|
||||
}
|
In neuem Issue referenzieren
Einen Benutzer sperren