Signed-off-by: Chaoscaot <chaoscaot444@gmail.com>
Dieser Commit ist enthalten in:
Chaoscaot 2021-04-18 13:58:02 +02:00
Ursprung d473245d9b
Commit 622d54c031
12 geänderte Dateien mit 883 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,81 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator;
import net.minecraft.server.v1_15_R1.*;
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 DetonatorEntity_15 extends EntityFallingBlock implements AbstractDetonatorEntity {
private static final Vec3D ZERO = new Vec3D(0, 0, 0);
private final Vector position;
private int references = 0;
public DetonatorEntity_15(World world, Vector position) {
super(((CraftWorld) world).getHandle(), position.getX(), position.getY(), position.getZ(), Blocks.RED_STAINED_GLASS.getBlockData());
this.position = position;
this.h(true);
this.setNoGravity(true);
this.ticksLived = -12000;
}
@Override
public void display(Player player) {
if (references++ > 0)
return;
PacketPlayOutSpawnEntity packetPlayOutSpawnEntity = new PacketPlayOutSpawnEntity(getId(), getUniqueID(), position.getX(), position.getY(), position.getZ(), 0, 0, EntityTypes.FALLING_BLOCK, Block.getCombinedId(Blocks.RED_STAINED_GLASS.getBlockData()), ZERO);
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
playerConnection.sendPacket(packetPlayOutSpawnEntity);
PacketPlayOutEntityMetadata packetPlayOutEntityMetadata = new PacketPlayOutEntityMetadata(getId(), datawatcher, true);
playerConnection.sendPacket(packetPlayOutEntityMetadata);
}
@Override
public boolean hide(Player player, boolean force) {
if (!force && --references > 0)
return false;
sendDestroy(player);
die();
return true;
}
private void sendDestroy(Player player) {
PacketPlayOutEntityDestroy packetPlayOutEntityDestroy = new PacketPlayOutEntityDestroy(getId());
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packetPlayOutEntityDestroy);
}
@Override
public void sendEntity(Player player) {
display(player);
}
@Override
public void sendEntityDestroy(Player player) {
hide(player, false);
}
}

Datei anzeigen

@ -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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator;
import org.bukkit.World;
import org.bukkit.util.Vector;
public class Detonator_15 {
static AbstractDetonatorEntity constructEntity(World world, Vector position) {
return new DetonatorEntity_15(world, position);
}
}

Datei anzeigen

