diff --git a/changelog.txt b/changelog.txt index 35dba5b92..bc268b298 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,5 @@ Alpha 0.1.8.44 +- Add 1.19.4 support. - Add support for PlotSquared 7. Thanks, Bloody_Mind, for the suggestion! - Added the "/BigDoors PrepareDatabaseForV2" command. This will export your database to the format used by v2. Note that both the export and v2 are still experimental! - Fix rare issue with retrieving permissions for offline players that could result in a server crash. Thanks, VikEnd, for the bug report! diff --git a/core/pom.xml b/core/pom.xml index 50524930e..8388b2f01 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -151,6 +151,13 @@ compile + + nl.pim16aap2.BigDoors + v1_19_R3 + 0.1.8.44-ALPHA + compile + + ${dependency.xseries.groupid} XSeries diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/BigDoors.java b/core/src/main/java/nl/pim16aap2/bigDoors/BigDoors.java index f53e391a0..5a8b9e3db 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/BigDoors.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/BigDoors.java @@ -18,6 +18,7 @@ import nl.pim16aap2.bigDoors.NMS.FallingBlockFactory_V1_19_R1; import nl.pim16aap2.bigDoors.NMS.FallingBlockFactory_V1_19_R1_1; import nl.pim16aap2.bigDoors.NMS.FallingBlockFactory_V1_19_R2; +import nl.pim16aap2.bigDoors.NMS.FallingBlockFactory_V1_19_R3; import nl.pim16aap2.bigDoors.codegeneration.FallbackGeneratorManager; import nl.pim16aap2.bigDoors.compatibility.FakePlayerCreator; import nl.pim16aap2.bigDoors.compatibility.ProtectionCompatManager; @@ -835,6 +836,9 @@ private boolean compatibleMCVer() case "v1_19_R2": fabf = new FallingBlockFactory_V1_19_R2(); break; + case "v1_19_R3": + fabf = new FallingBlockFactory_V1_19_R3(); + break; default: if (config.allowCodeGeneration()) fabf = FallbackGeneratorManager.getFallingBlockFactory(); @@ -1083,6 +1087,7 @@ public enum MCVersion v1_18_R2, v1_19_R1, v1_19_R2, + v1_19_R3, v1_20_R1, v1_21_R1, v1_22_R1, diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/EntityFallingBlockClassGenerator.java b/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/EntityFallingBlockClassGenerator.java index 6fbc483e5..a4b0c83fa 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/EntityFallingBlockClassGenerator.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/EntityFallingBlockClassGenerator.java @@ -151,7 +151,7 @@ private DynamicType.Builder addCTor(DynamicType.Builder builder) FieldAccessor.of(fieldNoClip).setsValue(true)).andThen( invoke(methodSetNoGravity).with(true)).andThen( invoke(methodSetMotVec).withMethodCall(construct(cTorVec3D).with(0d, 0d, 0d))).andThen( - invoke(methodSetStartPos).withMethodCall(construct(cTorBlockPosition) + invoke(methodSetStartPos).withMethodCall(invoke(methodNewBlockPosition) .withMethodCall(invoke(methodLocX)) .withMethodCall(invoke(methodLocY)) .withMethodCall(invoke(methodLocZ)))).andThen( diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/FallingBlockFactoryClassGenerator.java b/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/FallingBlockFactoryClassGenerator.java index 84f3b9667..eced89d6a 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/FallingBlockFactoryClassGenerator.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/FallingBlockFactoryClassGenerator.java @@ -111,7 +111,7 @@ private DynamicType.Builder addNMSBlockFactoryMethod(DynamicType.Builder b final MethodCall getNMSWorld = (MethodCall) invoke(methodGetNMSWorld).onArgument(0).withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC); - final MethodCall createBlockPosition = construct(cTorBlockPosition).withArgument(1, 2, 3); + final MethodCall createBlockPosition = invoke(methodNewBlockPosition).withArgument(1, 2, 3); final MethodCall getType = invoke(methodGetTypeFromBlockPosition) .onMethodCall(getNMSWorld).withMethodCall(createBlockPosition); diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/NMSBlockClassGenerator.java b/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/NMSBlockClassGenerator.java index 058924e0f..f0c9a7b95 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/NMSBlockClassGenerator.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/NMSBlockClassGenerator.java @@ -375,7 +375,7 @@ private DynamicType.Builder addPutBlockMethod(DynamicType.Builder builder) invoke(methodSetTypeAndData) .onMethodCall(worldCast) - .withMethodCall(construct(cTorBlockPosition) + .withMethodCall(invoke(methodNewBlockPosition) .withMethodCall(invoke(methodLocationGetX).onField(FIELD_LOCATION)) .withMethodCall(invoke(methodLocationGetY).onField(FIELD_LOCATION)) .withMethodCall(invoke(methodLocationGetZ).onField(FIELD_LOCATION))) diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/ReflectionRepository.java b/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/ReflectionRepository.java index 73dc6f1c7..991b975b6 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/ReflectionRepository.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/codegeneration/ReflectionRepository.java @@ -22,6 +22,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import static nl.pim16aap2.bigDoors.reflection.ReflectionBuilder.*; @@ -68,12 +70,12 @@ final class ReflectionRepository public static final Constructor cTorPublicNMSFallingBlockEntity; public static final Constructor cTorPrivateNMSFallingBlockEntity; - public static final Constructor cTorBlockPosition; public static final Constructor cTorVec3D; public static final Constructor ctorCraftEntity; public static final Constructor ctorBlockBase; public static final Constructor ctorLocation; + public static final Method methodNewBlockPosition; public static final Method methodGetBlockData; public static final Method methodSetBlockData; public static final Method methodGetBlockMaterial; @@ -213,8 +215,6 @@ final class ReflectionRepository cTorPublicNMSFallingBlockEntity = findConstructor().inClass(classEntityFallingBlock) .withParameters(classEntityTypes, classNMSWorld).get(); - cTorBlockPosition = findConstructor().inClass(classBlockPosition) - .withParameters(double.class, double.class, double.class).get(); cTorVec3D = findConstructor().inClass(classVec3D) .withParameters(double.class, double.class, double.class).get(); ctorCraftEntity = findConstructor().inClass(classCraftEntity) @@ -226,6 +226,9 @@ final class ReflectionRepository .get(); + methodNewBlockPosition = findMethod().inClass(classBlockPosition).withReturnType(classBlockPosition) + .withParameters(double.class, double.class, double.class) + .withModifiers(Modifier.STATIC, Modifier.PUBLIC).get(); methodGetBlockData = findMethod().inClass(Block.class).withName("getBlockData").withoutParameters().get(); methodSetBlockData = findMethod().inClass(Block.class).withName("setBlockData") .withParameters(BlockData.class).get(); @@ -241,8 +244,7 @@ final class ReflectionRepository .withoutParameters().withModifiers(Modifier.PUBLIC).get(); methodGetEntityHandle = findMethod().inClass(classCraftEntity).withName("getHandle") .withoutParameters().withModifiers(Modifier.PUBLIC).get(); - methodTick = findMethod().inClass(classEntityFallingBlock).withReturnType(void.class) - .withModifiers(Modifier.PUBLIC).withoutParameters().get(); + methodTick = findTickMethod(); methodHurtEntities = findMethod().inClass(classEntityFallingBlock).withReturnType(boolean.class) .withParameters(parameterBuilder() .withRequiredParameters(float.class, float.class) @@ -391,6 +393,25 @@ final class ReflectionRepository .exactCount(3).get()); } + private static Method findTickMethod() + { + final Set baseMethods = + findMethod().inClass(classNMSEntity).findMultiple().withReturnType(void.class) + .withModifiers(Modifier.PUBLIC).withoutParameters().atLeast(1).get() + .stream().map(Method::getName).collect(Collectors.toSet()); + final List fbMethods = + findMethod().inClass(classEntityFallingBlock).findMultiple().withReturnType(void.class) + .withModifiers(Modifier.PUBLIC).withoutParameters().atLeast(1).get(); + + final List filtered = + fbMethods.stream().filter(method -> baseMethods.contains(method.getName())).collect(Collectors.toList()); + + if (filtered.size() != 1) + throw new IllegalStateException("Found " + filtered.size() + + " methods that could be the tick method: " + filtered); + return filtered.get(0); + } + private ReflectionRepository() { } diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/util/ConfigLoader.java b/core/src/main/java/nl/pim16aap2/bigDoors/util/ConfigLoader.java index 553ec1d9a..11e06b7cc 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/util/ConfigLoader.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/util/ConfigLoader.java @@ -121,6 +121,10 @@ public class ConfigLoader populateResourcePacks( RESOURCEPACKS, "https://www.dropbox.com/s/8vpwzjkd9jnp1xu/BigDoorsResourcePack-Format12.zip?dl=1", MCVersion.v1_19_R2); + + populateResourcePacks( + RESOURCEPACKS, "https://www.dropbox.com/s/3b6ohu02ueq5no0/BigDoorsResourcePack-Format13.zip?dl=1", + MCVersion.v1_19_R3); } public ConfigLoader(BigDoors plugin) @@ -197,6 +201,8 @@ public void makeConfig() + RESOURCEPACKS.get(MCVersion.v1_19_R1) + "'", "The resource pack for 1.19.3 is: '" + RESOURCEPACKS.get(MCVersion.v1_19_R2) + "'", + "The resource pack for 1.19.4 is: '" + + RESOURCEPACKS.get(MCVersion.v1_19_R3) + "'", }; String[] multiplierComment = { "These multipliers affect the opening/closing speed of their respective door types.", "Note that the maximum speed is limited, so beyond a certain point rasising these values won't have any effect.", diff --git a/nms/pom.xml b/nms/pom.xml index 2355f178a..076ba3ffe 100644 --- a/nms/pom.xml +++ b/nms/pom.xml @@ -30,6 +30,7 @@ v1_19_R1 v1_19_R1_1 v1_19_R2 + v1_19_R3 diff --git a/nms/v1_19_R3/pom.xml b/nms/v1_19_R3/pom.xml new file mode 100644 index 000000000..f1f255e2e --- /dev/null +++ b/nms/v1_19_R3/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + jar + v1_19_R3 + + + nl.pim16aap2.BigDoors + nms + 0.1.8.44-ALPHA + + + + 8 + 8 + UTF-8 + + + + + org.spigotmc + spigot + 1.19.4-R0.1-SNAPSHOT + provided + + + + nl.pim16aap2.BigDoors + nms-api + 0.1.8.44-ALPHA + provided + + + diff --git a/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/CustomCraftFallingBlock_V1_19_R3.java b/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/CustomCraftFallingBlock_V1_19_R3.java new file mode 100644 index 000000000..727322fec --- /dev/null +++ b/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/CustomCraftFallingBlock_V1_19_R3.java @@ -0,0 +1,110 @@ +package nl.pim16aap2.bigDoors.NMS; + +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_19_R3.util.CraftMagicNumbers; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingBlock; +import org.bukkit.util.EulerAngle; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; + +public class CustomCraftFallingBlock_V1_19_R3 extends CraftEntity implements FallingBlock, CustomCraftFallingBlock +{ + CustomCraftFallingBlock_V1_19_R3(final Server server, final CustomEntityFallingBlock_V1_19_R3 entity) + { + super((org.bukkit.craftbukkit.v1_19_R3.CraftServer) server, entity); + setVelocity(new Vector(0, 0, 0)); + setDropItem(false); + } + + @Override + public CustomEntityFallingBlock_V1_19_R3 getHandle() + { + return (CustomEntityFallingBlock_V1_19_R3) entity; + } + + @Override + public boolean isOnGround() + { + return false; + } + + @Override + public String toString() + { + return "CraftFallingBlock"; + } + + @Override + public @NotNull EntityType getType() + { + return EntityType.FALLING_BLOCK; + } + + @Override + public void setVisibleByDefault(boolean flag) + { + } + + @Override + public boolean isVisibleByDefault() + { + return true; + } + + @Override + @Deprecated + public @NotNull Material getMaterial() + { + return CraftMagicNumbers.getMaterial(getHandle().k()).getItemType(); + } + + @Override + public @NotNull BlockData getBlockData() + { + return CraftBlockData.fromData(this.getHandle().k()); + } + + @Override + public boolean getDropItem() + { + return false; + } + + @Override + public void setDropItem(final boolean drop) + { + } + + @Override + public boolean canHurtEntities() + { + return false; + } + + @Override + public void setHurtEntities(final boolean hurtEntities) + { + } + + @Override + public void setTicksLived(final int value) + { + super.setTicksLived(value); + getHandle().b = value; + } + + @Override + public void setHeadPose(EulerAngle pose) + { + } + + @Override + public void setBodyPose(EulerAngle eulerAngle) + { + } +} diff --git a/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/CustomEntityFallingBlock_V1_19_R3.java b/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/CustomEntityFallingBlock_V1_19_R3.java new file mode 100644 index 000000000..d18b0526a --- /dev/null +++ b/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/CustomEntityFallingBlock_V1_19_R3.java @@ -0,0 +1,105 @@ +package nl.pim16aap2.bigDoors.NMS; + +import net.minecraft.CrashReportSystemDetails; +import net.minecraft.core.BlockPosition; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.GameProfileSerializer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.level.WorldServer; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.EnumMoveType; +import net.minecraft.world.entity.item.EntityFallingBlock; +import net.minecraft.world.level.block.state.IBlockData; +import net.minecraft.world.phys.Vec3D; +import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; +import org.bukkit.event.entity.CreatureSpawnEvent; + +/** + * v1_19_R1 implementation of {@link CustomEntityFallingBlock}. + * + * @author Pim + * @see CustomEntityFallingBlock + */ +public class CustomEntityFallingBlock_V1_19_R3 extends EntityFallingBlock implements CustomEntityFallingBlock +{ + private IBlockData block; + + public CustomEntityFallingBlock_V1_19_R3( + final org.bukkit.World world, final double d0, final double d1, final double d2, final IBlockData iblockdata) + { + super(EntityTypes.L, ((CraftWorld) world).getHandle()); + block = iblockdata; + + this.e(d0, d1, d2); + super.b = 0; + super.i = false; + super.ae = true; + this.e(true); + this.f(new Vec3D(0.0, 0.0, 0.0)); + this.a(BlockPosition.a(this.dl(), this.dn(), this.dr())); + spawn(); + } + + public void spawn() + { + ((WorldServer)super.H).addWithUUID(this, CreatureSpawnEvent.SpawnReason.CUSTOM); + } + + @Override + public void l() + { + if (block.h()) + ai(); + else + { + a(EnumMoveType.a, dj()); + if (++b > 12000) + ai(); + + f(dj().d(0.9800000190734863D, 1.0D, 0.9800000190734863D)); + } + } + + @Override + public boolean a(float f, float f1, DamageSource damagesource) + { + return false; + } + + @Override + protected void b(final NBTTagCompound nbttagcompound) + { + nbttagcompound.a("BlockState", GameProfileSerializer.a(block)); + nbttagcompound.a("Time", b); + nbttagcompound.a("DropItem", false); + nbttagcompound.a("HurtEntities", aq); + nbttagcompound.a("FallHurtAmount", 0.0f); + nbttagcompound.a("FallHurtMax", 0); + if (d != null) + nbttagcompound.a("TileEntityData", d); + } + + @Override + protected void a(final NBTTagCompound nbttagcompound) + { + block = GameProfileSerializer.a(super.H.a(Registries.e), nbttagcompound.p("BlockState")); + b = nbttagcompound.h("Time"); + + if (nbttagcompound.b("TileEntityData", 10)) + super.d = nbttagcompound.p("TileEntityData"); + } + + @Override + public void a(final CrashReportSystemDetails crashreportsystemdetails) + { + super.a(crashreportsystemdetails); + crashreportsystemdetails.a("Animated BigDoors block with state: ", block.toString()); + } + + @Override + public IBlockData k() + { + return block; + } +} diff --git a/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/FallingBlockFactory_V1_19_R3.java b/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/FallingBlockFactory_V1_19_R3.java new file mode 100644 index 000000000..b8c0a5e07 --- /dev/null +++ b/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/FallingBlockFactory_V1_19_R3.java @@ -0,0 +1,34 @@ +package nl.pim16aap2.bigDoors.NMS; + +import net.minecraft.core.BlockPosition; +import net.minecraft.world.level.block.state.BlockBase; +import net.minecraft.world.level.block.state.BlockBase.Info; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; + +public class FallingBlockFactory_V1_19_R3 implements FallingBlockFactory +{ + @Override + public CustomCraftFallingBlock fallingBlockFactory(Location loc, NMSBlock block, byte matData, Material mat) + { + IBlockData blockData = ((NMSBlock_V1_19_R3) block).getMyBlockData(); + CustomEntityFallingBlock_V1_19_R3 fBlockNMS + = new CustomEntityFallingBlock_V1_19_R3(loc.getWorld(), loc.getX(), loc.getY(), loc.getZ(), blockData); + CustomCraftFallingBlock_V1_19_R3 entity = new CustomCraftFallingBlock_V1_19_R3(Bukkit.getServer(), fBlockNMS); + entity.setCustomName("BigDoorsEntity"); + entity.setCustomNameVisible(false); + return entity; + } + + @Override + public NMSBlock nmsBlockFactory(World world, int x, int y, int z) + { + final Info blockInfo = + Info.a((BlockBase) ((CraftWorld) world).getHandle().a_(new BlockPosition(x, y, z)).b()); + return new NMSBlock_V1_19_R3(world, x, y, z, blockInfo); + } +} diff --git a/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/NMSBlock_V1_19_R3.java b/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/NMSBlock_V1_19_R3.java new file mode 100644 index 000000000..df0a9bc84 --- /dev/null +++ b/nms/v1_19_R3/src/main/java/nl/pim16aap2/bigDoors/NMS/NMSBlock_V1_19_R3.java @@ -0,0 +1,214 @@ +package nl.pim16aap2.bigDoors.NMS; + +import com.cryptomorin.xseries.XMaterial; +import net.minecraft.core.BlockPosition; +import net.minecraft.core.EnumDirection; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.BlockRotatable; +import net.minecraft.world.level.block.EnumBlockRotation; +import net.minecraft.world.level.block.state.BlockBase; +import net.minecraft.world.level.block.state.IBlockData; +import nl.pim16aap2.bigDoors.util.DoorDirection; +import nl.pim16aap2.bigDoors.util.NMSUtil; +import nl.pim16aap2.bigDoors.util.RotateDirection; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.MultipleFacing; +import org.bukkit.block.data.Waterlogged; +import org.bukkit.block.data.type.Fence; +import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; + +import java.util.Objects; +import java.util.Set; + +public class NMSBlock_V1_19_R3 extends BlockBase implements NMSBlock +{ + private IBlockData blockData; + private CraftBlockData craftBlockData; + private final XMaterial xmat; + private Location loc; + + public NMSBlock_V1_19_R3(World world, int x, int y, int z, Info blockInfo) + { + super(blockInfo); + + loc = new Location(world, x, y, z); + + craftBlockData = (CraftBlockData) world.getBlockAt(x, y, z).getBlockData(); + if (craftBlockData instanceof Waterlogged) + ((Waterlogged) craftBlockData).setWaterlogged(false); + + updateBlockData(); + + xmat = XMaterial.matchXMaterial(world.getBlockAt(x, y, z).getType().toString()).orElse(XMaterial.BEDROCK); + } + + @Override + public boolean canRotate() + { + return craftBlockData instanceof MultipleFacing; + } + + @Override + public void rotateBlock(RotateDirection rotDir) + { + EnumBlockRotation rot; + switch (rotDir) + { + case CLOCKWISE: + rot = EnumBlockRotation.b; + break; + case COUNTERCLOCKWISE: + rot = EnumBlockRotation.d; + break; + default: + rot = EnumBlockRotation.a; + } + blockData = blockData.a(rot); + updateCraftBlockData(); + } + + private void updateBlockData() + { + blockData = craftBlockData.getState(); + } + + private void updateCraftBlockData() + { + this.craftBlockData = CraftBlockData.fromData(blockData); + } + + @Override + public void putBlock(Location loc) + { + this.loc = loc; + + if (craftBlockData instanceof MultipleFacing) + updateCraftBlockDataMultipleFacing(); + + ((CraftWorld) Objects.requireNonNull(loc.getWorld())) + .getHandle().a(new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()), blockData, 1); + } + + private void updateCraftBlockDataMultipleFacing() + { + final Set allowedFaces = ((MultipleFacing) craftBlockData).getAllowedFaces(); + allowedFaces.forEach( + (blockFace) -> + { + final org.bukkit.block.Block otherBlock = + loc.clone().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ()).getBlock(); + final org.bukkit.block.data.BlockData otherData = otherBlock.getBlockData(); + + if (blockFace.equals(BlockFace.UP)) + ((MultipleFacing) craftBlockData).setFace(blockFace, true); + else if (otherBlock.getType().isSolid()) + { + + ((MultipleFacing) craftBlockData).setFace(blockFace, true); + + final boolean isOtherMultipleFacing = otherData instanceof MultipleFacing; + final boolean materialMatch = otherBlock.getType().equals(xmat.parseMaterial()); + final boolean areBothFence = craftBlockData instanceof Fence && otherData instanceof Fence; + + if (isOtherMultipleFacing && (materialMatch || areBothFence)) + { + final Set otherAllowedFaces = ((MultipleFacing) otherData).getAllowedFaces(); + if (otherAllowedFaces.contains(blockFace.getOppositeFace())) + { + ((MultipleFacing) otherData).setFace(blockFace.getOppositeFace(), true); + otherBlock.setBlockData(otherData); + } + } + } + else + ((MultipleFacing) craftBlockData).setFace(blockFace, false); + }); + this.updateBlockData(); + } + + @Override + public void rotateVerticallyInDirection(DoorDirection openDirection) + { + NMSUtil.rotateVerticallyInDirection(openDirection, craftBlockData); + this.updateBlockData(); + } + + @Override + public void rotateBlockUpDown(boolean ns) + { + EnumDirection.EnumAxis axis = blockData.c(BlockRotatable.g); + EnumDirection.EnumAxis newAxis = axis; + switch (axis) + { + case a: + newAxis = ns ? EnumDirection.EnumAxis.a : EnumDirection.EnumAxis.b; + break; + case b: + newAxis = ns ? EnumDirection.EnumAxis.c : EnumDirection.EnumAxis.a; + break; + case c: + newAxis = ns ? EnumDirection.EnumAxis.b : EnumDirection.EnumAxis.c; + break; + } + blockData = blockData.a(BlockRotatable.g, newAxis); + this.updateCraftBlockData(); + } + + @Override + public void rotateCylindrical(RotateDirection rotDir) + { + if (rotDir.equals(RotateDirection.CLOCKWISE)) + blockData = blockData.a(EnumBlockRotation.b); + else + blockData = blockData.a(EnumBlockRotation.d); + this.updateCraftBlockData(); + } + + /** + * Gets the IBlockData (NMS) of this block. + * + * @return The IBlockData (NMS) of this block. + */ + IBlockData getMyBlockData() + { + return blockData; + } + + @Override + public String toString() + { + return blockData.toString(); + } + + @Override + public void deleteOriginalBlock(boolean applyPhysics) + { + final World world = Objects.requireNonNull(loc.getWorld()); + if (!applyPhysics) + { + world.getBlockAt(loc).setType(Material.AIR, false); + } + else + { + world.getBlockAt(loc).setType(Material.CAVE_AIR, false); + world.getBlockAt(loc).setType(Material.AIR, true); + } + } + + @Override + public Item k() + { + return null; + } + + @Override + protected Block q() + { + return null; + } +} diff --git a/pom.xml b/pom.xml index daf88356d..3566c593c 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 3.4.1 4.9.0 3.0.0-M7 - 9.2.0 + 9.3.1 com.github.cryptomorin