feat: use ProjectE EMC registry if installed

This commit is contained in:
Timo Ley 2022-12-02 12:36:58 +01:00
parent c4637fff54
commit a56eba3482
32 changed files with 1057 additions and 43 deletions

View File

@ -1,8 +1,10 @@
package com.pahimar.ee3;
import com.pahimar.ee3.api.exchange.IEnergyValueRegistry;
import com.pahimar.ee3.array.AlchemyArrayRegistry;
import com.pahimar.ee3.blacklist.BlacklistRegistry;
import com.pahimar.ee3.command.CommandEE;
import com.pahimar.ee3.exchange.EMCRegistry;
import com.pahimar.ee3.exchange.EnergyValueRegistry;
import com.pahimar.ee3.handler.*;
import com.pahimar.ee3.init.*;
@ -21,6 +23,8 @@ import com.pahimar.ee3.util.FluidHelper;
import com.pahimar.ee3.util.LogHelper;
import com.pahimar.ee3.util.SerializationHelper;
import com.pahimar.ee3.util.TileEntityDataHelper;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
@ -28,6 +32,8 @@ import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.*;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import moze_intel.projecte.api.ProjectEAPI;
import moze_intel.projecte.api.proxy.IEMCProxy;
import java.io.File;
@ -40,6 +46,8 @@ public class EquivalentExchange3
@SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.SERVER_PROXY_CLASS)
public static IProxy proxy;
public static IEnergyValueRegistry REGISTRY;
@EventHandler
public void invalidFingerprint(FMLFingerprintViolationEvent event) {
@ -63,6 +71,13 @@ public class EquivalentExchange3
@EventHandler
public void preInit(FMLPreInitializationEvent event) {
if (Loader.isModLoaded("ProjectE")) {
IEMCProxy proxy = ProjectEAPI.getEMCProxy();
REGISTRY = new EMCRegistry(proxy);
} else {
REGISTRY = EnergyValueRegistry.INSTANCE;
}
ConfigurationHandler.init(event.getSuggestedConfigurationFile());
Files.init(event);
@ -142,9 +157,9 @@ public class EquivalentExchange3
}
}
public EnergyValueRegistry getEnergyValueRegistry()
public IEnergyValueRegistry getEnergyValueRegistry()
{
return EnergyValueRegistry.INSTANCE;
return REGISTRY;
}
public RecipeRegistry getRecipeRegistry()

View File

