Skip to content

Commit

Permalink
upgrade material half property, use it in other_block, fixes #2065
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Nov 4, 2019
1 parent 78082e1 commit e251d4b
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 40 deletions.
@@ -1,6 +1,7 @@
package com.denizenscript.denizen.objects;

import com.denizenscript.denizen.objects.notable.NotableManager;
import com.denizenscript.denizen.objects.properties.material.MaterialHalf;
import com.denizenscript.denizen.objects.properties.material.MaterialSwitchFace;
import com.denizenscript.denizen.objects.properties.material.MaterialLeaves;
import com.denizenscript.denizen.scripts.commands.world.SwitchCommand;
Expand Down Expand Up @@ -2748,29 +2749,24 @@ else if (attribute.startsWith("vertical", 2)) {
// @attribute <LocationTag.other_block>
// @returns LocationTag
// @description
// If the location is part of a double-block structure
// (double chests, doors, beds, etc), returns the location of the other block in the double-block structure.
// If the location is part of a double-block structure (double chests, double plants, doors, beds, etc),
// returns the location of the other block in the double-block structure.
// You can test if this will be valid with <@link tag MaterialTag.is_bisected>.
// -->
registerTag("other_block", (attribute, object) -> {
BlockState state = object.getBlockStateForTag(attribute);
if (state instanceof Chest
&& NMSHandler.getVersion().isAtLeast(NMSVersion.v1_13)) {
Vector direction = DirectionalBlocksHelper.getFacing(object.getBlockForTag(attribute));
if (DirectionalBlocksHelper.isLeftHalf(object.getBlockForTag(attribute))) {
direction = new Vector(-direction.getZ(), 0, direction.getX());
}
else if (DirectionalBlocksHelper.isRightHalf(object.getBlockForTag(attribute))) {
direction = new Vector(direction.getZ(), 0, -direction.getX());
if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_13)) {
Block b = object.getBlockForTag(attribute);
MaterialTag material = new MaterialTag(b);
if (MaterialHalf.describes(material)) {
return new LocationTag(object.clone().add(MaterialHalf.getFrom(material).getRelativeBlockVector()));
}
else {
if (!attribute.hasAlternative()) {
Debug.echoError("Block is a single-block chest.");
}
return null;
if (!attribute.hasAlternative()) {
Debug.echoError("Block of type " + object.getBlockTypeForTag(attribute).name() + " isn't supported by other_block.");
}
return new LocationTag(object.clone().add(direction));
return null;
}
else if (state instanceof Chest) {
BlockState state = object.getBlockStateForTag(attribute);
if (state instanceof Chest) {
// There is no remotely sane API for this.
InventoryHolder holder = ((Chest) state).getBlockInventory().getHolder();
if (holder instanceof DoubleChest) {
Expand All @@ -2784,16 +2780,6 @@ else if (state instanceof Chest) {
}
}
}
else if (state instanceof Bed
&& NMSHandler.getVersion().isAtLeast(NMSVersion.v1_13)) {
// There's no pre-1.13 API for this *at all*, and the new API isn't very sane, but can be used.
boolean isTop = DirectionalBlocksHelper.isTopHalf(object.getBlockForTag(attribute));
BlockFace direction = DirectionalBlocksHelper.getFace(object.getBlockForTag(attribute));
if (!isTop) {
direction = direction.getOppositeFace();
}
return new LocationTag(object.clone().add(direction.getDirection()));
}
else if (state.getData() instanceof Door) {
if (((Door) state.getData()).isTopHalf()) {
return new LocationTag(object.clone().subtract(0, 1, 0));
Expand Down
Expand Up @@ -522,8 +522,8 @@ public static void registerTags() {
// @returns ElementTag(Boolean)
// @group properties
// @description
// Returns whether the material is a bisected material.
// When this returns true, <@link tag MaterialTag.half>,
// Returns whether the material is a bisected material (doors, beds, double chests, double plants, ...).
// When this returns true, <@link tag MaterialTag.half>, <@link tag MaterialTag.relative_vector>
// and <@link mechanism MaterialTag.half> are accessible.
// -->
registerTag("is_bisected", (attribute, object) -> {
Expand Down
@@ -1,19 +1,36 @@
package com.denizenscript.denizen.objects.properties.material;

import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizen.objects.MaterialTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.Mechanism;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.properties.Property;
import com.denizenscript.denizencore.tags.Attribute;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.type.Bed;
import org.bukkit.block.data.type.Chest;
import org.bukkit.util.Vector;

public class MaterialHalf implements Property {

public static boolean describes(ObjectTag material) {
return material instanceof MaterialTag
&& ((MaterialTag) material).hasModernData()
&& ((MaterialTag) material).getModernData().data instanceof Bisected;
&& isHalfData(((MaterialTag) material).getModernData().data);
}

public static boolean isHalfData(BlockData data) {
if (data instanceof Bisected || data instanceof Bed) {
return true;
}
if (data instanceof Chest && ((Chest) data).getType() != Chest.Type.SINGLE) {
return true;
}
return false;
}

public static MaterialHalf getFrom(ObjectTag _material) {
Expand Down Expand Up @@ -53,23 +70,92 @@ public ObjectTag getObjectAttribute(Attribute attribute) {
// @mechanism MaterialTag.half
// @group properties
// @description
// Returns the current half for a bisected material (like stairs).
// Output is "BOTTOM" or "TOP".
// Returns the current half for a bisected material (like a door, double-plant, chest, or a bed).
// Output for "Bisected" blocks (doors/double plants/...) is "BOTTOM" or "TOP".
// Output for beds is "HEAD" or "FOOT".
// Output for chests is "LEFT" or "RIGHT".
// -->
if (attribute.startsWith("half")) {
return new ElementTag(getBisected().getHalf().name()).getObjectAttribute(attribute.fulfill(1));
return new ElementTag(getHalfName()).getObjectAttribute(attribute.fulfill(1));
}

// <--[tag]
// @attribute <MaterialTag.relative_vector>
// @returns ElementTag
// @mechanism MaterialTag.half
// @group properties
// @description
// Returns a vector location of the other block for a bisected material.
// -->
if (attribute.startsWith("relative_vector")) {
return new LocationTag(getRelativeBlockVector()).getObjectAttribute(attribute.fulfill(1));
}

return null;
}

public Bisected getBisected() {
return (Bisected) material.getModernData().data;
public static String getHalfName(BlockData data) {
if (data instanceof Bisected) {
return ((Bisected) data).getHalf().name();
}
else if (data instanceof Bed) {
return ((Bed) data).getPart().name();
}
else if (data instanceof Chest) {
return ((Chest) data).getType().name();
}
return null;
}

public String getHalfName() {
return getHalfName(material.getModernData().data);
}

public static void setHalfByName(BlockData data, String name) {
if (data instanceof Bisected) {
((Bisected) data).setHalf(Bisected.Half.valueOf(name));
}
else if (data instanceof Bed) {
((Bed) data).setPart(Bed.Part.valueOf(name));
}
else if (data instanceof Chest) {
((Chest) data).setType(Chest.Type.valueOf(name));
}
}

public static Vector getRelativeBlockVector(BlockData data) {
if (data instanceof Bisected) {
if (((Bisected) data).getHalf() == Bisected.Half.TOP) {
return new Vector(0, 0, -1);
}
else {
return new Vector(0, 0, 1);
}
}
else if (data instanceof Bed) {
BlockFace face = ((Directional) data).getFacing();
if (((Bed) data).getPart() == Bed.Part.FOOT) {
face = face.getOppositeFace();
}
return face.getDirection();
}
else if (data instanceof Chest) {
Vector direction = ((Directional) data).getFacing().getDirection();
if (((Chest) data).getType() == Chest.Type.LEFT) {
return new Vector(-direction.getZ(), 0, direction.getX());
}
return new Vector(direction.getZ(), 0, -direction.getX());
}
return null;
}

public Vector getRelativeBlockVector() {
return getRelativeBlockVector(material.getModernData().data);
}

@Override
public String getPropertyString() {
return String.valueOf(getBisected().getHalf());
return getHalfName();
}

@Override
Expand All @@ -85,12 +171,12 @@ public void adjust(Mechanism mechanism) {
// @name half
// @input Element
// @description
// Sets the current half for a bisected material (like stairs).
// Sets the current half for a bisected material (like a door, double-plant, chest, or a bed).
// @tags
// <MaterialTag.half>
// -->
if (mechanism.matches("half") && mechanism.requireEnum(false, Bisected.Half.values())) {
getBisected().setHalf(Bisected.Half.valueOf(mechanism.getValue().asString().toUpperCase()));
if (mechanism.matches("half")) {
setHalfByName(material.getModernData().data, mechanism.getValue().asString().toUpperCase());
}
}
}

0 comments on commit e251d4b

Please sign in to comment.