@ -19,16 +19,24 @@
package de.steamwar.bausystem;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.UtilityClass;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
@UtilityClass
public class SWUtils {
@Getter
@Setter
private static Plugin bausystem;
public static void giveItemToPlayer(Player player, ItemStack itemStack) {
if (itemStack == null || itemStack.getType() == Material.AIR) {
return;
@ -51,4 +59,8 @@ public class SWUtils {
public static void sendToActionbar(Player p, String message) {
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message));
}
public static NamespacedKey getNamespaceKey(String name) {
return new NamespacedKey(getBausystem(), name);
}
}

Datei anzeigen

@ -0,0 +1,35 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator;
import de.steamwar.bausystem.shared.AbstractEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public interface AbstractDetonatorEntity extends AbstractEntity {
void display(Player player);
boolean hide(Player player, boolean always);
int getId();
Entity getBukkitEntity();
}

Datei anzeigen

@ -0,0 +1,50 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
public enum Detoblock {
SWITCH(0, true, "Hebel"),
WOOD_BUTTON(30, "Knopf"),
STONE_BUTTON(20, "Knopf"),
PRESSURE_PLATE(30, "Druckplatte"),
WEIGHTED_PRESSURE_PLATE(20, "Druckplatte"),
TRIPWIRE(30, "Tripwire"),
NOTEBLOCK(1, "Noteblock"),
REDSTONETORCH(0, true, "Redstonefackel"),
POWERABLE(0, true, "Aktivierbarer Block"),
INVALID(-1, "Invalider");
@Getter
private final int time;
@Getter
private final boolean toggle;
@Getter
private final String name;
Detoblock(int time, String name) {
this.time = time;
this.name = name;
toggle = false;
}
}

Datei anzeigen

@ -35,6 +35,8 @@ public class BauSystem extends JavaPlugin implements Listener {
@Override
public void onEnable() {
instance = this;
SWUtils.setBausystem(instance);
LinkageUtils.link();
}

Datei anzeigen

@ -0,0 +1,207 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.config.ColorConfig;
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
import de.steamwar.core.VersionedRunnable;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Lightable;
import org.bukkit.block.data.Openable;
import org.bukkit.block.data.Powerable;
import org.bukkit.block.data.type.Switch;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.stream.Collectors;
@UtilityClass
public class Detonator {
private static final Map<Player, List<AbstractDetonatorEntity>> ENTITIES_MAP = new HashMap<>();
private static final Vector HALF = new Vector(0.5, 0, 0.5);
public static boolean isDetonator(ItemStack itemStack) {
return ItemStorage.isDetonator(itemStack);
}
public static void showDetonator(Player p, List<Location> locs) {
List<Vector> vecs = locs.stream().map(Location::toVector).collect(Collectors.toList());
List<AbstractDetonatorEntity> entities = new LinkedList<>();
VersionedRunnable.call(new VersionedRunnable(() -> {
vecs.forEach(vector -> entities.add(Detonator_15.constructEntity(p.getWorld(), vector.add(HALF))));
}, 15));
entities.forEach(abstractDetonatorEntity -> abstractDetonatorEntity.display(p));
ENTITIES_MAP.putIfAbsent(p, entities);
}
public static void hideDetonator(Player p) {
ENTITIES_MAP.remove(p).forEach(abstractDetonatorEntity -> abstractDetonatorEntity.hide(p, true));
}
public static List<AbstractDetonatorEntity> getDetoEntities(Player p) {
return ENTITIES_MAP.getOrDefault(p, new ArrayList<>());
}
public static boolean hasActiveDetonatorShow(Player p) {
return ENTITIES_MAP.containsKey(p);
}
public static void activateDetonator(DetonatorStorage detonator) {
Player p = detonator.getPlayer();
Map<Integer, Set<Block>> deactivate = new HashMap<>();
Set<Location> invalid = new HashSet<>();
for (Location location : detonator.getLocations()) {
Block block = location.getBlock();
Detoblock detoblock = getBlock(block);
if (detoblock == Detoblock.INVALID) {
invalid.add(location);
continue;
}
if (detoblock.isToggle()) {
setBlockPower(block, !getBlockPower(block));
updateButton(block, detoblock);
} else {
setBlockPower(block, true);
updateButton(block, detoblock);
deactivate.computeIfAbsent(detoblock.getTime(), integer -> new HashSet<>()).add(block);
}
}
int s = detonator.getLocations().size() - invalid.size();
SWUtils.sendToActionbar(p, ColorConfig.HIGHLIGHT.toString() + s + " Punkt" + (s > 1 ? "e" : "") + " ausgelöst");
invalid.forEach(detonator::removeLocation);
if (!invalid.isEmpty()) {
int invalidPoints = invalid.size();
p.sendMessage(BauSystem.PREFIX + ColorConfig.DISABLE + invalid.size() + " Punkt" + (invalidPoints > 1 ? "e" : "") + "konnte" + (invalidPoints > 1 ? "n" : "") + " nicht ausgeführt werden und wurde" + (invalidPoints > 1 ? "e" : "") + " entfernt");
detonator.write();
}
deactivate.forEach((integer, blocks1) ->
Bukkit.getScheduler().scheduleSyncDelayedTask(BauSystem.getInstance(), () -> blocks1.forEach(block -> {
setBlockPower(block, false);
updateButton(block, getBlock(block));
}), integer));
}
public static void updateButton(Block block, Detoblock detoblock) {
if (block.getBlockData() instanceof Switch) {
Switch sw = (Switch) block.getBlockData();
update(block.getRelative(sw.getFacing().getOppositeFace()));
} else if (detoblock == Detoblock.TRIPWIRE) {
update(block);
} else if (detoblock == Detoblock.PRESSURE_PLATE || detoblock == Detoblock.WEIGHTED_PRESSURE_PLATE) {
update(block.getRelative(BlockFace.DOWN));
} else if (detoblock == Detoblock.REDSTONETORCH) {
update(block.getRelative(BlockFace.UP));
}
}
private static void update(Block block) {
BlockData data = block.getBlockData();
block.setType(Material.BARRIER, true);
block.setBlockData(data, true);
}
private static void setBlockPower(Block block, boolean state) {
BlockData data = block.getBlockData();
if (data instanceof Powerable) {
Powerable pow = (Powerable) data;
pow.setPowered(state);
}
if (data instanceof Openable) {
Openable openable = (Openable) data;
openable.setOpen(state);
}
if (data instanceof Lightable) {
Lightable lightable = (Lightable) data;
lightable.setLit(state);
}
block.setBlockData(data);
}
private static boolean getBlockPower(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Powerable) {
Powerable pow = (Powerable) data;
return pow.isPowered();
}
if (data instanceof Lightable) {
Lightable lightable = (Lightable) data;
return lightable.isLit();
}
return false;
}
static Detoblock getBlock(Block block) {
switch (block.getType()) {
case LEVER:
return Detoblock.SWITCH;
case ACACIA_BUTTON:
case BIRCH_BUTTON:
case DARK_OAK_BUTTON:
case JUNGLE_BUTTON:
case OAK_BUTTON:
case SPRUCE_BUTTON:
return Detoblock.WOOD_BUTTON;
case STONE_BUTTON:
return Detoblock.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 Detoblock.PRESSURE_PLATE;
case HEAVY_WEIGHTED_PRESSURE_PLATE:
case LIGHT_WEIGHTED_PRESSURE_PLATE:
return Detoblock.WEIGHTED_PRESSURE_PLATE;
case TRIPWIRE:
return Detoblock.TRIPWIRE;
case NOTE_BLOCK:
return Detoblock.NOTEBLOCK;
case REDSTONE_TORCH:
case REDSTONE_WALL_TORCH:
return Detoblock.REDSTONETORCH;
default:
if (block.getBlockData() instanceof Powerable) {
return Detoblock.POWERABLE;
} else {
return Detoblock.INVALID;
}
}
}
}

Datei anzeigen

@ -0,0 +1,84 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.config.ColorConfig;
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
import de.steamwar.command.SWCommand;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
@Linked(LinkageType.COMMAND)
public class DetonatorCommand extends SWCommand {
@Getter
private static final ItemStack WAND;
static {
WAND = new ItemStack(Material.BLAZE_ROD);
ItemStorage.setDetonator(WAND);
ItemMeta meta = WAND.getItemMeta();
meta.setDisplayName(ColorConfig.HIGHLIGHT + "Fernzünder");
meta.setLore(Arrays.asList(ColorConfig.HIGHLIGHT + "Links Klick " + ColorConfig.OTHER + "- " + ColorConfig.BASE + "Setzte einen Punkt zum Aktivieren",
ColorConfig.HIGHLIGHT + "Links Klick + Shift " + ColorConfig.OTHER + "- " + ColorConfig.BASE + "Füge einen Punkt hinzu",
ColorConfig.HIGHLIGHT + "Rechts Klick " + ColorConfig.OTHER + "- " + ColorConfig.BASE + "Löse alle Punkte aus"));
WAND.setItemMeta(meta);
}
protected DetonatorCommand() {
super("detonator", "dt");
}
@Register(help = true)
public void genericHelp(Player p, String... args) {
p.sendMessage(ColorConfig.BASE + "---===(" + ColorConfig.HIGHLIGHT + "Fernzünder" + ColorConfig.BASE + ")===---");
p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "detonator wand " + ColorConfig.OTHER + "-" + ColorConfig.BASE + " Gibt den Fernzünder");
p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "detonator click " + ColorConfig.OTHER + "-" + ColorConfig.BASE + " Aktiviere einen Fernzünder (Haupthand -> Hotbar -> Inventar)");
p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "detonator clear " + ColorConfig.OTHER + "-" + ColorConfig.BASE + " Cleare einen Fernzünder");
}
@Register("wand")
public void giveWand(Player p) {
SWUtils.giveItemToPlayer(p, getWAND());
}
@Register("click")
public void clickDetonator(Player p) {
Detonator.activateDetonator(new ItemStorage(p));
}
@Register("clear")
public void clearDetonator(Player p) {
DetonatorStorage storage = new ItemStorage(p);
storage.clear();
storage.write();
}
}