@ -14,34 +14,23 @@ public final class EnergyValueRegistryProxy {
@Mod.Instance("EE3")
private static Object ee3Mod;
@Deprecated
public static Map<WrappedStack, EnergyValue> getPreCalculationEnergyValues() {
return getEnergyValues(Phase.PRE_CALCULATION);
}
@Deprecated
public static Map<WrappedStack, EnergyValue> getPostCalculationEnergyValues() {
return getEnergyValues(Phase.POST_CALCULATION);
}
@Deprecated
public static Map<WrappedStack, EnergyValue> getEnergyValues() {
return getEnergyValues(Phase.ALL);
}
@Deprecated
public static Map<WrappedStack, EnergyValue> getEnergyValues(Phase phase) {
init();
if (ee3Mod != null) {
if (phase == Phase.PRE_ASSIGNMENT || phase == Phase.PRE_CALCULATION) {
EE3Wrapper.ee3mod.getEnergyValueRegistry().getPreCalculationStackValueMap();
}
else if (phase == Phase.POST_ASSIGNMENT || phase == Phase.POST_CALCULATION) {
EE3Wrapper.ee3mod.getEnergyValueRegistry().getPostCalculationStackValueMap();
}
else if (phase == Phase.ALL) {
EE3Wrapper.ee3mod.getEnergyValueRegistry().getEnergyValues();
}
}
return null;
}
@ -91,10 +80,12 @@ public final class EnergyValueRegistryProxy {
return null;
}
@Deprecated
public static List getStacksInRange(Number start, Number finish) {
return getStacksInRange(start, finish);
}
@Deprecated
public static List getStacksInRange(EnergyValue start, EnergyValue finish) {
init();

View File

@ -0,0 +1,21 @@
package com.pahimar.ee3.api.exchange;
import java.util.Set;
import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy.Phase;
import net.minecraft.item.ItemStack;
public interface IEnergyValueRegistry {
boolean hasEnergyValue(Object object, boolean strict);
EnergyValue getEnergyValue(Object object, boolean strict);
EnergyValue getEnergyValueForStack(Object object, boolean strict);
Set<ItemStack> getStacksInRange(EnergyValue start, EnergyValue finish);
void setEnergyValue(Object object, EnergyValue energyValue, Phase phase);
}

View File

@ -0,0 +1,81 @@
package com.pahimar.ee3.exchange;
import java.util.Set;
import com.pahimar.ee3.api.exchange.EnergyValue;
import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy.Phase;
import moze_intel.projecte.api.proxy.IEMCProxy;
import com.pahimar.ee3.api.exchange.IEnergyValueRegistry;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class EMCRegistry implements IEnergyValueRegistry {
public static EMCRegistry INSTANCE = null;
private IEMCProxy emc;
public EMCRegistry(IEMCProxy proxy) {
emc = proxy;
}
@Override
public boolean hasEnergyValue(Object object, boolean strict) {
WrappedStack wrapped = WrappedStack.wrap(object);
if (wrapped == null) return false;
object = wrapped.getWrappedObject();
if (object instanceof Item) {
return emc.hasValue((Item) object);
} else if (object instanceof ItemStack) {
return emc.hasValue((ItemStack) object);
} else if (object instanceof Block) {
return emc.hasValue((Block) object);
}
return false;
}
@Override
public EnergyValue getEnergyValue(Object object, boolean strict) {
WrappedStack wrapped = WrappedStack.wrap(object);
if (wrapped == null) return null;
object = wrapped.getWrappedObject();
if (object instanceof Item) {
return new EnergyValue(emc.getValue((Item) object));
} else if (object instanceof ItemStack) {
return new EnergyValue(emc.getValue((ItemStack) object));
} else if (object instanceof Block) {
return new EnergyValue(emc.getValue((Block) object));
}
return null;
}
@Override
public EnergyValue getEnergyValueForStack(Object object, boolean strict) {
WrappedStack wrapped = WrappedStack.wrap(object);
if (wrapped == null) return null;
EnergyValue value = getEnergyValue(object, strict);
if (value == null) return null;
return new EnergyValue(wrapped.getStackSize() * value.getValue());
}
@Override
public Set<ItemStack> getStacksInRange(EnergyValue start, EnergyValue finish) {
return null;
}
@Override
public void setEnergyValue(Object object, EnergyValue energyValue, Phase phase) {
if (phase != Phase.PRE_CALCULATION) return;
if (object instanceof Item) {
emc.registerCustomEMC(new ItemStack((Item) object), (int) energyValue.getValue());
} else if (object instanceof ItemStack) {
emc.registerCustomEMC((ItemStack) object, (int) energyValue.getValue());
} else if (object instanceof Block) {
emc.registerCustomEMC(new ItemStack((Block) object), (int) energyValue.getValue());
}
}
}

View File

@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableSortedMap;
import com.pahimar.ee3.api.event.EnergyValueEvent;
import com.pahimar.ee3.api.exchange.EnergyValue;
import com.pahimar.ee3.api.exchange.IEnergyValueProvider;
import com.pahimar.ee3.api.exchange.IEnergyValueRegistry;
import com.pahimar.ee3.handler.ConfigurationHandler;
import com.pahimar.ee3.recipe.RecipeRegistry;
import com.pahimar.ee3.reference.Comparators;
@ -28,7 +29,7 @@ import java.util.stream.Collectors;
import static com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy.Phase;
public class EnergyValueRegistry {
public class EnergyValueRegistry implements IEnergyValueRegistry {
public static final EnergyValueRegistry INSTANCE = new EnergyValueRegistry();
@ -486,10 +487,10 @@ public class EnergyValueRegistry {
if (valueMap != null) {
if (energyValueBound != null) {
if (isUpperBound) {
return FilterUtils.filterByEnergyValue(valueMap, itemStacks, energyValueBound, FilterUtils.ValueFilterType.VALUE_LOWER_THAN_BOUND, Comparators.ENERGY_VALUE_ITEM_STACK_COMPARATOR);
return FilterUtils.filterByEnergyValue(itemStacks, energyValueBound, FilterUtils.ValueFilterType.VALUE_LOWER_THAN_BOUND, Comparators.ENERGY_VALUE_ITEM_STACK_COMPARATOR);
}
else {
return FilterUtils.filterByEnergyValue(valueMap, itemStacks, energyValueBound, FilterUtils.ValueFilterType.VALUE_GREATER_THAN_BOUND, Comparators.ENERGY_VALUE_ITEM_STACK_COMPARATOR);
return FilterUtils.filterByEnergyValue(itemStacks, energyValueBound, FilterUtils.ValueFilterType.VALUE_GREATER_THAN_BOUND, Comparators.ENERGY_VALUE_ITEM_STACK_COMPARATOR);
}
}
}

View File

@ -2,6 +2,8 @@ package com.pahimar.ee3.init;
import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy;
import com.pahimar.ee3.exchange.OreStack;
import cpw.mods.fml.common.Loader;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
@ -16,6 +18,22 @@ public class EnergyValues {
public static void init() {
/* Equivalent Exchange 3 */
/**
* Alchemical Dusts
*/
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.alchemicalDust, 1, 0), 1, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.alchemicalDust, 1, 1), 64, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.alchemicalDust, 1, 2), 2048, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.alchemicalDust, 1, 3), 8192, Phase.PRE_CALCULATION);
/**
* Minium Shard
*/
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.shardMinium), 8192, Phase.PRE_CALCULATION);
if (Loader.isModLoaded("ProjectE")) return;
// OreDictionary assignment
EnergyValueRegistryProxy.setEnergyValue(new OreStack("cobblestone"), 1, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(new OreStack("dustRedstone"), 32, Phase.PRE_CALCULATION);
@ -153,19 +171,5 @@ public class EnergyValues {
EnergyValueRegistryProxy.setEnergyValue(Items.nether_star, 24576, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(Items.netherbrick, 1, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(Items.quartz, 256, Phase.PRE_CALCULATION);
/* Equivalent Exchange 3 */
/**
* Alchemical Dusts
*/
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.alchemicalDust, 1, 0), 1, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.alchemicalDust, 1, 1), 64, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.alchemicalDust, 1, 2), 2048, Phase.PRE_CALCULATION);
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.alchemicalDust, 1, 3), 8192, Phase.PRE_CALCULATION);
/**
* Minium Shard
*/
EnergyValueRegistryProxy.setEnergyValue(new ItemStack(ModItems.shardMinium), 8192, Phase.PRE_CALCULATION);
}
}

