Merge branch 'master' into SkullCommand
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Dieser Commit ist enthalten in:
Commit
5019f79b67
@ -28,6 +28,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.network.syncher.DataWatcher;
|
||||
import net.minecraft.server.level.PlayerInteractManager;
|
||||
import net.minecraft.world.level.EnumGamemode;
|
||||
import net.minecraft.world.phys.Vec3D;
|
||||
@ -44,7 +45,6 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.LongSupplier;
|
||||
|
||||
public class NMSWrapper19 implements NMSWrapper {
|
||||
@ -91,7 +91,9 @@ public class NMSWrapper19 implements NMSWrapper {
|
||||
|
||||
if (entity instanceof TNTPrimed) {
|
||||
net.minecraft.world.entity.Entity serverEntity = ((CraftEntity) entity).getHandle();
|
||||
packets.add(new PacketPlayOutEntityMetadata(serverEntity.ah(), Objects.requireNonNull(serverEntity.al().c())));
|
||||
List<DataWatcher.b<?>> list = serverEntity.al().c();
|
||||
if(list != null)
|
||||
packets.add(new PacketPlayOutEntityMetadata(serverEntity.ah(), list));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -21,19 +21,60 @@ package de.steamwar.bausystem.utils;
|
||||
|
||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerMovementWrapper19 implements PlayerMovementWrapper {
|
||||
|
||||
private static class Position {
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
}
|
||||
|
||||
private Map<UUID, Position> playerLocationMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void setPosition(Player player, Object object) {
|
||||
Position position = playerLocationMap.computeIfAbsent(player.getUniqueId(), uuid -> {
|
||||
Position pos = new Position();
|
||||
Location location = player.getLocation();
|
||||
pos.x = location.getX();
|
||||
pos.y = location.getY();
|
||||
pos.z = location.getZ();
|
||||
pos.yaw = location.getYaw();
|
||||
pos.pitch = location.getPitch();
|
||||
return pos;
|
||||
});
|
||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||
if (packetPlayInFlying.h) {
|
||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
||||
position.x = packetPlayInFlying.a;
|
||||
position.y = packetPlayInFlying.b;
|
||||
position.z = packetPlayInFlying.c;
|
||||
position.yaw = packetPlayInFlying.d;
|
||||
position.pitch = packetPlayInFlying.e;
|
||||
} else {
|
||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
||||
position.x = packetPlayInFlying.a;
|
||||
position.y = packetPlayInFlying.b;
|
||||
position.z = packetPlayInFlying.c;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(Player player) {
|
||||
Position position = playerLocationMap.remove(player.getUniqueId());
|
||||
if (position != null) {
|
||||
player.teleport(new Location(player.getWorld(), position.x, position.y, position.z, position.yaw, position.pitch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -509,6 +509,18 @@ SCRIPT_GUI_CONSTANT_TPS_LORE = §etps§7 of the server
|
||||
SCRIPT_GUI_CONSTANT_TPS_LIMIT_NAME = §7Constant §etps_limit
|
||||
SCRIPT_GUI_CONSTANT_TPS_LIMIT_LORE = §etps_limit§7 of the server
|
||||
|
||||
# Shield Printing
|
||||
SHIELD_PRINTING_NO_REGION = §cYou are not in a region.
|
||||
SHIELD_PRINTING_NOT_RUNNING = §cThe shield printing is not running.
|
||||
SHIELD_PRINTING_DISALLOWED = §cYou are not allowed to use shield printing here.
|
||||
SHIELD_PRINTING_BOSSBAR = §fMovements: {0}
|
||||
SHIELD_PRINTING_BOSSBAR_COPIED = §fMovements: {0} Copied: {1}
|
||||
|
||||
SHIELD_PRINTING_START = §aThe shield printing has been started.
|
||||
SHIELD_PRINTING_COPY = §aThe shield has been copied.
|
||||
SHIELD_PRINTING_APPLY = §aThe shield has been applied.
|
||||
SHIELD_PRINTING_STOP = §aThe shield printing has been stopped.
|
||||
|
||||
# Unsign Book
|
||||
UNSIGN_HELP=§8/§eunsign §8- §7Make a signed book writable again
|
||||
|
||||
@ -655,8 +667,10 @@ INVENTORY_FILL_DISABLE = §cInventoryFiller deactivated
|
||||
KILLCHECKER_HELP_ENABLE = §8/§ekillchecker enable §8- §7Enables Killchecker / Recalculates kills
|
||||
KILLCHECKER_HELP_DISABLE = §8/§ekillchecker disable §8- §7Disables Killchecker
|
||||
KILLCHECKER_INFO = §7Shows the overlaps of cannon kills in your build area.
|
||||
KILLCHECKER_INFO2 = §7Only colorable blocks like Wool, Terractotta, Stained Glass and Concrete are counted.
|
||||
KILLCHECKER_ENABLE = §aKillchecker activated
|
||||
KILLCHECKER_DISABLE = §cKillchecker deactivated
|
||||
KILLCHECKER_BOSSBAR = §e§l{0} §7(§e{1}%§7) §e§l{2}§7 cannons
|
||||
|
||||
# BlockCounter
|
||||
BLOCK_COUNTER_HELP_TOGGLE = §8/§eblockcounter §8- §7Toggle on/off
|
||||
@ -918,6 +932,8 @@ SKULL_GUI_ITEM_NAME = §ePlayer Heads
|
||||
ANVIL_INV_NAME=Player name
|
||||
# StructureVoid
|
||||
STRUCTURE_VOID_COMMAND_HELP=§8/§estructureVoid §8-§7 Receive a StructureVoid
|
||||
# Dragon Egg
|
||||
DRAGON_EGG_COMMAND_HELP=§8/§edragonegg §8-§7 Receive a Dragon Egg
|
||||
# NightVision
|
||||
NIGHT_VISION_HELP=§8/§enightvision §8-§7 Toggel nightvision.
|
||||
NIGHT_VISION_OFF=§eNightvision deactivated
|
||||
|
@ -502,6 +502,18 @@ SCRIPT_GUI_CONSTANT_TPS_LORE = §etps§7 vom Server
|
||||
SCRIPT_GUI_CONSTANT_TPS_LIMIT_NAME = §7Constant §etps_limit
|
||||
SCRIPT_GUI_CONSTANT_TPS_LIMIT_LORE = §etps_limit§7 vom Server
|
||||
|
||||
# Shield Printing
|
||||
SHIELD_PRINTING_NO_REGION = §cDu bist in keiner Region.
|
||||
SHIELD_PRINTING_NOT_RUNNING = §cShield printing ist nicht aktiv.
|
||||
SHIELD_PRINTING_DISALLOWED = §cDu darfst Shield printing nicht benutzen.
|
||||
SHIELD_PRINTING_BOSSBAR = §fBewegungen: {0}
|
||||
SHIELD_PRINTING_BOSSBAR_COPIED = §fBewegungen: {0} Kopiert: {1}
|
||||
|
||||
SHIELD_PRINTING_START = §aShield printing wurde gestartet.
|
||||
SHIELD_PRINTING_COPY = §aSchilde wurden kopiert.
|
||||
SHIELD_PRINTING_APPLY = §aSchilde wurden angewendet.
|
||||
SHIELD_PRINTING_STOP = §aShield printing wurde gestoppt.
|
||||
|
||||
# Unsign Book
|
||||
UNSIGN_HELP=§8/§eunsign §8- §7Mache ein Buch beschreibbar
|
||||
|
||||
@ -628,8 +640,10 @@ INVENTORY_FILL_DISABLE = §cInventoryFiller deactivated
|
||||
KILLCHECKER_HELP_ENABLE = §8/§ekillchecker enable §8- §7Aktiviert Killchecker / Berechnet kills neu
|
||||
KILLCHECKER_HELP_DISABLE = §8/§ekillchecker disable §8- §7Deaktiviert Killchecker
|
||||
KILLCHECKER_INFO = §7Zeigt Überlappungen der Kanonen Kills im Baubereich an.
|
||||
KILLCHECKER_INFO2 = §7Nur farbige Blöcke wie Wolle, Terracotta, Stained Glass und Concrete wird gezählt.
|
||||
KILLCHECKER_ENABLE = §aKillchecker aktiviert
|
||||
KILLCHECKER_DISABLE = §cKillchecker deaktiviert
|
||||
KILLCHECKER_BOSSBAR = §e§l{0} §7(§e{1}%§7) §e§l{2}§7 Kanonnen
|
||||
|
||||
# BlockCounter
|
||||
BLOCK_COUNTER_HELP_TOGGLE = §8/§eblockcounter §8- §7Wechsel zwischen an und aus
|
||||
@ -889,6 +903,8 @@ SKULL_GUI_ITEM_NAME = §eSpieler Köpfe
|
||||
ANVIL_INV_NAME=Spieler name
|
||||
# StructureVoid
|
||||
STRUCTURE_VOID_COMMAND_HELP=§8/§estructureVoid §8-§7 Erhalte ein StructureVoid
|
||||
# Dragon Egg
|
||||
DRAGON_EGG_COMMAND_HELP=§8/§edragonegg §8-§7 Erhalte ein Drachenei
|
||||
# NightVision
|
||||
NIGHT_VISION_HELP=§8/§enightvision §8-§7 Schalte Nightvision an oder aus.
|
||||
NIGHT_VISION_OFF=§eNightvision deaktiviert
|
||||
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.killchecker;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class Cuboid {
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private double dx;
|
||||
private double dy;
|
||||
private double dz;
|
||||
}
|
@ -21,8 +21,10 @@ package de.steamwar.bausystem.features.killchecker;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.linkage.LinkedInstance;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -42,17 +44,21 @@ public class KillcheckerCommand extends SWCommand implements Listener {
|
||||
|
||||
private Map<Region, KillcheckerVisualizer> visualizers = new HashMap<>();
|
||||
|
||||
@LinkedInstance
|
||||
public BossBarService bossBarService;
|
||||
|
||||
public KillcheckerCommand() {
|
||||
super("killchecker");
|
||||
addDefaultHelpMessage("KILLCHECKER_INFO");
|
||||
addDefaultHelpMessage("KILLCHECKER_INFO2");
|
||||
}
|
||||
|
||||
@Register(value = "enable", description = "KILLCHECKER_HELP_ENABLE")
|
||||
public void genericCommand(Player player) {
|
||||
public void genericCommand(Player player, @OptionalValue("-outline") @StaticValue(value = {"-area", "-outline"}, allowISE = true) boolean onlyOutline) {
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
KillcheckerVisualizer killcheckerVisualizer = visualizers.computeIfAbsent(region, KillcheckerVisualizer::new);
|
||||
KillcheckerVisualizer killcheckerVisualizer = visualizers.computeIfAbsent(region, region1 -> new KillcheckerVisualizer(region1, bossBarService));
|
||||
killcheckerVisualizer.recalc();
|
||||
killcheckerVisualizer.show(player);
|
||||
killcheckerVisualizer.show(player, onlyOutline);
|
||||
BauSystem.MESSAGE.send("KILLCHECKER_ENABLE", player);
|
||||
}
|
||||
|
||||
@ -73,7 +79,7 @@ public class KillcheckerCommand extends SWCommand implements Listener {
|
||||
Player player = event.getPlayer();
|
||||
Set<Region> regions = new HashSet<>();
|
||||
visualizers.forEach((region, visualizer) -> {
|
||||
if (visualizer.hide(player)) {
|
||||
if (visualizer.disconnect(player)) {
|
||||
regions.add(region);
|
||||
}
|
||||
});
|
||||
|
@ -19,11 +19,13 @@
|
||||
|
||||
package de.steamwar.bausystem.features.killchecker;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.region.Point;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||
import de.steamwar.bausystem.region.utils.RegionType;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||
import de.steamwar.entity.REntity;
|
||||
import de.steamwar.entity.REntityServer;
|
||||
import de.steamwar.entity.RFallingBlockEntity;
|
||||
@ -31,6 +33,9 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -40,33 +45,59 @@ import java.util.Set;
|
||||
|
||||
public class KillcheckerVisualizer {
|
||||
|
||||
private static final Material[] materials = new Material[] {Material.YELLOW_STAINED_GLASS, Material.ORANGE_STAINED_GLASS, Material.RED_STAINED_GLASS, Material.PURPLE_STAINED_GLASS, Material.BLACK_STAINED_GLASS};
|
||||
private static final Material[] MATERIALS = new Material[] {Material.YELLOW_STAINED_GLASS, Material.ORANGE_STAINED_GLASS, Material.RED_STAINED_GLASS, Material.PURPLE_STAINED_GLASS, Material.BLACK_STAINED_GLASS};
|
||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
||||
|
||||
private Point minPoint;
|
||||
private Point maxPoint;
|
||||
private static final double SURROUND = 4;
|
||||
|
||||
private final Point minPoint;
|
||||
private final Point maxPoint;
|
||||
|
||||
private Set<Player> players = new HashSet<>();
|
||||
private final int yArea;
|
||||
private final int zArea;
|
||||
private final int xArea;
|
||||
|
||||
public KillcheckerVisualizer(Region region) {
|
||||
private final Set<Player> players = new HashSet<>();
|
||||
private final Set<Player> areaPlayers = new HashSet<>();
|
||||
|
||||
private final Region region;
|
||||
private final BossBarService bossBarService;
|
||||
|
||||
public KillcheckerVisualizer(Region region, BossBarService bossBarService) {
|
||||
this.region = region;
|
||||
this.minPoint = region.getMinPoint(RegionType.BUILD, RegionExtensionType.NORMAL);
|
||||
this.maxPoint = region.getMaxPoint(RegionType.BUILD, RegionExtensionType.NORMAL);
|
||||
|
||||
yArea = (maxPoint.getX() - minPoint.getX()) * (maxPoint.getZ() - minPoint.getZ());
|
||||
zArea = (maxPoint.getX() - minPoint.getX()) * (maxPoint.getY() - minPoint.getY());
|
||||
xArea = (maxPoint.getY() - minPoint.getY()) * (maxPoint.getZ() - minPoint.getZ());
|
||||
|
||||
this.bossBarService = bossBarService;
|
||||
}
|
||||
|
||||
private REntityServer rEntityServer = new REntityServer();
|
||||
private final REntityServer outline = new REntityServer();
|
||||
private final REntityServer inner = new REntityServer();
|
||||
|
||||
private Map<Point, Integer> killCount = new HashMap<>();
|
||||
private Map<Point, REntity> rEntities = new HashMap<>();
|
||||
private final Map<Point, Integer> killCount = new HashMap<>();
|
||||
private final Set<Point> outlinePointsCache = new HashSet<>();
|
||||
private final Map<Point, REntity> rEntities = new HashMap<>();
|
||||
|
||||
private double percent = 0;
|
||||
private int kills = 0;
|
||||
private int cannonCount = 0;
|
||||
|
||||
public void recalc() {
|
||||
Set<Cuboid> cuboids = new HashSet<>();
|
||||
Set<Point> points = new HashSet<>();
|
||||
for (int x = minPoint.getX() + 1; x < maxPoint.getX() - 1; x++) {
|
||||
for (int x = minPoint.getX() + 1; x < maxPoint.getX(); x++) {
|
||||
for (int y = minPoint.getY(); y < maxPoint.getY(); y++) {
|
||||
for (int z = minPoint.getZ() + 1; z < maxPoint.getZ() - 1; z++) {
|
||||
for (int z = minPoint.getZ() + 1; z < maxPoint.getZ(); z++) {
|
||||
if (points.contains(new Point(x, y, z))) continue;
|
||||
Block block = WORLD.getBlockAt(x, y, z);
|
||||
if (block.getType().isAir()) continue;
|
||||
String name = block.getType().name();
|
||||
if (!name.endsWith("_WOOL") && !name.endsWith("_STAINED_GLASS") && !name.endsWith("_CONCRETE") && !name.endsWith("_TERRACOTTA")) continue;
|
||||
if (name.equals("_GLAZED_TERRACOTTA")) continue;
|
||||
Cuboid cuboid = create(block.getType(), x, y, z);
|
||||
cuboids.add(cuboid);
|
||||
for (int dx = (int) cuboid.getX(); dx <= cuboid.getDx(); dx++) {
|
||||
@ -79,60 +110,162 @@ public class KillcheckerVisualizer {
|
||||
}
|
||||
}
|
||||
}
|
||||
cannonCount = cuboids.size();
|
||||
|
||||
Map<Point, Integer> kill = new HashMap<>();
|
||||
for (int x = minPoint.getX(); x < maxPoint.getX(); x++) {
|
||||
for (int z = minPoint.getZ(); z < maxPoint.getZ(); z++) {
|
||||
int yKills = 0;
|
||||
int yCount = 0;
|
||||
Set<Point> yPoints = new HashSet<>();
|
||||
for (int x = minPoint.getX(); x <= maxPoint.getX(); x++) {
|
||||
for (int z = minPoint.getZ(); z <= maxPoint.getZ(); z++) {
|
||||
Set<Cuboid> cuboidSet = new HashSet<>();
|
||||
for (Cuboid cuboid : cuboids) {
|
||||
if (x >= cuboid.getX() - 3.5 && x <= cuboid.getDx() + 3.5 && z >= cuboid.getZ() - 3.5 && z <= cuboid.getDz() + 3.5) {
|
||||
if (x >= cuboid.getX() - SURROUND && x < cuboid.getDx() + SURROUND && z >= cuboid.getZ() - SURROUND && z < cuboid.getDz() + SURROUND) {
|
||||
cuboidSet.add(cuboid);
|
||||
}
|
||||
}
|
||||
if (cuboidSet.size() > 1) {
|
||||
Point p1 = new Point(x, minPoint.getY(), z);
|
||||
kill.put(p1, Math.max(kill.getOrDefault(p1, 0), cuboidSet.size()));
|
||||
Point p2 = new Point(x, maxPoint.getY(), z);
|
||||
yCount++;
|
||||
yKills += splitIntoDoubleKills(cuboidSet.size());
|
||||
Point p2 = new Point(x, maxPoint.getY() + 1, z);
|
||||
yPoints.add(p2);
|
||||
kill.put(p2, Math.max(kill.getOrDefault(p2, 0), cuboidSet.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = minPoint.getY(); y < maxPoint.getY(); y++) {
|
||||
for (int z = minPoint.getZ(); z < maxPoint.getZ(); z++) {
|
||||
int xKills = 0;
|
||||
int xCount = 0;
|
||||
Set<Point> xPoints = new HashSet<>();
|
||||
for (int y = minPoint.getY(); y <= maxPoint.getY(); y++) {
|
||||
for (int z = minPoint.getZ(); z <= maxPoint.getZ(); z++) {
|
||||
Set<Cuboid> cuboidSet = new HashSet<>();
|
||||
for (Cuboid cuboid : cuboids) {
|
||||
if (y >= cuboid.getY() - 3.5 && y <= cuboid.getDy() + 3.5 && z >= cuboid.getZ() - 3.5 && z <= cuboid.getDz() + 3.5) {
|
||||
if (y >= cuboid.getY() - SURROUND && y < cuboid.getDy() + SURROUND && z >= cuboid.getZ() - SURROUND && z < cuboid.getDz() + SURROUND) {
|
||||
cuboidSet.add(cuboid);
|
||||
}
|
||||
}
|
||||
if (cuboidSet.size() > 1) {
|
||||
Point p1 = new Point(minPoint.getX(), y, z);
|
||||
xCount++;
|
||||
xKills += splitIntoDoubleKills(cuboidSet.size());
|
||||
Point p1 = new Point(minPoint.getX() - 1, y, z);
|
||||
xPoints.add(p1);
|
||||
kill.put(p1, Math.max(kill.getOrDefault(p1, 0), cuboidSet.size()));
|
||||
Point p2 = new Point(maxPoint.getX(), y, z);
|
||||
Point p2 = new Point(maxPoint.getX() + 1, y, z);
|
||||
xPoints.add(p2);
|
||||
kill.put(p2, Math.max(kill.getOrDefault(p2, 0), cuboidSet.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = minPoint.getX(); x < maxPoint.getX(); x++) {
|
||||
for (int y = minPoint.getY(); y < maxPoint.getY(); y++) {
|
||||
int zKills = 0;
|
||||
int zCount = 0;
|
||||
Set<Point> zPoints = new HashSet<>();
|
||||
for (int x = minPoint.getX(); x <= maxPoint.getX(); x++) {
|
||||
for (int y = minPoint.getY(); y <= maxPoint.getY(); y++) {
|
||||
Set<Cuboid> cuboidSet = new HashSet<>();
|
||||
for (Cuboid cuboid : cuboids) {
|
||||
if (x >= cuboid.getX() - 3.5 && x <= cuboid.getDx() + 3.5 && y >= cuboid.getY() - 3.5 && y <= cuboid.getDy() + 3.5) {
|
||||
if (x >= cuboid.getX() - SURROUND && x < cuboid.getDx() + SURROUND && y >= cuboid.getY() - SURROUND && y < cuboid.getDy() + SURROUND) {
|
||||
cuboidSet.add(cuboid);
|
||||
}
|
||||
}
|
||||
if (cuboidSet.size() > 1) {
|
||||
Point p1 = new Point(x, y, minPoint.getZ());
|
||||
zCount++;
|
||||
zKills += splitIntoDoubleKills(cuboidSet.size());
|
||||
Point p1 = new Point(x, y, minPoint.getZ() - 1);
|
||||
zPoints.add(p1);
|
||||
kill.put(p1, Math.max(kill.getOrDefault(p1, 0), cuboidSet.size()));
|
||||
Point p2 = new Point(x, y, maxPoint.getZ());
|
||||
Point p2 = new Point(x, y, maxPoint.getZ() + 1);
|
||||
zPoints.add(p2);
|
||||
kill.put(p2, Math.max(kill.getOrDefault(p2, 0), cuboidSet.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<Point> outlinePoints = new HashSet<>();
|
||||
yPoints.forEach(point -> {
|
||||
Point p1 = new Point(point.getX() - 1, point.getY(), point.getZ());
|
||||
Point p2 = new Point(point.getX() + 1, point.getY(), point.getZ());
|
||||
Point p3 = new Point(point.getX(), point.getY(), point.getZ() - 1);
|
||||
Point p4 = new Point(point.getX(), point.getY(), point.getZ() + 1);
|
||||
|
||||
Point p5 = new Point(point.getX() - 1, point.getY(), point.getZ() - 1);
|
||||
Point p6 = new Point(point.getX() - 1, point.getY(), point.getZ() + 1);
|
||||
Point p7 = new Point(point.getX() + 1, point.getY(), point.getZ() - 1);
|
||||
Point p8 = new Point(point.getX() + 1, point.getY(), point.getZ() + 1);
|
||||
|
||||
int count = kill.get(point);
|
||||
|
||||
int surrounded = 0;
|
||||
if (kill.getOrDefault(p1, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p2, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p3, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p4, 0) == count) surrounded++;
|
||||
if (surrounded != 4) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p5, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p6, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p7, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p8, 0) != count) outlinePoints.add(point);
|
||||
});
|
||||
xPoints.forEach(point -> {
|
||||
Point p1 = new Point(point.getX(), point.getY() - 1, point.getZ());
|
||||
Point p2 = new Point(point.getX(), point.getY() + 1, point.getZ());
|
||||
Point p3 = new Point(point.getX(), point.getY(), point.getZ() - 1);
|
||||
Point p4 = new Point(point.getX(), point.getY(), point.getZ() + 1);
|
||||
|
||||
Point p5 = new Point(point.getX(), point.getY() - 1, point.getZ() - 1);
|
||||
Point p6 = new Point(point.getX(), point.getY() - 1, point.getZ() + 1);
|
||||
Point p7 = new Point(point.getX(), point.getY() + 1, point.getZ() - 1);
|
||||
Point p8 = new Point(point.getX(), point.getY() + 1, point.getZ() + 1);
|
||||
|
||||
int count = kill.get(point);
|
||||
|
||||
int surrounded = 0;
|
||||
if (kill.getOrDefault(p1, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p2, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p3, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p4, 0) == count) surrounded++;
|
||||
if (surrounded != 4) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p5, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p6, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p7, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p8, 0) != count) outlinePoints.add(point);
|
||||
});
|
||||
zPoints.forEach(point -> {
|
||||
Point p1 = new Point(point.getX() - 1, point.getY(), point.getZ());
|
||||
Point p2 = new Point(point.getX() + 1, point.getY(), point.getZ());
|
||||
Point p3 = new Point(point.getX(), point.getY() - 1, point.getZ());
|
||||
Point p4 = new Point(point.getX(), point.getY() + 1, point.getZ());
|
||||
|
||||
Point p5 = new Point(point.getX() - 1, point.getY() - 1, point.getZ());
|
||||
Point p6 = new Point(point.getX() - 1, point.getY() + 1, point.getZ());
|
||||
Point p7 = new Point(point.getX() + 1, point.getY() - 1, point.getZ());
|
||||
Point p8 = new Point(point.getX() + 1, point.getY() + 1, point.getZ());
|
||||
|
||||
int count = kill.get(point);
|
||||
|
||||
int surrounded = 0;
|
||||
if (kill.getOrDefault(p1, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p2, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p3, 0) == count) surrounded++;
|
||||
if (kill.getOrDefault(p4, 0) == count) surrounded++;
|
||||
if (surrounded != 4) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p5, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p6, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p7, 0) != count) outlinePoints.add(point);
|
||||
if (kill.getOrDefault(p8, 0) != count) outlinePoints.add(point);
|
||||
});
|
||||
|
||||
double xPercent = zCount / (double) xArea;
|
||||
double yPercent = yCount / (double) yArea;
|
||||
double zPercent = xCount / (double) zArea;
|
||||
percent = (xPercent + yPercent + zPercent) / 3;
|
||||
kills = zKills + yKills + xKills;
|
||||
players.forEach(this::updateBossBar);
|
||||
|
||||
Set<Point> pointSet = new HashSet<>(killCount.keySet());
|
||||
Set<Point> outlinePointsCacheLast = new HashSet<>(outlinePointsCache);
|
||||
outlinePointsCache.clear();
|
||||
for (Point point : pointSet) {
|
||||
if (!kill.containsKey(point)) {
|
||||
rEntities.get(point).die();
|
||||
@ -142,16 +275,37 @@ public class KillcheckerVisualizer {
|
||||
}
|
||||
kill.forEach((point, count) -> {
|
||||
if (rEntities.containsKey(point)) {
|
||||
if (killCount.get(point) == count) return;
|
||||
if (killCount.get(point) == count && outlinePoints.contains(point) == outlinePointsCacheLast.contains(point)) return;
|
||||
rEntities.get(point).die();
|
||||
}
|
||||
RFallingBlockEntity entity = new RFallingBlockEntity(rEntityServer, point.toLocation(WORLD, 0.5, 0, 0.5), materials[Math.min(count - 1, materials.length) - 1]);
|
||||
RFallingBlockEntity entity = new RFallingBlockEntity(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0.5, 0, 0.5), MATERIALS[Math.min(count - 1, MATERIALS.length) - 1]);
|
||||
entity.setNoGravity(true);
|
||||
rEntities.put(point, entity);
|
||||
if (outlinePoints.contains(point)) outlinePointsCache.add(point);
|
||||
killCount.put(point, count);
|
||||
});
|
||||
}
|
||||
|
||||
private int splitIntoDoubleKills(int kills) {
|
||||
return kills * (kills - 1) / 2;
|
||||
}
|
||||
|
||||
private void updateBossBar(Player player) {
|
||||
BauSystemBossbar bossbar = bossBarService.get(player, region, "killchecker");
|
||||
bossbar.setTitle(BauSystem.MESSAGE.parse("KILLCHECKER_BOSSBAR", player, kills, ((int) (percent * 1000) / 10.0), cannonCount));
|
||||
bossbar.setProgress(percent);
|
||||
|
||||
if (percent >= 0.35) {
|
||||
bossbar.setColor(BarColor.RED);
|
||||
} else if (percent >= 0.25) {
|
||||
bossbar.setColor(BarColor.PURPLE);
|
||||
} else if (percent >= 0.15) {
|
||||
bossbar.setColor(BarColor.YELLOW);
|
||||
} else {
|
||||
bossbar.setColor(BarColor.GREEN);
|
||||
}
|
||||
}
|
||||
|
||||
private Cuboid create(Material type, int x, int y, int z) {
|
||||
Set<Point> checked = new HashSet<>();
|
||||
Set<Point> points = new HashSet<>();
|
||||
@ -202,16 +356,42 @@ public class KillcheckerVisualizer {
|
||||
return new Cuboid(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
}
|
||||
|
||||
public boolean show(Player player) {
|
||||
rEntityServer.addPlayer(player);
|
||||
public boolean show(Player player, boolean onlyOutline) {
|
||||
outline.addPlayer(player);
|
||||
if (!onlyOutline) {
|
||||
inner.addPlayer(player);
|
||||
areaPlayers.add(player);
|
||||
} else if (areaPlayers.contains(player)) {
|
||||
inner.removePlayer(player);
|
||||
areaPlayers.remove(player);
|
||||
}
|
||||
updateBossBar(player);
|
||||
return players.add(player);
|
||||
}
|
||||
|
||||
public boolean hide(Player player) {
|
||||
rEntityServer.removePlayer(player);
|
||||
outline.removePlayer(player);
|
||||
if (areaPlayers.contains(player)) {
|
||||
inner.removePlayer(player);
|
||||
}
|
||||
players.remove(player);
|
||||
areaPlayers.remove(player);
|
||||
bossBarService.remove(player, region, "killchecker");
|
||||
if (players.isEmpty()) {
|
||||
rEntityServer.close();
|
||||
outline.close();
|
||||
inner.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean disconnect(Player player) {
|
||||
players.remove(player);
|
||||
areaPlayers.remove(player);
|
||||
bossBarService.remove(player, region, "killchecker");
|
||||
if (players.isEmpty()) {
|
||||
outline.close();
|
||||
inner.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -24,6 +24,7 @@ import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
@ -46,34 +47,25 @@ public enum LoaderButton {
|
||||
switch (block.getType()) {
|
||||
case LEVER:
|
||||
return LoaderButton.SWITCH;
|
||||
case ACACIA_BUTTON:
|
||||
case BIRCH_BUTTON:
|
||||
case DARK_OAK_BUTTON:
|
||||
case JUNGLE_BUTTON:
|
||||
case OAK_BUTTON:
|
||||
case SPRUCE_BUTTON:
|
||||
return LoaderButton.WOOD_BUTTON;
|
||||
case STONE_BUTTON:
|
||||
return LoaderButton.STONE_BUTTON;
|
||||
case ACACIA_PRESSURE_PLATE:
|
||||
case BIRCH_PRESSURE_PLATE:
|
||||
case DARK_OAK_PRESSURE_PLATE:
|
||||
case JUNGLE_PRESSURE_PLATE:
|
||||
case OAK_PRESSURE_PLATE:
|
||||
case SPRUCE_PRESSURE_PLATE:
|
||||
case STONE_PRESSURE_PLATE:
|
||||
return LoaderButton.PRESSURE_PLATE;
|
||||
case HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
case LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
return LoaderButton.WEIGHTED_PRESSURE_PLATE;
|
||||
case TRIPWIRE:
|
||||
return LoaderButton.TRIPWIRE;
|
||||
case NOTE_BLOCK:
|
||||
return LoaderButton.NOTEBLOCK;
|
||||
case DAYLIGHT_DETECTOR:
|
||||
return LoaderButton.DAYLIGHTSENSOR;
|
||||
case HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
case LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
return LoaderButton.WEIGHTED_PRESSURE_PLATE;
|
||||
default:
|
||||
return LoaderButton.INVALID;
|
||||
if (block.getType().name().contains("STONE_BUTTON")) {
|
||||
return LoaderButton.STONE_BUTTON;
|
||||
} else if (block.getType().name().contains("BUTTON")) {
|
||||
return LoaderButton.WOOD_BUTTON;
|
||||
} else if (block.getType().name().contains("PRESSURE_PLATE")) {
|
||||
return LoaderButton.PRESSURE_PLATE;
|
||||
} else {
|
||||
return LoaderButton.INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
@ -83,7 +84,7 @@ public class TNTListener implements Listener {
|
||||
explode(event.blockList(), event.getBlock().getLocation(), null, null);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onExplode(EntityExplodeEvent event) {
|
||||
explode(event.blockList(), event.getLocation(), EventType.TNTExplodeInBuild, event);
|
||||
}
|
||||
|
@ -191,30 +191,6 @@ public final class ScriptExecutor {
|
||||
|
||||
private String[] replaceExpressions(String s) {
|
||||
s = s.replaceAll(" +", " ");
|
||||
// TODO: Remove this code as the Expression System below will replace it!
|
||||
Set<String> variables = new HashSet<>(localVariables.allVariables());
|
||||
variables.addAll(Constants.allVariables());
|
||||
variables.addAll(globalVariables.allVariables());
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (String variable : variables) {
|
||||
s = s.replace("<" + variable + ">", getValue(variable));
|
||||
s = s.replace("<" + variable + ".type>", getOrItselfValue(variable).type());
|
||||
}
|
||||
for (String constVariable : Constants.allVariables()) {
|
||||
s = s.replace("<const." + constVariable + ">", getConstant(constVariable));
|
||||
s = s.replace("<const." + constVariable + ".type>", Constants.getConstant(constVariable, player).type());
|
||||
}
|
||||
for (String localVariable : localVariables.allVariables()) {
|
||||
s = s.replace("<local." + localVariable + ">", getLocal(localVariable));
|
||||
s = s.replace("<local." + localVariable + ".type>", getLocalVariables().getValue(localVariable).type());
|
||||
}
|
||||
for (String globalVariable : globalVariables.allVariables()) {
|
||||
s = s.replace("<global." + globalVariable + ">", getGlobal(globalVariable));
|
||||
s = s.replace("<global." + globalVariable + ".type>", globalVariables.getValue(globalVariable).type());
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
int depth = 0;
|
||||
StringBuilder st = new StringBuilder();
|
||||
|
@ -47,7 +47,7 @@ public class ScriptListener implements Listener {
|
||||
new ScriptExecutor((BookMeta) item.getItemMeta(), event.getPlayer(), null);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
GLOBAL_CONTEXT.put(event.getPlayer(), new Context());
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class If implements SpecialCommand {
|
||||
BauSystem.MESSAGE.send("SCRIPT_COMMAND_ERROR_NO_BOOLEAN", scriptExecutor.getPlayer());
|
||||
return false;
|
||||
}
|
||||
if (v.asBoolean()) {
|
||||
if (v.asBoolean() && command.length > 2) {
|
||||
jumpToIndex(scriptExecutor, command[2]);
|
||||
} else if (command.length > 3) {
|
||||
jumpToIndex(scriptExecutor, command[3]);
|
||||
|
@ -80,7 +80,7 @@ public class Substring implements SpecialCommand {
|
||||
} else {
|
||||
result = new Value.StringValue(v1.asString().substring((int) v2.asLong()));
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
} catch (ArrayIndexOutOfBoundsException | StringIndexOutOfBoundsException e) {
|
||||
result = new Value.StringValue("");
|
||||
}
|
||||
scriptExecutor.getLocalVariables().putValue(resultName, result);
|
||||
|
@ -30,6 +30,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
@ -58,7 +59,7 @@ public class EventListener implements Listener {
|
||||
}, 2, 2);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
manager.callEvent(EventType.SelfJoin, event.getPlayer(), event);
|
||||
}
|
||||
|
@ -41,6 +41,9 @@ public class DivideOperator implements Operator {
|
||||
if (is(value, Value.StringValue.class, Value.BooleanValue.class) || is(value2, Value.StringValue.class, Value.BooleanValue.class)) {
|
||||
throw new IllegalArgumentException("SCRIPT_COMMAND_ARITHMETIC_DIV_ERROR");
|
||||
}
|
||||
if (value2.asDouble() == 0) {
|
||||
return new Value.DoubleValue(Double.NaN);
|
||||
}
|
||||
return new Value.DoubleValue(value.asDouble() / value2.asDouble());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.shieldprinting;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||
import de.steamwar.bausystem.utils.bossbar.RegionedBossbar;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockFormEvent;
|
||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||
import org.bukkit.event.block.EntityBlockFormEvent;
|
||||
import org.bukkit.event.entity.EntityAirChangeEvent;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ShieldPrinting implements Listener {
|
||||
|
||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
||||
|
||||
static {
|
||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||
ShieldPrintingCommand.SHIELD_PRINTING_MAP.values().forEach(shieldPrinting -> {
|
||||
shieldPrinting.fallingBlocks.replaceAll((entity, location) -> {
|
||||
if (entity.isDead()) return null;
|
||||
return location;
|
||||
});
|
||||
});
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vector of current position, Vector of origin
|
||||
*/
|
||||
private Map<Vector, Vector> shieldMap = new HashMap<>();
|
||||
private Map<Vector, BlockData> shieldData = new HashMap<>();
|
||||
|
||||
private final Region region;
|
||||
|
||||
public ShieldPrinting(Region region) {
|
||||
this.region = region;
|
||||
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
|
||||
updateBossbars();
|
||||
}
|
||||
|
||||
public void copy() {
|
||||
for (Map.Entry<Vector, Vector> entry : shieldMap.entrySet()) {
|
||||
shieldData.put(entry.getValue(), entry.getKey().toLocation(WORLD).getBlock().getBlockData());
|
||||
}
|
||||
updateBossbars();
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
for (Map.Entry<Vector, BlockData> entry : shieldData.entrySet()) {
|
||||
entry.getKey().toLocation(WORLD).getBlock().setBlockData(entry.getValue(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
HandlerList.unregisterAll(this);
|
||||
shieldMap.clear();
|
||||
shieldData.clear();
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BossBarService.instance.remove(player, region, "shieldprinting");
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
|
||||
update(event.getDirection(), event.getBlocks());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
|
||||
update(event.getDirection(), event.getBlocks());
|
||||
}
|
||||
|
||||
private void update(BlockFace direction, List<Block> blockList) {
|
||||
Set<Vector> toRemove = new HashSet<>();
|
||||
Map<Vector, Vector> temp = new HashMap<>();
|
||||
for (Block block : blockList) {
|
||||
if (Region.getRegion(block.getLocation()) != region) continue;
|
||||
Vector vector = block.getLocation().toVector();
|
||||
Vector origin = vector.clone();
|
||||
vector = vector.add(direction.getDirection());
|
||||
if (shieldMap.containsKey(origin)) {
|
||||
toRemove.add(origin);
|
||||
temp.put(vector, shieldMap.get(origin));
|
||||
} else {
|
||||
temp.put(vector, origin);
|
||||
}
|
||||
}
|
||||
shieldMap.keySet().removeAll(toRemove);
|
||||
shieldMap.putAll(temp);
|
||||
|
||||
toRemove.clear();
|
||||
for (Map.Entry<Vector, Vector> entry : shieldMap.entrySet()) {
|
||||
if (entry.getKey().equals(entry.getValue())) {
|
||||
toRemove.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
shieldMap.keySet().removeAll(toRemove);
|
||||
|
||||
updateBossbars();
|
||||
}
|
||||
|
||||
private Map<Entity, Location> fallingBlocks = new HashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public void onEntitySpawn(EntitySpawnEvent event) {
|
||||
if (event.getEntityType() != EntityType.FALLING_BLOCK) return;
|
||||
if (Region.getRegion(event.getLocation()) != region) return;
|
||||
fallingBlocks.put(event.getEntity(), event.getLocation().getBlock().getLocation());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
||||
if (!event.getBlock().getType().isAir()) return;
|
||||
if (event.getEntityType() != EntityType.FALLING_BLOCK) return;
|
||||
if (Region.getRegion(event.getBlock().getLocation()) != region) return;
|
||||
Location origin = fallingBlocks.remove(event.getEntity());
|
||||
if (origin == null) return;
|
||||
Location destination = event.getBlock().getLocation();
|
||||
Vector originOrigin = shieldMap.remove(origin.toVector());
|
||||
shieldMap.put(destination.toVector(), originOrigin != null ? originOrigin : origin.toVector());
|
||||
|
||||
updateBossbars();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (event.getClickedBlock() == null) return;
|
||||
if (event.getItem() == null) return;
|
||||
if (Region.getRegion(event.getClickedBlock().getLocation()) != region) return;
|
||||
Vector vector = event.getClickedBlock().getLocation().toVector();
|
||||
if (!shieldMap.containsKey(vector)) return;
|
||||
event.getClickedBlock().setType(Material.AIR);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
updateBossbar(event.getPlayer());
|
||||
}
|
||||
|
||||
private void updateBossbars() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
updateBossbar(player);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBossbar(Player player) {
|
||||
BauSystemBossbar bossbar = BossBarService.instance.get(player, region, "shieldprinting");
|
||||
bossbar.setColor(BarColor.YELLOW);
|
||||
bossbar.setTitle(BauSystem.MESSAGE.parse(shieldData.isEmpty() ? "SHIELD_PRINTING_BOSSBAR" : "SHIELD_PRINTING_BOSSBAR_COPIED", player, shieldMap.size(), shieldData.size()));
|
||||
}
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.shieldprinting;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.command.TypeValidator;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Linked
|
||||
public class ShieldPrintingCommand extends SWCommand implements Listener {
|
||||
|
||||
public ShieldPrintingCommand() {
|
||||
super("shieldprinting");
|
||||
}
|
||||
|
||||
static final Map<Region, ShieldPrinting> SHIELD_PRINTING_MAP = new HashMap<>();
|
||||
|
||||
@Register
|
||||
public void genericCommand(@Validator Player player, ShieldPrintingState shieldPrintingState) {
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
if (region.isGlobal()) {
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_NO_REGION", player);
|
||||
return;
|
||||
}
|
||||
ShieldPrinting shieldPrinting;
|
||||
switch (shieldPrintingState) {
|
||||
case START:
|
||||
shieldPrinting = SHIELD_PRINTING_MAP.put(region, new ShieldPrinting(region));
|
||||
if (shieldPrinting != null) {
|
||||
shieldPrinting.disable();
|
||||
}
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_START", player);
|
||||
break;
|
||||
case COPY:
|
||||
shieldPrinting = SHIELD_PRINTING_MAP.get(region);
|
||||
if (shieldPrinting == null) {
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player);
|
||||
return;
|
||||
}
|
||||
shieldPrinting.copy();
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_COPY", player);
|
||||
break;
|
||||
case APPLY:
|
||||
shieldPrinting = SHIELD_PRINTING_MAP.get(region);
|
||||
if (shieldPrinting == null) {
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player);
|
||||
return;
|
||||
}
|
||||
shieldPrinting.apply();
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_APPLY", player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Register("stop")
|
||||
public void stopCommand(@Validator Player player) {
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
if (region.isGlobal()) {
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_NO_REGION", player);
|
||||
return;
|
||||
}
|
||||
ShieldPrinting shieldPrinting = SHIELD_PRINTING_MAP.remove(region);
|
||||
if (shieldPrinting == null) {
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player);
|
||||
return;
|
||||
}
|
||||
shieldPrinting.disable();
|
||||
BauSystem.MESSAGE.send("SHIELD_PRINTING_STOP", player);
|
||||
}
|
||||
|
||||
@ClassValidator(value = Player.class, local = true)
|
||||
public TypeValidator<Player> validator() {
|
||||
return (commandSender, player, messageSender) -> {
|
||||
if (!Permission.hasPermission(player, Permission.WORLD)) {
|
||||
messageSender.send("SHIELD_PRINTING_DISALLOWED", player);
|
||||
return false;
|
||||
}
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
if (region.isGlobal()) {
|
||||
messageSender.send("SHIELD_PRINTING_NO_REGION", player);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (event.getClickedBlock() == null) {
|
||||
return;
|
||||
}
|
||||
Region region = Region.getRegion(event.getClickedBlock().getLocation());
|
||||
if (region.isGlobal()) {
|
||||
return;
|
||||
}
|
||||
ShieldPrinting shieldPrinting = SHIELD_PRINTING_MAP.get(region);
|
||||
if (shieldPrinting == null) {
|
||||
return;
|
||||
}
|
||||
shieldPrinting.onPlayerInteract(event);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.shieldprinting;
|
||||
|
||||
public enum ShieldPrintingState {
|
||||
|
||||
START,
|
||||
COPY,
|
||||
APPLY
|
||||
}
|
@ -136,22 +136,22 @@ public class TNTElementGUI {
|
||||
// Alignment
|
||||
inv.setItem(23, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_NEGATIVE_Z", player), clickType -> { // Z negative
|
||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||
tntElement.align(new Vector(0.5, 0, 0.49));
|
||||
tntElement.align(new Vector(0, 0, 0.49));
|
||||
tntElement.change();
|
||||
}));
|
||||
inv.setItem(25, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_POSITIVE_Z", player), clickType -> { // Z positive
|
||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||
tntElement.align(new Vector(0.5, 0, 0.51));
|
||||
tntElement.align(new Vector(0, 0, 0.51));
|
||||
tntElement.change();
|
||||
}));
|
||||
inv.setItem(15, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_POSITIVE_X", player), clickType -> { // X positive
|
||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||
tntElement.align(new Vector(0.51, 0, 0.5));
|
||||
tntElement.align(new Vector(0.51, 0, 0));
|
||||
tntElement.change();
|
||||
}));
|
||||
inv.setItem(33, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_NEGATIVE_X", player), clickType -> { // X negative
|
||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||
tntElement.align(new Vector(0.49, 0, 0.5));
|
||||
tntElement.align(new Vector(0.49, 0, 0));
|
||||
tntElement.change();
|
||||
}));
|
||||
inv.setItem(24, new SWItem(Material.SUNFLOWER, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_CENTER", player), clickType -> { // CENTER
|
||||
|
@ -293,22 +293,25 @@ public class TNTElement implements SimulatorElement {
|
||||
parentVector = tntGroup.getPosition();
|
||||
}
|
||||
|
||||
if (vector.getX() - (int) vector.getX() == 0.49) {
|
||||
vector.setX(vector.getX() + 0.02);
|
||||
}
|
||||
if (vector.getX() - (int) vector.getX() == -0.49) {
|
||||
vector.setX(vector.getX() - 0.02);
|
||||
}
|
||||
if (vector.getZ() - (int) vector.getZ() == 0.49) {
|
||||
vector.setZ(vector.getZ() + 0.02);
|
||||
}
|
||||
if (vector.getZ() - (int) vector.getZ() == -0.49) {
|
||||
vector.setZ(vector.getZ() - 0.02);
|
||||
if (offset.getX() != 0) {
|
||||
if (vector.getX() - (int) vector.getX() == 0.49) {
|
||||
vector.setX(vector.getX() + 0.02);
|
||||
}
|
||||
if (vector.getX() - (int) vector.getX() == -0.49) {
|
||||
vector.setX(vector.getX() - 0.02);
|
||||
}
|
||||
vector.setX(vector.getBlockX() + offset.getX());
|
||||
}
|
||||
|
||||
vector.setX(vector.getBlockX() + offset.getX());
|
||||
vector.setY(vector.getBlockY() + offset.getY());
|
||||
vector.setZ(vector.getBlockZ() + offset.getZ());
|
||||
if (offset.getZ() != 0) {
|
||||
if (vector.getZ() - (int) vector.getZ() == 0.49) {
|
||||
vector.setZ(vector.getZ() + 0.02);
|
||||
}
|
||||
if (vector.getZ() - (int) vector.getZ() == -0.49) {
|
||||
vector.setZ(vector.getZ() - 0.02);
|
||||
}
|
||||
vector.setZ(vector.getBlockZ() + offset.getZ());
|
||||
}
|
||||
|
||||
setPosition(vector.subtract(parentVector));
|
||||
}
|
||||
|
@ -20,13 +20,27 @@
|
||||
package de.steamwar.bausystem.features.tpslimit;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.core.BountifulWrapper;
|
||||
import de.steamwar.core.ChatWrapper;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import yapion.utils.ReflectionsUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@UtilityClass
|
||||
public class FreezeUtils {
|
||||
@ -64,10 +78,89 @@ public class FreezeUtils {
|
||||
if (freezeEnabled) {
|
||||
try {
|
||||
field.set(getWorldHandle.invoke(world), state);
|
||||
cacheEntityPackets(state);
|
||||
frozen = state;
|
||||
} catch (IllegalAccessException e) {
|
||||
// Ignored;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> packets = new ArrayList<>();
|
||||
private Set<Entity> entities = new HashSet<>();
|
||||
private BukkitTask task = null;
|
||||
|
||||
private Class<?> vec3dClass = Reflection.getClass("{nms.world.phys}.Vec3D");
|
||||
private Reflection.FieldAccessor<Object> zeroVec3d = (Reflection.FieldAccessor<Object>) Reflection.getField(vec3dClass, vec3dClass, 0);
|
||||
private Object ZERO_VEC3D = zeroVec3d.get(null);
|
||||
private Class<?> velocityPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity");
|
||||
private Reflection.ConstructorInvoker velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass);
|
||||
|
||||
private Class<?> teleportPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
|
||||
private Class<?> entityClass = Reflection.getClass("{nms.world.entity}.Entity");
|
||||
private Reflection.ConstructorInvoker teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass);
|
||||
|
||||
private Class<?> craftEntityClass = Reflection.getClass("{obc}.entity.CraftEntity");
|
||||
private Reflection.MethodInvoker getHandle = Reflection.getMethod(craftEntityClass, "getHandle");
|
||||
|
||||
private Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5, Boolean.class);
|
||||
private Object fuseDataWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);
|
||||
|
||||
private void cacheEntityPackets(boolean state) {
|
||||
if (state) {
|
||||
createPackets();
|
||||
|
||||
if (task == null) {
|
||||
task = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
createPackets();
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
for (Object packet : packets) {
|
||||
TinyProtocol.instance.sendPacket(player, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(BauSystem.getInstance(), 1, 1);
|
||||
}
|
||||
} else {
|
||||
packets.clear();
|
||||
entities.clear();
|
||||
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createPackets() {
|
||||
if (FreezeUtils.entities.stream().anyMatch(Entity::isDead)) {
|
||||
entities.clear();
|
||||
packets.clear();
|
||||
}
|
||||
List<Entity> entities = Bukkit.getWorlds().get(0).getEntities().stream()
|
||||
.filter(e -> !(e instanceof Player))
|
||||
.filter(e -> !FreezeUtils.entities.contains(e))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Entity entity : entities) {
|
||||
packets.add(teleportPacketConstructor.invoke(getHandle.invoke(entity)));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
packets.add(velocityPacketConstructor.invoke(entity.getEntityId(), ZERO_VEC3D));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), noGravityDataWatcher, true));
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof TNTPrimed)) continue;
|
||||
TNTPrimed tnt = (TNTPrimed) entity;
|
||||
int fuse = tnt.getFuseTicks();
|
||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, fuse - (fuse % 5) + 1));
|
||||
}
|
||||
|
||||
FreezeUtils.entities.addAll(entities);
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
@ -180,7 +181,7 @@ public class Recorder implements Listener {
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof TNTPrimed)) {
|
||||
@ -188,7 +189,8 @@ public class Recorder implements Listener {
|
||||
}
|
||||
TraceRecorder traceRecorder = get((TNTPrimed) entity);
|
||||
Region region = tntTraceRecorderMap.get((TNTPrimed) entity);
|
||||
traceRecorder.explode((TNTPrimed) entity, !event.blockList().isEmpty() && region.inRegion(event.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
|
||||
boolean inBuildRegion = event.blockList().stream().anyMatch(block -> region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
|
||||
traceRecorder.explode((TNTPrimed) entity, inBuildRegion);
|
||||
tntTraceRecorderMap.remove(entity);
|
||||
tick();
|
||||
}
|
||||
|
@ -202,6 +202,8 @@ public class EntityShowMode implements ShowMode<TNTPosition> {
|
||||
entity.setDisplayName(fuseTicks + "");
|
||||
} else if (showModeParameter.isCount()) {
|
||||
entity.setDisplayName(new HashSet<>(records).size() + "");
|
||||
} else if (showModeParameter.isTicksSinceStart()) {
|
||||
entity.setDisplayName((80 - fuseTicks) + tntPosition.getRecord().getOffset() + "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ public class ShowModeParameter {
|
||||
private boolean ticks = false;
|
||||
private boolean count = false;
|
||||
private boolean buildDestroyOnly = false;
|
||||
private boolean ticksSinceStart = false;
|
||||
|
||||
public void enableWater() {
|
||||
this.water = true;
|
||||
@ -63,4 +64,8 @@ public class ShowModeParameter {
|
||||
public void enableBuildDestroyOnly() {
|
||||
this.buildDestroyOnly = true;
|
||||
}
|
||||
|
||||
public void enableTicksSinceStart() {
|
||||
this.ticksSinceStart = true;
|
||||
}
|
||||
}
|
||||
|
@ -38,9 +38,10 @@ public enum ShowModeParameterType {
|
||||
}, Arrays.asList("-advanced", "-a"), "INTERPOLATE_Y", "INTERPOLATE_XZ"),
|
||||
SOURCE(ShowModeParameter::enableSourceOnly, Arrays.asList("-source", "-sourceonly", "-ignite"), "TICKS", "ADVANCED", "INTERPOLATE_Y", "INTERPOLATE_XZ", "WATER"),
|
||||
EXPLODE(ShowModeParameter::enableExplodeOnly, Arrays.asList("-explode", "-explodeonly"), "TICKS", "ADVANCED", "INTERPOLATE_Y", "INTERPOLATE_XZ", "WATER"),
|
||||
TICKS(ShowModeParameter::enableTicks, Arrays.asList("-ticks", "-t"), "EXPLODE", "SOURCE", "COUNT"),
|
||||
COUNT(ShowModeParameter::enableCount, Arrays.asList("-count", "-c"), "COUNT"),
|
||||
BUILD_DESTROY_ONLY(ShowModeParameter::enableBuildDestroyOnly, Arrays.asList("-builddestroy", "-builddestoryonly"), "WATER");
|
||||
TICKS(ShowModeParameter::enableTicks, Arrays.asList("-ticks", "-t"), "EXPLODE", "SOURCE", "COUNT", "TICKS_SINCE_START"),
|
||||
COUNT(ShowModeParameter::enableCount, Arrays.asList("-count", "-c"), "TICKS", "TICKS_SINCE_START"),
|
||||
BUILD_DESTROY_ONLY(ShowModeParameter::enableBuildDestroyOnly, Arrays.asList("-builddestroy", "-builddestoryonly"), "WATER"),
|
||||
TICKS_SINCE_START(ShowModeParameter::enableTicksSinceStart, Arrays.asList("-tickssincestart", "-tss"), "TICKS", "COUNT");
|
||||
|
||||
@Getter
|
||||
private final Consumer<ShowModeParameter> showModeParameterConsumer;
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.util;
|
||||
|
||||
import de.steamwar.bausystem.SWUtils;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@Linked
|
||||
public class DragonEggCommand extends SWCommand {
|
||||
|
||||
public DragonEggCommand() {
|
||||
super("dragonegg", "enderdragon", "dragon", "egg", "enderei", "ender");
|
||||
}
|
||||
|
||||
@Register(description = "DRAGON_EGG_COMMAND_HELP")
|
||||
public void genericCommand(Player p) {
|
||||
SWUtils.giveItemToPlayer(p, new ItemStack(Material.DRAGON_EGG, 1));
|
||||
}
|
||||
}
|
@ -97,6 +97,7 @@ public class XrayCommand extends SWCommand implements Listener {
|
||||
techHiderCommand.disable(region, player);
|
||||
if (hidden.get(region).contains(player)) {
|
||||
hidden.get(region).remove(player);
|
||||
PlayerMovementWrapper.impl.disable(player);
|
||||
BauSystem.MESSAGE.sendPrefixless("XRAY_OFF", player, ChatMessageType.ACTION_BAR);
|
||||
} else {
|
||||
hidden.get(region).add(player);
|
||||
|
@ -27,4 +27,6 @@ public interface PlayerMovementWrapper {
|
||||
PlayerMovementWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
||||
|
||||
void setPosition(Player player, Object object);
|
||||
default void disable(Player player) {
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.utils.bossbar;
|
||||
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarFlag;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
|
||||
public interface BauSystemBossbar {
|
||||
|
||||
String getTitle();
|
||||
void setTitle(String title);
|
||||
|
||||
double getProgress();
|
||||
void setProgress(double progress);
|
||||
|
||||
BarColor getColor();
|
||||
void setColor(BarColor color);
|
||||
|
||||
BarStyle getStyle();
|
||||
void setStyle(BarStyle style);
|
||||
|
||||
boolean hasFlag(BarFlag flag);
|
||||
void addFlag(BarFlag flag);
|
||||
void removeFlag(BarFlag flag);
|
||||
|
||||
boolean isVisible();
|
||||
void setVisible(boolean visible);
|
||||
|
||||
Region getRegion();
|
||||
|
||||
void cleanup();
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.utils.bossbar;
|
||||
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Linked
|
||||
public class BossBarService implements Listener {
|
||||
|
||||
public static BossBarService instance;
|
||||
|
||||
public BossBarService() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private final Map<Player, Map<Region, Map<String, BauSystemBossbar>>> playerBossBars = new HashMap<>();
|
||||
|
||||
public synchronized BauSystemBossbar get(Player player, Region region, String key) {
|
||||
return playerBossBars.computeIfAbsent(player, p -> new HashMap<>())
|
||||
.computeIfAbsent(region, r -> new HashMap<>())
|
||||
.computeIfAbsent(key, k -> {
|
||||
BossBar bossBar = Bukkit.createBossBar("", BarColor.WHITE, BarStyle.SOLID);
|
||||
bossBar.addPlayer(player);
|
||||
if (region.isGlobal()) {
|
||||
return new GlobalBossbar(bossBar);
|
||||
} else {
|
||||
return new RegionedBossbar(bossBar, region, player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void removeAll(Player player, String key) {
|
||||
Map<Region, Map<String, BauSystemBossbar>> regionMap = playerBossBars.get(player);
|
||||
if (regionMap == null) return;
|
||||
for (Map<String, BauSystemBossbar> bossBarMap : regionMap.values()) {
|
||||
BauSystemBossbar bossBar = bossBarMap.remove(key);
|
||||
if (bossBar == null) continue;
|
||||
bossBar.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeAll(Player player) {
|
||||
Map<Region, Map<String, BauSystemBossbar>> regionMap = playerBossBars.remove(player);
|
||||
if (regionMap == null) return;
|
||||
for (Map<String, BauSystemBossbar> bossBarMap : regionMap.values()) {
|
||||
for (BauSystemBossbar bossBar : bossBarMap.values()) {
|
||||
bossBar.cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void remove(Player player, Region region, String key) {
|
||||
Map<Region, Map<String, BauSystemBossbar>> regionMap = playerBossBars.get(player);
|
||||
if (regionMap == null) return;
|
||||
Map<String, BauSystemBossbar> bossBarMap = regionMap.get(region);
|
||||
if (bossBarMap == null) return;
|
||||
BauSystemBossbar bossBar = bossBarMap.remove(key);
|
||||
if (bossBar == null) return;
|
||||
bossBar.cleanup();
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
removeAll(event.getPlayer());
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.utils.bossbar;
|
||||
|
||||
import de.steamwar.bausystem.region.GlobalRegion;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarFlag;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
|
||||
public class GlobalBossbar implements BauSystemBossbar {
|
||||
|
||||
private BossBar bossBar;
|
||||
|
||||
public GlobalBossbar(BossBar bossBar) {
|
||||
this.bossBar = bossBar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return bossBar.getTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
bossBar.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getProgress() {
|
||||
return bossBar.getProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(double progress) {
|
||||
bossBar.setProgress(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BarColor getColor() {
|
||||
return bossBar.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(BarColor color) {
|
||||
bossBar.setColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BarStyle getStyle() {
|
||||
return bossBar.getStyle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStyle(BarStyle style) {
|
||||
bossBar.setStyle(style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFlag(BarFlag flag) {
|
||||
return bossBar.hasFlag(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFlag(BarFlag flag) {
|
||||
bossBar.addFlag(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFlag(BarFlag flag) {
|
||||
bossBar.removeFlag(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return bossBar.isVisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
bossBar.setVisible(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region getRegion() {
|
||||
return GlobalRegion.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
bossBar.removeAll();
|
||||
bossBar = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 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.utils.bossbar;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||
import de.steamwar.bausystem.region.utils.RegionType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarFlag;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
public class RegionedBossbar implements BauSystemBossbar, Listener {
|
||||
|
||||
private BossBar bossBar;
|
||||
private Region region;
|
||||
private Player player;
|
||||
|
||||
public RegionedBossbar(BossBar bossBar, Region region, Player player) {
|
||||
this.bossBar = bossBar;
|
||||
this.region = region;
|
||||
this.player = player;
|
||||
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return bossBar.getTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
bossBar.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getProgress() {
|
||||
return bossBar.getProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(double progress) {
|
||||
bossBar.setProgress(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BarColor getColor() {
|
||||
return bossBar.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(BarColor color) {
|
||||
bossBar.setColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BarStyle getStyle() {
|
||||
return bossBar.getStyle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStyle(BarStyle style) {
|
||||
bossBar.setStyle(style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFlag(BarFlag flag) {
|
||||
return bossBar.hasFlag(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFlag(BarFlag flag) {
|
||||
bossBar.addFlag(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFlag(BarFlag flag) {
|
||||
bossBar.removeFlag(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return bossBar.isVisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
bossBar.setVisible(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
if (event.getPlayer() != player) return;
|
||||
if (region.inRegion(event.getTo(), RegionType.NORMAL, RegionExtensionType.NORMAL)) {
|
||||
bossBar.addPlayer(player);
|
||||
} else {
|
||||
bossBar.removePlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
if (event.getPlayer() != player) return;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
if (bossBar != null) {
|
||||
bossBar.removeAll();
|
||||
bossBar = null;
|
||||
}
|
||||
region = null;
|
||||
player = null;
|
||||
|
||||
PlayerMoveEvent.getHandlerList().unregister(this);
|
||||
PlayerQuitEvent.getHandlerList().unregister(this);
|
||||
}
|
||||
}
|
In neuem Issue referenzieren
Einen Benutzer sperren