From 9ee4c3f255e836c843f4a2203e17769e53ea581e Mon Sep 17 00:00:00 2001 From: yoyosource Date: Sun, 18 Apr 2021 00:16:08 +0200 Subject: [PATCH] Add SimulatorCommand --- .../simulator/SimulatorEntity_15.java | 59 +++ .../features/simulator/Simulator_15.java | 13 +- .../features/tracer/TraceEntity_15.java | 40 +- .../bausystem/shared/BaseEntity_15.java | 60 +++ .../simulator/AbstractSimulatorEntity.java | 35 ++ .../features/tracer/AbstractTraceEntity.java | 40 +- .../bausystem/shared/AbstractEntity.java | 23 + .../bausystem/shared/ReferenceCounter.java | 36 ++ .../features/simulator/SimulatorCommand.java | 78 ++++ .../features/simulator/SimulatorPosition.java | 23 + .../features/simulator/TNTSimulator.java | 431 ++++++++++++++++++ .../simulator/TNTSimulatorListener.java | 128 ++++++ .../show/SimulatorEntityShowMode.java | 64 +++ .../features/tracer/RoundedTNTPosition.java | 65 --- .../features/tracer/TNTPosition.java | 46 +- .../features/tracer/TraceCommand.java | 6 +- .../features/tracer/show/Record.java | 5 +- .../features/tracer/show/StoredRecords.java | 4 +- .../tracer/show/TraceShowManager.java | 19 +- ...ShowMode.java => TraceEntityShowMode.java} | 28 +- .../steamwar/bausystem/shared/Position.java | 30 ++ .../bausystem/shared/RoundedPosition.java | 63 +++ .../steamwar/bausystem/shared/ShowMode.java | 28 ++ 23 files changed, 1153 insertions(+), 171 deletions(-) create mode 100644 BauSystem_15/src/de/steamwar/bausystem/features/simulator/SimulatorEntity_15.java rename BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowMode.java => BauSystem_15/src/de/steamwar/bausystem/features/simulator/Simulator_15.java (72%) create mode 100644 BauSystem_15/src/de/steamwar/bausystem/shared/BaseEntity_15.java create mode 100644 BauSystem_API/src/de/steamwar/bausystem/features/simulator/AbstractSimulatorEntity.java create mode 100644 BauSystem_API/src/de/steamwar/bausystem/shared/AbstractEntity.java create mode 100644 BauSystem_API/src/de/steamwar/bausystem/shared/ReferenceCounter.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorPosition.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/simulator/show/SimulatorEntityShowMode.java delete mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/tracer/RoundedTNTPosition.java rename BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/{EntityShowMode.java => TraceEntityShowMode.java} (79%) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/shared/Position.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/shared/ShowMode.java diff --git a/BauSystem_15/src/de/steamwar/bausystem/features/simulator/SimulatorEntity_15.java b/BauSystem_15/src/de/steamwar/bausystem/features/simulator/SimulatorEntity_15.java new file mode 100644 index 00000000..6e10e2b1 --- /dev/null +++ b/BauSystem_15/src/de/steamwar/bausystem/features/simulator/SimulatorEntity_15.java @@ -0,0 +1,59 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 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.simulator; + +import de.steamwar.bausystem.shared.BaseEntity_15; +import de.steamwar.bausystem.shared.ReferenceCounter; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +class SimulatorEntity_15 extends BaseEntity_15 implements AbstractSimulatorEntity { + + private ReferenceCounter referenceCounter = new ReferenceCounter(); + + public SimulatorEntity_15(World world, Vector position, boolean tnt) { + super(world, position, tnt ? Material.TNT : Material.WHITE_STAINED_GLASS); + + this.setNoGravity(true); + this.ticksLived = -12000; + } + + @Override + public void display(Player player) { + if (referenceCounter.increment() > 0) { + return; + } + + sendEntity(player); + } + + @Override + public boolean hide(Player player, boolean force) { + if (!force && referenceCounter.decrement() > 0) { + return false; + } + + sendDestroy(player); + die(); + return true; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowMode.java b/BauSystem_15/src/de/steamwar/bausystem/features/simulator/Simulator_15.java similarity index 72% rename from BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowMode.java rename to BauSystem_15/src/de/steamwar/bausystem/features/simulator/Simulator_15.java index c271b332..c593dbcd 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/ShowMode.java +++ b/BauSystem_15/src/de/steamwar/bausystem/features/simulator/Simulator_15.java @@ -17,12 +17,15 @@ along with this program. If not, see . */ -package de.steamwar.bausystem.features.tracer.show; +package de.steamwar.bausystem.features.simulator; -import de.steamwar.bausystem.features.tracer.TNTPosition; +import org.bukkit.World; +import org.bukkit.util.Vector; -public interface ShowMode { - void show(TNTPosition position); +public class Simulator_15 { + + public static AbstractSimulatorEntity create(World world, Vector tntPosition, boolean tnt) { + return new SimulatorEntity_15(world, tntPosition, tnt); + } - void hide(); } diff --git a/BauSystem_15/src/de/steamwar/bausystem/features/tracer/TraceEntity_15.java b/BauSystem_15/src/de/steamwar/bausystem/features/tracer/TraceEntity_15.java index 80f1bc46..e427ec59 100644 --- a/BauSystem_15/src/de/steamwar/bausystem/features/tracer/TraceEntity_15.java +++ b/BauSystem_15/src/de/steamwar/bausystem/features/tracer/TraceEntity_15.java @@ -19,26 +19,21 @@ package de.steamwar.bausystem.features.tracer; -import net.minecraft.server.v1_15_R1.*; +import de.steamwar.bausystem.shared.BaseEntity_15; +import de.steamwar.bausystem.shared.ReferenceCounter; +import net.minecraft.server.v1_15_R1.ChatComponentText; +import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -class TraceEntity_15 extends EntityFallingBlock implements AbstractTraceEntity { - - private static final Vec3D ZERO = new Vec3D(0, 0, 0); - private final Vector position; - private final boolean tnt; +class TraceEntity_15 extends BaseEntity_15 implements AbstractTraceEntity { private boolean exploded = false; - private int references = 0; + private ReferenceCounter referenceCounter = new ReferenceCounter(); public TraceEntity_15(World world, Vector position, boolean tnt) { - super(((CraftWorld) world).getHandle(), position.getX(), position.getY(), position.getZ(), tnt ? Blocks.TNT.getBlockData() : Blocks.WHITE_STAINED_GLASS.getBlockData()); - this.position = position; - this.tnt = tnt; + super(world, position, tnt ? Material.TNT : Material.WHITE_STAINED_GLASS); this.setNoGravity(true); this.ticksLived = -12000; @@ -50,31 +45,24 @@ class TraceEntity_15 extends EntityFallingBlock implements AbstractTraceEntity { this.setCustomNameVisible(true); this.setCustomName(new ChatComponentText("Bumm")); this.exploded = true; - if (references++ > 0) + if (referenceCounter.increment() > 0) { sendDestroy(player); - } else if (references++ > 0) + } + } else if (referenceCounter.increment() > 0) { return; + } - PacketPlayOutSpawnEntity packetPlayOutSpawnEntity = new PacketPlayOutSpawnEntity(getId(), getUniqueID(), position.getX(), position.getY(), position.getZ(), 0, 0, EntityTypes.FALLING_BLOCK, tnt ? Block.getCombinedId(Blocks.TNT.getBlockData()) : Block.getCombinedId(Blocks.WHITE_STAINED_GLASS.getBlockData()), ZERO); - PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; - playerConnection.sendPacket(packetPlayOutSpawnEntity); - - PacketPlayOutEntityMetadata packetPlayOutEntityMetadata = new PacketPlayOutEntityMetadata(getId(), datawatcher, true); - playerConnection.sendPacket(packetPlayOutEntityMetadata); + sendEntity(player); } @Override public boolean hide(Player player, boolean force) { - if (!force && --references > 0) + if (!force && referenceCounter.decrement() > 0) { return false; + } sendDestroy(player); die(); return true; } - - private void sendDestroy(Player player) { - PacketPlayOutEntityDestroy packetPlayOutEntityDestroy = new PacketPlayOutEntityDestroy(getId()); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packetPlayOutEntityDestroy); - } } diff --git a/BauSystem_15/src/de/steamwar/bausystem/shared/BaseEntity_15.java b/BauSystem_15/src/de/steamwar/bausystem/shared/BaseEntity_15.java new file mode 100644 index 00000000..e1e0f02b --- /dev/null +++ b/BauSystem_15/src/de/steamwar/bausystem/shared/BaseEntity_15.java @@ -0,0 +1,60 @@ +/* + * 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.shared; + +import net.minecraft.server.v1_15_R1.*; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public class BaseEntity_15 extends EntityFallingBlock { + + private static final Vec3D ZERO = new Vec3D(0, 0, 0); + + private final IBlockData iBlockData; + private final Vector position; + + public BaseEntity_15(World world, Vector position, Material blockType) { + super(((CraftWorld) world).getHandle(), position.getX(), position.getY(), position.getZ(), ((CraftBlockData) blockType.createBlockData()).getState()); + this.iBlockData = ((CraftBlockData) blockType.createBlockData()).getState(); + this.position = position; + + this.setNoGravity(true); + this.ticksLived = -12000; + } + + protected void sendEntity(Player player) { + PacketPlayOutSpawnEntity packetPlayOutSpawnEntity = new PacketPlayOutSpawnEntity(getId(), getUniqueID(), position.getX(), position.getY(), position.getZ(), 0, 0, EntityTypes.FALLING_BLOCK, Block.getCombinedId(iBlockData), ZERO); + PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; + playerConnection.sendPacket(packetPlayOutSpawnEntity); + + PacketPlayOutEntityMetadata packetPlayOutEntityMetadata = new PacketPlayOutEntityMetadata(getId(), datawatcher, true); + playerConnection.sendPacket(packetPlayOutEntityMetadata); + } + + protected void sendDestroy(Player player) { + PacketPlayOutEntityDestroy packetPlayOutEntityDestroy = new PacketPlayOutEntityDestroy(getId()); + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packetPlayOutEntityDestroy); + } +} diff --git a/BauSystem_API/src/de/steamwar/bausystem/features/simulator/AbstractSimulatorEntity.java b/BauSystem_API/src/de/steamwar/bausystem/features/simulator/AbstractSimulatorEntity.java new file mode 100644 index 00000000..ec788d36 --- /dev/null +++ b/BauSystem_API/src/de/steamwar/bausystem/features/simulator/AbstractSimulatorEntity.java @@ -0,0 +1,35 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 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.simulator; + +import de.steamwar.bausystem.shared.AbstractEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public interface AbstractSimulatorEntity extends AbstractEntity { + + void display(Player player); + + boolean hide(Player player, boolean always); + + int getId(); + + Entity getBukkitEntity(); +} diff --git a/BauSystem_API/src/de/steamwar/bausystem/features/tracer/AbstractTraceEntity.java b/BauSystem_API/src/de/steamwar/bausystem/features/tracer/AbstractTraceEntity.java index 82f012e9..63c6eb42 100644 --- a/BauSystem_API/src/de/steamwar/bausystem/features/tracer/AbstractTraceEntity.java +++ b/BauSystem_API/src/de/steamwar/bausystem/features/tracer/AbstractTraceEntity.java @@ -1,34 +1,32 @@ /* - This file is a part of the SteamWar software. - - Copyright (C) 2020 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 . -*/ + * 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.tracer; +import de.steamwar.bausystem.shared.AbstractEntity; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -public interface AbstractTraceEntity { +public interface AbstractTraceEntity extends AbstractEntity { void display(Player player, boolean exploded); boolean hide(Player player, boolean always); - int getId(); - - Entity getBukkitEntity(); } diff --git a/BauSystem_API/src/de/steamwar/bausystem/shared/AbstractEntity.java b/BauSystem_API/src/de/steamwar/bausystem/shared/AbstractEntity.java new file mode 100644 index 00000000..6627cae9 --- /dev/null +++ b/BauSystem_API/src/de/steamwar/bausystem/shared/AbstractEntity.java @@ -0,0 +1,23 @@ +/* + * 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.shared; + +public interface AbstractEntity { +} diff --git a/BauSystem_API/src/de/steamwar/bausystem/shared/ReferenceCounter.java b/BauSystem_API/src/de/steamwar/bausystem/shared/ReferenceCounter.java new file mode 100644 index 00000000..0ccbe672 --- /dev/null +++ b/BauSystem_API/src/de/steamwar/bausystem/shared/ReferenceCounter.java @@ -0,0 +1,36 @@ +/* + * 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.shared; + +import java.util.concurrent.atomic.AtomicInteger; + +public final class ReferenceCounter { + + private AtomicInteger references = new AtomicInteger(0); + + public int increment() { + return references.getAndIncrement(); + } + + public int decrement() { + return references.decrementAndGet(); + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java new file mode 100644 index 00000000..d45e24cc --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java @@ -0,0 +1,78 @@ +/* + * + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.simulator; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.command.SWCommand; +import de.steamwar.core.Core; +import org.bukkit.entity.Player; + +public class SimulatorCommand extends SWCommand { + + public SimulatorCommand() { + super("simulator", "sim"); + if(Core.getVersion() < 15) + unregister(); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§esimulator §8- §7Legt dir den Simulatorstab ins Inventar"); + p.sendMessage("§8/§esimulator start §8- §7Startet die Simulation"); + p.sendMessage("§8/§esimulator gui §8- §7Öffnet die GUI"); + p.sendMessage("§8/§esimulator delete §8- §7Löscht alle TNT"); + } + + @Register + public void genericCommand(Player p) { + if (cannotUse(p)) return; + SWUtils.giveItemToPlayer(p, TNTSimulator.WAND); + } + + @Register({"start"}) + public void startCommand(Player p) { + if (cannotUse(p)) return; + TNTSimulator.get(p).start(); + } + + @Register({"gui"}) + public void guiCommand(Player p) { + if (cannotUse(p)) return; + TNTSimulator.get(p).showGUI(); + } + + @Register({"delete"}) + public void deleteCommand(Player p) { + if (cannotUse(p)) return; + TNTSimulator.get(p).delete(); + } + + private boolean cannotUse(Player player) { + if (!Permission.hasPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Simulator nutzen"); + return true; + } + return false; + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorPosition.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorPosition.java new file mode 100644 index 00000000..9e76bffb --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorPosition.java @@ -0,0 +1,23 @@ +/* + * 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.simulator; + +public class SimulatorPosition { +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java new file mode 100644 index 00000000..ee8ab535 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java @@ -0,0 +1,431 @@ +/* + * + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.simulator; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.simulator.show.SimulatorEntityShowMode; +import de.steamwar.inventory.SWAnvilInv; +import de.steamwar.inventory.SWInventory; +import de.steamwar.inventory.SWItem; +import de.steamwar.inventory.SWListInv; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Consumer; +import org.bukkit.util.RayTraceResult; +import org.bukkit.util.Vector; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +public class TNTSimulator { + + private static final World WORLD = Bukkit.getWorlds().get(0); + private static final List LORE = Collections.singletonList("§eZum Ändern klicken"); + private static final List EMPTY = new ArrayList<>(); + public static final ItemStack WAND = new SWItem(Material.BLAZE_ROD, "§eKanonensimulator", Arrays.asList("§eRechtsklick §8- §7Füge eine Position hinzu", "§eSneaken §8- §7Auf den Block zentrieren", "§eLinksklick §8- §7Starte die Simulation", "§eRechtsklick Luft §8- §7Öffne die GUI"), false, null).getItemStack(); + + private static final Map TNT_SIMULATOR_MAP = new HashMap<>(); + + public static TNTSimulator get(Player player) { + return TNT_SIMULATOR_MAP.computeIfAbsent(player, p -> new TNTSimulator(player)); + } + + public void delete() { + TNTSimulator simulator = TNT_SIMULATOR_MAP.remove(player); + simulator.hide(); + } + + private final Set spawns = new HashSet<>(); + private final Player player; + + private AbstractSimulatorEntity cursor = null; + private boolean printed = false; + + private TNTSimulator(Player player){ + this.player = player; + } + + public List getEntities(){ + return spawns.stream().map(spawn -> spawn.entity.getBukkitEntity()).collect(Collectors.toList()); + } + + public void show(RayTraceResult result){ + printed = true; + + if(cursor != null) + cursor.hide(player, false); + + spawns.forEach(TNTSpawn::show); + + if(result == null) + return; + + if(result.getHitEntity() != null){ + TNTSpawn entity = getEntity(result.getHitEntity()); + entity.hide(); + + cursor = SimulatorEntityShowMode.createEntity(player, entity.position, false); + cursor.display(player); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§ePosition bearbeiten")); + return; + } + + cursor = SimulatorEntityShowMode.createEntity(player, getPos(result), true); + cursor.display(player); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§ePosition setzen")); + } + + public void edit(RayTraceResult result){ + if(result == null) { + showGUI(); + return; + } + + show(result); + + if(result.getHitEntity() != null){ + TNTSpawn entity = getEntity(result.getHitEntity()); + entity.editTNT(); + return; + } + + spawns.add(new TNTSpawn(getPos(result), cursor)); + } + + public void hide(){ + if(!printed) + return; + + printed = false; + if(cursor != null) + cursor.hide(player, true); + cursor = null; + spawns.forEach(TNTSpawn::hide); + } + + public void start() { + Map> first = new HashMap<>(); + Map> second = new HashMap<>(); + int lastTick = 0; + + for (TNTSpawn tntSpawn : spawns) { + Map> list = tntSpawn.comparator ? second : first; + for (int i = 0; i < tntSpawn.count; i++) { + list.computeIfAbsent(tntSpawn.getTickOffset(), integer -> new ArrayList<>()).add(tntSpawn); + } + if (lastTick < tntSpawn.getTickOffset()) { + lastTick = tntSpawn.getTickOffset(); + } + } + int finalLastTick = lastTick; + + AtomicInteger currentTick = new AtomicInteger(0); + Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), bukkitTask -> { + int tick = currentTick.get(); + spawnRandomList(first.getOrDefault(tick, EMPTY)); + spawnRandomList(second.getOrDefault(tick, EMPTY)); + if (tick > finalLastTick) bukkitTask.cancel(); + currentTick.incrementAndGet(); + }, 1, 1); + } + + public void showGUI() { + List> swListEntryList = spawns.stream().map(spawn -> { + List lore = new ArrayList<>(); + lore.add("§7TNT-Anzahl§8: §e" + spawn.count); + lore.add("§7Tick§8: §e" + spawn.tickOffset); + lore.add("§7Fuse-Tick§8: §e" + spawn.fuseTicks); + lore.add(""); + lore.add("§7x§8: §e" + spawn.position.getX()); + lore.add("§7y§8: §e" + spawn.position.getY()); + lore.add("§7z§8: §e" + spawn.position.getZ()); + SWItem swItem = new SWItem(Material.TNT, "§eTNT", lore, false, null); + swItem.getItemStack().setAmount(spawn.count); + return new SWListInv.SWListEntry<>(swItem, spawn); + }).sorted(Comparator.comparing(SWListInv.SWListEntry::getObject)).collect(Collectors.toList()); + + SWListInv swListInv = new SWListInv<>(player, "Kanonensimulator", false, swListEntryList, (clickType, spawn) -> spawn.editTNT()); + swListInv.setItem(51, new SWItem(Material.BARRIER, "§cTNT löschen", clickType -> { + delete(); + player.closeInventory(); + })); + swListInv.setItem(47, new SWItem(Material.FLINT_AND_STEEL, "§eStarten", clickType -> { + start(); + player.closeInventory(); + })); + swListInv.open(); + } + + private TNTSpawn getEntity(Entity entity){ + for(TNTSpawn spawn : spawns){ + if(spawn.entity.getId() == entity.getEntityId()) + return spawn; + } + throw new IllegalStateException(); + } + + private void spawnRandomList(List tntSpawns) { + if (tntSpawns.isEmpty()) return; + Collections.shuffle(tntSpawns); + for (TNTSpawn tntSpawn : tntSpawns) { + tntSpawn.spawn(); + } + } + + private Vector getPos(RayTraceResult result){ + Vector pos = result.getHitPosition(); + + BlockFace face = result.getHitBlockFace(); + if(face != null){ + switch (face) { + case DOWN: + pos.setY(pos.getY() - 0.98); + break; + case EAST: + pos.setX(pos.getX() + 0.49); + break; + case WEST: + pos.setX(pos.getX() - 0.49); + break; + case NORTH: + pos.setZ(pos.getZ() - 0.49); + break; + case SOUTH: + pos.setZ(pos.getZ() + 0.49); + break; + default: + break; + } + + if(face.getModY() == 0 && !player.isSneaking()){ + pos.setY(pos.getY() - 0.49); + } + } + + if(player.isSneaking()){ + pos.setX(pos.getBlockX() + 0.5); + if(face == null || face.getModY() == 0) + pos.setY(pos.getBlockY() + 0.0); + pos.setZ(pos.getBlockZ() + 0.5); + } + + return pos; + } + + private class TNTSpawn implements Comparable { + + private final AbstractSimulatorEntity entity; + private boolean printed = false; + + private final Vector position; + private int fuseTicks = 80; + private int count = 1; + private int tickOffset = 0; + private boolean xVelocity = false; + private boolean yVelocity = false; + private boolean zVelocity = false; + private boolean comparator = false; + + private TNTSpawn(Vector position, AbstractSimulatorEntity entity) { + this.position = position; + this.entity = entity; + show(); + editTNT(); + } + + private void show(){ + if(printed) + return; + printed = true; + entity.display(player); + } + + private void hide(){ + if(!printed) + return; + printed = false; + entity.hide(player, false); + } + + private void spawn() { + WORLD.spawn(position.toLocation(WORLD), TNTPrimed.class, tntPrimed -> { + tntPrimed.setFuseTicks(fuseTicks); + if (!xVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setX(0)); + if (!yVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setY(0)); + if (!zVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setZ(0)); + }); + } + + private void setFuseTicks(int fuseTicks) { + if (fuseTicks < 0) + fuseTicks = 0; + if (fuseTicks > 80) + fuseTicks = 80; + this.fuseTicks = fuseTicks; + } + + private void setCount(int count) { + if(count < 1) + count = 1; + if(count > 400) + count = 400; + this.count = count; + } + + private int getTickOffset() { + return tickOffset; + } + + private void setTickOffset(int tickOffset) { + if(tickOffset < 0) + tickOffset = 0; + if(tickOffset > 400) + tickOffset = 400; + this.tickOffset = tickOffset; + } + + @Override + public int compareTo(TNTSpawn tntSpawn) { + return -Integer.compare(tickOffset, tntSpawn.tickOffset); + } + + private void editTNT() { + SWInventory swInventory = new SWInventory(player, 27, "TNT konfigurieren"); + + // Change Count of spawned TNT + swInventory.setItem(0, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { + setCount(count + 1); + editTNT(); + })); + SWItem countItem = new SWItem(Material.TNT, "§7TNT-Anzahl §8- §e" + count, LORE, false, clickType -> changeCount(player, "Anzahl TNT", count, c -> { + setCount(c); + editTNT(); + }, this::editTNT)); + countItem.getItemStack().setAmount(count); + swInventory.setItem(9, countItem); + swInventory.setItem(18, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { + setCount(count - 1); + editTNT(); + })); + + // Change TickOffset + swInventory.setItem(1, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { + setTickOffset(tickOffset + 1); + editTNT(); + })); + SWItem tickItem = new SWItem(SWItem.getMaterial("DIODE"), "§7Tick §8- §e" + tickOffset, LORE, false, clickType -> changeCount(player, "Tick Offset", tickOffset, tick -> { + setTickOffset(tick); + editTNT(); + }, this::editTNT)); + tickItem.getItemStack().setAmount(Math.max(tickOffset, 1)); + swInventory.setItem(10, tickItem); + swInventory.setItem(19, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { + setTickOffset(tickOffset - 1); + editTNT(); + })); + + // Change FuseTicks + swInventory.setItem(2, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { + setFuseTicks(fuseTicks + 1); + editTNT(); + })); + SWItem fuseTickItem = new SWItem(Material.CLOCK, "§7Lebensdauer §8- §e" + fuseTicks, LORE, false, clickType -> changeCount(player, "Fuse-Ticks", fuseTicks, tick -> { + setFuseTicks(tick); + editTNT(); + }, this::editTNT)); + fuseTickItem.getItemStack().setAmount(Math.max(fuseTicks, 1)); + swInventory.setItem(11, fuseTickItem); + swInventory.setItem(20, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { + setFuseTicks(fuseTicks - 1); + editTNT(); + })); + + // Velocity Settings + swInventory.setItem(14, Material.TNT, "TNT", clickType -> {}); + swInventory.setItem(22, new SWItem(getDye(xVelocity), getColor(xVelocity), "§7TNT §eSprung X §8- " + active(xVelocity), clickType -> { + xVelocity = !xVelocity; + editTNT(); + })); + swInventory.setItem(5, new SWItem(getDye(yVelocity), getColor(yVelocity), "§7TNT §eSprung Y §8- " + active(yVelocity), clickType -> { + yVelocity = !yVelocity; + editTNT(); + })); + swInventory.setItem(24, new SWItem(getDye(zVelocity), getColor(zVelocity), "§7TNT §eSprung Z §8- " + active(zVelocity), clickType -> { + zVelocity = !zVelocity; + editTNT(); + })); + + // Repeater before Comparator + swInventory.setItem(8, new SWItem(comparator ? SWItem.getMaterial("REDSTONE_COMPARATOR_OFF") : SWItem.getMaterial("DIODE"), "§7Gezündet durch §8- §e" + (comparator ? "Comparator" : "Repeater"), clickType -> { + comparator = !comparator; + editTNT(); + })); + + swInventory.setItem(17, new SWItem(Material.TNT, "§eZündphase hinzufügen", clickType -> { + spawns.add(new TNTSpawn(position, entity)); + })); + + // Delete tnt + swInventory.setItem(26, new SWItem(Material.BARRIER, "§cEntfernen", clickType -> { + hide(); + spawns.remove(this); + player.closeInventory(); + })); + + swInventory.open(); + } + + private void changeCount(Player player, String name, int defaultValue, Consumer result, Runnable failure) { + SWAnvilInv swAnvilInv = new SWAnvilInv(player, name, defaultValue + ""); + swAnvilInv.setItem(Material.PAPER); + swAnvilInv.setCallback(s -> { + try { + result.accept(Integer.parseInt(s)); + } catch (NumberFormatException e) { + failure.run(); + } + }); + swAnvilInv.open(); + } + + private Material getDye(boolean b) { + return SWItem.getDye(getColor(b)); + } + + private byte getColor(boolean b) { + return (byte) (b ? 10 : 1); + } + + private String active(boolean b) { + return b ? "§aan" : "§caus"; + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java new file mode 100644 index 00000000..1ef92b0a --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java @@ -0,0 +1,128 @@ +/* + * + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.simulator; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import org.bukkit.FluidCollisionMode; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.util.BoundingBox; +import org.bukkit.util.RayTraceResult; +import org.bukkit.util.Vector; + +import static de.steamwar.bausystem.features.simulator.TNTSimulator.WAND; +import static de.steamwar.bausystem.features.simulator.TNTSimulator.get; + +public class TNTSimulatorListener implements Listener { + + private boolean permissionCheck(Player player) { + if (!Permission.hasPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Simulator nutzen"); + return false; + } + return true; + } + + private RayTraceResult trace(Player player, Location to) { + Location startPos = to.clone().add(0.0, player.getEyeHeight(), 0.0); + Vector direction = to.getDirection(); + RayTraceResult blocks = player.getWorld().rayTraceBlocks(startPos, direction, 10.0, FluidCollisionMode.NEVER, true); + + Entity nearestHitEntity = null; + RayTraceResult nearestHitResult = null; + double nearestDistanceSq = Double.MAX_VALUE; + for (Entity entity : get(player).getEntities()) { + BoundingBox boundingBox = entity.getBoundingBox(); + RayTraceResult hitResult = boundingBox.rayTrace(startPos.toVector(), direction, 10.0); + if (hitResult != null) { + double distanceSq = startPos.toVector().distanceSquared(hitResult.getHitPosition()); + if (distanceSq < nearestDistanceSq) { + nearestHitEntity = entity; + nearestHitResult = hitResult; + nearestDistanceSq = distanceSq; + } + } + } + RayTraceResult entities = nearestHitEntity == null ? null : new RayTraceResult(nearestHitResult.getHitPosition(), nearestHitEntity, nearestHitResult.getHitBlockFace()); + + if (blocks == null) { + return entities; + } else if (entities == null) { + return blocks; + } else { + Vector startVec = startPos.toVector(); + double blockHitDistance = startVec.distance(blocks.getHitPosition()); + double entityHitDistanceSquared = startVec.distanceSquared(entities.getHitPosition()); + return entityHitDistanceSquared < blockHitDistance * blockHitDistance ? entities : blocks; + } + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent e) { + Player player = e.getPlayer(); + TNTSimulator simulator = get(player); + if (!player.getInventory().getItemInMainHand().isSimilar(WAND)) { + simulator.hide(); + return; + } + + simulator.show(trace(player, e.getTo())); + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getItem() == null || !event.getItem().isSimilar(WAND)) { + return; + } + + event.setCancelled(true); + if (!permissionCheck(event.getPlayer())) { + return; + } + + switch (event.getAction()) { + case LEFT_CLICK_BLOCK: + case LEFT_CLICK_AIR: + get(event.getPlayer()).start(); + break; + case RIGHT_CLICK_BLOCK: + case RIGHT_CLICK_AIR: + get(event.getPlayer()).edit(trace(event.getPlayer(), event.getPlayer().getLocation())); + break; + default: + break; + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + get(event.getPlayer()).delete(); + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/show/SimulatorEntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/show/SimulatorEntityShowMode.java new file mode 100644 index 00000000..c78f8377 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/show/SimulatorEntityShowMode.java @@ -0,0 +1,64 @@ +/* + * 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.simulator.show; + +import de.steamwar.bausystem.features.simulator.AbstractSimulatorEntity; +import de.steamwar.bausystem.features.simulator.Simulator_15; +import de.steamwar.bausystem.shared.Position; +import de.steamwar.bausystem.shared.RoundedPosition; +import de.steamwar.bausystem.shared.ShowMode; +import de.steamwar.core.VersionedCallable; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.HashMap; +import java.util.Map; + +public class SimulatorEntityShowMode implements ShowMode { + + protected final Player player; + + private final Map tntEntityMap = new HashMap<>(); + private final Map updateEntityMap = new HashMap<>(); + + public SimulatorEntityShowMode(Player player) { + this.player = player; + } + + @Override + public void show(Position position) { + RoundedPosition roundedPosition = new RoundedPosition(position); + AbstractSimulatorEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); + entity.display(player); + } + + public static AbstractSimulatorEntity createEntity(Player player, Vector position, boolean tnt) { + return VersionedCallable.call(new VersionedCallable<>(() -> Simulator_15.create(player.getWorld(), position, tnt), 15)); + } + + @Override + public void hide() { + tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + tntEntityMap.clear(); + updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + updateEntityMap.clear(); + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/RoundedTNTPosition.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/RoundedTNTPosition.java deleted file mode 100644 index 965448aa..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/RoundedTNTPosition.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * / - */ - -package de.steamwar.bausystem.features.tracer; - -import org.bukkit.util.Vector; - -import java.util.Objects; - -public class RoundedTNTPosition { - - private static final int factor = 10; - - private int x; - private int y; - private int z; - - public RoundedTNTPosition(TNTPosition tntPosition) { - this(tntPosition.getLocation().getX(), tntPosition.getLocation().getY(), tntPosition.getLocation().getZ()); - } - - public RoundedTNTPosition(Vector vector) { - this(vector.getX(), vector.getY(), vector.getZ()); - } - - public RoundedTNTPosition(double x, double y, double z) { - this.x = (int) (x * factor); - this.y = (int) (y * factor); - this.z = (int) (z * factor); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof RoundedTNTPosition)) return false; - RoundedTNTPosition that = (RoundedTNTPosition) o; - return x == that.x && - y == that.y && - z == that.z; - } - - @Override - public int hashCode() { - return Objects.hash(x, y, z); - } - -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java index bc0a85c4..717c2414 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TNTPosition.java @@ -1,46 +1,42 @@ /* - This file is a part of the SteamWar software. - - Copyright (C) 2020 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 . -*/ + * 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.tracer; import de.steamwar.bausystem.features.tracer.show.Record; +import de.steamwar.bausystem.shared.Position; import org.bukkit.entity.Entity; import org.bukkit.util.Vector; -public class TNTPosition { +public class TNTPosition extends Position { private final Record.TNTRecord record; - private final Vector location; private final Vector previousLocation; private final boolean exploded; public TNTPosition(Record.TNTRecord record, Entity entity, Vector previousLocation, boolean exploded) { - this.location = entity.getLocation().toVector(); + super(entity.getLocation().toVector()); this.record = record; this.previousLocation = previousLocation; this.exploded = exploded; } - public Vector getLocation() { - return location; - } - public Vector getPreviousLocation() { return previousLocation; } @@ -56,7 +52,7 @@ public class TNTPosition { @Override public String toString() { return "Position{" + - "location=" + location + + "location=" + super.getLocation() + '}'; } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java index 6b7060fe..62458fdf 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java @@ -27,7 +27,7 @@ import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; import de.steamwar.bausystem.features.tracer.show.ShowModeParameterType; import de.steamwar.bausystem.features.tracer.show.StoredRecords; import de.steamwar.bausystem.features.tracer.show.TraceShowManager; -import de.steamwar.bausystem.features.tracer.show.mode.EntityShowMode; +import de.steamwar.bausystem.features.tracer.show.mode.TraceEntityShowMode; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; import de.steamwar.command.SWCommand; @@ -95,7 +95,7 @@ public class TraceCommand extends SWCommand { @Register({"show"}) public void showCommand(Player p) { if (!permissionCheck(p)) return; - TraceShowManager.show(p, new EntityShowMode(p, new ShowModeParameter())); + TraceShowManager.show(p, new TraceEntityShowMode(p, new ShowModeParameter())); p.sendMessage(BauSystem.PREFIX + "§aAlle TNT-Positionen angezeigt"); } @@ -106,7 +106,7 @@ public class TraceCommand extends SWCommand { for (ShowModeParameterType showModeParameterType : showModeParameterTypes) { showModeParameterType.getShowModeParameterConsumer().accept(showModeParameter); } - TraceShowManager.show(p, new EntityShowMode(p, showModeParameter)); + TraceShowManager.show(p, new TraceEntityShowMode(p, showModeParameter)); p.sendMessage(BauSystem.PREFIX + "§aAlle TNT-Positionen angezeigt"); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java index 3fdca202..642f7fd9 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.tracer.show; import de.steamwar.bausystem.features.tracer.TNTPosition; +import de.steamwar.bausystem.shared.ShowMode; import org.bukkit.entity.TNTPrimed; import java.util.ArrayList; @@ -38,7 +39,7 @@ public class Record { return startTime; } - public void showAll(ShowMode mode) { + public void showAll(ShowMode mode) { for (TNTRecord record : tnt) record.showAll(mode); } @@ -62,7 +63,7 @@ public class Record { public static class TNTRecord { private final List positions = new ArrayList<>(41); - public void showAll(ShowMode mode) { + public void showAll(ShowMode mode) { for (TNTPosition position : positions) mode.show(position); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java index e1d69b2a..09cd96d8 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java @@ -19,7 +19,9 @@ package de.steamwar.bausystem.features.tracer.show; +import de.steamwar.bausystem.features.tracer.TNTPosition; import de.steamwar.bausystem.features.tracer.record.RecordStateMachine; +import de.steamwar.bausystem.shared.ShowMode; import java.util.ArrayList; import java.util.List; @@ -32,7 +34,7 @@ public class StoredRecords { records.add(record); } - public static void showAll(ShowMode mode) { + public static void showAll(ShowMode mode) { for (Record record : records) record.showAll(mode); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java index 2a6d750c..fca38c75 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java @@ -2,6 +2,7 @@ package de.steamwar.bausystem.features.tracer.show; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.tracer.TNTPosition; +import de.steamwar.bausystem.shared.ShowMode; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -15,30 +16,30 @@ public class TraceShowManager implements Listener { private TraceShowManager() { } - private static final Map showModes = new HashMap<>(); + private static final Map> showModes = new HashMap<>(); - public static void show(Player player, ShowMode showMode) { + public static void show(Player player, ShowMode traceShowMode) { hide(player); - showModes.put(player, showMode); - StoredRecords.showAll(showMode); + showModes.put(player, traceShowMode); + StoredRecords.showAll(traceShowMode); } public static void hide(Player player) { - ShowMode showMode = showModes.remove(player); - if (showMode == null) + ShowMode traceShowMode = showModes.remove(player); + if (traceShowMode == null) return; - showMode.hide(); + traceShowMode.hide(); } /* Only to be called by record */ static void show(TNTPosition tnt) { - for (ShowMode mode : showModes.values()) + for (ShowMode mode : showModes.values()) mode.show(tnt); } /* Only to be called by StoredRecords */ static void clear() { - for (ShowMode mode : showModes.values()) + for (ShowMode mode : showModes.values()) mode.hide(); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/EntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java similarity index 79% rename from BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/EntityShowMode.java rename to BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java index 57e33805..547c34e0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/EntityShowMode.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java @@ -22,11 +22,11 @@ package de.steamwar.bausystem.features.tracer.show.mode; import de.steamwar.bausystem.features.tracer.AbstractTraceEntity; -import de.steamwar.bausystem.features.tracer.RoundedTNTPosition; import de.steamwar.bausystem.features.tracer.TNTPosition; import de.steamwar.bausystem.features.tracer.TNTTracer_15; -import de.steamwar.bausystem.features.tracer.show.ShowMode; import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; +import de.steamwar.bausystem.shared.RoundedPosition; +import de.steamwar.bausystem.shared.ShowMode; import de.steamwar.core.VersionedCallable; import org.bukkit.entity.Player; import org.bukkit.util.Consumer; @@ -35,15 +35,15 @@ import org.bukkit.util.Vector; import java.util.HashMap; import java.util.Map; -public class EntityShowMode implements ShowMode { +public class TraceEntityShowMode implements ShowMode { protected final Player player; protected final ShowModeParameter showModeParameter; - private final Map tntEntityMap = new HashMap<>(); - private final Map updateEntityMap = new HashMap<>(); + private final Map tntEntityMap = new HashMap<>(); + private final Map updateEntityMap = new HashMap<>(); - public EntityShowMode(Player player, ShowModeParameter showModeParameter) { + public TraceEntityShowMode(Player player, ShowModeParameter showModeParameter) { this.player = player; this.showModeParameter = showModeParameter; } @@ -53,15 +53,15 @@ public class EntityShowMode implements ShowMode { if (!showModeParameter.isWater() && position.isExploded() && checkWater(position.getLocation())) { // Basic for (TNTPosition pos : position.getRecord().getPositions()) { - RoundedTNTPosition roundedTNTPosition = new RoundedTNTPosition(pos); - tntEntityMap.computeIfPresent(roundedTNTPosition, (p, tnt) -> { + RoundedPosition roundedPosition = new RoundedPosition(pos); + tntEntityMap.computeIfPresent(roundedPosition, (p, tnt) -> { return tnt.hide(player, false) ? null : tnt; }); } // Advanced for (TNTPosition pos : position.getRecord().getPositions()) { applyOnPosition(pos, updatePointPosition -> { - updateEntityMap.computeIfPresent(new RoundedTNTPosition(updatePointPosition), (p, point) -> { + updateEntityMap.computeIfPresent(new RoundedPosition(updatePointPosition), (p, point) -> { return point.hide(player, false) ? null : point; }); }); @@ -69,12 +69,12 @@ public class EntityShowMode implements ShowMode { return; } - RoundedTNTPosition roundedTNTPosition = new RoundedTNTPosition(position); - AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedTNTPosition, pos -> createEntity(player, position.getLocation(), true)); + RoundedPosition roundedPosition = new RoundedPosition(position); + AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); entity.display(player, position.isExploded()); applyOnPosition(position, updatePointPosition -> { - updateEntityMap.computeIfAbsent(new RoundedTNTPosition(updatePointPosition), pos -> { + updateEntityMap.computeIfAbsent(new RoundedPosition(updatePointPosition), pos -> { return createEntity(player, updatePointPosition, false); }).display(player, position.isExploded()); }); @@ -111,9 +111,9 @@ public class EntityShowMode implements ShowMode { @Override public void hide() { - tntEntityMap.forEach((roundedTNTPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); tntEntityMap.clear(); - updateEntityMap.forEach((roundedTNTPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); updateEntityMap.clear(); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/shared/Position.java b/BauSystem_Main/src/de/steamwar/bausystem/shared/Position.java new file mode 100644 index 00000000..a0ae2560 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/shared/Position.java @@ -0,0 +1,30 @@ +/* + * 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.shared; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.util.Vector; + +@Getter +@AllArgsConstructor +public class Position { + private final Vector location; +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java b/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java new file mode 100644 index 00000000..55e791d3 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java @@ -0,0 +1,63 @@ +/* + * 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.shared; + +import org.bukkit.util.Vector; + +import java.util.Objects; + +public class RoundedPosition { + + private static final int factor = 10; + + private int x; + private int y; + private int z; + + public RoundedPosition(Position position) { + this(position.getLocation().getX(), position.getLocation().getY(), position.getLocation().getZ()); + } + + public RoundedPosition(Vector vector) { + this(vector.getX(), vector.getY(), vector.getZ()); + } + + public RoundedPosition(double x, double y, double z) { + this.x = (int) (x * factor); + this.y = (int) (y * factor); + this.z = (int) (z * factor); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof RoundedPosition)) return false; + RoundedPosition that = (RoundedPosition) o; + return x == that.x && + y == that.y && + z == that.z; + } + + @Override + public int hashCode() { + return Objects.hash(x, y, z); + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/shared/ShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/shared/ShowMode.java new file mode 100644 index 00000000..edc10243 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/shared/ShowMode.java @@ -0,0 +1,28 @@ +/* + * 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.shared; + +import de.steamwar.bausystem.shared.Position; + +public interface ShowMode { + void show(T position); + + void hide(); +}