2.0 Release Beta

Fixes bugs
Adds Silk Touch feature to storages!
This commit is contained in:
jameslfc19 2020-07-14 00:15:48 +01:00
parent b429acdf0d
commit 455d1392ce
12 changed files with 183 additions and 50 deletions

View File

@ -6,7 +6,7 @@
<groupId>com.jamesdpeters.minecraft.chests</groupId>
<artifactId>ChestsPlusPlus-Master</artifactId>
<version>2.0-Release</version>
<version>2.0-BETA</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>

View File

@ -79,7 +79,7 @@ public class AutoCraftCommand extends ServerCommand {
if(args.length > 1){
if (player.hasPermission(Permissions.AUTOCRAFT_ADD)) {
Block targetBlock = player.getTargetBlockExact(5);
if (targetBlock != null) Config.getAutoCraft().createStorage(player, targetBlock, args[1]);
if (targetBlock != null) Config.getAutoCraft().createStorage(player, targetBlock, args[1],true);
else Config.getAutoCraft().getMessages().mustLookAtBlock(player);
} else {
Messages.NO_PERMISSION(player);

View File

@ -82,7 +82,7 @@ public class ChestLinkCommand extends ServerCommand {
if(args.length > 1){
if(sender.hasPermission(Permissions.ADD)) {
Block targetBlock = player.getTargetBlockExact(5);
if (targetBlock != null) Config.getChestLink().createStorage(player,targetBlock,args[1]);
if (targetBlock != null) Config.getChestLink().createStorage(player,targetBlock,args[1],true);
else Config.getChestLink().getMessages().mustLookAtBlock(player);
return true;
} else {

View File

@ -55,7 +55,6 @@ public class ChestsPlusPlusCommand extends ServerCommand {
return true;
case RELOAD:
ChestsPlusPlus.PLUGIN.onDisable();
ChestsPlusPlus.PLUGIN.onEnable();
return true;

View File

@ -1,6 +1,8 @@
package com.jamesdpeters.minecraft.chests.listeners;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.misc.Messages;
import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.misc.Values;
import com.jamesdpeters.minecraft.chests.runnables.ChestLinkVerifier;
import com.jamesdpeters.minecraft.chests.serialize.Config;
@ -10,12 +12,15 @@ import com.jamesdpeters.minecraft.chests.storage.abstracts.StorageType;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -25,12 +30,16 @@ import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import java.util.stream.Collectors;
public class StorageListener implements Listener {
private BlockData air = Material.AIR.createBlockData();
@EventHandler
public void playerInteract(BlockPlaceEvent event){
if(event.getBlockPlaced().getState() instanceof Sign){
@ -105,6 +114,28 @@ public class StorageListener implements Listener {
@EventHandler
public void onChestPlace(BlockPlaceEvent event){
for(StorageType storageType : Config.getStorageTypes()){
if(storageType.isValidBlockType(event.getBlockPlaced())){
ItemMeta itemMeta = event.getItemInHand().getItemMeta();
if(itemMeta != null){
String playerUUID = itemMeta.getPersistentDataContainer().get(Values.playerUUID, PersistentDataType.STRING);
String storageID = itemMeta.getPersistentDataContainer().get(Values.storageID, PersistentDataType.STRING);
BlockFace blockFace = storageType.onStoragePlacedBlockFace(event.getPlayer(),event.getBlockPlaced());
Block signSpace = event.getBlockPlaced().getRelative(blockFace);
if(signSpace.getType() != Material.AIR){
event.setCancelled(true);
return;
}
if(storageType.hasPermissionToAdd(event.getPlayer())){
storageType.createStorageFacing(event.getPlayer(), event.getBlockPlaced(), storageID, blockFace,false);
// storageType.add(event.getPlayer(), storageID, event.getBlockPlaced().getLocation(), event.getPlayer().)
} else {
Messages.NO_PERMISSION(event.getPlayer());
}
}
}
}
if(event.getBlockPlaced().getState() instanceof Chest){
new ChestLinkVerifier(event.getBlock()).check();
}
@ -113,11 +144,38 @@ public class StorageListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onChestBreak(BlockBreakEvent event){
if(event.isCancelled()) return;
for (StorageType storageType : Config.getStorageTypes()) {
if(storageType.isValidBlockType(event.getBlock())) {
AbstractStorage storage = storageType.removeBlock(event.getBlock().getLocation());
boolean hasPickedUp = false;
ItemStack mainHand = event.getPlayer().getInventory().getItemInMainHand();
if(mainHand.containsEnchantment(Enchantment.SILK_TOUCH)){
hasPickedUp = true;
}
AbstractStorage storage = storageType.removeBlock(event.getBlock().getLocation(),hasPickedUp);
if (storage != null) {
storageType.getMessages().storageRemoved(event.getPlayer(), storage.getIdentifier(), storage.getOwner().getName());
if(hasPickedUp){
event.setCancelled(true);
Block storageBlock = event.getBlock();
Location signLoc = storage.getSignLocation(storageBlock.getLocation());
//Custom dropped Chest
ItemStack customChest = new ItemStack(storageBlock.getType(),1);
ItemMeta itemMeta = customChest.getItemMeta();
if(itemMeta != null){
itemMeta.setDisplayName(ChatColor.AQUA+""+storageType.getSignTag()+" "+storage.getIdentifier());
itemMeta.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, storage.getOwner().getUniqueId().toString());
itemMeta.getPersistentDataContainer().set(Values.storageID, PersistentDataType.STRING, storage.getIdentifier());
}
customChest.setItemMeta(itemMeta);
storageBlock.getWorld().dropItemNaturally(storageBlock.getLocation(),customChest);
if(signLoc != null) signLoc.getBlock().setType(Material.AIR);
storageBlock.setType(Material.AIR);
} else {
storageType.getMessages().storageRemoved(event.getPlayer(), storage.getIdentifier(), storage.getOwner().getName());
}
}
}
}

View File

@ -14,6 +14,7 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.stream.Collectors;
@ -133,6 +134,22 @@ public class Utils {
return targetBlock.getFace(adjacentBlock);
}
public static BlockFace getNearestBlockFace(Player player, Location blockPlaced){
Vector blockCentre = blockPlaced.add(0.5, 0, 0.5).toVector().setY(0);
Vector directionLoc = player.getEyeLocation().toVector().setY(0);
double angle = Math.toDegrees(calculateXZAngle(blockCentre,directionLoc));
if(angle <= 45 && angle > -45) return BlockFace.EAST;
if(angle <= 135 && angle > 45) return BlockFace.SOUTH;
if(angle <= -45 && angle > -135) return BlockFace.NORTH;
if(angle <= -135 || angle > 135) return BlockFace.WEST;
return null;
}
private static double calculateXZAngle(Vector origin, Vector to){
Vector vec = to.subtract(origin);
return Math.atan2(vec.getZ(), vec.getX());
}
public static boolean isSideFace(BlockFace face){
if(face == BlockFace.NORTH) return true;
if(face == BlockFace.EAST) return true;

View File

@ -12,4 +12,5 @@ public class Values {
public final static NamespacedKey playerUUID = new NamespacedKey(ChestsPlusPlus.PLUGIN,"playerUUID");
public final static NamespacedKey PluginKey = new NamespacedKey(ChestsPlusPlus.PLUGIN,"ChestsPlusPlus");
public final static NamespacedKey storageID = new NamespacedKey(ChestsPlusPlus.PLUGIN,"storageID");
}

View File

@ -78,6 +78,7 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
} else {
locationInfoList = (List<LocationInfo>) map.get("locationInfo");
locationInfoList.removeAll(Collections.singletonList(null));
locationInfoList.removeIf(locationInfo -> locationInfo.getLocation() == null);
}
//Read owners UUID and find the player for that ID.
@ -123,18 +124,26 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
startSignChangeTask();
} else {
for (LocationInfo locationInfo : locationInfoList) {
locationInfo.getSignLocation().getBlock().getState().update();
if(locationInfo.getSignLocation() != null) locationInfo.getSignLocation().getBlock().getState().update();
if(locationInfo.getBlockStand() != null) locationInfo.getBlockStand().remove();
if(locationInfo.getToolItemStand() != null) locationInfo.getToolItemStand().remove();
}
}
}
private int startSignChangeTask(){
return Bukkit.getScheduler().scheduleSyncRepeatingTask(ChestsPlusPlus.PLUGIN, () -> Bukkit.getOnlinePlayers().forEach(player -> {
return Bukkit.getScheduler().scheduleSyncRepeatingTask(ChestsPlusPlus.PLUGIN, this::updateSign, 1, 1);
}
private void updateSign(){
Bukkit.getOnlinePlayers().forEach(player -> {
for (LocationInfo locationInfo : locationInfoList) {
if (displayItem != null) player.sendBlockChange(locationInfo.getSignLocation(), air);
else locationInfo.getSignLocation().getBlock().getState().update();
if (locationInfo.getSignLocation() != null) {
if (displayItem != null) player.sendBlockChange(locationInfo.getSignLocation(), air);
else locationInfo.getSignLocation().getBlock().getState().update();
}
}
}), 1, 5);
});
}
/**
@ -206,7 +215,10 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
LocationInfo locationInfo = new LocationInfo(location);
locationInfo.setSignLocation(signLocation);
locationInfoList.add(locationInfo);
updateClient(locationInfo);
if(shouldDisplayArmourStands()){
updateSign();
updateClient(locationInfo);
}
}
/**
@ -230,7 +242,11 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
* @return true if this storage contains this location
*/
public boolean containsLocation(Location location){
return locationInfoList.stream().anyMatch(locationInfo -> locationInfo.getLocation().equals(location));
return locationInfoList.stream().filter(locationInfo -> locationInfo.getLocation() != null).anyMatch(locationInfo -> locationInfo.getLocation().equals(location));
}
public LocationInfo getLocationInfo(Location location){
return locationInfoList.stream().filter(locationInfo -> locationInfo.getLocation().equals(location)).findFirst().orElse(null);
}
public int getLocationsSize(){
@ -279,6 +295,7 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
}
public Location getSignLocation(Location storageBlock){
if(storageBlock == null) return null;
World world = storageBlock.getWorld();
Block block = storageBlock.getBlock();
@ -327,7 +344,7 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
* @param player - the player being added.
* @return true if the player was added
*/
public boolean addMember(Player player){
public boolean addMember(OfflinePlayer player){
if(player != null){
if(members == null) members = new ArrayList<>();
if(bukkitMembers == null) bukkitMembers = new ArrayList<>();
@ -345,7 +362,7 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
* @param player - player being removed.
* @return true if player was removed.
*/
public boolean removeMember(Player player){
public boolean removeMember(OfflinePlayer player){
if(player != null){
if(bukkitMembers != null) bukkitMembers.remove(player);
if(members != null){
@ -360,14 +377,16 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
private ItemStack displayItem;
public void onItemDisplayUpdate(ItemStack newItem){
if(displayItem == null || displayItem.getType().equals(Material.AIR)){
Bukkit.getScheduler().cancelTask(signUpdateTask);
signUpdateTask = -1;
} else {
if(signUpdateTask == -1) signUpdateTask = startSignChangeTask();
if(shouldDisplayArmourStands()) {
if (displayItem == null || displayItem.getType().equals(Material.AIR)) {
Bukkit.getScheduler().cancelTask(signUpdateTask);
signUpdateTask = -1;
} else {
if (signUpdateTask == -1) signUpdateTask = startSignChangeTask();
}
}
displayItem = newItem;
updateClients();
if(shouldDisplayArmourStands()) updateClients();
}
private EulerAngle BLOCK_POSE = new EulerAngle( Math.toRadians( -15 ), Math.toRadians( -45 ), Math.toRadians(0) );
@ -389,25 +408,24 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
private BlockData air = Material.AIR.createBlockData();
private void updateClient(LocationInfo location){
if(location.getLocation() == null) return;
World world = location.getLocation().getWorld();
if(world != null) {
if(location.getSignLocation() == null) return;
Block anchor = location.getSignLocation().getBlock();
BlockFace facing;
if(anchor.getBlockData() instanceof Directional){
facing = ((Directional) anchor.getBlockData()).getFacing();
} else {
Bukkit.broadcastMessage("Not directional");
return;
}
if(displayItem != null && !ApiSpecific.getMaterialChecker().isIgnored(displayItem)) {
boolean isBlock = !ApiSpecific.getMaterialChecker().isGraphically2D(displayItem);
boolean isBlock = !ApiSpecific.getMaterialChecker().isGraphically2D(displayItem);
boolean isTool = ApiSpecific.getMaterialChecker().isTool(displayItem);
Location standLoc = isTool ? getHeldItemArmorStandLoc(anchor, facing) : getArmorStandLoc(anchor, facing, isBlock);
//Get currently stored armorStand if there isn't one spawn it.
ArmorStand stand = isTool ? location.getToolItemStand() : (isBlock ? location.getBlockStand() : location.getItemStand());
if(stand == null || !stand.isValid()) {
@ -429,8 +447,6 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
if(isTool) setArmorStandHelmet(location.getItemStand(), null);
else setArmorStandHelmet(location.getToolItemStand(), null);
}
} else {
anchor.getState().update();
setArmorStandHelmet(location.getToolItemStand(), null);

View File

@ -57,6 +57,7 @@ public class StorageInfo<T extends AbstractStorage> {
* @return @{@link AutoCraftingStorage}
*/
public T getStorage(Location location) {
if(storage == null) return null;
if(!storage.containsLocation(location)){
storage.addLocation(location, storage.getSignLocation(location));
Player player = storage.getOwner().getPlayer();

View File

@ -19,6 +19,7 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockPlaceEvent;
@ -74,7 +75,17 @@ public abstract class StorageType<T extends AbstractStorage> {
public abstract boolean hasPermissionToAdd(Player player);
public abstract void createStorage(Player player, Block block, String identifier);
public void createStorage(Player player, Block block, String identifier, boolean requireSign){
createStorage(player, player, block, identifier, requireSign);
}
public abstract void createStorage(Player player, OfflinePlayer owner, Block block, String identifier, boolean requireSign);
public abstract void createStorageFacing(Player player, OfflinePlayer owner, Block block, String identifier, BlockFace facing, boolean requireSign);
public void createStorageFacing(Player player, Block block, String identifier, BlockFace facing, boolean requireSign){
createStorageFacing(player, player, block, identifier, facing, requireSign);
}
public abstract BlockFace onStoragePlacedBlockFace(Player player, Block placed);
/**
* @return the direction the storage at the given location is facing.
@ -192,10 +203,17 @@ public abstract class StorageType<T extends AbstractStorage> {
return false;
}
public T removeBlock(T storage, Location location) {
/**
* Removes a block from the given storage system.
* @param storage - @{@link AbstractStorage}
* @param location - the @{@link Location} to remove
* @param hasPickedUp - true if the player Silk Touched the block.
* @return
*/
public T removeBlock(T storage, Location location, boolean hasPickedUp) {
if (storage != null) {
storage.removeLocation(location);
if (storage.getLocationsSize() == 0) {
if (storage.getLocationsSize() == 0 && !hasPickedUp) {
storage.dropInventory(location);
getStorageMap(storage.getOwner().getUniqueId()).remove(storage.getIdentifier());
}
@ -206,12 +224,12 @@ public abstract class StorageType<T extends AbstractStorage> {
}
public T removeBlock(OfflinePlayer owner, String identifier, Location chestLocation) {
return removeBlock(getStorageMap(owner.getUniqueId()).get(identifier), chestLocation);
return removeBlock(getStorageMap(owner.getUniqueId()).get(identifier), chestLocation, false);
}
public T removeBlock(Location chestLocation) {
public T removeBlock(Location chestLocation, boolean hasPickedUp) {
T storage = getStorage(chestLocation);
return removeBlock(storage, chestLocation);
return removeBlock(storage, chestLocation, hasPickedUp);
}
public void removeStorage(Player player, String group) {
@ -262,12 +280,12 @@ public abstract class StorageType<T extends AbstractStorage> {
/* HELPER UTILS */
protected void placeSign(Block placedAgainst, Block toReplace, BlockFace facing, Player player, String identifier, String linkTag){
protected void placeSign(Block placedAgainst, Block toReplace, BlockFace facing, Player player, OfflinePlayer ownerPlayer, String identifier, String linkTag, boolean requireSign){
if(toReplace.getType() == Material.AIR){
BlockState replacedBlockState = toReplace.getState();
Material signMaterial = Material.OAK_WALL_SIGN;
if(player.getGameMode() != GameMode.CREATIVE) {
if(player.getGameMode() != GameMode.CREATIVE && requireSign) {
if (player.getEquipment() != null) {
if (!Tag.SIGNS.isTagged(player.getEquipment().getItemInMainHand().getType())) {
Messages.MUST_HOLD_SIGN(player);
@ -286,7 +304,7 @@ public abstract class StorageType<T extends AbstractStorage> {
String[] args = identifier.split(":");
owner = args[0];
group = args[1];
OfflinePlayer ownerPlayer = Config.getOfflinePlayer(owner);
ownerPlayer = Config.getOfflinePlayer(owner);
if(ownerPlayer != null){
uuid = ownerPlayer.getUniqueId().toString();
} else {
@ -295,10 +313,9 @@ public abstract class StorageType<T extends AbstractStorage> {
}
} else {
group = identifier;
uuid = player.getUniqueId().toString();
uuid = ownerPlayer.getUniqueId().toString();
}
String[] lines = new String[4];
lines[0] = linkTag;
lines[1] = Values.identifier(group);

View File

@ -61,23 +61,33 @@ public class AutoCraftingStorageType extends StorageType<AutoCraftingStorage> {
}
@Override
public void createStorage(Player player, Block block, String identifier) {
public void createStorage(Player player, OfflinePlayer owner, Block block, String identifier, boolean requireSign) {
if(isValidBlockType(block)){
BlockFace facing = Utils.getBlockFace(player);
if(facing != null) {
if(Utils.isSideFace(facing)) {
Block toReplace = block.getRelative(facing);
StorageInfo info = getStorageUtils().getStorageInfo(block.getLocation());
if(info != null){
Messages.ALREADY_PART_OF_GROUP(player,"Crafting Table");
return;
}
placeSign(block, toReplace, facing, player, identifier, Values.AutoCraftTag);
}
createStorageFacing(player, owner, block, identifier, facing, requireSign);
}
}
}
@Override
public void createStorageFacing(Player player, OfflinePlayer owner, Block block, String identifier, BlockFace facing, boolean requireSign) {
if(Utils.isSideFace(facing)) {
Block toReplace = block.getRelative(facing);
StorageInfo info = getStorageUtils().getStorageInfo(block.getLocation());
if(info != null){
Messages.ALREADY_PART_OF_GROUP(player,"Crafting Table");
return;
}
placeSign(block, toReplace, facing, player, owner, identifier, Values.AutoCraftTag,requireSign);
}
}
@Override
public BlockFace onStoragePlacedBlockFace(Player player, Block placed) {
return Utils.getNearestBlockFace(player,placed.getLocation());
}
@Override
public BlockFace getStorageFacing(Block block) {
for(BlockFace face : blockfaces){

View File

@ -54,18 +54,32 @@ public class ChestLinkStorageType extends StorageType<ChestLinkStorage> {
}
@Override
public void createStorage(Player player, Block block, String identifier) {
public void createStorage(Player player, OfflinePlayer owner, Block block, String identifier, boolean requireSign) {
if(block.getState() instanceof Chest){
new ChestLinkVerifier(block).withDelay(0).check();
if(block.getBlockData() instanceof Directional) {
Directional chest = (Directional) block.getBlockData();
BlockFace facing = chest.getFacing();
Block toReplace = block.getRelative(facing);
placeSign(block,toReplace,facing,player,identifier,Values.ChestLinkTag);
placeSign(block,toReplace,facing,player,owner,identifier,Values.ChestLinkTag, requireSign);
}
}
}
@Override
public void createStorageFacing(Player player, OfflinePlayer owner, Block block, String identifier, BlockFace facing, boolean requireSign) {
//Chests already get placed facing in the correct direction.
createStorage(player,owner,block,identifier,requireSign);
}
@Override
public BlockFace onStoragePlacedBlockFace(Player player, Block placed) {
if(placed.getBlockData() instanceof Directional){
return ((Directional) placed.getBlockData()).getFacing();
}
return null;
}
@Override
public String getSignTag() {
return Values.ChestLinkTag;