Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add block/meta and item/meta pair classes #98

Merged
merged 12 commits into from
Jan 9, 2025
83 changes: 83 additions & 0 deletions src/main/java/com/gtnewhorizon/gtnhlib/util/data/BlockMeta.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.gtnewhorizon.gtnhlib.util.data;

import java.util.Objects;

import javax.annotation.Nonnull;

import net.minecraft.block.Block;

/**
* A mutable implementation of {@link ImmutableBlockMeta}. If your API should return a mutable pair, return this
* instead. Must follow the same contracts as the immutable version if this is ever upcast to a
* {@link ImmutableBlockMeta} in your API. If this type is exposed instead of the immutable interface, assume that the
* contained values can change.
*/
public class BlockMeta implements ImmutableBlockMeta {
YannickMG marked this conversation as resolved.
Show resolved Hide resolved

@Nonnull
private Block block;
private int meta;

public BlockMeta(@Nonnull Block block, int meta) {
this.block = block;
this.meta = meta;
}

public BlockMeta(@Nonnull Block block) {
this(block, 0);
}

@Override
@Nonnull
public Block getBlock() {
return block;
}

@Override
public int getBlockMeta() {
return meta;
}

/**
* Note: see the header comment in {@link ImmutableBlockMeta} for this method's contract.
*/
public BlockMeta setBlock(@Nonnull Block block) {
this.block = Objects.requireNonNull(block);

return this;
}

/**
* Note: see the header comment in {@link ImmutableBlockMeta} for this method's contract.
*/
public BlockMeta setBlockMeta(int meta) {
this.meta = meta;

return this;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + block.hashCode();
result = prime * result + meta;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
BlockMeta other = (BlockMeta) obj;
if (!block.equals(other.block)) return false;
if (meta != other.meta) return false;
return true;
}

@Override
public String toString() {
return "BlockMeta [block=" + block + ", meta=" + meta + "]";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.gtnewhorizon.gtnhlib.util.data;

import java.util.function.Supplier;

import net.minecraft.block.Block;

/**
* A supplier that provides an Block. This is its own type because superclasses save their generics, allowing the JVM to
* differentiate between functional interfaces at runtime. Without this interface, two methods overloads that accept a
* Supplier with different generics but an otherwise identical method signature would cause a compilation error.
*/
@FunctionalInterface
public interface BlockSupplier extends Supplier<Block> {

}
15 changes: 15 additions & 0 deletions src/main/java/com/gtnewhorizon/gtnhlib/util/data/IMod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.gtnewhorizon.gtnhlib.util.data;

/**
* An interface for any mod enums. Represents a mod.
*/
public interface IMod {

boolean isModLoaded();

/** Gets the mod id. */
String getID();

/** Gets the mod's resource location prefix. */
String getResourceLocation();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.gtnewhorizon.gtnhlib.util.data;

import javax.annotation.Nonnull;

import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraftforge.oredict.OreDictionary;

/**
* An immutable block-meta pair. This must not be cast down to its mutable version unless you have a very good reason.
* It can be assumed that the values of {@link #getBlock()} and {@link #getBlockMeta()} will never change for this
* object if the object is exposed through an API.
*/
public interface ImmutableBlockMeta {

/**
* The value of this must not change while this object is exposed via an API.
*
* @return The block stored in this pair.
*/
@Nonnull
public Block getBlock();

/**
* The value of this must not change while this object is exposed via an API.
*
* @return The block's metadata stored in this pair. May be {@link OreDictionary#WILDCARD_VALUE}.
*/
public int getBlockMeta();

/**
* Gets the corresponding item for this block. Subclasses may provide a faster implementation.
*/
public default Item getItem() {
return Item.getItemFromBlock(getBlock());
}

/**
* Checks if this pair matches the given block & meta.
*
* @param block The block.
* @param meta The meta. If this parameter or {@link #getBlockMeta()} equals {@link OreDictionary#WILDCARD_VALUE}
* then meta checks are ignored.
* @return Whether this pair matches or not.
*/
public default boolean matches(Block block, int meta) {
return getBlock() == block
&& (meta == OreDictionary.WILDCARD_VALUE || getBlockMeta() == OreDictionary.WILDCARD_VALUE
|| getBlockMeta() == meta);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.gtnewhorizon.gtnhlib.util.data;

import javax.annotation.Nonnull;

import net.minecraft.block.Block;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;

/**
* An immutable item-meta pair. This must not be cast down to its mutable version unless you have a very good reason. It
* can be assumed that the values of {@link #getItem()} and {@link #getItemMeta()} will never change for this object if
* the object is exposed through an API.
*/
public interface ImmutableItemMeta {

/**
* The value of this must not change while this object is exposed via an API.
*
* @return The item stored in this pair.
*/
@Nonnull
public Item getItem();

/**
* The value of this must not change while this object is exposed via an API.
*
* @return The item's metadata stored in this pair. May be {@link OreDictionary#WILDCARD_VALUE}.
*/
public int getItemMeta();

/**
* Gets the corresponding block for this item. Subclasses may provide a faster implementation.
*/
public default Block getBlock() {
return Block.getBlockFromItem(getItem());
}

/**
* Checks if this pair matches the given ItemStack's item and metadata.
*/
public default boolean matches(ItemStack stack) {
if (stack == null) return false;

return matches(stack.getItem(), Items.feather.getDamage(stack));
}

/**
* Checks if this pair matches the given item & meta.
*
* @param Item The item.
* @param meta The meta. If this parameter or {@link #getItemMeta()} equals {@link OreDictionary#WILDCARD_VALUE}
* then meta checks are ignored.
* @return Whether this pair matches or not.
*/
public default boolean matches(Item item, int meta) {
return getItem() == item
&& (meta == OreDictionary.WILDCARD_VALUE || getItemMeta() == OreDictionary.WILDCARD_VALUE
|| getItemMeta() == meta);
}

/** Converts this pair to an ItemStack. */
public default ItemStack toStack(int amount) {
int meta = getItemMeta();

return new ItemStack(getItem(), amount, meta == OreDictionary.WILDCARD_VALUE ? 0 : meta);
}
}
82 changes: 82 additions & 0 deletions src/main/java/com/gtnewhorizon/gtnhlib/util/data/ItemMeta.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.gtnewhorizon.gtnhlib.util.data;

import java.util.Objects;

import javax.annotation.Nonnull;

import net.minecraft.item.Item;

/**
* A mutable implementation of {@link ImmutableItemMeta}. If your API should return a mutable pair, return this instead.
* Must follow the same contracts as the immutable version if this is ever upcast to a {@link ImmutableItemMeta} in your
* API. If this type is exposed instead of the immutable interface, assume that the contained values can change.
*/
public class ItemMeta implements ImmutableItemMeta {

@Nonnull
private Item item;
private int meta;

public ItemMeta(@Nonnull Item item, int meta) {
this.item = item;
this.meta = meta;
}

public ItemMeta(@Nonnull Item item) {
this(item, 0);
}

@Override
@Nonnull
public Item getItem() {
return item;
}

@Override
public int getItemMeta() {
return meta;
}

/**
* Note: see the header comment in {@link ImmutableItemMeta} for this method's contract.
*/
public ItemMeta setItem(@Nonnull Item item) {
this.item = Objects.requireNonNull(item);

return this;
}

/**
* Note: see the header comment in {@link ImmutableItemMeta} for this method's contract.
*/
public ItemMeta setItemMeta(int meta) {
this.meta = meta;

return this;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + item.hashCode();
result = prime * result + meta;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
ItemMeta other = (ItemMeta) obj;
if (!item.equals(other.item)) return false;
if (meta != other.meta) return false;
return true;
}

@Override
public String toString() {
return "ItemMeta [item=" + item + ", meta=" + meta + "]";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.gtnewhorizon.gtnhlib.util.data;

import java.util.function.Supplier;

import net.minecraft.item.ItemStack;

/**
* A supplier that provides an ItemStack. This is its own type because superclasses save their generics, allowing the
* JVM to differentiate between functional interfaces at runtime. Without this interface, two methods overloads that
* accept a Supplier with different generics but an otherwise identical method signature would cause a compilation
* error.
*/
@FunctionalInterface
public interface ItemStackSupplier extends Supplier<ItemStack> {

}
15 changes: 15 additions & 0 deletions src/main/java/com/gtnewhorizon/gtnhlib/util/data/ItemSupplier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.gtnewhorizon.gtnhlib.util.data;

import java.util.function.Supplier;

import net.minecraft.item.Item;

/**
* A supplier that provides an Item. This is its own type because superclasses save their generics, allowing the JVM to
* differentiate between functional interfaces at runtime. Without this interface, two methods overloads that accept a
* Supplier with different generics but an otherwise identical method signature would cause a compilation error.
*/
@FunctionalInterface
public interface ItemSupplier extends Supplier<Item> {

}
Loading