187 lines
6.4 KiB
Java
187 lines
6.4 KiB
Java
/*
|
|
* This file is part of Applied Energistics 2.
|
|
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
|
*
|
|
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
*/
|
|
|
|
package appeng.util.item;
|
|
|
|
import java.util.Objects;
|
|
|
|
import com.google.common.base.Preconditions;
|
|
|
|
import net.minecraft.item.Item;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.CompoundNBT;
|
|
|
|
import appeng.api.config.FuzzyMode;
|
|
|
|
final class AESharedItemStack implements Comparable<AESharedItemStack> {
|
|
private final ItemStack itemStack;
|
|
private final int itemId;
|
|
private final int itemDamage;
|
|
private final int hashCode;
|
|
|
|
public AESharedItemStack(final ItemStack itemStack) {
|
|
this.itemStack = itemStack;
|
|
this.itemId = Item.getIdFromItem(itemStack.getItem());
|
|
this.itemDamage = itemStack.getDamage();
|
|
this.hashCode = this.makeHashCode();
|
|
}
|
|
|
|
Bounds getBounds(final FuzzyMode fuzzy) {
|
|
return new Bounds(this.itemStack, fuzzy);
|
|
}
|
|
|
|
ItemStack getDefinition() {
|
|
return this.itemStack;
|
|
}
|
|
|
|
int getItemDamage() {
|
|
return this.itemDamage;
|
|
}
|
|
|
|
int getItemID() {
|
|
return this.itemId;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return this.hashCode;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(final Object obj) {
|
|
if (obj instanceof AESharedItemStack) {
|
|
final AESharedItemStack other = (AESharedItemStack) obj;
|
|
|
|
Preconditions.checkState(this.itemStack.getCount() == 1, "ItemStack#getCount() has to be 1");
|
|
Preconditions.checkArgument(other.getDefinition().getCount() == 1, "ItemStack#getCount() has to be 1");
|
|
|
|
if (this.itemStack == other.itemStack) {
|
|
return true;
|
|
}
|
|
return ItemStack.areItemStacksEqual(this.itemStack, other.itemStack);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public int compareTo(final AESharedItemStack b) {
|
|
Preconditions.checkState(this.itemStack.getCount() == 1, "ItemStack#getCount() has to be 1");
|
|
Preconditions.checkArgument(b.getDefinition().getCount() == 1, "ItemStack#getCount() has to be 1");
|
|
|
|
if (this.itemStack == b.getDefinition()) {
|
|
return 0;
|
|
}
|
|
|
|
final int id = this.itemId - b.itemId;
|
|
if (id != 0) {
|
|
return id;
|
|
}
|
|
|
|
final int damageValue = this.itemDamage - b.itemDamage;
|
|
if (damageValue != 0) {
|
|
return damageValue;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private int makeHashCode() {
|
|
return Objects.hash(this.itemId, this.itemDamage, this.itemStack.hasTag() ? this.itemStack.getTag() : 0);
|
|
}
|
|
|
|
/**
|
|
* Creates the lower and upper bounds for a specific shared itemstack.
|
|
*/
|
|
public static final class Bounds {
|
|
/**
|
|
* Bounds enforced by {@link ItemStack#isEmpty()}
|
|
*/
|
|
private static final int MIN_DAMAGE_VALUE = 0;
|
|
private static final int MAX_DAMAGE_VALUE = Short.MAX_VALUE;
|
|
|
|
private final AESharedItemStack lower;
|
|
private final AESharedItemStack upper;
|
|
|
|
public Bounds(final ItemStack stack, final FuzzyMode fuzzy) {
|
|
Preconditions.checkState(!stack.isEmpty(), "ItemStack#isEmpty() has to be false");
|
|
Preconditions.checkState(stack.getCount() == 1, "ItemStack#getCount() has to be 1");
|
|
|
|
final CompoundNBT tag = stack.hasTag() ? stack.getTag() : null;
|
|
|
|
this.lower = this.makeLowerBound(stack, tag, fuzzy);
|
|
this.upper = this.makeUpperBound(stack, tag, fuzzy);
|
|
}
|
|
|
|
public AESharedItemStack lower() {
|
|
return this.lower;
|
|
}
|
|
|
|
public AESharedItemStack upper() {
|
|
return this.upper;
|
|
}
|
|
|
|
private AESharedItemStack makeLowerBound(final ItemStack itemStack, final CompoundNBT tag,
|
|
final FuzzyMode fuzzy) {
|
|
final ItemStack newDef = itemStack.copy();
|
|
|
|
if (newDef.getItem().isDamageable()) {
|
|
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
|
newDef.setDamage(MIN_DAMAGE_VALUE);
|
|
} else if (fuzzy == FuzzyMode.PERCENT_99) {
|
|
if (itemStack.getDamage() == MIN_DAMAGE_VALUE) {
|
|
newDef.setDamage(MIN_DAMAGE_VALUE);
|
|
} else {
|
|
newDef.setDamage(MIN_DAMAGE_VALUE + 1);
|
|
}
|
|
} else {
|
|
final int breakpoint = fuzzy.calculateBreakPoint(itemStack.getMaxDamage());
|
|
final int damage = breakpoint <= itemStack.getDamage() ? breakpoint : 0;
|
|
newDef.setDamage(damage);
|
|
}
|
|
}
|
|
|
|
return new AESharedItemStack(newDef);
|
|
}
|
|
|
|
private AESharedItemStack makeUpperBound(final ItemStack itemStack, final CompoundNBT tag,
|
|
final FuzzyMode fuzzy) {
|
|
final ItemStack newDef = itemStack.copy();
|
|
|
|
if (newDef.getItem().isDamageable()) {
|
|
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
|
newDef.setDamage(itemStack.getMaxDamage() + 1);
|
|
} else if (fuzzy == FuzzyMode.PERCENT_99) {
|
|
if (itemStack.getDamage() == MIN_DAMAGE_VALUE) {
|
|
newDef.setDamage(MIN_DAMAGE_VALUE);
|
|
} else {
|
|
newDef.setDamage(itemStack.getMaxDamage() + 1);
|
|
}
|
|
} else {
|
|
final int breakpoint = fuzzy.calculateBreakPoint(itemStack.getMaxDamage());
|
|
final int damage = itemStack.getDamage() < breakpoint ? breakpoint - 1
|
|
: itemStack.getMaxDamage() + 1;
|
|
newDef.setDamage(damage);
|
|
}
|
|
}
|
|
|
|
return new AESharedItemStack(newDef);
|
|
}
|
|
|
|
}
|
|
}
|