Fix for Armor Stand Displays

This commit is contained in:
jameslfc19 2020-07-04 00:10:16 +01:00
parent 2a7d73c839
commit cb7ff74d17
13 changed files with 167 additions and 76 deletions

View File

@ -23,7 +23,6 @@ public abstract class MaterialChecker {
version_1_14_Items.addAll(Tag.SMALL_FLOWERS.getValues());
version_1_14_Items.addAll(Tag.RAILS.getValues());
version_1_14_Items.addAll(Tag.CORAL_PLANTS.getValues());
version_1_14_Items.addAll(Tag.BANNERS.getValues());
version_1_14_Items.addAll(getGlassPanes());
version_1_14_Items.add(Material.BROWN_MUSHROOM);
version_1_14_Items.add(Material.RED_MUSHROOM);
@ -44,9 +43,33 @@ public abstract class MaterialChecker {
version_1_14_Items.add(Material.PEONY);
version_1_14_Items.add(Material.TALL_GRASS);
version_1_14_Items.add(Material.LARGE_FERN);
version_1_14_Items.add(Material.BELL);
version_1_14_Items.add(Material.CAMPFIRE);
version_1_14_Items.add(Material.LANTERN);
version_1_14_Items.add(Material.TURTLE_EGG);
version_1_14_Items.add(Material.SUGAR_CANE);
version_1_14_Items.add(Material.KELP);
version_1_14_Items.add(Material.BAMBOO);
version_1_14_Items.add(Material.LEVER);
version_1_14_Items.add(Material.TRIPWIRE_HOOK);
version_1_14_Items.add(Material.REPEATER);
version_1_14_Items.add(Material.COMPARATOR);
version_1_14_Items.add(Material.CAULDRON);
version_1_14_Items.add(Material.BREWING_STAND);
version_1_14_Items.add(Material.HOPPER);
version_1_14_Ignored_Items = new ArrayList<>();
version_1_14_Ignored_Items.addAll(Tag.BEDS.getValues());
version_1_14_Ignored_Items.addAll(Tag.BANNERS.getValues());
version_1_14_Ignored_Items.add(Material.DRAGON_HEAD);
version_1_14_Ignored_Items.add(Material.PLAYER_HEAD);
version_1_14_Ignored_Items.add(Material.ZOMBIE_HEAD);
version_1_14_Ignored_Items.add(Material.SKELETON_SKULL);
version_1_14_Ignored_Items.add(Material.CREEPER_HEAD);
version_1_14_Ignored_Items.add(Material.SHIELD);
version_1_14_Ignored_Items.add(Material.CROSSBOW);
version_1_14_Ignored_Items.add(Material.TRIDENT);
}
public static MaterialChecker Version_1_14 = new MaterialChecker() {
@ -64,6 +87,7 @@ public abstract class MaterialChecker {
/**
* API-Specific implementation for materials checks.
* Should return a list of materials where the texture for this item is displayed as 2D rather than a 3D model.
* Should add the materials from the previous version (e.g 1.16 adds 1.15 which adds 1.14)
* @return
* List of Materials.
*/
@ -85,6 +109,15 @@ public abstract class MaterialChecker {
return !itemStack.getType().isBlock();
}
/**
* Whether this item should be ignored when displaying. (Beds don't look good so are ignored.)
* @param itemStack
* @return
*/
public boolean isIgnored(ItemStack itemStack){
return ignoredMaterials().contains(itemStack.getType());
}
private static List<Material> getGlassPanes(){
List<Material> materials = new ArrayList<>();
materials.add(Material.GLASS_PANE);
@ -107,4 +140,21 @@ public abstract class MaterialChecker {
return materials;
}
/**
* This returns true if an item is held like a pickaxe/sword etc.
* @param itemStack
* @return
*/
public boolean isTool(ItemStack itemStack){
String matType = itemStack.getType().toString();
if(matType.contains("AXE")) return true;
if(matType.contains("SWORD")) return true;
if(matType.contains("PICKAXE")) return true;
if(matType.contains("HOE")) return true;
if(matType.contains("SHOVEL")) return true;
if(itemStack.getType() == Material.FISHING_ROD) return true;
if(itemStack.getType() == Material.CARROT_ON_A_STICK) return true;
return false;
}
}

View File

@ -27,5 +27,6 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.15-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
<orderEntry type="library" name="Maven: org.bukkit:craftbukkit:1.15.2-R0.1-SNAPSHOT" level="project" />
</component>
</module>

View File

@ -33,6 +33,12 @@
<version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@ -1,10 +1,8 @@
package com.jamesdpeters.minecraft.chests;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Material;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MaterialChecker_1_15 extends MaterialChecker {

View File

@ -29,5 +29,6 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.16-R0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.26" level="project" />
<orderEntry type="module" module-name="ChestsPlusPlus_1_15" />
<orderEntry type="library" name="Maven: org.bukkit:craftbukkit:1.15.2-R0.1-SNAPSHOT" level="project" />
</component>
</module>

View File

@ -3,6 +3,7 @@ package com.jamesdpeters.minecraft.chests;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Arrays;
@ -12,14 +13,28 @@ public class MaterialChecker_1_16 extends MaterialChecker {
private List<Material> materials;
private List<Material> ignoredMaterials;
MaterialChecker_1_15 version1_15;
public MaterialChecker_1_16(){
version1_15 = new MaterialChecker_1_15();
materials = new ArrayList<>();
materials.addAll(version_1_14_Items);
materials.addAll(version1_15.graphically2DList());
materials.addAll(Tag.CROPS.getValues());
materials.addAll(Tag.TALL_FLOWERS.getValues());
materials.addAll(Tag.FLOWERS.getValues());
materials.add(Material.WARPED_FUNGUS);
materials.add(Material.WARPED_ROOTS);
materials.add(Material.TWISTING_VINES);
materials.add(Material.NETHER_SPROUTS);
materials.add(Material.WEEPING_VINES);
materials.add(Material.CRIMSON_ROOTS);
materials.add(Material.CRIMSON_FUNGUS);
materials.add(Material.SOUL_CAMPFIRE);
materials.add(Material.SOUL_LANTERN);
materials.add(Material.CHAIN);
ignoredMaterials = new ArrayList<>();
ignoredMaterials.addAll(version_1_14_Ignored_Items);
ignoredMaterials.addAll(version1_15.ignoredMaterials());
}
@Override
@ -32,4 +47,9 @@ public class MaterialChecker_1_16 extends MaterialChecker {
return ignoredMaterials;
}
@Override
public boolean isTool(ItemStack itemStack) {
if(itemStack.getType() == Material.WARPED_FUNGUS_ON_A_STICK) return true;
return version1_15.isTool(itemStack);
}
}

View File

@ -27,9 +27,7 @@ public class ApiSpecific {
private static Version getVersion(){
String version = Bukkit.getBukkitVersion().split("-")[0];
System.out.println(version);
String[] versionRevisions = version.split("\\.");
System.out.println(Arrays.toString(versionRevisions));
String minorVersion = versionRevisions[1];
//Switch minor revision number e.g 1.xx

View File

@ -1,9 +1,11 @@
package com.jamesdpeters.minecraft.chests.listeners;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.serialize.Config;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.scheduler.BukkitRunnable;
@ -24,4 +26,9 @@ public class WorldListener implements Listener {
}.runTaskLater(ChestsPlusPlus.PLUGIN,5);
}
}
@EventHandler
public void onWorldLoad(WorldLoadEvent event){
Utils.removeEntities(event.getWorld());
}
}

View File

@ -120,55 +120,13 @@ public class Utils {
* Removes all entities that contain a value of 1 under the Values.PluginKey key.
*/
public static void removeEntities(){
Bukkit.getServer().getWorlds().forEach(world -> {
world.getEntities().forEach(entity -> {
Integer val = entity.getPersistentDataContainer().get(Values.PluginKey, PersistentDataType.INTEGER);
if(val != null && val == 1) entity.remove();
});
Bukkit.getServer().getWorlds().forEach(Utils::removeEntities);
}
public static void removeEntities(World world){
world.getEntities().forEach(entity -> {
Integer val = entity.getPersistentDataContainer().get(Values.PluginKey, PersistentDataType.INTEGER);
if(val != null && val == 1) entity.remove();
});
}
/**
* Used to test if an item is graphically a block (e.g a sign is a block but is held like an item.)
* @param itemStack
* @return
*/
public static boolean isGraphicallyBlock(ItemStack itemStack){
switch (itemStack.getType()){
//Signs
case ACACIA_SIGN:
case ACACIA_WALL_SIGN:
case BIRCH_SIGN:
case BIRCH_WALL_SIGN:
case DARK_OAK_SIGN:
case DARK_OAK_WALL_SIGN:
case JUNGLE_SIGN:
case JUNGLE_WALL_SIGN:
case OAK_SIGN:
case OAK_WALL_SIGN:
case SPRUCE_SIGN:
case SPRUCE_WALL_SIGN:
//Doors
case ACACIA_DOOR:
case BIRCH_DOOR:
case DARK_OAK_DOOR:
case JUNGLE_DOOR:
case OAK_DOOR:;
case SPRUCE_DOOR:
case IRON_DOOR:
//Saplings
case SPRUCE_SAPLING:
case ACACIA_SAPLING:
case BAMBOO_SAPLING:
case BIRCH_SAPLING:
case DARK_OAK_SAPLING:
case JUNGLE_SAPLING:
case OAK_SAPLING:
return false;
}
Bukkit.broadcastMessage("Type: "+itemStack.getType()+" isItem: "+itemStack.getType().isItem());
return itemStack.getType().isSolid();
}
}

View File

@ -17,7 +17,7 @@ import java.util.UUID;
public class LocationInfo implements ConfigurationSerializable {
private Location location;
private ArmorStand itemStand, blockStand;
private ArmorStand itemStand, blockStand, toolItemStand;
@Override
public Map<String, Object> serialize() {
@ -46,6 +46,10 @@ public class LocationInfo implements ConfigurationSerializable {
return itemStand;
}
public ArmorStand getToolItemStand() {
return toolItemStand;
}
public LocationInfo setBlockStand(ArmorStand blockStand) {
this.blockStand = blockStand;
return this;
@ -56,6 +60,11 @@ public class LocationInfo implements ConfigurationSerializable {
return this;
}
public LocationInfo setToolItemStand(ArmorStand toolItemStand) {
this.toolItemStand = toolItemStand;
return this;
}
public static List<LocationInfo> convert(List<Location> locationList){
List<LocationInfo> locationInfos = new ArrayList<>();
for (Location location : locationList) {

View File

@ -3,7 +3,6 @@ package com.jamesdpeters.minecraft.chests.storage.abstracts;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.api_interfaces.ApiSpecific;
import com.jamesdpeters.minecraft.chests.misc.Permissions;
import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.misc.Values;
import com.jamesdpeters.minecraft.chests.serialize.LocationInfo;
import org.bukkit.Bukkit;
@ -144,6 +143,12 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
protected abstract void setIdentifier(String newIdentifier);
public abstract String getIdentifier();
/**
* This is the distance from a full block to the size of the storage block. (e.g Chest is smaller than a regular block.)
* @return
*/
public abstract double getBlockOffset();
/**
* This is called when a block is added to the storage system.
* @param block - the block that was added.
@ -303,6 +308,10 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
*/
protected abstract ItemStack getArmorStandItem();
private EulerAngle BLOCK_POSE = new EulerAngle( Math.toRadians( -15 ), Math.toRadians( -45 ), Math.toRadians(0) );
private EulerAngle STANDARD_ITEM_POSE = new EulerAngle(Math.toRadians(90),0,Math.toRadians(180));
private EulerAngle TOOL_ITEM_POSE = new EulerAngle(Math.toRadians(-145),0,Math.toRadians(0));
/**
* Updates nearby clients for all locations of this storage:
* - If getArmorStandItem() is non-null the block in-front of the storage is set to Air and an @{@link ArmorStand} is
@ -328,19 +337,20 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
ItemStack displayItem = getArmorStandItem();
if(displayItem != null) {
if(displayItem != null && !ApiSpecific.getMaterialChecker().isIgnored(displayItem)) {
boolean isBlock = !ApiSpecific.getMaterialChecker().isGraphically2D(displayItem);
Location standLoc = getArmorStandLoc(anchor,facing, isBlock);
boolean isTool = ApiSpecific.getMaterialChecker().isTool(displayItem);
Location standLoc = isTool ? getHeldItemArmorStandLoc(anchor,facing) : getArmorStandLoc(anchor,facing, isBlock);
//Make client think sign is invisible.
player.sendBlockChange(anchor.getLocation(), air);
//Get currently stored armorStand if there isn't one spawn it.
ArmorStand stand = isBlock ? location.getBlockStand() : location.getItemStand();
ArmorStand stand = isTool ? location.getToolItemStand() : (isBlock ? location.getBlockStand() : location.getItemStand());
if(stand == null || !stand.isValid()){
stand = createArmorStand(world,standLoc,isBlock);
addArmorStand(isBlock, location, stand);
stand = createArmorStand(world,standLoc,isBlock,isTool);
addArmorStand(isBlock, isTool, location, stand);
}
stand.setItemInHand(displayItem);
@ -349,12 +359,21 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
stand.setFireTicks(Integer.MAX_VALUE);
//Set other armor stand helmet to null.
setArmorStandHelmet(!isBlock, location, null);
if(isBlock){
setArmorStandHelmet(location.getToolItemStand(), null);
setArmorStandHelmet(location.getItemStand(), null);
} else {
setArmorStandHelmet(location.getBlockStand(), null);
if(isTool) setArmorStandHelmet(location.getItemStand(), null);
else setArmorStandHelmet(location.getToolItemStand(), null);
}
} else {
anchor.getState().update();
setArmorStandHelmet(true,location,null);
setArmorStandHelmet(false,location,null);
setArmorStandHelmet(location.getToolItemStand(),null);
setArmorStandHelmet(location.getItemStand(),null);
setArmorStandHelmet(location.getBlockStand(),null);
}
}
}
@ -369,7 +388,7 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
* @param standLoc - location to spawn the @{@link ArmorStand} at.
* @return instance of @{@link ArmorStand} that was spawned.
*/
private ArmorStand createArmorStand(World world, Location standLoc, boolean isBlock){
private ArmorStand createArmorStand(World world, Location standLoc, boolean isBlock, boolean isTool){
ArmorStand stand = world.spawn(standLoc, ArmorStand.class);
stand.setVisible(false);
stand.setGravity(false);
@ -379,9 +398,11 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
stand.setBasePlate(false);
stand.setSmall(true);
stand.setCanPickupItems(false);
EulerAngle angle = isBlock ? new EulerAngle( Math.toRadians( -15 ), Math.toRadians( -45 ), Math.toRadians(0) ) : new EulerAngle(Math.toRadians(90),0,Math.toRadians(180));
EulerAngle angle = isTool ? TOOL_ITEM_POSE : (isBlock ? BLOCK_POSE : STANDARD_ITEM_POSE);
stand.setRightArmPose(angle);
// stand.setArms(true);
//Store value of 1 in armour stand to indicate it belongs to this plugin.
stand.getPersistentDataContainer().set(Values.PluginKey, PersistentDataType.INTEGER, 1);
return stand;
@ -395,30 +416,42 @@ public abstract class AbstractStorage implements ConfigurationSerializable {
* @return the calculated location for the @{@link ArmorStand}
*/
private Location getArmorStandLoc(Block anchor, BlockFace facing, boolean isBlock){
// double directionFactor = isBlock ? 0.6 : 0.3;
double directionFactor = isBlock ? 0.65 : 0.275;
double perpendicularFactor = isBlock ? 0.025 : 0.125;
// double y = -0.4;
double y = isBlock ? -0.3 : 0.1;
float yaw = 180;
return getArmorStandLoc(anchor, facing, directionFactor, perpendicularFactor, y, yaw);
}
private Location getHeldItemArmorStandLoc(Block anchor, BlockFace facing){
double directionFactor = 0.36;
double perpendicularFactor = 0;
double y = 0.275;
float yaw = -90;
return getArmorStandLoc(anchor, facing, directionFactor, perpendicularFactor, y, yaw);
}
private Location getArmorStandLoc(Block anchor, BlockFace facing, double directionFactor, double perpendicularFactor, double y, float yaw){
//Get centre of block location.
Location standLoc = anchor.getLocation().add(0.5,-0.5,0.5);
Vector direction = facing.getDirection();
directionFactor = directionFactor + getBlockOffset();
double x = directionFactor*direction.getX() - perpendicularFactor*direction.getZ();
double z = directionFactor*direction.getZ() + perpendicularFactor*direction.getX();
float yaw = 180;
standLoc.setYaw(getYaw(direction.getX(),direction.getZ())+yaw);
return standLoc.subtract(x, y, z);
}
private void setArmorStandHelmet(boolean isBlock, LocationInfo location, ItemStack helmet){
ArmorStand stand = isBlock ? location.getBlockStand() : location.getItemStand();
private void setArmorStandHelmet(ArmorStand stand, ItemStack helmet){
if(stand != null) stand.setItemInHand(helmet);
}
private void addArmorStand(boolean isBlock, LocationInfo location, ArmorStand stand){
if(isBlock) location.setBlockStand(stand);
private void addArmorStand(boolean isBlock, boolean isTool, LocationInfo location, ArmorStand stand){
if(isTool) location.setToolItemStand(stand);
else if(isBlock) location.setBlockStand(stand);
else location.setItemStand(stand);
}

View File

@ -84,6 +84,11 @@ public class AutoCraftingStorage extends AbstractStorage implements Configuratio
return identifier;
}
@Override
public double getBlockOffset() {
return -0.07;
}
public VirtualCraftingHolder getVirtualCraftingHolder() {
return virtualCraftingHolder;
}

View File

@ -188,6 +188,11 @@ public class ChestLinkStorage extends AbstractStorage implements ConfigurationSe
return inventoryName;
}
@Override
public double getBlockOffset() {
return 0;
}
@Override
public String toString() {
return inventoryName+": "+getLocations().toString();