Datei anzeigen

@ -0,0 +1,158 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.config.ColorConfig;
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Linked(LinkageType.LISTENER)
public class DetonatorListener implements Listener {
private static final Set<Player> HAS_UPDATED = new HashSet<>();
public DetonatorListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(BauSystem.getInstance(), PacketType.Play.Client.USE_ENTITY) {
@Override
public void onPacketReceiving(PacketEvent event) {
List<AbstractDetonatorEntity> entities = new ArrayList<>(Detonator.getDetoEntities(event.getPlayer()));
if (entities.isEmpty()) {
return;
}
PacketContainer container = event.getPacket();
int entityId = container.getIntegers().read(0);
entities.removeIf(abstractDetonatorEntity -> abstractDetonatorEntity.getId() != entityId);
if (entities.isEmpty()) {
return;
}
AbstractDetonatorEntity entity = entities.get(0);
Location location = entity.getBukkitEntity().getLocation().getBlock().getLocation();
addLocationToDetonator(location, event.getPlayer());
HAS_UPDATED.add(event.getPlayer());
event.setCancelled(true);
}
});
}
private static void addLocationToDetonator(Location location, Player p) {
Detoblock detoblock = Detonator.getBlock(location.getBlock());
if (detoblock == Detoblock.INVALID) {
SWUtils.sendToActionbar(p, ColorConfig.HIGHLIGHT + "Der Block konnte nicht hinzugefügt werden");
return;
}
DetonatorStorage detonator = new ItemStorage(p);
if (!p.isSneaking()) {
detonator.clear();
}
if (detonator.getLocations().contains(location)) {
detonator.removeLocation(location);
SWUtils.sendToActionbar(p, ColorConfig.HIGHLIGHT + detoblock.getName() + " entfernt");
} else {
detonator.addLocation(location);
SWUtils.sendToActionbar(p, ColorConfig.HIGHLIGHT + detoblock.getName() + " hinzugefügt");
}
detonator.write();
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
Player p = event.getPlayer();
if (Detonator.isDetonator(p.getInventory().getItemInMainHand())) {
event.setCancelled(true);
addLocationToDetonator(event.getBlock().getLocation(), p);
HAS_UPDATED.add(event.getPlayer());
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (!Detonator.isDetonator(event.getItem())) {
return;
}
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
event.setCancelled(true);
DetonatorStorage detonator = new ItemStorage(event.getPlayer());
Detonator.activateDetonator(detonator);
HAS_UPDATED.add(event.getPlayer());
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerMove(PlayerMoveEvent event) {
if (!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) {
if (Detonator.hasActiveDetonatorShow(event.getPlayer())) {
Detonator.hideDetonator(event.getPlayer());
}
} else {
if (!Detonator.hasActiveDetonatorShow(event.getPlayer())) {
Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations());
}
}
if (HAS_UPDATED.contains(event.getPlayer())) {
HAS_UPDATED.remove(event.getPlayer());
if (Detonator.hasActiveDetonatorShow(event.getPlayer())) {
Detonator.hideDetonator(event.getPlayer());
Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations());
}
}
}
@EventHandler
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
if (Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) {
HAS_UPDATED.add(event.getPlayer());
}
}
@EventHandler
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
if (Detonator.isDetonator(event.getMainHandItem()) || Detonator.isDetonator(event.getOffHandItem())) {
HAS_UPDATED.add(event.getPlayer());
}
}
}