View File

@ -7,7 +7,7 @@ public class Reference
public static final String MOD_NAME = "Equivalent Exchange 3";
public static final String FINGERPRINT = "@FINGERPRINT@";
public static final String MOD_VERSION = "@MOD_VERSION@";
public static final String DEPENDENCIES = "required-after:Forge@[10.13.3,)";
public static final String DEPENDENCIES = "required-after:Forge@[10.13.3,);after:ProjectE";
public static final String SERVER_PROXY_CLASS = "com.pahimar.ee3.proxy.ServerProxy";
public static final String CLIENT_PROXY_CLASS = "com.pahimar.ee3.proxy.ClientProxy";
public static final String GUI_FACTORY_CLASS = "com.pahimar.ee3.client.gui.GuiFactory";

View File

@ -1,8 +1,7 @@
package com.pahimar.ee3.util;
import com.pahimar.ee3.api.exchange.EnergyValue;
import com.pahimar.ee3.exchange.EnergyValueRegistry;
import com.pahimar.ee3.exchange.WrappedStack;
import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy;
import com.pahimar.ee3.reference.Comparators;
import net.minecraft.item.ItemStack;
@ -62,14 +61,10 @@ public class FilterUtils {
}
public static Set<ItemStack> filterByEnergyValue(Collection<ItemStack> itemStacks, Number valueBound, ValueFilterType filterType, Comparator comparator) {
return filterByEnergyValue(EnergyValueRegistry.INSTANCE.getEnergyValues(), itemStacks, new EnergyValue(valueBound.floatValue()), filterType, comparator);
return filterByEnergyValue(itemStacks, new EnergyValue(valueBound.floatValue()), filterType, comparator);
}
public static Set<ItemStack> filterByEnergyValue(Collection<ItemStack> itemStacks, EnergyValue valueBound, ValueFilterType filterType, Comparator comparator) {
return filterByEnergyValue(EnergyValueRegistry.INSTANCE.getEnergyValues(), itemStacks, valueBound, filterType, comparator);
}
public static Set<ItemStack> filterByEnergyValue(Map<WrappedStack, EnergyValue> valueMap, Collection<ItemStack> itemStacks, EnergyValue valueBound, ValueFilterType filterType, Comparator comparator) {
Set<ItemStack> filteredSet = (comparator != null ? new TreeSet<>(comparator) : new TreeSet<>(Comparators.DISPLAY_NAME_COMPARATOR));
@ -81,7 +76,7 @@ public class FilterUtils {
else {
for (ItemStack itemStack : itemStacks) {
EnergyValue energyValue = EnergyValueRegistry.INSTANCE.getEnergyValue(valueMap, itemStack, false);
EnergyValue energyValue = EnergyValueRegistryProxy.getEnergyValue(itemStack, false);
if (energyValue != null && Float.compare(energyValue.getValue(), 0) > 0) {
if (filterType == ValueFilterType.VALUE_LOWER_THAN_BOUND && energyValue.compareTo(valueBound) <= 0) {

View File

@ -0,0 +1,97 @@
package moze_intel.projecte.api;
import cpw.mods.fml.common.FMLLog;
import moze_intel.projecte.api.proxy.IEMCProxy;
import moze_intel.projecte.api.proxy.IBlacklistProxy;
import moze_intel.projecte.api.proxy.IConversionProxy;
import moze_intel.projecte.api.proxy.ITransmutationProxy;
public final class ProjectEAPI
{
private static IEMCProxy emcProxy;
private static ITransmutationProxy transProxy;
private static IBlacklistProxy blacklistProxy;
private static IConversionProxy recipeProxy;
private ProjectEAPI() {}
/**
* Retrieves the proxy for EMC-based API queries.
* @return The proxy for EMC-based API queries
*/
public static IEMCProxy getEMCProxy()
{
if (emcProxy == null)
{
try
{
Class<?> clazz = Class.forName("moze_intel.projecte.impl.EMCProxyImpl");
emcProxy = (IEMCProxy) clazz.getField("instance").get(null);
} catch (ReflectiveOperationException ex)
{
FMLLog.warning("[ProjectEAPI] Error retrieving EMCProxyImpl, ProjectE may be absent, damaged, or outdated.");
}
}
return emcProxy;
}
/**
* Retrieves the proxy for EMC-Recipe-Calculation-based API queries.
* @return The proxy for EMC-Recipe-Calculation-based API queries
*/
public static IConversionProxy getConversionProxy()
{
if (recipeProxy == null)
{
try
{
Class<?> clazz = Class.forName("moze_intel.projecte.impl.ConversionProxyImpl");
recipeProxy = (IConversionProxy) clazz.getField("instance").get(null);
} catch (ReflectiveOperationException ex)
{
FMLLog.warning("[ProjectEAPI] Error retrieving ConversionProxyImpl, ProjectE may be absent, damaged, or outdated.");
}
}
return recipeProxy;
}
/**
* Retrieves the proxy for Transmutation-based API queries.
* @return The proxy for Transmutation-based API queries
*/
public static ITransmutationProxy getTransmutationProxy()
{
if (transProxy == null)
{
try
{
Class<?> clazz = Class.forName("moze_intel.projecte.impl.TransmutationProxyImpl");
transProxy = (ITransmutationProxy) clazz.getField("instance").get(null);
} catch (ReflectiveOperationException ex)
{
FMLLog.warning("[ProjectEAPI] Error retrieving TransmutationProxyImpl, ProjectE may be absent, damaged, or outdated.");
}
}
return transProxy;
}
/**
* Retrieves the proxy for black/whitelist-based API queries.
* @return The proxy for black/whitelist-based API queries
*/
public static IBlacklistProxy getBlacklistProxy()
{
if (blacklistProxy == null)
{
try
{
Class<?> clazz = Class.forName("moze_intel.projecte.impl.BlacklistProxyImpl");
blacklistProxy = (IBlacklistProxy) clazz.getField("instance").get(null);
} catch (ReflectiveOperationException ex)
{
FMLLog.warning("[ProjectEAPI] Error retrieving BlacklistProxyImpl, ProjectE may be absent, damaged, or outdated.");
}
}
return blacklistProxy;
}
}

View File

@ -0,0 +1,10 @@
package moze_intel.projecte.api.event;
import cpw.mods.fml.common.eventhandler.Event;
/**
* This event is fired after all EMC values are recalculated
* This event is not cancelable, and has no result
* This event is fired on MinecraftForge#EVENT_BUS
*/
public class EMCRemapEvent extends Event {}

View File

@ -0,0 +1,21 @@
package moze_intel.projecte.api.event;
import java.util.UUID;
import net.minecraft.entity.player.EntityPlayer;
import cpw.mods.fml.common.eventhandler.Event;
/**
* This event is fired after a players transmutation knowledge is changed
* This event is not cancelable, and has no result
* This event is fired on MinecraftForge#EVENT_BUS
*/
public class PlayerKnowledgeChangeEvent extends Event
{
public final UUID playerUUID;
public PlayerKnowledgeChangeEvent(EntityPlayer entityPlayer)
{
playerUUID = entityPlayer.getUniqueID();
}
}

View File

@ -0,0 +1,22 @@
package moze_intel.projecte.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* This interfaces specifies items that perform a specific function every tick when inside an Alchemical Bag, on a player
*
* @author williewillus
*/
public interface IAlchBagItem
{
/**
* Called on both client and server every time the alchemical bag ticks this item
*
* @param inv The inventory of the bag
* @param player The player whose bag is being ticked
* @param stack The ItemStack being ticked
* @return Whether the inventory was changed by this item ticking
*/
boolean updateInAlchBag(ItemStack[] inv, EntityPlayer player, ItemStack stack);
}

View File

@ -0,0 +1,22 @@
package moze_intel.projecte.api.item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* This interface specifies items that perform a specific function every tick when inside an Alchemical Chest
*
* @author williewillus
*/
public interface IAlchChestItem
{
/**
* Called on both client and server every time the alchemical chest ticks this item
* Implementers that modify the chest inventory (serverside) MUST call markDirty() on the tile entity.
* If you do not, your changes may not be saved when the world/chunk unloads!
*
* @param world The World
* @param stack The ItemStack being ticked
*/
void updateInAlchChest(World world, int x, int y, int z, ItemStack stack);
}

View File

@ -0,0 +1,17 @@
package moze_intel.projecte.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* This interface specifies items that perform a specific function when the Extra Function key is activated (default C)
*/
public interface IExtraFunction
{
/**
* Called serverside when the server receives a Extra Function key packet
* @param stack The ItemStack performing this function
* @param player The player performing this function
*/
void doExtraFunction(ItemStack stack, EntityPlayer player);
}

View File

@ -0,0 +1,24 @@
package moze_intel.projecte.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* This interface specifies items that have a charge that changes when the respective keybinding is activated (default V)
*/
public interface IItemCharge
{
/**
* Returns the current charge on the given ItemStack
* @param stack Stack whose charge we want
* @return The charge on the stack
*/
byte getCharge(ItemStack stack);
/**
* Called serverside when the player presses the charge keybinding; reading sneaking state is up to you
* @param player The player
* @param stack The item being charged
*/
void changeCharge(EntityPlayer player, ItemStack stack);
}

View File

@ -0,0 +1,41 @@
package moze_intel.projecte.api.item;
import net.minecraft.item.ItemStack;
/**
* This interface defines the contract for items that wish to expose their internal EMC storage for external manipulation
*
* @author williewillus
*/
public interface IItemEmc
{
/**
* Adds EMC to the itemstack
* @param stack The itemstack to add to
* @param toAdd The maximum amount to add
* @return The amount that was actually added
*/
double addEmc(ItemStack stack, double toAdd);
/**
* Extracts EMC from the itemstack
* @param stack The itemstack to remove from
* @param toRemove The maximum amount to remove
* @return The amount that was actually extracted
*/
double extractEmc(ItemStack stack, double toRemove);
/**
* Gets the current EMC this stack is showing to the public
* @param stack The stack to query
* @return The current publicly-accessible EMC stored in this stack
*/
double getStoredEmc(ItemStack stack);
/**
* Gets the maximum EMC that is allowed to be stored in this stack
* @param stack The stack to query
* @return The maximum amount of publicly-accessible EMC that can be stored in this stack
*/
double getMaximumEmc(ItemStack stack);
}

View File

@ -0,0 +1,24 @@
package moze_intel.projecte.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* This interface specifies items that switch between modes when the mode switch keybind is activated (default G)
*/
public interface IModeChanger
{
/**
* Gets the mode from this ItemStack
* @param stack The stack we want the mode of
* @return The mode of this ItemStack
*/
byte getMode(ItemStack stack);
/**
* Called serverside when the player presses change mode
* @param player The player pressing the change mode key
* @param stack The stack whose mode we are changing
*/
void changeMode(EntityPlayer player, ItemStack stack);
}

View File

@ -0,0 +1,28 @@
package moze_intel.projecte.api.item;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import java.util.List;
/**
* This interface specifies items that perform a specific function every tick when inside an activated Dark Matter Pedestal
*
* @author williewillus
*/
public interface IPedestalItem {
String TOOLTIPDISABLED = EnumChatFormatting.RED + StatCollector.translateToLocal("pe.pedestal.item_disabled");
/***
* Called on both client and server each time an active DMPedestalTile ticks with this item inside
*/
void updateInPedestal(World world, int x, int y, int z);
/***
* Called clientside when inside the pedestal gui to add special function descriptions
* @return Brief strings describing the item's function in an activated pedestal
*/
List<String> getPedestalDescription();
}

View File

@ -0,0 +1,18 @@
package moze_intel.projecte.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* This interface specifies items that fire a projectile when the Shoot Projectile keybind is activated (default R)
*/
public interface IProjectileShooter
{
/**
* Called serverside when the player presses the Fire Projectile Button
* @param player The player pressing the key
* @param stack The stack we are using to shoot
* @return If the projectile was actually fired
*/
boolean shootProjectile(EntityPlayer player, ItemStack stack);
}

View File

@ -0,0 +1,8 @@
/**
* Increment apiVersion every time the API changes.
* (Adding methods, removing methods, changing method signatures, etc.)
*/
@API(owner = "ProjectE", apiVersion = "7", provides = "ProjectEAPI")
package moze_intel.projecte.api;
import cpw.mods.fml.common.API;

View File

@ -0,0 +1,37 @@
package moze_intel.projecte.api.proxy;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
public interface IBlacklistProxy
{
/**
* Blacklist an Entity class from being repelled by the Interdiction Torch
* Call this during the postinit phase
* @param clazz The entity class to blacklist
*/
void blacklistInterdiction(Class<? extends Entity> clazz);
/**
* Blacklist an Entity class from being repelled by the SWRG's repel mode
* Call this during the postinit phase
* @param clazz The entity class to blacklist
*/
void blacklistSwiftwolf(Class<? extends Entity> clazz);
/**
* Prevent the Watch of Flowing Time from speeding up this TileEntity
* Modders: Use this only to prevent things from breaking badly - leave balance to the modpacker and player
* Call this during the postinit phase
* @param clazz The TileEntity to blacklist
*/
void blacklistTimeWatch(Class<? extends TileEntity> clazz);
/**
* Whitelist an ItemStack, allowing stacks of its kind to dupe NBT during Transmutation and Condensation
* Call this during the postinit phase
* @param stack The stack to whitelist
*/
void whitelistNBT(ItemStack stack);
}

View File

@ -0,0 +1,65 @@
package moze_intel.projecte.api.proxy;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import java.util.Map;
public interface IConversionProxy
{
/**
* Add a Conversion to the EMC Calculation.
*
* Adding a Conversion allows ProjectE to calculate the EMC value for the output based on the specified ingredients.
* These do not need to be actually Conversions. You can use it to make the EMC value of an item relative to the EMC value of other items.
* ProjectE will automatically select the Conversion with the lowest EMC value.
*
* Has to be called after {@code FMLInitializationEvent} and before {@code FMLServerStartingEvent}.
*
* You can use the following things for the {@code output}-Parameter and the keys in the {@code ingredients} Map:
* <ul>
* <li>{@link ItemStack} - The ItemId and Metadata will be used to identify this ItemStack (May contain a {@code Block} or {@code Item}). You can use {@link net.minecraftforge.oredict.OreDictionary#WILDCARD_VALUE} as metadata.</li>
* <li>{@link Block} - Same as calling it with {@code new ItemStack(block)}. Uses the Id and metadata = 0</li>
* <li>{@link Item} - Same as calling it with {@code new ItemStack(item)}. Uses the Id and metadata = 0</li>
* <li>{@link FluidStack} - {@link FluidStack#getFluid()} and {@link Fluid#getName()} will be used to identify this Fluid.</li>
* <li>{@link String} - will be interpreted as an OreDictionary name.</li>
* <li>{@link Object} - (No subclasses of {@code Object} - only {@code Object}!) can be used as a intermediate fake object for complex conversion.</li>
* </ul>
* All {@code Object}s will be assumed to be a single instance. No stacksize will be used.
*
* Use the {@code amount} parameter to specify how many {@code output}s are created.
* Use the value in the {@code ingredients}-Map to specify how much of an ingredient is required.
* (Use Millibuckets for Fluids)
*
* Examples:
*
* <pre>{@code
* //Furnace Crafting Recipe:
* addConversion(1, Blocks.furnace, ImmutableMap.of((Object)Blocks.cobblestone, 8));
* //alternatively:
* addConversion(1, Blocks.furnace, ImmutableMap.<Object, Integer>of(Blocks.cobblestone, 8));
*
* //Bed Crafting Recipe with OreDictionary Names:
* //3 "plankWood" and 3 "blockWool" turn into 1 Blocks.bed
* addConversion(1, Blocks.bed, ImmutableMap.<Object, Integer>of("plankWood", 3, "blockWool", 3));
*
* //For Recipes that have multiple possible Ingredients, that don't belong to a known OreDict entry you can use a fake-item Object:
* Object blackOrWhite = new Object();
* //1 White Wool can be turned into 1 'blackOrWhite'
* addConversion(1, blackOrWhite, ImmutableMap.of((Object)new ItemStack(Blocks.wool, 1, 0), 1));
* //1 Black Wool can be turned into 1 'blackOrWhite'
* addConversion(1, blackOrWhite, ImmutableMap.of((Object)new ItemStack(Blocks.wool, 1, 15), 1));
* //Bed created with black or white wool only
* addConversion(1, Blocks.bed, ImmutableMap.of(blackOrWhite, 3, "plankWood", 3));
* }
* </pre>
*
* @param amount
* @param output
* @param ingredients
*/
void addConversion(int amount, Object output, Map<Object, Integer> ingredients);
}

View File

@ -0,0 +1,88 @@
package moze_intel.projecte.api.proxy;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import java.util.Map;
public interface IEMCProxy
{
/**
* Registers a custom EMC value for this ItemStack
* Call this during any of the main loading phases (Preinit, Init, Postinit)
* @param stack The stack we want to define EMC for
* @param value The value to define. Values below 0 are changed to 0
*/
void registerCustomEMC(ItemStack stack, int value);
/**
* Register a custom EMC value for emc calculation that is used in Recipes.
* You can use the following things for the {@code o}-Parameter:
* <ul>
* <li>{@link ItemStack} - The Modname:unlocalizedName and Metadata will be used to identify this ItemStack (May contain a {@code Block} or {@code Item})</li>
* <li>{@link String} - will be interpreted as an OreDictionary name.</li>
* <li>{@link Object} - (No subclasses of {@code Object} - only {@code Object}!) can be used as a intermediate fake object for complex recipes.</li>
* </ul>
* @param o
* @param value
* @see IConversionProxy#addConversion(int, Object, Map)
*/
void registerCustomEMC(Object o, int value);
/**
* Queries the EMC value registry if the given block has an EMC value
* Can be called at any time, but will only return valid results if a world is loaded
* Can be called on both sides
* @param block The block we want to query
* @return Whether the block has an emc value
*/
boolean hasValue(Block block);
/**
* Queries the EMC value registry if the given item with a damage value of 0 has an EMC value
* Can be called at any time, but will only return valid results if a world is loaded
* Can be called on both sides
* @param item The item we want to query
* @return Whether the item has an emc value
*/
boolean hasValue(Item item);
/**
* Queries the EMC value registry if the given ItemStack has an EMC value
* This will also use the damage value to check if the Item has an EMC value
* Can be called at any time, but will only return valid results if a world is loaded
* Can be called on both sides
* @param stack The stack we want to query
* @return Whether the ItemStack has an emc value
*/
boolean hasValue(ItemStack stack);
/**
* Queries the EMC value for the provided block
* Can be called at any time, but will only return valid results if a world is loaded
* Can be called on both sides
* @param block The block we want to query
* @return The block's EMC value, or 0 if there is none
*/
int getValue(Block block);
/**
* Queries the EMC value for the provided item
* Can be called at any time, but will only return valid results if a world is loaded
* Can be called on both sides
* @param item The item we want to query
* @return The item's EMC value, or 0 if there is none
*/
int getValue(Item item);
/**
* Queries the EMC value for the provided stack
* Can be called at any time, but will only return valid results if a world is loaded
* Can be called on both sides
* This takes into account bonuses such as stored emc in power items and enchantments
* @param stack The stack we want to query
* @return The stack's EMC value, or 0 if there is none
*/
int getValue(ItemStack stack);
}

View File

@ -0,0 +1,87 @@
package moze_intel.projecte.api.proxy;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import javax.annotation.Nullable;
import java.util.List;
import java.util.UUID;
public interface ITransmutationProxy
{
/**
* Register a world transmutation with the Philosopher's Stone
* Calls this during the postinit phase
* @param origin Original block when targeting world transmutation
* @param originMeta Original metadata
* @param result1 First result block
* @param result1Meta First result metadata
* @param result2 Alternate result (when sneaking). You may pass null, in which there will be no alternate transmutation
* @param result2meta Alternate result metadata. If result2 is null, this value is ignored
* @return Whether the registration succeeded. It may fail if transmutations already exist for block origin
*/
boolean registerWorldTransmutation(Block origin, int originMeta, Block result1, int result1Meta, @Nullable Block result2, int result2meta);
/**
* Queries the knowledge of the provided player
* Can be called on both sides, only if the client player exists or the server is started
* If called on the client side, playerUUID is ignored and the client player is used instead
* @param playerUUID The Player to query
* @param stack The ItemStack to query
* @return Whether the player has knowledge for this ItemStack, false if player is not found
*/
boolean hasKnowledgeFor(UUID playerUUID, ItemStack stack);
/**
* Queries all the knowledge of the provided player
* Can be called on both sides, only if the client player exists or the server is started
* If called on the client side, playerUUID is ignored and the client player is used instead
* @param playerUUID The Player to query
* @return List<ItemStack> List of ItemStacks the player has transmutation knowledge of.
*/
List<ItemStack> getKnowledge(UUID playerUUID);
/**
* Queries the knowledge of the provided player
* Can be called on both sides, only if the client player exists or the server is started
* If called on the client side, playerUUID is ignored and the client player is used instead
* @param playerUUID The Player to query
* @return Whether the player has full/override knowledge from the Tome, false if player is not found
* @deprecated as of API version 8, use {@link #hasKnowledgeFor(UUID, ItemStack)}
*/
@Deprecated
boolean hasFullKnowledge(UUID playerUUID);
/**
* Adds to the knowledge of the provided player. Only works if player is online
* Calls may only be issued on the server side, and if the server is running
* @param playerUUID The Player to modify
* @param stack The ItemStack to add
*/
void addKnowledge(UUID playerUUID, ItemStack stack);
/**
* Removes from the knowledge of the provided player. Only works if player is online
* Calls may only be issued on the server side, and if the server is running
* @param playerUUID The Player to modify
* @param stack The ItemStack to remove
*/
void removeKnowledge(UUID playerUUID, ItemStack stack);
/**
* Sets the player's personal transmutation emc to that provided. Only works if player is online
* Calls may only be issued on the server side, and if the server is running
* @param playerUUID The Player to modify
* @param emc The value to set
*/
void setEMC(UUID playerUUID, double emc);
/**
* Gets the player's personal transmutation emc
* Can be called on both sides, only if the client player exists or the server is started
* If called on the client side, playerUUID is ignored and the client player is used instead
* @param playerUUID The Player to modify
* @return The emc, or NaN if player is not found
*/
double getEMC(UUID playerUUID);
}

View File

@ -0,0 +1,22 @@
package moze_intel.projecte.api.tile;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Implement this interface to specify that "EMC can be given to this Tile Entity from an external source"
* The contract of this interface is only the above statement
* However, ProjectE implements an "active-push" system, where providers automatically send EMC to acceptors. You are recommended to follow this convention
* Reference implementation provided in TileEmcHandler
*
* @author williewillus
*/
public interface IEmcAcceptor extends IEmcStorage
{
/**
* Accept, at most, the given amount of EMC from the given side
* @param side The side to accept EMC from
* @param toAccept The maximum amount to accept
* @return The amount actually accepted
*/
double acceptEMC(ForgeDirection side, double toAccept);
}

View File

@ -0,0 +1,22 @@
package moze_intel.projecte.api.tile;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Implement this interface to specify that "EMC can be taken from this Tile Entity from an external source"
* The contract of this interface is limited to only the above statement
* However, ProjectE implements an "active-push" system, where providers automatically send EMC to acceptors. You are recommended to follow this convention
* Reference implementation provided in TileEmcHandler
*
* @author williewillus
*/
public interface IEmcProvider extends IEmcStorage
{
/**
* Extract, at most, the given amount of EMC from the given side
* @param side The side to extract EMC from
* @param toExtract The maximum amount to extract
* @return The amount actually extracted
*/
double provideEMC(ForgeDirection side, double toExtract);
}

View File

@ -0,0 +1,23 @@
package moze_intel.projecte.api.tile;
/**
* Defines the contract for arbitrary objects that can store EMC
* You usually do not want to use this directly
* Use extensions IEMCAcceptor and IEMCProvider, or the provided reference implementations instead
*
* @author williewillus
*/
public interface IEmcStorage
{
/**
* Gets the current amount of EMC in this IEMCStorage
* @return The current EMC stored
*/
double getStoredEmc();
/**
* Gets the maximum amount of EMC this IEMCStorage is allowed to contain
* @return The maximum EMC allowed
*/
double getMaximumEmc();
}

View File

@ -0,0 +1,50 @@
package moze_intel.projecte.api.tile;
/**
* This interface is now DEPRECATED. Do not use! Update to IEMCAcceptor, IEMCProvider, or TileEmcHandler ASAP!!
* You will not crash, but using this will have no effect as the ProjectE machines no longer recognize nor implement this interface
*/
@Deprecated
public interface ITileEmc
{
/**
* Set the EMC value of this Tile Entity
* @param value The EMC amount to set
*/
@Deprecated
void setEmc(double value);
/**
* Add EMC to this Tile Entity
* @param value The EMC amount to add
*/
@Deprecated
void addEmc(double value);
/**
* Remove EMC from the tile entity
* @param value The EMC amount to remove
*/
@Deprecated
void removeEmc(double value);
/**
* @return The stored EMC in this TileEntity
*/
@Deprecated
double getStoredEmc();
/**
* @return Whether or not the EMC buffer is full
*/
@Deprecated
boolean hasMaxedEmc();
/**
* If this returns true, the Tile Entity will accept EMC from any valid provider
* EMC will be received only on the server side
* @return If this Tile Entity can accept EMC from adjacent providers
*/
@Deprecated
boolean isRequestingEmc();
}

View File

@ -0,0 +1,19 @@
package moze_intel.projecte.api.tile;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Reference implementation of IEMCAcceptor
*
* @author williewillus
*/
public class TileEmcAcceptor extends TileEmcBase implements IEmcAcceptor
{
@Override
public double acceptEMC(ForgeDirection side, double toAccept)
{
double toAdd = Math.min(maximumEMC - currentEMC, toAccept);
addEMC(toAdd);
return toAdd;
}
}

View File

@ -0,0 +1,90 @@
package moze_intel.projecte.api.tile;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
/**
* Base class for the reference implementations TileEmcProvider, TileEmcAcceptor, and TileEmcHandler
* Usually you want to use one of three derived reference implementations
* Extend this if you want fine-grained control over all aspects of how your tile provides or accepts EMC
*
* @author williewillus
*/
public class TileEmcBase extends TileEntity implements IEmcStorage
{
protected double maximumEMC;
protected double currentEMC = 0;
protected TileEmcBase()
{
setMaximumEMC(Double.MAX_VALUE);
}
public final void setMaximumEMC(double max)
{
maximumEMC = max;
if (currentEMC > maximumEMC)
{
currentEMC = maximumEMC;
}
}
@Override
public double getStoredEmc()
{
return currentEMC;
}
@Override
public double getMaximumEmc()
{
return maximumEMC;
}
/**
* Add EMC directly into the internal buffer. Use for internal implementation of your tile
*/
protected void addEMC(double toAdd)
{
currentEMC += toAdd;
if (currentEMC > maximumEMC)
{
currentEMC = maximumEMC;
}
}
/**
* Removes EMC directly into the internal buffer. Use for internal implementation of your tile
*/
protected void removeEMC(double toRemove)
{
currentEMC -= toRemove;
if (currentEMC < 0)
{
currentEMC = 0;
}
}
@Override
public void writeToNBT(NBTTagCompound tag)
{
super.writeToNBT(tag);
if (currentEMC > maximumEMC)
{
currentEMC = maximumEMC;
}
tag.setDouble("EMC", currentEMC);
}
@Override
public void readFromNBT(NBTTagCompound tag)
{
super.readFromNBT(tag);
double set = tag.getDouble("EMC");
if (set > maximumEMC)
{
set = maximumEMC;
}
currentEMC = set;
}
}

View File

@ -0,0 +1,52 @@
package moze_intel.projecte.api.tile;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Reference implementation of both IEMCAcceptor and IEMCProvider
*
* @author williewillus
*/
public class TileEmcHandler extends TileEmcBase implements IEmcAcceptor, IEmcProvider
{
public TileEmcHandler()
{
this.maximumEMC = Double.MAX_VALUE;
}
public TileEmcHandler(double max)
{
this.maximumEMC = max;
}
// -- IEMCAcceptor -- //
@Override
public double acceptEMC(ForgeDirection side, double toAccept)
{
double toAdd = Math.min(maximumEMC - currentEMC, toAccept);
currentEMC += toAdd;
return toAdd;
}
// -- IEMCProvider -- //
@Override
public double provideEMC(ForgeDirection side, double toExtract)
{
double toRemove = Math.min(currentEMC, toExtract);
currentEMC -= toRemove;
return toRemove;
}
// -- IEMCStorage --//
@Override
public double getStoredEmc()
{
return currentEMC;
}
@Override
public double getMaximumEmc()
{
return maximumEMC;
}
}

View File

@ -0,0 +1,19 @@
package moze_intel.projecte.api.tile;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Reference implementation for IEMCProvider
*
* @author williewillus
*/
public class TileEmcProvider extends TileEmcBase implements IEmcProvider
{
@Override
public double provideEMC(ForgeDirection side, double toExtract)
{
double toRemove = Math.min(currentEMC, toExtract);
removeEMC(toRemove);
return toRemove;
}
}