diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties
index fcf18e04..302865d8 100644
--- a/BauSystem_Main/src/BauSystem.properties
+++ b/BauSystem_Main/src/BauSystem.properties
@@ -499,12 +499,19 @@ REGION_TNT_BUILD=§cEine Explosion hätte Blöcke im Baubereich zerstört
# Unsign Book
UNSIGN_HELP_1=§8/§eunsign §8- §7Mache ein Buch beschreibbar
-
# Team
LOCK_SCHEM_NO_USER=§7Dieser Spieler existiert nicht!
LOCK_SCHEM_NO_SCHEM=§7Dieser Spieler besitzt keine Schematic mit diesem Namen!
LOCK_SCHEM_LOCKED=§e{0} §7von §e{1} §7wurde von §e{2} §7auf §eNORMAL §7zurück gesetz. §f§lGrund: §f{3}
LOCK_SCHEM_HELP=§8/§eschemlock §8[§7Owner§8] [§7Schematic§8] [§7Grund§8] - §7Sperre eine Schematic
-
AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 5 Minuten nichts passiert.
-AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt
\ No newline at end of file
+AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt
+WARP_EXISTS=§7Der Warp mit dem namen §e{0} §7existiert bereits
+WARP_NAME_RESERVED=§7Du kannst nicht §c{0} §7als name für einen Warp nutzen
+WARP_CREATED=§7Der Warp §e{0} §7wurde erstellt
+WARP_DELETED=§e{0} §7wurde gelöcht
+WARP_GUI_NO=§cHier giebt es noch keine Warps
+WARP_GUI_DISTANCE=§7Distanz: §e{0} §7Blöcke
+WARP_INFO_NAME=§7Name: §e{0}
+WARP_INFO_CREATOR=§7Ersteller: §e{0}
+WARP_INFO_CREATED=§7Erstellt am: §e{0}
\ No newline at end of file
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/warp/Moon.java b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/Moon.java
new file mode 100644
index 00000000..02ed15e0
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/Moon.java
@@ -0,0 +1,59 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2021 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bausystem.features.warp;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.inventory.SWItem;
+import lombok.experimental.UtilityClass;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.Particle;
+import org.bukkit.entity.Player;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+import org.bukkit.util.Vector;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+@UtilityClass
+public class Moon {
+
+ public static void startMoon(Player player) {
+ player.getInventory().setHelmet(new SWItem(Material.GLASS, "§3Atemkugel").getItemStack());
+ AtomicInteger countDown = new AtomicInteger(5);
+ Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), bukkitTask -> {
+ if (countDown.get() == 0) {
+ AtomicInteger iter = new AtomicInteger(1000);
+ Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), bukkitTask1 -> {
+ if (player.getLocation().getY() > 300 || iter.getAndDecrement() <= 0) {
+ player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_FALLING, 60 * 5 * 20, 1, false, false));
+ bukkitTask1.cancel();
+ } else {
+ player.setVelocity(player.getVelocity().add(new Vector(0, 0.2, 0)));
+ player.getWorld().spawnParticle(Particle.FLAME, player.getLocation(), 5);
+ }
+ }, 0, 1);
+ bukkitTask.cancel();
+ } else {
+ player.sendMessage("§7Noch §e§l" + countDown.getAndDecrement() + " §7Sekunden!");
+ }
+ }, 0, 20);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/warp/Warp.java b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/Warp.java
new file mode 100644
index 00000000..0458670d
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/Warp.java
@@ -0,0 +1,155 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2021 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bausystem.features.warp;
+
+import de.steamwar.bausystem.worlddata.WorldData;
+import lombok.Getter;
+import org.bukkit.*;
+import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerTeleportEvent;
+import yapion.hierarchy.types.YAPIONArray;
+import yapion.hierarchy.types.YAPIONObject;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@Getter
+public class Warp {
+
+ private final Instant created;
+ private final YAPIONObject object;
+ private String name;
+ private double x;
+ private double y;
+ private double z;
+ private float yaw;
+ private float pitch;
+ private Material mat;
+ private String creator;
+
+ private Warp(YAPIONObject object) {
+ this.object = object;
+ name = object.getPlainValue("name");
+ x = object.getPlainValue("x");
+ y = object.getPlainValue("y");
+ z = object.getPlainValue("z");
+ yaw = object.getPlainValue("yaw");
+ pitch = object.getPlainValue("pitch");
+ mat = Material.getMaterial(object.getPlainValue("material"));
+ creator = object.getPlainValue("owner");
+ created = Instant.ofEpochSecond(object.getPlainValue("time"));
+ }
+
+ private Warp() {
+ object = new YAPIONObject();
+ object.add("time", Instant.now().getEpochSecond());
+ created = Instant.ofEpochSecond(object.getPlainValue("time"));
+ }
+
+ public static List getWarps() {
+ List warpList = new ArrayList<>();
+ YAPIONArray warpsObject = WorldData.getWarpData();
+ warpsObject.forEach(yapionAnyType -> warpList.add(new Warp((YAPIONObject) yapionAnyType)));
+ return warpList;
+ }
+
+ public static Optional getWarp(String name) {
+ YAPIONArray warpsObject = WorldData.getWarpData();
+ return warpsObject.stream().filter(yapionAnyType -> name.equals(((YAPIONObject) yapionAnyType).getPlainValueOrDefault("name", null))).map(yapionAnyType -> new Warp((YAPIONObject) yapionAnyType)).findAny();
+ }
+
+ public static Warp createWarp(String name, double x, double y, double z, float yaw, float pitch, Material mat, String creator) {
+ Warp warp = new Warp();
+ warp.setName(name);
+ warp.setX(x);
+ warp.setY(y);
+ warp.setZ(z);
+ warp.setYaw(yaw);
+ warp.setPitch(pitch);
+ warp.setMat(mat);
+ warp.setCreator(creator);
+ YAPIONArray warpsObject = WorldData.getWarpData();
+ warpsObject.add(warp.object);
+
+ return warp;
+ }
+
+ public static Warp createWarp(String name, Player player, Material mat) {
+ Location loc = player.getLocation();
+ return createWarp(name, loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), mat, player.getName());
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ object.add("name", name);
+ }
+
+ public void setX(double x) {
+ this.x = x;
+ object.add("x", x);
+ }
+
+ public void setY(double y) {
+ this.y = y;
+ object.add("y", y);
+ }
+
+ public void setZ(double z) {
+ this.z = z;
+ object.add("z", z);
+ }
+
+ public void setYaw(float yaw) {
+ this.yaw = yaw;
+ object.add("yaw", yaw);
+ }
+
+ public void setPitch(float pitch) {
+ this.pitch = pitch;
+ object.add("pitch", pitch);
+ }
+
+ public void setMat(Material mat) {
+ this.mat = mat;
+ object.add("material", mat.name());
+ }
+
+ public void setCreator(String creator) {
+ this.creator = creator;
+ object.add("owner", creator);
+ }
+
+ public void delete() {
+ YAPIONArray warpsObject = WorldData.getWarpData();
+ warpsObject.removeIf(yapionAnyType -> ((YAPIONObject) yapionAnyType).getPlainValue("name").equals(name));
+ }
+
+ public Location toLocation() {
+ return new Location(Bukkit.getWorlds().get(0), x, y, z, yaw, pitch);
+ }
+
+ public void teleport(Player player) {
+ Location loc = toLocation();
+ player.teleport(loc, PlayerTeleportEvent.TeleportCause.PLUGIN);
+ player.playSound(loc, Sound.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1, 1);
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpCommand.java
new file mode 100644
index 00000000..7de20794
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpCommand.java
@@ -0,0 +1,178 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2021 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bausystem.features.warp;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.bausystem.config.ColorConfig;
+import de.steamwar.bausystem.linkage.LinkageType;
+import de.steamwar.bausystem.linkage.Linked;
+import de.steamwar.command.SWCommand;
+import de.steamwar.command.SWCommandUtils;
+import de.steamwar.command.TypeMapper;
+import net.md_5.bungee.api.ChatColor;
+import net.md_5.bungee.api.chat.ClickEvent;
+import net.md_5.bungee.api.chat.ComponentBuilder;
+import net.md_5.bungee.api.chat.HoverEvent;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Linked(LinkageType.COMMAND)
+public class WarpCommand extends SWCommand {
+
+ private static final String[] FORBIDDEN_NAMES = new String[]{
+ "add", "create", "delete", "list", "info", "gui"
+ };
+
+ protected WarpCommand() {
+ super("warp");
+ }
+
+ @ClassMapper(Warp.class)
+ public static TypeMapper getWarpMapper() {
+ return SWCommandUtils.createMapper(s -> Warp.getWarp(s).orElse(null), (commandSender, s) -> {
+ return Warp.getWarps().stream().map(Warp::getName).collect(Collectors.toList());
+ });
+ }
+
+ @Register(help = true)
+ public void genericHelp(Player player, String... args) {
+ if (args.length > 0 && args[0].equals("moon")) {
+ Moon.startMoon(player);
+ return;
+ }
+ BauSystem.MESSAGE.sendPrefixless("COMMAND_HELP_HEAD", player, "Warp");
+ }
+
+ @Register("add")
+ @Register("create")
+ public void addWarp(Player player, String name) {
+ if (!permissionCheck(player)) return;
+ for (String forbiddenName : FORBIDDEN_NAMES) {
+ if (name.equalsIgnoreCase(forbiddenName)) {
+ BauSystem.MESSAGE.send("WARP_NAME_RESERVED", player, name);
+ return;
+ }
+ }
+ if (Warp.getWarp(name).isPresent()) {
+ BauSystem.MESSAGE.send("WARP_EXISTS", player, name);
+ return;
+ }
+ Warp.createWarp(name, player, Material.BEACON);
+ BauSystem.MESSAGE.send("WARP_CREATED", player, name);
+ }
+
+ @Register
+ public void tpWarp(Player player, Warp warp) {
+ warp.teleport(player);
+ }
+
+ @Register("delete")
+ public void deleteWarp(Player player, Warp warp) {
+ if (permissionCheck(player)) return;
+ warp.delete();
+ BauSystem.MESSAGE.send("WARP_DELETED", player, warp.getName());
+ }
+
+ @Register("gui")
+ public void gui(Player player) {
+ WarpGui.openGui(player);
+ }
+
+ @Register("list")
+ public void listWarps(Player player) {
+ listWarps(player, 0);
+ }
+
+ @Register("list")
+ public void listWarps(Player player, int page) {
+ List warps = Warp.getWarps();
+ int pageCount = (int) Math.ceil(warps.size() / 18d);
+ for (int i = page * 18; i < warps.size() && i < (page + 1) * 18; i++) {
+ Warp warp = warps.get(i);
+ TextComponent component = new TextComponent();
+ component.setText(warp.getName());
+ component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/warp " + warp.getName()));
+ component.setColor(ChatColor.YELLOW);
+ component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§7Zu §e" + warp.getName() + " §7teleportieren")));
+ player.spigot().sendMessage(component);
+ }
+
+ TextComponent beforePage = new TextComponent("««");
+ if (page > 0) {
+ beforePage.setColor(ChatColor.YELLOW);
+ beforePage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§eVorherige Seite").create()));
+ beforePage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/warp list " + (page - 1)));
+ } else {
+ beforePage.setColor(ChatColor.RED);
+ }
+
+ TextComponent nextPage = new TextComponent(" Seite (" + (page + 1) + "/" + Math.max(pageCount, 1) + ") »»");
+ if (page < pageCount - 1) {
+ nextPage.setColor(ChatColor.YELLOW);
+ nextPage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§eNächste Seite").create()));
+ nextPage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/warp list " + (page + 1)));
+ } else {
+ nextPage.setColor(ChatColor.RED);
+ }
+
+ beforePage.addExtra(nextPage);
+ player.spigot().sendMessage(beforePage);
+ }
+
+ @Register("info")
+ public void warpInfo(Player player, Warp warp) {
+ BauSystem.MESSAGE.send("COMMAND_HELP_HEAD", player, warp.getName());
+ BauSystem.MESSAGE.sendPrefixless("WARP_INFO_NAME", player, warp.getName());
+ BauSystem.MESSAGE.sendPrefixless("WARP_INFO_CREATOR", player, warp.getCreator());
+ BauSystem.MESSAGE.sendPrefixless("WARP_INFO_CREATED", player, Timestamp.from(warp.getCreated()).toLocalDateTime());
+ player.sendMessage("§7X: §e" + warp.getX());
+ player.sendMessage("§7Y: §e" + warp.getY());
+ player.sendMessage("§7Z: §e" + warp.getZ());
+ BauSystem.MESSAGE.sendPrefixless("WARP_GUI_DISTANCE", player, warp.toLocation().distance(player.getLocation()));
+ }
+
+ @SuppressWarnings("BooleanMethodIsAlwaysInverted")
+ private boolean permissionCheck(Player player) {
+ if (!Permission.hasPermission(player, Permission.WORLD)) {
+ player.sendMessage(BauSystem.PREFIX + ColorConfig.DISABLE + "Du darfst hier nicht den Warp verändern");
+ return false;
+ }
+ return true;
+ }
+
+ @Linked(LinkageType.COMMAND)
+ public static class WarpsLink extends SWCommand {
+
+ protected WarpsLink() {
+ super("warps");
+ }
+
+ @Register(help = true)
+ public void genericCommand(Player player, String... args) {
+ player.performCommand("warp list " + String.join(" ", args));
+ }
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpGui.java
new file mode 100644
index 00000000..b1c7fc47
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpGui.java
@@ -0,0 +1,96 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2021 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bausystem.features.warp;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import de.steamwar.inventory.SWListInv;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class WarpGui {
+
+ public static void openGui(Player player) {
+ List> entries = new ArrayList<>();
+ Warp.getWarps().forEach(warp -> entries.add(new SWListInv.SWListEntry<>(new SWItem(
+ warp.getMat(),
+ "§e" + warp.getName(),
+ Arrays.asList("§7X: §e" + (int) warp.getX(),
+ "§7Y: §e" + (int) warp.getY(),
+ "§7Z: §e" + (int) warp.getZ(),
+ BauSystem.MESSAGE.parse("WARP_GUI_DISTANCE", player, (int) warp.toLocation().distance(player.getLocation()))),
+ false,
+ clickType -> {
+ }
+ ), warp)));
+
+ SWListInv inv = new SWListInv<>(player, "Warps", false, entries, (clickType, warp) -> {
+ if (clickType.isRightClick() && Permission.hasPermission(player, Permission.WORLD)) {
+ openWarpGui(player, warp);
+ } else {
+ warp.teleport(player);
+ }
+ });
+
+ if (entries.isEmpty()) {
+ inv.setItem(22, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("WARP_GUI_NO", player), clickType -> {
+ }));
+ }
+
+ inv.open();
+ }
+
+ public static void openWarpGui(Player player, Warp warp) {
+ SWInventory inv = new SWInventory(player, 9, warp.getName());
+ inv.setItem(0, new SWItem(Material.ENDER_PEARL, "§7Zu §e" + warp.getName() + " §7teleportieren", clickType -> {
+ player.closeInventory();
+ warp.teleport(player);
+ }));
+
+ inv.setItem(2, new SWItem(warp.getMat(), "§e" + warp.getMat().name(), clickType -> changeMaterial(player, warp)));
+
+ inv.setItem(8, new SWItem(Material.BARRIER, "§e" + warp.getName() + " §7löschen", clickType -> {
+ player.closeInventory();
+ warp.delete();
+ }));
+
+ inv.open();
+ }
+
+ public static void changeMaterial(Player player, Warp warp) {
+ List> materials = new ArrayList<>();
+ for (Material value : Material.values()) {
+ if (value.isLegacy() || value.isAir()) continue;
+ materials.add(new SWListInv.SWListEntry<>(new SWItem(value, "§e" + value.name()), value));
+ }
+
+ SWListInv inv = new SWListInv<>(player, "Material auswählen", materials, (clickType, material) -> {
+ player.closeInventory();
+ warp.setMat(material);
+ });
+ inv.open();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/worlddata/WorldData.java b/BauSystem_Main/src/de/steamwar/bausystem/worlddata/WorldData.java
index f5eab71f..62f54e8f 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/worlddata/WorldData.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/worlddata/WorldData.java
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.worlddata;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import yapion.hierarchy.output.FileOutput;
+import yapion.hierarchy.types.YAPIONArray;
import yapion.hierarchy.types.YAPIONObject;
import yapion.parser.YAPIONParser;
@@ -33,7 +34,7 @@ import java.io.IOException;
@UtilityClass
public class WorldData {
- private File optionsFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "options.yapion");
+ private final File optionsFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "options.yapion");
private YAPIONObject worldData;
public YAPIONObject getWorldData() {
@@ -47,6 +48,10 @@ public class WorldData {
return getWorldData().getYAPIONObjectOrSetDefault("regions", new YAPIONObject());
}
+ public YAPIONArray getWarpData() {
+ return getWorldData().getYAPIONArrayOrSetDefault("warps", new YAPIONArray());
+ }
+
private void read() {
worldData = new YAPIONObject();
if (optionsFile.length() != 0) {