Datei anzeigen

@ -0,0 +1,40 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator.storage;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.List;
public interface DetonatorStorage {
void addLocation(Location location);
List<Location> getLocations();
void removeLocation(Location location);
void clear();
void write();
Player getPlayer();
}

Datei anzeigen

@ -0,0 +1,184 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.detonator.storage;
import de.steamwar.bausystem.SWUtils;
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.LinkedList;
import java.util.List;
import java.util.function.IntFunction;
public class ItemStorage implements DetonatorStorage {
private static final NamespacedKey DETO_KEY = SWUtils.getNamespaceKey("deto");
private static final NamespacedKey SLOT_KEY = SWUtils.getNamespaceKey("slots");
private static final IntFunction<NamespacedKey> DETOLOCATION_BUILDER = integer -> SWUtils.getNamespaceKey("deto_loc_" + integer);
@Getter
private final Player p;
private final List<Location> locs;
private int slot;
private ItemStack itemStack;
public ItemStorage(Player p) {
this.p = p;
if (isDetonator(p.getInventory().getItemInMainHand())) {
slot = p.getInventory().getHeldItemSlot();
itemStack = p.getInventory().getItemInMainHand();
} else {
ItemStack[] inv = p.getInventory().getContents();
for (int i = 0; i < inv.length; i++) {
if (isDetonator(inv[i])) {
slot = i;
itemStack = inv[i];
break;
}
}
}
locs = read();
}
public static ItemStack setDetonator(ItemStack item) {
ItemMeta meta = item.getItemMeta();
if (meta == null) {
return item;
}
PersistentDataContainer dataContainer = meta.getPersistentDataContainer();
dataContainer.set(DETO_KEY, PersistentDataType.BYTE, (byte) 1);
dataContainer.set(SLOT_KEY, PersistentDataType.INTEGER, 0);
item.setItemMeta(meta);
return item;
}
public static boolean isDetonator(ItemStack item) {
if (item == null) {
return false;
}
ItemMeta meta = item.getItemMeta();
if (meta == null) {
return false;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
return container.has(DETO_KEY, PersistentDataType.BYTE) && container.has(SLOT_KEY, PersistentDataType.INTEGER);
}
@Override
public void addLocation(Location location) {
locs.add(location);
}
@Override
public List<Location> getLocations() {
return locs;
}
@Override
public void removeLocation(Location location) {
locs.remove(location);
}
@Override
public void clear() {
internalClear();
locs.clear();
apply();
}
@Override
public void write() {
write(locs);
}
@Override
public Player getPlayer() {
return p;
}
private List<Location> read() {
List<Location> tempLocs = new LinkedList<>();
ItemMeta meta = itemStack.getItemMeta();
PersistentDataContainer container = meta.getPersistentDataContainer();
int length = length();
for (int i = 0; i < length; i++) {
NamespacedKey key = DETOLOCATION_BUILDER.apply(i);
int[] loc = container.get(key, PersistentDataType.INTEGER_ARRAY);
tempLocs.add(new Location(p.getWorld(), loc[0], loc[1], loc[2]));
}
return tempLocs;
}
private int length() {
ItemMeta meta = itemStack.getItemMeta();
PersistentDataContainer container = meta.getPersistentDataContainer();
return container.get(SLOT_KEY, PersistentDataType.INTEGER);
}
private void internalClear() {
ItemMeta meta = itemStack.getItemMeta();
PersistentDataContainer container = meta.getPersistentDataContainer();
int length = length();
for (int i = 0; i < length; i++) {
NamespacedKey key = DETOLOCATION_BUILDER.apply(i);
container.remove(key);
}
container.set(SLOT_KEY, PersistentDataType.INTEGER, 0);
itemStack.setItemMeta(meta);
}
private void write(List<Location> locs) {
internalClear();
ItemMeta meta = itemStack.getItemMeta();
PersistentDataContainer container = meta.getPersistentDataContainer();
int i = 0;
for (Location loc : locs) {
NamespacedKey key = DETOLOCATION_BUILDER.apply(i);
int[] slotLoc = new int[]{
loc.getBlockX(),
loc.getBlockY(),
loc.getBlockZ()
};
container.set(key, PersistentDataType.INTEGER_ARRAY, slotLoc);
i++;
}
container.set(SLOT_KEY, PersistentDataType.INTEGER, i);
itemStack.setItemMeta(meta);
apply();
}
private void apply() {
p.getInventory().setItem(slot, itemStack);
}
}