Trace Refactor #233
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.portablehole;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// @Linked
|
||||
public class PortableHoleListener implements Listener {
|
||||
|
||||
private Map<Long, List<BlockState>> toReplace = new HashMap<>();
|
||||
|
||||
{
|
||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||
List<BlockState> blockStates = toReplace.remove(TPSUtils.currentRealTick.get());
|
||||
if (blockStates == null) return;
|
||||
blockStates.forEach(blockState -> {
|
||||
blockState.update(true, false);
|
||||
});
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (!event.hasItem()) return;
|
||||
if (event.getItem().getType() != Material.FIREWORK_STAR) return;
|
||||
|
||||
BlockFace blockFace;
|
||||
if (event.getPlayer().getLocation().getPitch() < -45) {
|
||||
blockFace = BlockFace.UP;
|
||||
} else if (event.getPlayer().getLocation().getPitch() > 45) {
|
||||
blockFace = BlockFace.DOWN;
|
||||
} else if (event.getPlayer().getLocation().getYaw() > 135) {
|
||||
blockFace = BlockFace.NORTH;
|
||||
} else if (event.getPlayer().getLocation().getYaw() > 45) {
|
||||
blockFace = BlockFace.WEST;
|
||||
} else if (event.getPlayer().getLocation().getYaw() > -45) {
|
||||
blockFace = BlockFace.SOUTH;
|
||||
} else if (event.getPlayer().getLocation().getYaw() > -135) {
|
||||
blockFace = BlockFace.EAST;
|
||||
} else {
|
||||
blockFace = BlockFace.NORTH;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Location source = event.getPlayer().getLocation().getBlock().getLocation().clone();
|
||||
source.add(blockFace.getDirection().clone().multiply(i + 1 + (blockFace == BlockFace.UP ? 1 : 0)));
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
long reappearTime = TPSUtils.currentRealTick.get() + 100;
|
||||
if (blockFace == BlockFace.UP || blockFace == BlockFace.DOWN) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
Block block = source.clone().add(dx, 0, dz).getBlock();
|
||||
BlockState blockState = block.getState();
|
||||
if (blockState.getType().isAir()) continue;
|
||||
toReplace.computeIfAbsent(reappearTime, __ -> new ArrayList<>()).add(blockState);
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
} else if (blockFace == BlockFace.NORTH || blockFace == BlockFace.SOUTH) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dy = 0; dy <= 2; dy++) {
|
||||
Block block = source.clone().add(dx, dy, 0).getBlock();
|
||||
BlockState blockState = block.getState();
|
||||
if (blockState.getType().isAir()) continue;
|
||||
toReplace.computeIfAbsent(reappearTime, __ -> new ArrayList<>()).add(blockState);
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int dy = 0; dy <= 2; dy++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
Block block = source.clone().add(0, dy, dz).getBlock();
|
||||
BlockState blockState = block.getState();
|
||||
if (blockState.getType().isAir()) continue;
|
||||
toReplace.computeIfAbsent(reappearTime, __ -> new ArrayList<>()).add(blockState);
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, i);
|
||||
}
|
||||
}
|
||||
}
|
@ -149,7 +149,6 @@ public class TNTPoint implements Externalizable {
|
||||
objectOutput.writeBoolean(destroyedTestBlock);
|
||||
objectOutput.writeLong(ticksSinceStart);
|
||||
objectOutput.writeInt(fuse);
|
||||
objectOutput.writeUTF(location.getWorld().getName());
|
||||
objectOutput.writeDouble(location.getX());
|
||||
objectOutput.writeDouble(location.getY());
|
||||
objectOutput.writeDouble(location.getZ());
|
||||
@ -168,11 +167,10 @@ public class TNTPoint implements Externalizable {
|
||||
destroyedTestBlock = objectInput.readBoolean();
|
||||
ticksSinceStart = objectInput.readLong();
|
||||
fuse = objectInput.readInt();
|
||||
String worldName = objectInput.readUTF();
|
||||
double locX = objectInput.readDouble();
|
||||
double locY = objectInput.readDouble();
|
||||
double locZ = objectInput.readDouble();
|
||||
location = new Location(Bukkit.getWorld(worldName), locX, locY, locZ);
|
||||
location = new Location(Bukkit.getWorlds().get(0), locX, locY, locZ);
|
||||
double velX = objectInput.readDouble();
|
||||
double velY = objectInput.readDouble();
|
||||
double velZ = objectInput.readDouble();
|
||||
@ -192,15 +190,11 @@ public class TNTPoint implements Externalizable {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof TNTPoint))
|
||||
return false;
|
||||
if (!(obj instanceof TNTPoint)) return false;
|
||||
TNTPoint record = (TNTPoint) obj;
|
||||
if (record.isExplosion() != explosion)
|
||||
return false;
|
||||
if (!record.getLocation().equals(location))
|
||||
return false;
|
||||
if (!record.getVelocity().equals(velocity))
|
||||
return false;
|
||||
if (record.isExplosion() != explosion) return false;
|
||||
if (!record.getLocation().equals(location)) return false;
|
||||
if (!record.getVelocity().equals(velocity)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import de.steamwar.entity.REntity;
|
||||
import de.steamwar.entity.REntityServer;
|
||||
import lombok.Cleanup;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.*;
|
||||
@ -73,6 +74,7 @@ public class Trace {
|
||||
|
||||
private final Map<Player, REntityServer> entityServerMap = new HashMap<>();
|
||||
|
||||
@SneakyThrows
|
||||
public Trace(Region region, List<TNTPoint> recordList) {
|
||||
this.uuid = UUID.randomUUID();
|
||||
recordsSaveFile = new File(TraceManager.tracesFolder, uuid + ".records");
|
||||
@ -81,17 +83,14 @@ public class Trace {
|
||||
records = new SoftReference<>(recordList);
|
||||
metadataSaveFile = new File(TraceManager.tracesFolder, uuid + ".meta");
|
||||
|
||||
try {
|
||||
@Cleanup
|
||||
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(metadataSaveFile));
|
||||
outputStream.writeUTF(uuid.toString());
|
||||
outputStream.writeUTF(region.getName());
|
||||
outputStream.writeObject(date);
|
||||
} catch (IOException | ClassCastException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@Cleanup
|
||||
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(metadataSaveFile));
|
||||
outputStream.writeUTF(uuid.toString());
|
||||
outputStream.writeUTF(region.getName());
|
||||
outputStream.writeObject(date);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public Trace(File metadataSaveFile) {
|
||||
String uuid = null;
|
||||
Region region = null;
|
||||
@ -106,8 +105,6 @@ public class Trace {
|
||||
region = Region.getREGION_MAP().get(inputStream.readUTF());
|
||||
date = (Date) inputStream.readObject();
|
||||
inputStream.close();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
this.uuid = UUID.fromString(uuid);
|
||||
this.region = region;
|
||||
@ -115,8 +112,6 @@ public class Trace {
|
||||
recordsSaveFile = new File(TraceManager.tracesFolder, uuid + ".records");
|
||||
this.records = new SoftReference<>(null);
|
||||
}
|
||||
|
||||
System.out.println(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,8 +170,9 @@ public class Trace {
|
||||
* @param playerTraceShowData The showData for modifying the rendering
|
||||
*/
|
||||
private void render(List<TNTPoint> records, REntityServer entityServer, PlayerTraceShowData playerTraceShowData) {
|
||||
if (records.isEmpty())
|
||||
if (records.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<TNTPoint> workingRecords = new ArrayList<>(records);
|
||||
Set<ViewFlag> flagList = playerTraceShowData.getEffectiveViewFlags();
|
||||
@ -221,7 +217,8 @@ public class Trace {
|
||||
private List<List<TNTPoint>> bundleRecords(List<TNTPoint> records, BundleFilter filter) {
|
||||
List<List<TNTPoint>> bundles = new ArrayList<>();
|
||||
|
||||
recordsLoop: for (TNTPoint record : records) {
|
||||
recordsLoop:
|
||||
for (TNTPoint record : records) {
|
||||
if (bundles.isEmpty()) {
|
||||
List<TNTPoint> firstBundle = new ArrayList<>();
|
||||
firstBundle.add(record);
|
||||
@ -246,26 +243,6 @@ public class Trace {
|
||||
return bundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the passed player stop following any other players trace render
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void unfollow(Player player) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides this trail for the given player
|
||||
*
|
||||
@ -273,11 +250,13 @@ public class Trace {
|
||||
*/
|
||||
public void hide(Player player) {
|
||||
REntityServer entityServer = entityServerMap.remove(player);
|
||||
if (entityServer == null)
|
||||
if (entityServer == null) {
|
||||
return;
|
||||
}
|
||||
entityServer.removePlayer(player);
|
||||
if (entityServer.getPlayers().isEmpty())
|
||||
if (entityServer.getPlayers().isEmpty()) {
|
||||
entityServer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
@ -287,36 +266,36 @@ public class Trace {
|
||||
entityServerMap.clear();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void loadRecords() {
|
||||
try {
|
||||
List<TNTPoint> records = new ArrayList<>();
|
||||
@Cleanup
|
||||
FileInputStream fileInputStream = new FileInputStream(recordsSaveFile);
|
||||
@Cleanup
|
||||
ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
|
||||
while (fileInputStream.getChannel().position() < recordsSaveFile.length()) {
|
||||
records.add((TNTPoint) inputStream.readObject());
|
||||
}
|
||||
List<TNTPoint> records = new ArrayList<>();
|
||||
|
||||
System.out.println("Loaded... " + records);
|
||||
@Cleanup
|
||||
FileInputStream fileInputStream = new FileInputStream(recordsSaveFile);
|
||||
|
||||
Map<Integer, List<TNTPoint>> histories = new HashMap<>();
|
||||
for (TNTPoint record : records) {
|
||||
int tntId = record.getTntId();
|
||||
List<TNTPoint> history = histories.computeIfAbsent(tntId, id -> new ArrayList<>());
|
||||
history.add(record);
|
||||
record.setHistory(history);
|
||||
}
|
||||
|
||||
this.records = new SoftReference<>(records);
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
@Cleanup
|
||||
ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
|
||||
while (fileInputStream.getChannel().position() < recordsSaveFile.length()) {
|
||||
records.add((TNTPoint) inputStream.readObject());
|
||||
}
|
||||
|
||||
System.out.println("Loaded... " + records);
|
||||
|
||||
Map<Integer, List<TNTPoint>> histories = new HashMap<>();
|
||||
for (TNTPoint record : records) {
|
||||
int tntId = record.getTntId();
|
||||
List<TNTPoint> history = histories.computeIfAbsent(tntId, id -> new ArrayList<>());
|
||||
history.add(record);
|
||||
record.setHistory(history);
|
||||
}
|
||||
|
||||
this.records = new SoftReference<>(records);
|
||||
}
|
||||
|
||||
public List<TNTPoint> getRecords() {
|
||||
if (records.get() == null)
|
||||
if (records.get() == null) {
|
||||
loadRecords();
|
||||
}
|
||||
return records.get();
|
||||
}
|
||||
|
||||
|
@ -73,8 +73,7 @@ public class TraceCommand extends SWCommand {
|
||||
}
|
||||
|
||||
@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) {
|
||||
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);
|
||||
}
|
||||
@ -87,9 +86,7 @@ public class TraceCommand extends SWCommand {
|
||||
}
|
||||
|
||||
@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) {
|
||||
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;
|
||||
@ -117,8 +114,7 @@ public class TraceCommand extends SWCommand {
|
||||
}
|
||||
|
||||
@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) {
|
||||
public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString, int to) {
|
||||
TraceManager.instance.renderAt(player, from, to);
|
||||
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM_TO", player, from, to);
|
||||
}
|
||||
@ -143,8 +139,7 @@ public class TraceCommand extends SWCommand {
|
||||
}
|
||||
|
||||
@Register(value = "isolate", description = "TRACE_COMMAND_HELP_ISOLATE")
|
||||
public void isolate(@Validator Player player, Trace trace,
|
||||
@ErrorMessage("TRACE_RECORD_ID_INVALID") TNTPoint... records) {
|
||||
public void isolate(@Validator Player player, Trace trace, @ErrorMessage("TRACE_RECORD_ID_INVALID") TNTPoint... records) {
|
||||
TraceManager.instance.isolate(player, records);
|
||||
// TODO: Add Message!
|
||||
}
|
||||
@ -156,18 +151,18 @@ 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 : TraceManager.instance.getAll()) {
|
||||
trace.follow(player, toFollow);
|
||||
if (player == toFollow) {
|
||||
// TODO: Implement message
|
||||
return;
|
||||
}
|
||||
TraceManager.instance.follow(player, toFollow);
|
||||
// TODO: Implement message
|
||||
}
|
||||
|
||||
@Register(value = "unfollow", description = "TRACE_COMMAND_HELP_SHOW")
|
||||
public void unfollow(@Validator Player player) {
|
||||
// TODO: Implement
|
||||
for (Trace trace : TraceManager.instance.getAll()) {
|
||||
trace.unfollow(player);
|
||||
}
|
||||
TraceManager.instance.unfollow(player);
|
||||
// TODO: Implement message
|
||||
}
|
||||
|
||||
@ClassMapper(value = Trace.class, local = true)
|
||||
@ -179,8 +174,7 @@ public class TraceCommand extends SWCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments,
|
||||
String s) {
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||
return TraceManager.instance.getAllIds().stream()
|
||||
.map(Object::toString)
|
||||
.collect(Collectors.toList());
|
||||
@ -194,8 +188,7 @@ public class TraceCommand extends SWCommand {
|
||||
@Override
|
||||
public TNTPoint map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||
Trace trace = previousArguments.getFirst(Trace.class).orElse(null);
|
||||
if (trace == null)
|
||||
return null;
|
||||
if (trace == null) return null;
|
||||
|
||||
int id = Integer.parseInt(s);
|
||||
return trace.getRecords().stream()
|
||||
@ -206,11 +199,9 @@ public class TraceCommand extends SWCommand {
|
||||
|
||||
// TODO change when new command framework update
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments,
|
||||
String s) {
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||
Trace trace = previousArguments.getFirst(Trace.class).orElse(null);
|
||||
if (trace == null)
|
||||
return null;
|
||||
if (trace == null) return null;
|
||||
return trace.getUsedIds();
|
||||
}
|
||||
};
|
||||
@ -230,8 +221,7 @@ public class TraceCommand extends SWCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments,
|
||||
String s) {
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||
if (s.length() == 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
@ -263,8 +253,7 @@ public class TraceCommand extends SWCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments,
|
||||
String s) {
|
||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||
return ViewFlag.flags.stream()
|
||||
.flatMap(viewFlag -> Stream.concat(Stream.of("--" + viewFlag.name),
|
||||
Arrays.stream(viewFlag.aliases).map(name -> "-" + name)))
|
||||
|
@ -204,8 +204,7 @@ public class TraceManager implements Listener {
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
PlayerTraceShowData previous = showDataPerRegionPerPlayer.getOrDefault(region, Collections.emptyMap())
|
||||
.remove(player);
|
||||
if (previous == null)
|
||||
return;
|
||||
if (previous == null) return;
|
||||
tracesByRegion.getOrDefault(player, Collections.emptyMap()).forEach((integer, trace) -> {
|
||||
trace.hide(player);
|
||||
followerMap.getOrDefault(player, Collections.emptySet()).forEach(trace::hide);
|
||||
@ -213,8 +212,7 @@ public class TraceManager implements Listener {
|
||||
}
|
||||
|
||||
public boolean follow(Player follower, Player following) {
|
||||
if (followerMap.containsKey(follower))
|
||||
return false;
|
||||
if (followerMap.containsKey(follower)) return false;
|
||||
if (followerMap.entrySet().stream().anyMatch(playerSetEntry -> playerSetEntry.getValue().contains(follower))) {
|
||||
unfollow(follower);
|
||||
}
|
||||
@ -229,8 +227,7 @@ public class TraceManager implements Listener {
|
||||
}
|
||||
|
||||
PlayerTraceShowData playerTraceShowData = playerPlayerTraceShowDataMap.get(following);
|
||||
if (playerTraceShowData == null)
|
||||
return;
|
||||
if (playerTraceShowData == null) return;
|
||||
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> {
|
||||
trace.render(follower, playerTraceShowData);
|
||||
});
|
||||
@ -239,30 +236,25 @@ public class TraceManager implements Listener {
|
||||
}
|
||||
|
||||
public void unfollow(Player follower) {
|
||||
if (followerMap.containsKey(follower))
|
||||
return;
|
||||
if (followerMap.containsKey(follower)) return;
|
||||
List<Player> toRemove = new ArrayList<>();
|
||||
Set<Player> toHide = new HashSet<>();
|
||||
followerMap.forEach((player, players) -> {
|
||||
if (players.remove(follower))
|
||||
toHide.add(follower);
|
||||
if (players.isEmpty())
|
||||
toRemove.add(player);
|
||||
if (players.remove(follower)) toHide.add(follower);
|
||||
if (players.isEmpty()) toRemove.add(player);
|
||||
});
|
||||
toRemove.forEach(followerMap::remove);
|
||||
|
||||
showDataPerRegionPerPlayer.forEach((region, playerPlayerTraceShowDataMap) -> {
|
||||
toHide.forEach(player -> {
|
||||
if (!playerPlayerTraceShowDataMap.containsKey(player))
|
||||
return;
|
||||
if (!playerPlayerTraceShowDataMap.containsKey(player)) return;
|
||||
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> {
|
||||
trace.hide(follower);
|
||||
});
|
||||
});
|
||||
|
||||
PlayerTraceShowData playerTraceShowData = playerPlayerTraceShowDataMap.get(follower);
|
||||
if (playerTraceShowData == null)
|
||||
return;
|
||||
if (playerTraceShowData == null) return;
|
||||
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> {
|
||||
trace.render(follower, playerTraceShowData);
|
||||
});
|
||||
|
@ -92,8 +92,7 @@ public class TraceRecorder implements Listener {
|
||||
*/
|
||||
public void checkForAutoTraceFinish() {
|
||||
for (Region region : autoTraceRegions) {
|
||||
if (autoTraceRegions.contains(region)
|
||||
&& trackedTNT.getOrDefault(region, Collections.emptyList()).size() == 0) {
|
||||
if (autoTraceRegions.contains(region) && trackedTNT.getOrDefault(region, Collections.emptyList()).size() == 0) {
|
||||
stopRecording(region);
|
||||
}
|
||||
}
|
||||
@ -105,8 +104,9 @@ public class TraceRecorder implements Listener {
|
||||
* @param region region to be recorded
|
||||
*/
|
||||
public int startRecording(Region region) {
|
||||
if (activeTraces.containsKey(region))
|
||||
if (activeTraces.containsKey(region)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
TraceRecordingWrapper wrappedTrace = new TraceRecordingWrapper(region);
|
||||
activeTraces.put(region, wrappedTrace);
|
||||
@ -120,8 +120,7 @@ public class TraceRecorder implements Listener {
|
||||
*/
|
||||
public void stopRecording(Region region) {
|
||||
TraceRecordingWrapper wrappedTrace = activeTraces.getOrDefault(region, null);
|
||||
if (wrappedTrace == null)
|
||||
return;
|
||||
if (wrappedTrace == null) return;
|
||||
|
||||
activeTraces.remove(region);
|
||||
for (TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) {
|
||||
@ -184,8 +183,7 @@ public class TraceRecorder implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onTNTSpawn(EntitySpawnEvent event) {
|
||||
if (!(event.getEntity() instanceof TNTPrimed))
|
||||
return;
|
||||
if (!(event.getEntity() instanceof TNTPrimed)) return;
|
||||
|
||||
Region region = Region.getRegion(event.getLocation());
|
||||
|
||||
@ -214,12 +212,10 @@ public class TraceRecorder implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onTNTExplode(EntityExplodeEvent event) {
|
||||
if (!(event.getEntity() instanceof TNTPrimed))
|
||||
return;
|
||||
if (!(event.getEntity() instanceof TNTPrimed)) return;
|
||||
|
||||
Region region = tntSpawnRegion.getOrDefault((TNTPrimed) event.getEntity(), null);
|
||||
if (region == null)
|
||||
return;
|
||||
if (region == null) return;
|
||||
trackedTNT.get(region).remove((TNTPrimed) event.getEntity());
|
||||
tntSpawnRegion.remove((TNTPrimed) event.getEntity());
|
||||
|
||||
|
@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.tracer;
|
||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -45,6 +46,7 @@ public class TraceRecordingWrapper {
|
||||
@Getter
|
||||
private final Trace trace;
|
||||
|
||||
@SneakyThrows
|
||||
public TraceRecordingWrapper(Region region) {
|
||||
this.region = region;
|
||||
startTick = TPSUtils.currentTick.get();
|
||||
@ -54,12 +56,7 @@ public class TraceRecordingWrapper {
|
||||
trace = new Trace(region, recordList);
|
||||
TraceManager.instance.add(trace);
|
||||
File recordsSaveFile = new File(TraceManager.tracesFolder, trace.getUuid() + ".records");
|
||||
try {
|
||||
recordsOutputStream = new ObjectOutputStream(new FileOutputStream(recordsSaveFile));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
recordsOutputStream = new ObjectOutputStream(new FileOutputStream(recordsSaveFile));
|
||||
}
|
||||
|
||||
public int getNextOpenRecordIdAndIncrement() {
|
||||
@ -80,6 +77,7 @@ public class TraceRecordingWrapper {
|
||||
recordsToAdd.forEach(record -> {
|
||||
try {
|
||||
recordsOutputStream.writeObject(record);
|
||||
recordsOutputStream.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -91,12 +89,9 @@ public class TraceRecordingWrapper {
|
||||
System.out.println(recordList);
|
||||
}
|
||||
|
||||
@SneakyThrows // TODO: Why is this not called?
|
||||
protected void finalizeRecording() {
|
||||
try {
|
||||
recordsOutputStream.flush();
|
||||
recordsOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
recordsOutputStream.flush();
|
||||
recordsOutputStream.close();
|
||||
}
|
||||
}
|
||||
|
252
MiningIII.md
Normale Datei
252
MiningIII.md
Normale Datei
@ -0,0 +1,252 @@
|
||||
# Mining III
|
||||
|
||||
Stats menu, blocks broken
|
||||
Pickaxe skins? / Cosmetics (Armor)
|
||||
Crystals?
|
||||
Music selector
|
||||
McPrison enchantments?
|
||||
Legendary enchantments? -> Overdrive entchantments via prestige points
|
||||
Combo Perk Enchantments?
|
||||
Show proc rate enchtantment
|
||||
Crystal Level increase by mining?
|
||||
Keeping -> Keep an enchantment or n levels on random enchantments
|
||||
Max upgrade? +5 upgrade?
|
||||
Auto buy?
|
||||
|
||||
## Enchantments
|
||||
|
||||
### Efficiency
|
||||
|
||||
- Increases Mining speed
|
||||
- id: efficiency
|
||||
- max: 10
|
||||
- cost_block_base: 50
|
||||
- cost_block_inc: 10
|
||||
- cost_shards_base: -80
|
||||
- cost_shards_inc: 20
|
||||
|
||||
### Haste
|
||||
|
||||
- Gain Haste
|
||||
- id: haste
|
||||
- max: 10
|
||||
- cost_block_base: 1000
|
||||
- cost_block_inc: 0
|
||||
- cost_gold_base: 100
|
||||
- cost_gold_inc: 100
|
||||
|
||||
### Speed
|
||||
|
||||
- Gain Speed
|
||||
- id: speed
|
||||
- max: 5
|
||||
- cost_blocks_base: 500
|
||||
- cost_blocks_inc: -100
|
||||
- cost_shards_base: 100
|
||||
- cost_shards_inc: 150
|
||||
|
||||
### Fortune
|
||||
|
||||
- Increases Blocks gained
|
||||
- id: fortune
|
||||
- max: 50
|
||||
- cost_block_base: 100
|
||||
- cost_block_inc: 25
|
||||
- cost_gold_base: 200
|
||||
- cost_gold_inc: 50
|
||||
- cost_shards_base: -40
|
||||
- cost_shards_inc: 10
|
||||
|
||||
### Prosperity
|
||||
|
||||
- Rare chance to greatly increse block gain
|
||||
- id: prosperity
|
||||
- max: 10
|
||||
- cost_block_base: 1000
|
||||
- cost_block_inc: 100
|
||||
- cost_gold_base: 1000
|
||||
- cost_gold_inc: 100
|
||||
- cost_shards_base: 100
|
||||
- cost_shards_inc: 100
|
||||
|
||||
### Gifted
|
||||
|
||||
- Get luckier prosperity procs
|
||||
- id: gifted
|
||||
- max: 25
|
||||
- cost_block_base: 10000
|
||||
- cost_block_inc: 1000
|
||||
- cost_shards_base: 1000
|
||||
- cost_shards_inc: 250
|
||||
|
||||
### Shard Fusing Tome
|
||||
|
||||
- Chance to turn ores into shards
|
||||
- id: shard_fusing_tome
|
||||
- max: 10
|
||||
- cost_block_base: 5000
|
||||
- cost_block_inc: 500
|
||||
- cost_shards_base: 1000
|
||||
- cost_shards_inc: 0
|
||||
|
||||
### Unstable shards
|
||||
|
||||
- Destroy every shard created by Shard Fusing Tome
|
||||
- id: unstable_shards
|
||||
- max: 1
|
||||
- cost_block_base: 100000
|
||||
- cost_block_inc: 0
|
||||
- cost_gold_base: 25000
|
||||
- cost_gold_inc: 0
|
||||
- cost_shards_base: 10000
|
||||
- cost_shards_inc: 0
|
||||
|
||||
### Gatherer
|
||||
|
||||
- Chance to gain Gold on Block break
|
||||
- id: gatherer
|
||||
- max: 10
|
||||
- cost_block_base: 1000
|
||||
- cost_block_inc: 1000
|
||||
- cost_gold_base: 1000
|
||||
- cost_gold_inc: 0
|
||||
|
||||
### Block Shatterer
|
||||
|
||||
- Greatly increase Block gain
|
||||
- id: block_shatterer
|
||||
- max: 10
|
||||
- cost_block_base: 5000
|
||||
- cost_block_inc: 5000
|
||||
- cost_gold_base: 1000
|
||||
- cost_gold_inc: 1000
|
||||
- cost_shards_base: 500
|
||||
- cost_shards_inc: 500
|
||||
|
||||
### Gold Shatterer
|
||||
|
||||
- Greatly increase Gold gain
|
||||
- id: gold_shatterer
|
||||
- max: 10
|
||||
- cost_block_base: 1000
|
||||
- cost_block_inc: 1000
|
||||
- cost_gold_base: 5000
|
||||
- cost_gold_inc: 5000
|
||||
- cost_shards_base: 500
|
||||
- cost_shards_inc: 500
|
||||
|
||||
### Shard Shatterer
|
||||
|
||||
- Greatly increase Shard gain
|
||||
- id: shard_shatterer
|
||||
- max: 10
|
||||
- cost_block_base: 5000
|
||||
- cost_block_inc: 5000
|
||||
- cost_gold_base: 500
|
||||
- cost_gold_inc: 500
|
||||
- cost_shards_base: 1000
|
||||
- cost_shards_inc: 1000
|
||||
|
||||
### Explosive
|
||||
|
||||
- Chance to explode
|
||||
- id: explosive
|
||||
- max: 30
|
||||
- cost_block_base: 200
|
||||
- cost_block_inc: 50
|
||||
- cost_gold_base: -700
|
||||
- cost_gold_inc: 100
|
||||
- cost_shards_base: -3200
|
||||
- cost_shards_inc: 200
|
||||
|
||||
### Laser
|
||||
|
||||
- Chance to fire a laser
|
||||
- id: laser
|
||||
- max: 300
|
||||
- cost_block_base: 1000
|
||||
- cost_block_inc: 0
|
||||
- cost_gold_base: 3000
|
||||
- cost_gold_inc: -20
|
||||
- cost_shards_base: 0
|
||||
- cost_shards_inc: 30
|
||||
|
||||
### Jackhammer
|
||||
|
||||
- Chance to destroy 3*3*3 (100) or 5*5*5 (200) area
|
||||
- id: jackhammer
|
||||
- max: 200
|
||||
- cost_block_base: 10000
|
||||
- cost_block_inc: 100
|
||||
- cost_gold_base: -12250
|
||||
- cost_gold_inc: 250
|
||||
- cost_shards_base: -74500
|
||||
- cost_shards_inc: 500
|
||||
|
||||
### Corrosive Mine
|
||||
|
||||
- Destroy level number of blocks in the vicinity
|
||||
- id: corrosive_mine
|
||||
- max: 25
|
||||
- cost_block_base: 5000
|
||||
- cost_block_inc: 100
|
||||
- cost_gold_base: 5000
|
||||
- cost_gold_inc: 100
|
||||
- cost_shards_base: 5000
|
||||
- cost_shards_inc: 100
|
||||
|
||||
### Jackpot
|
||||
|
||||
- Chance to receive the jackpot of 1000 blocks, 1000 gold and 1000 shards
|
||||
- id: jackpot
|
||||
- max: 1
|
||||
- cost_shards_base: 50000
|
||||
- cost_shards_inc: 0
|
||||
|
||||
### Dual Pickaxe
|
||||
|
||||
- Chance to proc enchantments on another block in vicinity
|
||||
- id: dual_pickaxe
|
||||
- max: 10
|
||||
- cost_block_base: 2500
|
||||
- cost_block_inc: 500
|
||||
- cost_gold_base: 2500
|
||||
- cost_gold_inc: 500
|
||||
- cost_shards_base: 2500
|
||||
- cost_shards_inc: 500
|
||||
|
||||
### Luck
|
||||
|
||||
- Chance for laser bounces to proc any enchantment
|
||||
- id: luck
|
||||
- max: 10
|
||||
- cost_block_base: 10000
|
||||
- cost_block_inc: 10000
|
||||
- cost_gold_base: 10000
|
||||
- cost_gold_inc: 10000
|
||||
- cost_shards_base: 10000
|
||||
- cost_shards_inc: 10000
|
||||
|
||||
### Lumberjack
|
||||
|
||||
- Change to axe while looking onto Wood
|
||||
- id: lumberjack
|
||||
- max: 1
|
||||
- cost_block_base: 5000
|
||||
- cost_block_inc: 0
|
||||
- cost_gold_base: 5000
|
||||
- cost_gold_inc: 0
|
||||
- cost_shards_base: 5000
|
||||
- cost_shards_inc: 0
|
||||
|
||||
### Soul Remover
|
||||
|
||||
- Change to shovel while looking onto Wood
|
||||
- id: soul_remover
|
||||
- max: 1
|
||||
- cost_block_base: 5000
|
||||
- cost_block_inc: 0
|
||||
- cost_gold_base: 5000
|
||||
- cost_gold_inc: 0
|
||||
- cost_shards_base: 5000
|
||||
- cost_shards_inc: 0
|
In neuem Issue referenzieren
Einen Benutzer sperren