diff options
author | Raven Szewczyk <git@eigenraven.me> | 2024-05-24 19:50:35 +0100 |
---|---|---|
committer | Raven Szewczyk <git@eigenraven.me> | 2024-05-24 19:50:35 +0100 |
commit | 6d1b2216464d4dad449ac6fcfec476832224a55e (patch) | |
tree | 526a0c15f7056313c80e6c0386e025e9b3f61781 /src/main/java/gtPlusPlus/api/objects | |
parent | b5d35f40afa606ed1b07061dad82e0521a59c186 (diff) | |
download | GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.gz GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.bz2 GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.zip |
Merge addon sources
Diffstat (limited to 'src/main/java/gtPlusPlus/api/objects')
18 files changed, 2148 insertions, 0 deletions
diff --git a/src/main/java/gtPlusPlus/api/objects/Logger.java b/src/main/java/gtPlusPlus/api/objects/Logger.java new file mode 100644 index 0000000000..0178bb141a --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/Logger.java @@ -0,0 +1,162 @@ +package gtPlusPlus.api.objects; + +import org.apache.logging.log4j.LogManager; + +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.preloader.CORE_Preloader; +import gtPlusPlus.preloader.asm.AsmConfig; + +public class Logger { + + public Logger() {} + + // Logging Functions + public static final org.apache.logging.log4j.Logger modLogger = Logger.makeLogger(); + + // Generate GT++ Logger + public static org.apache.logging.log4j.Logger makeLogger() { + final org.apache.logging.log4j.Logger gtPlusPlusLogger = LogManager.getLogger("GT++"); + return gtPlusPlusLogger; + } + + private static final boolean enabled = !AsmConfig.disableAllLogging; + + public static final org.apache.logging.log4j.Logger getLogger() { + return modLogger; + } + + // Non-Dev Comments + public static void INFO(final String s) { + if (enabled) { + modLogger.info(s); + } + } + + // Non-Dev Comments + public static void MACHINE_INFO(String s, Object... args) { + if (enabled) { + boolean localPlayer = CORE_Preloader.DEV_ENVIRONMENT; + if (CORE.ConfigSwitches.MACHINE_INFO || localPlayer) { + final String name1 = gtPlusPlus.core.util.reflect.ReflectionUtils.getMethodName(2); + modLogger.info("Machine Info: " + s + " | " + name1, args); + } + } + } + + // Developer Comments + public static void WARNING(final String s) { + if (enabled) { + if (CORE_Preloader.DEBUG_MODE) { + modLogger.warn(s); + } + } + } + + // Errors + public static void ERROR(final String s) { + if (enabled) { + if (CORE_Preloader.DEBUG_MODE) { + modLogger.fatal(s); + } + } + } + + // Developer Logger + public static void SPECIFIC_WARNING(final String whatToLog, final String msg, final int line) { + if (enabled) { + // if (!CORE_Preloader.DEBUG_MODE){ + FMLLog.warning("GT++ |" + line + "| " + whatToLog + " | " + msg); + // } + } + } + + // ASM Comments + public static void LOG_ASM(final String s) { + if (enabled) { + FMLRelaunchLog.info("[Special ASM Logging] ", s); + } + } + + /** + * Special Loggers + */ + + /** + * Special Logger for Bee related content + */ + public static void BEES(final String s) { + modLogger.info("[Bees] " + s); + } + + /** + * Special Logger for Debugging Bee related content + */ + public static void DEBUG_BEES(final String s) { + if (enabled) { + if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) { + modLogger.info("[Debug][Bees] " + s); + } + } + } + + /** + * Special Logger for Materials related content + */ + public static void MATERIALS(final String s) { + if (enabled) { + if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) { + modLogger.info("[Materials] " + s); + } + } + } + + /** + * Special Logger for Debugging Materials related content + */ + public static void DEBUG_MATERIALS(final String s) { + if (enabled) { + if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) { + modLogger.info("[Debug][Materials] " + s); + } + } + } + + /** + * Special Logger for Reflection related content + */ + public static void REFLECTION(final String s) { + if (enabled) { + if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) { + modLogger.info("[Reflection] " + s); + } + } + } + + /** + * Special Logger for Darkworld related content + */ + public static void WORLD(final String s) { + if (enabled) { + if (CORE_Preloader.DEV_ENVIRONMENT || CORE_Preloader.DEBUG_MODE) { + modLogger.info("[WorldGen] " + s); + } + } + } + + public static void RECIPE(String string) { + if (enabled) { + if ( + /* CORE_Preloader.DEV_ENVIRONMENT || */ CORE_Preloader.DEBUG_MODE) { + modLogger.info("[Recipe] " + string); + } + } + } + + public static void SPACE(final String s) { + if (enabled) { + modLogger.info("[Space] " + s); + } + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/data/AutoMap.java b/src/main/java/gtPlusPlus/api/objects/data/AutoMap.java new file mode 100644 index 0000000000..a3551326c2 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/data/AutoMap.java @@ -0,0 +1,364 @@ +package gtPlusPlus.api.objects.data; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + +public class AutoMap<V> implements Iterable<V>, Cloneable, Serializable, Collection<V>, Queue<V>, List<V> { + + /** + * The Internal Map + */ + protected final Map<Integer, V> mInternalMap; + + protected final Map<String, Integer> mInternalNameMap; + + /** + * The Internal ID + */ + private int mInternalID = 0; + + private static final long serialVersionUID = 3771412318075131790L; + + public AutoMap() { + this(new LinkedHashMap<>()); + } + + public Map<Integer, V> getMap() { + return mInternalMap; + } + + public AutoMap(Map<Integer, V> defaultMapType) { + mInternalMap = defaultMapType; + mInternalNameMap = new LinkedHashMap<>(); + } + + /** + * Generates an AutoMap from the List. + * + * @param aList - Data to be inserted into the AutoMap. + */ + public AutoMap(List<V> aList) { + mInternalMap = new LinkedHashMap<>(); + mInternalNameMap = new LinkedHashMap<>(); + if (aList != null && aList.size() > 0) { + for (V obj : aList) { + add(obj); + } + } + } + + /** + * Generates an AutoMap from a Set. + * + * @param aList - Data to be inserted into the AutoMap. + */ + public AutoMap(Set<V> aList) { + mInternalMap = new LinkedHashMap<>(); + mInternalNameMap = new LinkedHashMap<>(); + if (aList != null && aList.size() > 0) { + for (V obj : aList) { + add(obj); + } + } + } + + /** + * Generates an AutoMap from a Collection. + * + * @param aList - Data to be inserted into the AutoMap. + */ + public AutoMap(Collection<V> aList) { + mInternalMap = new LinkedHashMap<>(); + mInternalNameMap = new LinkedHashMap<>(); + if (aList != null && aList.size() > 0) { + for (V obj : aList) { + add(obj); + } + } + } + + /** + * Generates an AutoMap from a Array. + * + * @param aArray - Data to be inserted into the AutoMap. + */ + public AutoMap(V[] aArray) { + mInternalMap = new LinkedHashMap<>(); + mInternalNameMap = new LinkedHashMap<>(); + if (aArray != null && aArray.length > 0) { + for (V obj : aArray) { + add(obj); + } + } + } + + @Override + public Iterator<V> iterator() { + return values().iterator(); + } + + public synchronized boolean setValue(V object) { + int mOriginalID = this.mInternalID; + put(object); + if (this.mInternalMap.get(mOriginalID) + .equals(object) || mOriginalID > this.mInternalID) { + return true; + } else { + return false; + } + } + + public synchronized V put(V object) { + return set(object); + } + + @Override + public synchronized boolean add(V object) { + return set(object) != null; + } + + public synchronized V set(V object) { + if (object == null) { + return null; + } + mInternalNameMap.put("" + object.hashCode(), (mInternalID + 1)); + return mInternalMap.put(mInternalID++, object); + } + + @Override + public synchronized V get(int id) { + return mInternalMap.get(id); + } + + public synchronized Collection<V> values() { + return mInternalMap.values(); + } + + @Override + public synchronized int size() { + return mInternalMap.size(); + } + + public synchronized int hashCode() { + return mInternalMap.hashCode(); + } + + public synchronized boolean containsKey(int key) { + return mInternalMap.containsKey(key); + } + + public synchronized boolean containsValue(V value) { + return mInternalMap.containsValue(value); + } + + @Override + public synchronized boolean isEmpty() { + return mInternalMap.isEmpty(); + } + + @Override + public synchronized void clear() { + this.mInternalID = 0; + this.mInternalMap.clear(); + this.mInternalNameMap.clear(); + return; + } + + @Override + @SuppressWarnings("unchecked") + public V[] toArray() { + V[] toR = (V[]) java.lang.reflect.Array.newInstance( + mInternalMap.get(0) + .getClass(), + mInternalMap.size()); + for (int i = 0; i < mInternalMap.size(); i++) { + toR[i] = mInternalMap.get(i); + } + return toR; + } + + public final synchronized int getInternalID() { + return mInternalID; + } + + @Override + public final synchronized boolean remove(Object value) { + value.getClass(); + if (this.mInternalMap.containsValue(value)) { + return this.mInternalMap.remove(mInternalNameMap.get("" + value.hashCode()), value); + } + return false; + } + + @Override + public boolean contains(Object o) { + for (V g : this.mInternalMap.values()) { + if (g.equals(o)) { + return true; + } + } + return false; + } + + @SuppressWarnings("unchecked") + @Override + public <V> V[] toArray(V[] a) { + return (V[]) toArray(); + } + + @Override + public boolean containsAll(Collection<?> c) { + boolean aTrue = true; + for (Object g : c) { + if (!this.contains(g)) { + aTrue = false; + } + } + return aTrue; + } + + @Override + public boolean addAll(Collection<? extends V> c) { + boolean aTrue = true; + for (V g : c) { + if (!this.add(g)) { + aTrue = false; + } + } + return aTrue; + } + + @Override + public boolean removeAll(Collection<?> c) { + boolean aTrue = true; + for (Object g : c) { + if (!this.remove(g)) { + aTrue = false; + } + } + return aTrue; + } + + @Override + public boolean retainAll(Collection<?> c) { + AutoMap<?> aTempAllocation = new AutoMap<>(); + boolean aTrue = false; + aTempAllocation = this; + aTempAllocation.removeAll(c); + aTempAllocation.clear(); + aTrue = aTempAllocation.isEmpty(); + aTempAllocation.clear(); + return aTrue; + } + + @Override + public boolean offer(V e) { + return add(e); + } + + @Override + public V remove() { + V y = this.get(0); + if (remove(y)) return y; + else return null; + } + + @Override + public V poll() { + if (this.mInternalMap.isEmpty()) { + return null; + } + return remove(); + } + + @Override + public V element() { + if (this.mInternalMap.isEmpty()) { + return null; + } + return this.get(0); + } + + @Override + public V peek() { + return element(); + } + + @Override + public boolean addAll(int index, Collection<? extends V> c) { + for (V y : c) { + add(y); + } + return true; + } + + @Override + public V set(int index, V element) { + return mInternalMap.put(index, element); + } + + @Override + public void add(int index, V element) { + add(element); + } + + @Override + public V remove(int index) { + V h = mInternalMap.get(index); + set(index, null); + return h; + } + + @Override + public int indexOf(Object o) { + int aCount = 0; + for (V of : mInternalMap.values()) { + if (of != o) { + aCount++; + continue; + } else { + return aCount; + } + } + return -1; + } + + @Override + public int lastIndexOf(Object o) { + // TODO + return indexOf(o); + } + + @Override + public ListIterator<V> listIterator() { + // TODO Auto-generated method stub + return null; + } + + @Override + public ListIterator<V> listIterator(int index) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<V> subList(int fromIndex, int toIndex) { + AutoMap<V> aNewSubList = new AutoMap<>(); + for (int slot = fromIndex; slot <= toIndex; slot++) { + V obj = mInternalMap.get(slot); + if (obj == null) { + continue; + } else { + aNewSubList.put(obj); + } + } + return aNewSubList; + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/data/Pair.java b/src/main/java/gtPlusPlus/api/objects/data/Pair.java new file mode 100644 index 0000000000..93bf075c8f --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/data/Pair.java @@ -0,0 +1,35 @@ +package gtPlusPlus.api.objects.data; + +import java.io.Serializable; + +import com.google.common.base.Objects; + +public class Pair<K, V> implements Serializable { + + /** + * SVUID + */ + private static final long serialVersionUID = 1250550491092812443L; + + private final K key; + private final V value; + + public Pair(final K key, final V value) { + this.key = key; + this.value = value; + } + + public final K getKey() { + return this.key; + } + + public final V getValue() { + return this.value; + } + + @Override + public int hashCode() { + Integer aCode = Objects.hashCode(getKey(), getValue()); + return aCode != null ? aCode : super.hashCode(); + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/data/Quad.java b/src/main/java/gtPlusPlus/api/objects/data/Quad.java new file mode 100644 index 0000000000..a2597061e0 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/data/Quad.java @@ -0,0 +1,44 @@ +package gtPlusPlus.api.objects.data; + +import java.util.ArrayList; +import java.util.List; + +public class Quad<K, V, C, R> { + + private final K key; + private final V value; + private final C value2; + private final R value3; + + public Quad(final K key, final V value, final C value2, final R value3) { + this.key = key; + this.value = value; + this.value2 = value2; + this.value3 = value3; + } + + public final K getKey() { + return this.key; + } + + public final V getValue_1() { + return this.value; + } + + public final C getValue_2() { + return this.value2; + } + + public final R getValue_3() { + return this.value3; + } + + public final List values() { + List<Object> aVals = new ArrayList<>(); + aVals.add(key); + aVals.add(value); + aVals.add(value2); + aVals.add(value3); + return aVals; + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/data/Triplet.java b/src/main/java/gtPlusPlus/api/objects/data/Triplet.java new file mode 100644 index 0000000000..625ec630aa --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/data/Triplet.java @@ -0,0 +1,26 @@ +package gtPlusPlus.api.objects.data; + +public class Triplet<K, V, C> { + + private final K key; + private final V value; + private final C count; + + public Triplet(final K key, final V value, final C value2) { + this.key = key; + this.value = value; + this.count = value2; + } + + public final K getValue_1() { + return this.key; + } + + public final V getValue_2() { + return this.value; + } + + public final C getValue_3() { + return this.count; + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/data/TypeCounter.java b/src/main/java/gtPlusPlus/api/objects/data/TypeCounter.java new file mode 100644 index 0000000000..ea12972af4 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/data/TypeCounter.java @@ -0,0 +1,177 @@ +package gtPlusPlus.api.objects.data; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import gtPlusPlus.api.objects.Logger; + +public class TypeCounter<V> implements Set<V> { + + private Map<String, InternalTypeCounterObject<V>> mInternalMap = new LinkedHashMap<>(); + private String mHighestValueKey; + private int mHighestValue = 0; + private final Class mClass; + + public TypeCounter(Class o) { + Logger.WARNING("Created new TypeCounter for " + o.getName()); + mClass = o; + } + + public static class InternalTypeCounterObject<Z> { + + private final Z mObject; + private int mCounter = 0; + + public InternalTypeCounterObject(Z o) { + mObject = o; + } + + public String hash() { + return String.valueOf(mObject.hashCode()); + } + + public Z get() { + return mObject; + } + + public void add() { + mCounter++; + } + + public int count() { + return mCounter; + } + } + + @Override + public boolean add(V arg0) { + return add(arg0, null); + } + + public boolean add(V arg0, String aKeyName) { + String aKey = aKeyName != null ? aKeyName : arg0.toString(); + InternalTypeCounterObject<V> aValue = mInternalMap.get(aKey); + if (aValue == null) { + aValue = new InternalTypeCounterObject<>((V) arg0); + Logger.WARNING("Adding new key to map: " + aKey); + } + aValue.add(); + int a = aValue.count(); + if (a > mHighestValue) { + mHighestValue = a; + mHighestValueKey = aKey; + Logger.WARNING("New Highest Count - " + aKey + ":" + a); + } + mInternalMap.put(aKey, aValue); + Logger.WARNING(aKey + ":" + a); + return true; + } + + @Override + public boolean addAll(Collection arg0) { + boolean aReturn = true; + for (Object o : arg0) { + if (mClass.isInstance(o)) { + V j = (V) o; + boolean b = add(j); + if (!b) { + aReturn = false; + } + } + } + return aReturn; + } + + @Override + public void clear() { + mInternalMap.clear(); + } + + @Override + public boolean contains(Object arg0) { + return mInternalMap.containsKey(arg0.toString()); + } + + @Override + public boolean containsAll(Collection arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isEmpty() { + return mInternalMap.isEmpty(); + } + + @Override + public Iterator iterator() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean remove(Object arg0) { + InternalTypeCounterObject<V> aValue = mInternalMap.remove(arg0.toString()); + if (aValue != null) { + return true; + } else { + return false; + } + } + + @Override + public boolean removeAll(Collection arg0) { + boolean aReturn = true; + for (Object o : arg0) { + boolean a = remove(o); + if (!a) { + aReturn = false; + } + } + return aReturn; + } + + @Override + public boolean retainAll(Collection arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public int size() { + return this.mInternalMap.size(); + } + + @Override + public Object[] toArray() { + Object[] aArray = new Object[this.mInternalMap.size()]; + int aPos = 0; + for (String k : this.mInternalMap.keySet()) { + if (k != null) { + InternalTypeCounterObject<V> aVal = this.mInternalMap.get(k); + aArray[aPos++] = new Pair<>(k, aVal); + } + } + return aArray; + } + + @Override + public V[] toArray(Object[] a) { + Object[] aArray = new Object[a.length]; + int aPos = 0; + for (Object k : a) { + if (k != null) { + aArray[aPos++] = k; + } + } + return (V[]) aArray; + } + + public V getResults() { + InternalTypeCounterObject<V> x = mInternalMap.get(mHighestValueKey); + return x.get(); + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/data/WeightedCollection.java b/src/main/java/gtPlusPlus/api/objects/data/WeightedCollection.java new file mode 100644 index 0000000000..5d99097169 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/data/WeightedCollection.java @@ -0,0 +1,102 @@ +package gtPlusPlus.api.objects.data; + +import java.util.Collection; +import java.util.Map; +import java.util.NavigableMap; +import java.util.Random; +import java.util.Set; +import java.util.TreeMap; + +import gregtech.api.objects.XSTR; + +public class WeightedCollection<E> implements Map<Integer, E> { + + private NavigableMap<Integer, E> map = new TreeMap<>(); + private Random random; + private int total = 0; + + public WeightedCollection() { + this(new XSTR()); + } + + public WeightedCollection(Random random) { + this.random = random; + } + + public E add(int weight, E object) { + if (weight <= 0) return null; + total += weight; + return map.put(total, object); + } + + private E next() { + int value = random.nextInt(total) + 1; // Can also use floating-point weights + return map.ceilingEntry(value) + .getValue(); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return map.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return map.containsValue(value); + } + + public E get() { + return next(); + } + + @Override + public E get(Object key) { + return next(); + } + + @Override + public void putAll(Map m) { + map.putAll(m); + } + + @Override + public void clear() { + map.clear(); + this.total = 0; + } + + @Override + public Set keySet() { + return map.keySet(); + } + + @Override + public Collection values() { + return map.values(); + } + + @Override + public Set entrySet() { + return map.entrySet(); + } + + @Override + public E put(Integer key, E value) { + return add(key, value); + } + + @Override + public E remove(Object key) { + return map.remove(key); + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/data/weakref/WeakAutoMap.java b/src/main/java/gtPlusPlus/api/objects/data/weakref/WeakAutoMap.java new file mode 100644 index 0000000000..199d20e06a --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/data/weakref/WeakAutoMap.java @@ -0,0 +1,14 @@ +package gtPlusPlus.api.objects.data.weakref; + +import java.util.WeakHashMap; + +import gtPlusPlus.api.objects.data.AutoMap; + +public class WeakAutoMap<T> extends AutoMap<T> { + + private static final long serialVersionUID = 8328345351801363386L; + + public WeakAutoMap() { + super(new WeakHashMap<>()); + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/AABB.java b/src/main/java/gtPlusPlus/api/objects/minecraft/AABB.java new file mode 100644 index 0000000000..e516f12ddd --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/AABB.java @@ -0,0 +1,67 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraft.entity.Entity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +import gtPlusPlus.core.util.minecraft.EntityUtils; + +/** + * Generates an AABB around an entity. + * + * @author Alkalus + * + */ +public class AABB { + + private final AxisAlignedBB mAabb; + private final World mWorld; + + /** + * Creates a AxisAlignedBB based around an Entity. + * + * @param aEntity - The Entity to work with. + * @param x - Maximum X from origin. + * @param y - Maximum Y from origin. + * @param z - Maximum Z from origin. + */ + public AABB(Entity aEntity, int x, int y, int z) { + if (aEntity == null) { + mAabb = null; + mWorld = null; + } else { + mWorld = aEntity.worldObj; + BlockPos aEntityLocation = EntityUtils.findBlockPosUnderEntity(aEntity); + int xMin, xMax, yMin, yMax, zMin, zMax; + xMin = aEntityLocation.xPos; + yMin = aEntityLocation.yPos; + zMin = aEntityLocation.zPos; + xMax = aEntityLocation.xPos + x; + yMax = aEntityLocation.yPos + y; + zMax = aEntityLocation.zPos + z; + mAabb = AxisAlignedBB.getBoundingBox(xMin, yMin, zMin, xMax, yMax, zMax); + } + } + + /** + * Used to get the AxisAlignedBB from this class. + * + * @return + */ + public AxisAlignedBB get() { + return mAabb; + } + + /** + * Used to determine if this object is valid or not. + * + * @return + */ + public boolean valid() { + return mAabb != null && mWorld != null; + } + + public World world() { + return mWorld; + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/BTF_FluidTank.java b/src/main/java/gtPlusPlus/api/objects/minecraft/BTF_FluidTank.java new file mode 100644 index 0000000000..13f12503f0 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/BTF_FluidTank.java @@ -0,0 +1,185 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidTankInfo; + +public class BTF_FluidTank extends FluidTank { + + public FluidStack mFluid; + + public BTF_FluidTank(int capacity) { + super(capacity); + } + + /** + * Let's replace the Default handling with GT's own handling code, because it's probably better, right? + * + * @author Alkalus/GregoriusT + */ + @Override + public FluidStack getFluid() { + return this.getDrainableStack(); + } + + @Override + public int getFluidAmount() { + return this.getDrainableStack() != null ? this.getDrainableStack().amount : 0; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound aNBT) { + super.writeToNBT(aNBT); + if (this.mFluid != null) { + aNBT.setTag("mFluid", this.mFluid.writeToNBT(new NBTTagCompound())); + } + return aNBT; + } + + @Override + public FluidTank readFromNBT(NBTTagCompound aNBT) { + this.mFluid = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid")); + return this; + } + + /* + * public abstract boolean isLiquidInput(byte arg0); public abstract boolean isLiquidOutput(byte arg0); public + * abstract boolean doesFillContainers(); public abstract boolean doesEmptyContainers(); + */ + + public boolean canTankBeFilled() { + return true; + } + + public boolean canTankBeEmptied() { + return true; + } + + public boolean isFluidInputAllowed(FluidStack aFluid) { + return true; + } + + public FluidStack getFillableStack() { + return this.mFluid; + } + + public FluidStack setFillableStack(FluidStack aFluid) { + this.mFluid = aFluid; + return this.mFluid; + } + + public FluidStack getDrainableStack() { + return this.mFluid; + } + + public FluidStack setDrainableStack(FluidStack aFluid) { + this.mFluid = aFluid; + return this.mFluid; + } + + public boolean isFluidChangingAllowed() { + return true; + } + + @Override + public int fill(FluidStack aFluid, boolean doFill) { + if (aFluid != null && aFluid.getFluid() + .getID() > 0 && aFluid.amount > 0 && this.canTankBeFilled() && this.isFluidInputAllowed(aFluid)) { + if (this.getFillableStack() != null && this.getFillableStack() + .getFluid() + .getID() > 0) { + if (!this.getFillableStack() + .isFluidEqual(aFluid)) { + return 0; + } else { + int space = this.getCapacity() - this.getFillableStack().amount; + if (aFluid.amount <= space) { + if (doFill) { + FluidStack arg9999 = this.getFillableStack(); + arg9999.amount += aFluid.amount; + } + + return aFluid.amount; + } else { + if (doFill) { + this.getFillableStack().amount = this.getCapacity(); + } + + return space; + } + } + } else if (aFluid.amount <= this.getCapacity()) { + if (doFill) { + this.setFillableStack(aFluid.copy()); + } + + return aFluid.amount; + } else { + if (doFill) { + this.setFillableStack(aFluid.copy()); + this.getFillableStack().amount = this.getCapacity(); + } + + return this.getCapacity(); + } + } else { + return 0; + } + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (this.getDrainableStack() != null && this.canTankBeEmptied()) { + if (this.getDrainableStack().amount <= 0 && this.isFluidChangingAllowed()) { + this.setDrainableStack((FluidStack) null); + return null; + } else { + int used = maxDrain; + if (this.getDrainableStack().amount < maxDrain) { + used = this.getDrainableStack().amount; + } + + if (doDrain) { + FluidStack arg9999 = this.getDrainableStack(); + arg9999.amount -= used; + } + + FluidStack drained = this.getDrainableStack() + .copy(); + drained.amount = used; + if (this.getDrainableStack().amount <= 0 && this.isFluidChangingAllowed()) { + this.setDrainableStack((FluidStack) null); + } + + return drained; + } + } else { + return null; + } + } + + @Override + public int getCapacity() { + return super.getCapacity(); + } + + @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(this); + } + + @Override + public void setFluid(FluidStack fluid) { + setFillableStack(fluid); + } + + @Override + public void setCapacity(int capacity) { + super.setCapacity(capacity); + } + + public FluidStack drain(FluidStack aFluid, boolean doDrain) { + return drain(aFluid.amount, doDrain); + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/BTF_Inventory.java b/src/main/java/gtPlusPlus/api/objects/minecraft/BTF_Inventory.java new file mode 100644 index 0000000000..fc71869d9e --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/BTF_Inventory.java @@ -0,0 +1,231 @@ +package gtPlusPlus.api.objects.minecraft; + +import java.util.ArrayList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.util.GT_Utility; +import gregtech.common.covers.CoverInfo; +import gtPlusPlus.core.tileentities.base.TileEntityBase; +import gtPlusPlus.core.util.data.ArrayUtils; + +public class BTF_Inventory implements ISidedInventory { + + public final ItemStack[] mInventory; + public final TileEntityBase mTile; + + public BTF_Inventory(int aSlots, TileEntityBase tile) { + this.mInventory = new ItemStack[aSlots]; + this.mTile = tile; + } + + public ItemStack[] getRealInventory() { + purgeNulls(); + return this.mInventory; + } + + @Override + public int getSizeInventory() { + return this.mInventory.length; + } + + @Override + public ItemStack getStackInSlot(int aIndex) { + return aIndex >= 0 && aIndex < this.mInventory.length ? this.mInventory[aIndex] : null; + } + + @Override + public void setInventorySlotContents(int aIndex, ItemStack aStack) { + if (aIndex >= 0 && aIndex < this.mInventory.length) { + this.mInventory[aIndex] = aStack; + } + } + + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + public boolean isValidSlot(int aIndex) { + return true; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + public boolean setStackToZeroInsteadOfNull(int aIndex) { + return false; + } + + @Override + public boolean isItemValidForSlot(int aIndex, ItemStack aStack) { + return isValidSlot(aIndex); + } + + @Override + public ItemStack decrStackSize(int aIndex, int aAmount) { + ItemStack tStack = this.getStackInSlot(aIndex); + ItemStack rStack = GT_Utility.copy(new Object[] { tStack }); + if (tStack != null) { + if (tStack.stackSize <= aAmount) { + if (this.setStackToZeroInsteadOfNull(aIndex)) { + tStack.stackSize = 0; + } else { + this.setInventorySlotContents(aIndex, (ItemStack) null); + } + } else { + rStack = tStack.splitStack(aAmount); + if (tStack.stackSize == 0 && !this.setStackToZeroInsteadOfNull(aIndex)) { + this.setInventorySlotContents(aIndex, (ItemStack) null); + } + } + } + + return rStack; + } + + @Override + public int[] getAccessibleSlotsFromSide(int ordinalSide) { + final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide); + ArrayList<Integer> tList = new ArrayList<>(); + CoverInfo coverInfo = this.mTile.getCoverInfoAtSide(side); + boolean tSkip = coverInfo.letsItemsIn(-2) || coverInfo.letsItemsIn(-2); + + for (int rArray = 0; rArray < this.getSizeInventory(); ++rArray) { + if (this.isValidSlot(rArray) + && (tSkip || coverInfo.letsItemsOut(rArray) || coverInfo.letsItemsIn(rArray))) { + tList.add(rArray); + } + } + + int[] arg6 = new int[tList.size()]; + + for (int i = 0; i < arg6.length; ++i) { + arg6[i] = tList.get(i); + } + + return arg6; + } + + @Override + public boolean canInsertItem(int aIndex, ItemStack aStack, int ordinalSide) { + return this.isValidSlot(aIndex) && aStack != null + && aIndex < this.mInventory.length + && (this.mInventory[aIndex] == null || GT_Utility.areStacksEqual(aStack, this.mInventory[aIndex])) + && this.allowPutStack(this.mTile, aIndex, ForgeDirection.getOrientation(ordinalSide), aStack); + } + + @Override + public boolean canExtractItem(int aIndex, ItemStack aStack, int ordinalSide) { + return this.isValidSlot(aIndex) && aStack != null + && aIndex < this.mInventory.length + && this.allowPullStack(this.mTile, aIndex, ForgeDirection.getOrientation(ordinalSide), aStack); + } + + public boolean allowPullStack(TileEntityBase mTile2, int aIndex, ForgeDirection side, ItemStack aStack) { + return aIndex >= 0 && aIndex < this.getSizeInventory(); + } + + public boolean allowPutStack(TileEntityBase aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return (aIndex >= 0 && aIndex < this.getSizeInventory()) + && (this.mInventory[aIndex] == null || GT_Utility.areStacksEqual(this.mInventory[aIndex], aStack)); + } + + @Override + public ItemStack getStackInSlotOnClosing(int i) { + return null; + } + + @Override + public final boolean hasCustomInventoryName() { + return mTile != null ? mTile.hasCustomInventoryName() : false; + } + + @Override + public void markDirty() { + if (mTile != null) { + purgeNulls(); + mTile.markDirty(); + } + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public void openInventory() {} + + @Override + public void closeInventory() {} + + @Override + public final String getInventoryName() { + return this.mTile != null ? mTile.getInventoryName() : ""; + } + + public boolean isFull() { + for (int s = 0; s < this.getSizeInventory(); s++) { + ItemStack slot = mInventory[s]; + if (slot == null || slot.stackSize != slot.getMaxStackSize()) { + return false; + } + } + return true; + } + + public boolean isEmpty() { + for (int s = 0; s < this.getSizeInventory(); s++) { + ItemStack slot = mInventory[s]; + if (slot == null) { + continue; + } else { + return false; + } + } + return true; + } + + public boolean addItemStack(ItemStack aInput) { + if (aInput != null & (isEmpty() || !isFull())) { + for (int s = 0; s < this.getSizeInventory(); s++) { + if (mInventory != null && mInventory[s] != null) { + ItemStack slot = mInventory[s]; + if (slot == null || (slot != null && GT_Utility.areStacksEqual(aInput, slot) + && slot.stackSize != slot.getItem() + .getItemStackLimit(slot))) { + if (slot == null) { + slot = aInput.copy(); + } else { + slot.stackSize++; + } + this.setInventorySlotContents(s, slot); + return true; + } + } + } + } + return false; + } + + public final void purgeNulls() { + ItemStack[] aTemp = ArrayUtils.removeNulls(this.mInventory); + for (int g = 0; g < this.getSizeInventory(); g++) { + if (aTemp.length < this.getSizeInventory()) { + if (g <= aTemp.length - 1) { + this.mInventory[g] = aTemp[g]; + } else { + this.mInventory[g] = null; + } + } else { + this.mInventory[g] = aTemp[g]; + } + } + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/BlockPos.java b/src/main/java/gtPlusPlus/api/objects/minecraft/BlockPos.java new file mode 100644 index 0000000000..3853f61793 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/BlockPos.java @@ -0,0 +1,245 @@ +package gtPlusPlus.api.objects.minecraft; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +import net.minecraft.block.Block; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.DimensionManager; + +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gtPlusPlus.api.objects.data.AutoMap; + +public class BlockPos implements Serializable { + + private static final long serialVersionUID = -7271947491316682006L; + public final int xPos; + public final int yPos; + public final int zPos; + public final int dim; + public final transient World world; + + public static BlockPos generateBlockPos(String sUUID) { + String[] s2 = sUUID.split("@"); + return new BlockPos(s2); + } + + public BlockPos(String[] s) { + this(Integer.parseInt(s[1]), Integer.parseInt(s[2]), Integer.parseInt(s[3]), Integer.parseInt(s[0])); + } + + public BlockPos(int x, int y, int z) { + this(x, y, z, 0); + } + + public BlockPos(int x, int y, int z, int dim) { + this(x, y, z, DimensionManager.getWorld(dim)); + } + + public BlockPos(int x, int y, int z, World dim) { + this.xPos = x; + this.yPos = y; + this.zPos = z; + + if (dim != null) { + this.dim = dim.provider.dimensionId; + this.world = dim; + } else { + this.dim = 0; + this.world = null; + } + } + + public BlockPos(IGregTechTileEntity b) { + this(b.getXCoord(), b.getYCoord(), b.getZCoord(), b.getWorld()); + } + + public BlockPos(TileEntity b) { + this(b.xCoord, b.yCoord, b.zCoord, b.getWorldObj()); + } + + public String getLocationString() { + return "[X: " + this.xPos + "][Y: " + this.yPos + "][Z: " + this.zPos + "][Dim: " + this.dim + "]"; + } + + public String getUniqueIdentifier() { + String S = "" + this.dim + "@" + this.xPos + "@" + this.yPos + "@" + this.zPos; + return S; + } + + @Override + public int hashCode() { + int hash = 5; + hash += (13 * this.xPos); + hash += (19 * this.yPos); + hash += (31 * this.zPos); + hash += (17 * this.dim); + return hash; + } + + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (other == this) { + return true; + } + if (!(other instanceof BlockPos otherPoint)) { + return false; + } + return this.xPos == otherPoint.xPos && this.yPos == otherPoint.yPos + && this.zPos == otherPoint.zPos + && this.dim == otherPoint.dim; + } + + public int distanceFrom(BlockPos target) { + if (target.dim != this.dim) { + return Short.MIN_VALUE; + } + return distanceFrom(target.xPos, target.yPos, target.zPos); + } + + /** + * + * @param x X coordinate of target. + * @param y Y coordinate of target. + * @param z Z coordinate of target. + * @return square of distance + */ + public int distanceFrom(int x, int y, int z) { + int distanceX = this.xPos - x; + int distanceY = this.yPos - y; + int distanceZ = this.zPos - z; + return distanceX * distanceX + distanceY * distanceY + distanceZ * distanceZ; + } + + public boolean isWithinRange(BlockPos target, int range) { + if (target.dim != this.dim) { + return false; + } + return isWithinRange(target.xPos, target.yPos, target.zPos, range); + } + + public boolean isWithinRange(int x, int y, int z, int range) { + return distanceFrom(x, y, z) <= (range * range); + } + + public BlockPos getUp() { + return new BlockPos(this.xPos, this.yPos + 1, this.zPos, this.dim); + } + + public BlockPos getDown() { + return new BlockPos(this.xPos, this.yPos - 1, this.zPos, this.dim); + } + + public BlockPos getXPos() { + return new BlockPos(this.xPos + 1, this.yPos, this.zPos, this.dim); + } + + public BlockPos getXNeg() { + return new BlockPos(this.xPos - 1, this.yPos, this.zPos, this.dim); + } + + public BlockPos getZPos() { + return new BlockPos(this.xPos, this.yPos, this.zPos + 1, this.dim); + } + + public BlockPos getZNeg() { + return new BlockPos(this.xPos, this.yPos, this.zPos - 1, this.dim); + } + + public AutoMap<BlockPos> getSurroundingBlocks() { + AutoMap<BlockPos> sides = new AutoMap<>(); + sides.put(getUp()); + sides.put(getDown()); + sides.put(getXPos()); + sides.put(getXNeg()); + sides.put(getZPos()); + sides.put(getZNeg()); + return sides; + } + + public Block getBlockAtPos() { + return getBlockAtPos(this); + } + + public Block getBlockAtPos(BlockPos pos) { + return getBlockAtPos(world, pos); + } + + public Block getBlockAtPos(World world, BlockPos pos) { + return world.getBlock(pos.xPos, pos.yPos, pos.zPos); + } + + public int getMetaAtPos() { + return getMetaAtPos(this); + } + + public int getMetaAtPos(BlockPos pos) { + return getMetaAtPos(world, pos); + } + + public int getMetaAtPos(World world, BlockPos pos) { + return world.getBlockMetadata(pos.xPos, pos.yPos, pos.zPos); + } + + public boolean hasSimilarNeighbour() { + return hasSimilarNeighbour(false); + } + + /** + * @param strict - Does this check Meta Data? + * @return - Does this block have a neighbour that is the same? + */ + public boolean hasSimilarNeighbour(boolean strict) { + for (BlockPos g : getSurroundingBlocks().values()) { + if (getBlockAtPos(g) == getBlockAtPos()) { + if (!strict) { + return true; + } else { + if (getMetaAtPos() == getMetaAtPos(g)) { + return true; + } + } + } + } + return false; + } + + public AutoMap<BlockPos> getSimilarNeighbour() { + return getSimilarNeighbour(false); + } + + /** + * @param strict - Does this check Meta Data? + * @return - Does this block have a neighbour that is the same? + */ + public AutoMap<BlockPos> getSimilarNeighbour(boolean strict) { + AutoMap<BlockPos> sides = new AutoMap<>(); + for (BlockPos g : getSurroundingBlocks().values()) { + if (getBlockAtPos(g) == getBlockAtPos()) { + if (!strict) { + sides.put(g); + } else { + if (getMetaAtPos() == getMetaAtPos(g)) { + sides.put(g); + } + } + } + } + return sides; + } + + public Set<BlockPos> getValidNeighboursAndSelf() { + AutoMap<BlockPos> h = getSimilarNeighbour(true); + h.put(this); + Set<BlockPos> result = new HashSet<>(); + for (BlockPos f : h.values()) { + result.add(f); + } + return result; + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/CubicObject.java b/src/main/java/gtPlusPlus/api/objects/minecraft/CubicObject.java new file mode 100644 index 0000000000..5620b76895 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/CubicObject.java @@ -0,0 +1,56 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraftforge.common.util.ForgeDirection; + +import gtPlusPlus.api.objects.data.AutoMap; + +public class CubicObject<T> { + + public final T NORTH; + public final T SOUTH; + + public final T WEST; + public final T EAST; + + public final T UP; + public final T DOWN; + + public CubicObject(AutoMap<T> aDataSet) { + this(aDataSet.get(0), aDataSet.get(1), aDataSet.get(2), aDataSet.get(3), aDataSet.get(4), aDataSet.get(5)); + } + + public CubicObject(T[] aDataSet) { + this(aDataSet[0], aDataSet[1], aDataSet[2], aDataSet[3], aDataSet[4], aDataSet[5]); + } + + public CubicObject(T aDOWN, T aUP, T aNORTH, T aSOUTH, T aWEST, T aEAST) { + DOWN = aDOWN; + UP = aUP; + NORTH = aNORTH; + SOUTH = aSOUTH; + WEST = aWEST; + EAST = aEAST; + } + + public T get(int ordinalSide) { + return get(ForgeDirection.getOrientation(ordinalSide)); + } + + public T get(ForgeDirection side) { + if (side == ForgeDirection.DOWN) { + return DOWN; + } else if (side == ForgeDirection.UP) { + return UP; + } else if (side == ForgeDirection.NORTH) { + return NORTH; + } else if (side == ForgeDirection.SOUTH) { + return SOUTH; + } else if (side == ForgeDirection.WEST) { + return WEST; + } else if (side == ForgeDirection.EAST) { + return EAST; + } else { + return null; + } + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/FluidGT6.java b/src/main/java/gtPlusPlus/api/objects/minecraft/FluidGT6.java new file mode 100644 index 0000000000..c5c903cd1f --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/FluidGT6.java @@ -0,0 +1,33 @@ +package gtPlusPlus.api.objects.minecraft; + +import static gregtech.api.enums.Mods.GTPlusPlus; + +import net.minecraftforge.fluids.Fluid; + +import gregtech.api.GregTech_API; + +public class FluidGT6 extends Fluid implements Runnable { + + private final short[] mRGBa; + public final String mTextureName; + + public FluidGT6(final String aName, final String aTextureName, final short[] aRGBa) { + super(aName); + this.mRGBa = aRGBa; + this.mTextureName = aTextureName; + if (GregTech_API.sGTBlockIconload != null) { + GregTech_API.sGTBlockIconload.add(this); + } + } + + @Override + public int getColor() { + return (Math.max(0, Math.min(255, this.mRGBa[0])) << 16) | (Math.max(0, Math.min(255, this.mRGBa[1])) << 8) + | Math.max(0, Math.min(255, this.mRGBa[2])); + } + + @Override + public void run() { + this.setIcons(GregTech_API.sBlockIcons.registerIcon(GTPlusPlus.ID + ":" + "fluids/fluid." + this.mTextureName)); + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/ItemPackage.java b/src/main/java/gtPlusPlus/api/objects/minecraft/ItemPackage.java new file mode 100644 index 0000000000..d68ef1a93f --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/ItemPackage.java @@ -0,0 +1,57 @@ +package gtPlusPlus.api.objects.minecraft; + +import cpw.mods.fml.common.event.FMLLoadCompleteEvent; +import gtPlusPlus.api.interfaces.RunnableWithInfo; +import gtPlusPlus.core.handler.COMPAT_HANDLER; + +public abstract class ItemPackage implements RunnableWithInfo<String> { + + public ItemPackage() { + this(false); + } + + public ItemPackage(boolean hasExtraLateRun) { + // Register for late run + COMPAT_HANDLER.mObjectsToRunInPostInit.put(this); + if (hasExtraLateRun) { + COMPAT_HANDLER.mObjectsToRunInOnLoadComplete.put(this); + } + init(); + } + + @Override + public final void run() { + generateRecipes(); + } + + @Override + public final String getInfoData() { + return errorMessage(); + } + + public abstract String errorMessage(); + + public abstract boolean generateRecipes(); + + private void init() { + items(); + blocks(); + fluids(); + } + + public abstract void items(); + + public abstract void blocks(); + + public abstract void fluids(); + + /** + * Override this to handle GT Recipe map manipulation after they're Baked. + * + * @param event - the {@link FMLLoadCompleteEvent}. + * @return - Did we do anything? + */ + public boolean onLoadComplete(FMLLoadCompleteEvent event) { + return false; + }; +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/ItemStackData.java b/src/main/java/gtPlusPlus/api/objects/minecraft/ItemStackData.java new file mode 100644 index 0000000000..f5e483b91c --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/ItemStackData.java @@ -0,0 +1,34 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import gtPlusPlus.core.util.minecraft.ItemUtils; + +public class ItemStackData { + + protected final Item mItem; + protected final int mDamage; + protected final int mStackSize; + protected final NBTTagCompound mNBT; + protected final String mUniqueDataTag; + + public ItemStackData(ItemStack aStack) { + mItem = aStack.getItem(); + mDamage = aStack.getItemDamage(); + mStackSize = aStack.stackSize; + mNBT = (aStack.getTagCompound() != null ? aStack.getTagCompound() : new NBTTagCompound()); + mUniqueDataTag = "" + Item.getIdFromItem(mItem) + "" + mDamage + "" + mStackSize + "" + mNBT.getId(); + } + + public String getUniqueDataIdentifier() { + return this.mUniqueDataTag; + } + + public ItemStack getStack() { + ItemStack aTemp = ItemUtils.simpleMetaStack(mItem, mDamage, mStackSize); + aTemp.setTagCompound(mNBT); + return aTemp; + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/SafeTexture.java b/src/main/java/gtPlusPlus/api/objects/minecraft/SafeTexture.java new file mode 100644 index 0000000000..58a7affa90 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/SafeTexture.java @@ -0,0 +1,65 @@ +package gtPlusPlus.api.objects.minecraft; + +import java.util.HashMap; + +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTech_API; +import gtPlusPlus.core.util.Utils; + +/** + * A Server Side safe object that can hold {@link IIcon}s. + * + * @author Alkalus + * + */ +public class SafeTexture implements Runnable { + + @SideOnly(Side.CLIENT) + private static final HashMap<Integer, IIcon> mHashToIconCache = new HashMap<>(); + + @SideOnly(Side.CLIENT) + private static final HashMap<String, Integer> mPathToHashCash = new HashMap<>(); + + private static final HashMap<String, SafeTexture> mTextureObjectCache = new HashMap<>(); + + private final int mHash; + + private final String mTextureName; + + private static String getKey(String aTexPath) { + String aNameKey = Utils.sanitizeString(aTexPath); + aNameKey = aNameKey.replace('/', ' '); + aNameKey = aNameKey.toLowerCase(); + return aNameKey; + } + + public static SafeTexture register(String aTexturePath) { + String aNameKey = getKey(aTexturePath); + SafeTexture g = mTextureObjectCache.get(aNameKey); + if (g == null) { + g = new SafeTexture(aTexturePath); + mTextureObjectCache.put(aNameKey, g); + mPathToHashCash.put(aTexturePath, aTexturePath.hashCode()); + } + return g; + } + + private SafeTexture(String aTexturePath) { + mTextureName = aTexturePath; + mHash = getKey(aTexturePath).hashCode(); + GregTech_API.sGTBlockIconload.add(this); + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return mHashToIconCache.get(mHash); + } + + @Override + public void run() { + mHashToIconCache.put(getKey(mTextureName).hashCode(), GregTech_API.sBlockIcons.registerIcon(mTextureName)); + } +} diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/ShapedRecipe.java b/src/main/java/gtPlusPlus/api/objects/minecraft/ShapedRecipe.java new file mode 100644 index 0000000000..f799623dd6 --- /dev/null +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/ShapedRecipe.java @@ -0,0 +1,251 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.ShapedOreRecipe; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.AutoMap; +import gtPlusPlus.api.objects.data.Pair; +import gtPlusPlus.core.util.minecraft.ItemUtils; + +public class ShapedRecipe { + + private static final String CHARS = "abcdefghijklmnop"; + public ShapedOreRecipe mRecipe; + + ItemStack[] mBlackList = null; + + public ShapedRecipe(Object aInput1, Object aInput2, Object aInput3, Object aInput4, Object aInput5, Object aInput6, + Object aInput7, Object aInput8, Object aInput9, ItemStack aOutput) { + + this(new Object[] { aInput1, aInput2, aInput3, aInput4, aInput5, aInput6, aInput7, aInput8, aInput9 }, aOutput); + } + + public ShapedRecipe(Object[] aInputs, ItemStack aOutput) { + String aGridWhole = ""; + String aGrid[] = new String[3]; + char[] aChar = new char[9]; + String[] aLoggingInfo = new String[9]; + + if (mBlackList == null) { + mBlackList = new ItemStack[] {}; + } + + // Just to be safe + try { + int xSlot = 0; + int xNull = 0; + for (Object u : aInputs) { + String mInfo = ""; + if (u instanceof String) { + mInfo = (String) u; + Logger.RECIPE("Input slot " + xSlot++ + " contains " + mInfo); + } else if (u instanceof ItemStack || u instanceof Item) { + if (u instanceof Item) { + u = ItemUtils.getSimpleStack((Item) u); + } + mInfo = ((ItemStack) u).getDisplayName(); + Logger.RECIPE("Input slot " + xSlot++ + " contains " + mInfo); + } else if (u == null) { + xNull++; + } + } + Logger.RECIPE("Found " + xNull + " null inputs."); + // Check if the output is invalid + if (aOutput != null && xNull < 9) { + + for (ItemStack q : mBlackList) { + if (q != null) { + if (q.isItemEqual(aOutput)) { + Logger.RECIPE("Found recipe Alkalus is Debugging."); + } + } + } + + Object[] mVarags2 = null; + Logger.RECIPE("Generating Shaped Crafting Recipe for " + aOutput.getDisplayName()); + + if (aInputs.length < 9 || aInputs.length > 9) { + Logger.RECIPE( + "[Fix] Recipe for " + aOutput.getDisplayName() + + " has incorrect number of inputs. Size: " + + aInputs.length + + "."); + } + + // Build a Pair for each slot + AutoMap<Pair<Character, Object>> aRecipePairs = new AutoMap<>(); + int aCharSlot = 0; + int aMemSlot = 0; + int aInfoSlot = 0; + for (Object stack : aInputs) { + if (stack != null) { + String mInfo = ""; + if (stack instanceof String) { + mInfo = (String) stack; + } else if (stack instanceof ItemStack || stack instanceof Item) { + if (stack instanceof Item) { + stack = ItemUtils.getSimpleStack((Item) stack); + } + mInfo = ((ItemStack) stack).getDisplayName(); + } + aRecipePairs.put(new Pair<>(CHARS.charAt(aCharSlot), stack)); + Logger.RECIPE( + "Storing '" + CHARS.charAt(aCharSlot) + + "' with an object of type " + + stack.getClass() + .getSimpleName() + + " and a value of " + + mInfo); + aChar[aMemSlot++] = CHARS.charAt(aCharSlot); + aCharSlot++; + aLoggingInfo[aInfoSlot++] = mInfo; + } else { + aRecipePairs.put(new Pair<>(' ', (ItemStack) null)); + Logger.RECIPE("Storing ' ' with an object of type null"); + aChar[aMemSlot++] = ' '; + aLoggingInfo[aInfoSlot++] = "Empty"; + } + } + + Logger.RECIPE(aRecipePairs.size() + " Char|Object pairs registered for recipe."); + // If we have enough valid slots, iterate them and build a String which represents the entire grid. + // If this String is the correct length, we will split it into thirds and build the grid String array. + if (aRecipePairs.size() == 9) { + + for (Pair<Character, Object> h : aRecipePairs) { + if (h.getKey() != null) { + aGridWhole += String.valueOf(h.getKey()); + Logger.RECIPE("Adding '" + String.valueOf(h.getKey()) + "' to aGridWhole."); + } + } + + Logger.RECIPE("aGridWhole: " + aGridWhole + " | size: " + aGridWhole.length()); + + // Build crafting grid + if (aGridWhole.length() == 9) { + Logger.RECIPE("aGridWhole size == 9"); + aGrid[0] = "" + aGridWhole.charAt(0) + aGridWhole.charAt(1) + aGridWhole.charAt(2); + aGrid[1] = "" + aGridWhole.charAt(3) + aGridWhole.charAt(4) + aGridWhole.charAt(5); + aGrid[2] = "" + aGridWhole.charAt(6) + aGridWhole.charAt(7) + aGridWhole.charAt(8); + } else { + Logger.RECIPE( + "[Fix] Grid length for recipe outputting " + aOutput.getDisplayName() + " is not 9."); + } + + // Rebuild the Map without spaces + aRecipePairs.clear(); + aCharSlot = 0; + + // The amount of spaces in the Varags that the Shape strings takes. + // Currently they are inserted as a single array into index 0. + final int KEY_COUNTER = 1; + + int counter = KEY_COUNTER; + for (Object stack : aInputs) { + if (stack != null) { + String mInfo = ""; + if (stack instanceof String) { + mInfo = (String) stack; + } else if (stack instanceof ItemStack || stack instanceof Item) { + if (stack instanceof Item) { + stack = ItemUtils.getSimpleStack((Item) stack); + } + mInfo = ((ItemStack) stack).getDisplayName(); + } + aRecipePairs.put(new Pair<>(CHARS.charAt(aCharSlot), stack)); + Logger.RECIPE( + "Registering Pair of '" + CHARS.charAt(aCharSlot) + + "' and a " + + stack.getClass() + .getSimpleName() + + " object. Object has a value of " + + mInfo); + aCharSlot++; + counter++; + } + } + + Logger.RECIPE( + "Counter started at " + KEY_COUNTER + + ", counter is now at " + + counter + + ". Trying to create Varag array with a size of " + + (KEY_COUNTER + (counter - KEY_COUNTER) * 2)); + // Counter started at 3, counter is now at 4. Trying to create Varag array with a size of 2 + + // Register the shaped grid straight to the varags + mVarags2 = new Object[(KEY_COUNTER + (counter - KEY_COUNTER) * 2)]; + /* + * mVarags2[0] = aGrid[0]; mVarags2[1] = aGrid[1]; mVarags2[2] = aGrid[2]; + */ + mVarags2[0] = aGrid; + + // Add Each Char, then Item to the varags, sequentially. + int counter2 = KEY_COUNTER; + for (Pair<Character, Object> r : aRecipePairs) { + char c = r.getKey(); + Object o = r.getValue(); + + if (o instanceof ItemStack || o instanceof Item) { + if (o instanceof Item) { + o = ItemUtils.getSimpleStack((Item) o); + } + o = ((ItemStack) o).copy(); + } + + mVarags2[counter2] = (char) c; + mVarags2[counter2 + 1] = o; + counter2 += 2; + } + + Logger.RECIPE("Recipe Summary"); + Logger.RECIPE("+ = + = + = +"); + Logger.RECIPE("= " + aChar[0] + " = " + aChar[1] + " = " + aChar[2] + " ="); + Logger.RECIPE("+ = + = + = +"); + Logger.RECIPE("= " + aChar[3] + " = " + aChar[4] + " = " + aChar[5] + " ="); + Logger.RECIPE("+ = + = + = +"); + Logger.RECIPE("= " + aChar[6] + " = " + aChar[7] + " = " + aChar[8] + " ="); + Logger.RECIPE("+ = + = + = +"); + for (int r = 0; r < 9; r++) { + if (aChar[r] != ' ') { + Logger.RECIPE("" + aChar[r] + " : " + aLoggingInfo[r]); + } + } + + } else { + Logger.RECIPE( + "[Fix] Recipe for " + aOutput.getDisplayName() + " contains a strange number of inputs."); + } + + // Try set the recipe for this object. + ShapedOreRecipe testRecipe = null; + try { + testRecipe = new ShapedOreRecipe(aOutput, mVarags2); + } catch (Throwable t) { + Logger.RECIPE("[Fix][0] Error thrown when making a ShapedOreRecipe object."); + t.printStackTrace(); + } + if (testRecipe == null) { + this.mRecipe = null; + Logger.RECIPE("[Fix] Failed to generate a shaped recipe."); + } else { + this.mRecipe = testRecipe; + Logger.RECIPE("Generated a shaped recipe successfully."); + } + } + + // Output was not valid + else { + this.mRecipe = null; + Logger.RECIPE("[Fix] Failed to generate a shaped recipe. Output was not valid."); + } + + } catch (Throwable t) { + this.mRecipe = null; + Logger.RECIPE("[Fix][1] Error thrown when making a ShapedOreRecipe object."); + t.printStackTrace(); + } + } +} |