diff --git a/.gitignore b/.gitignore index 471713c99..a956e7ab8 100755 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,4 @@ run/ *.iws .idea/ out/ -translation-diff.diff -src/main/java/moze_intel/* \ No newline at end of file +translation-diff.diff \ No newline at end of file diff --git a/src/main/java/moze_intel/projecte/api/PESounds.java b/src/main/java/moze_intel/projecte/api/PESounds.java new file mode 100644 index 000000000..24c44a4d8 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/PESounds.java @@ -0,0 +1,21 @@ +package moze_intel.projecte.api; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraftforge.fml.common.registry.ForgeRegistries; + +public final class PESounds { + + public static final SoundEvent WIND = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("projecte", "item.pewindmagic")); + public static final SoundEvent WATER = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("projecte", "item.pewatermagic")); + public static final SoundEvent POWER = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("projecte", "item.pepower")); + public static final SoundEvent HEAL = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("projecte", "item.peheal")); + public static final SoundEvent DESTRUCT = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("projecte", "item.pedestruct")); + public static final SoundEvent CHARGE = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("projecte", "item.pecharge")); + public static final SoundEvent UNCHARGE = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("projecte", "item.peuncharge")); + public static final SoundEvent TRANSMUTE = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("projecte", "item.petransmute")); + + private PESounds() { + } + +} diff --git a/src/main/java/moze_intel/projecte/api/ProjectEAPI.java b/src/main/java/moze_intel/projecte/api/ProjectEAPI.java new file mode 100644 index 000000000..2e715d3ea --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/ProjectEAPI.java @@ -0,0 +1,101 @@ +package moze_intel.projecte.api; + +import moze_intel.projecte.api.capabilities.IAlchBagProvider; +import moze_intel.projecte.api.capabilities.IKnowledgeProvider; +import moze_intel.projecte.api.proxy.IBlacklistProxy; +import moze_intel.projecte.api.proxy.IConversionProxy; +import moze_intel.projecte.api.proxy.IEMCProxy; +import moze_intel.projecte.api.proxy.ITransmutationProxy; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.CapabilityInject; +import net.minecraftforge.fml.common.FMLLog; + +public final class ProjectEAPI { + private static IEMCProxy emcProxy; + private static ITransmutationProxy transProxy; + private static IBlacklistProxy blacklistProxy; + private static IConversionProxy recipeProxy; + + private ProjectEAPI() { + } + + /** + * The capability object for IAlchBagProvider + */ + @CapabilityInject(IAlchBagProvider.class) + public static final Capability ALCH_BAG_CAPABILITY = null; + + /** + * The capability object for IKnowledgeProvider + */ + @CapabilityInject(IKnowledgeProvider.class) + public static final Capability KNOWLEDGE_CAPABILITY = null; + + /** + * 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; + } +} \ No newline at end of file diff --git a/src/main/java/moze_intel/projecte/api/capabilities/IAlchBagProvider.java b/src/main/java/moze_intel/projecte/api/capabilities/IAlchBagProvider.java new file mode 100644 index 000000000..b214e5435 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/capabilities/IAlchBagProvider.java @@ -0,0 +1,38 @@ +package moze_intel.projecte.api.capabilities; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.INBTSerializable; +import net.minecraftforge.items.IItemHandler; + +import javax.annotation.Nonnull; + +/** + * This interface defines the contract for some object that exposes sixteen colored inventories, + * for the purpose of usage as Alchemical Bags. + * This is exposed through the Capability system. + * Acquire an instance of this using {@link net.minecraft.entity.Entity#getCapability(Capability, EnumFacing)}. + */ +public interface IAlchBagProvider extends INBTSerializable { + + /** + * Note: modifying this clientside is not advised + * + * @param color The bag color to acquire + * @return The inventory representing this alchemical bag + */ + @Nonnull + IItemHandler getBag(@Nonnull EnumDyeColor color); + + /** + * Syncs the bag inventory associated with this color to the player provided (usually the owner of this capability instance) + * + * @param color The bag color to sync. If null, syncs every color. + * @param player The player to sync the bags to. + */ + void sync(@Nonnull EnumDyeColor color, @Nonnull EntityPlayerMP player); + +} diff --git a/src/main/java/moze_intel/projecte/api/capabilities/IKnowledgeProvider.java b/src/main/java/moze_intel/projecte/api/capabilities/IKnowledgeProvider.java new file mode 100644 index 000000000..e8882935d --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/capabilities/IKnowledgeProvider.java @@ -0,0 +1,81 @@ +package moze_intel.projecte.api.capabilities; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.INBTSerializable; +import net.minecraftforge.items.IItemHandler; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +/** + * This interface defines the contract for some object that exposes transmutation knowledge through the Capability system. + * Acquire an instance of this using {@link net.minecraft.entity.Entity#getCapability(Capability, EnumFacing)}. + */ +public interface IKnowledgeProvider extends INBTSerializable { + + /** + * @return Whether the player has the "tome" flag set, meaning all knowledge checks automatically return true + */ + boolean hasFullKnowledge(); + + /** + * @param fullKnowledge Whether the player has the "tome" flag set, meaning all knowledge checks automatically return true + */ + void setFullKnowledge(boolean fullKnowledge); + + /** + * Clears all knowledge. Additionally, clears the "tome" flag. + */ + void clearKnowledge(); + + /** + * @param stack The stack to query + * @return Whether the player has transmutation knowledge for this stack + */ + boolean hasKnowledge(@Nullable ItemStack stack); + + /** + * @param stack The stack to add to knowledge + * @return Whether the operation was successful + */ + boolean addKnowledge(@Nonnull ItemStack stack); + + /** + * @param stack The stack to remove from knowledge + * @return Whether the operation was successful + */ + boolean removeKnowledge(@Nonnull ItemStack stack); + + /** + * @return An unmodifiable but live view of the knowledge list. + */ + @Nonnull + List getKnowledge(); + + /** + * @return The player's input and lock slots + */ + @Nonnull + IItemHandler getInputAndLocks(); + + /** + * @return The emc in this player's transmutation tablet network + */ + double getEmc(); + + /** + * @param emc The emc to set in this player's transmutation tablet network + */ + void setEmc(double emc); + + /** + * @param player The player to sync to. + */ + void sync(@Nonnull EntityPlayerMP player); + +} diff --git a/src/main/java/moze_intel/projecte/api/event/EMCRemapEvent.java b/src/main/java/moze_intel/projecte/api/event/EMCRemapEvent.java new file mode 100644 index 000000000..f6374d405 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/event/EMCRemapEvent.java @@ -0,0 +1,11 @@ +package moze_intel.projecte.api.event; + +import net.minecraftforge.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 { +} diff --git a/src/main/java/moze_intel/projecte/api/event/PlayerKnowledgeChangeEvent.java b/src/main/java/moze_intel/projecte/api/event/PlayerKnowledgeChangeEvent.java new file mode 100644 index 000000000..db61ba58d --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/event/PlayerKnowledgeChangeEvent.java @@ -0,0 +1,26 @@ +package moze_intel.projecte.api.event; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.fml.common.eventhandler.Event; + +import javax.annotation.Nonnull; +import java.util.UUID; + +/** + * 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 { + private final UUID playerUUID; + + public PlayerKnowledgeChangeEvent(@Nonnull EntityPlayer entityPlayer) { + playerUUID = entityPlayer.getUniqueID(); + } + + @Nonnull + public UUID getPlayerUUID() { + return playerUUID; + } + +} diff --git a/src/main/java/moze_intel/projecte/api/item/IAlchBagItem.java b/src/main/java/moze_intel/projecte/api/item/IAlchBagItem.java new file mode 100644 index 000000000..b9261fc16 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/item/IAlchBagItem.java @@ -0,0 +1,24 @@ +package moze_intel.projecte.api.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.IItemHandler; + +import javax.annotation.Nonnull; + +/** + * 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(@Nonnull IItemHandler inv, @Nonnull EntityPlayer player, @Nonnull ItemStack stack); +} diff --git a/src/main/java/moze_intel/projecte/api/item/IAlchChestItem.java b/src/main/java/moze_intel/projecte/api/item/IAlchChestItem.java new file mode 100644 index 000000000..8c3c4a97a --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/item/IAlchChestItem.java @@ -0,0 +1,24 @@ +package moze_intel.projecte.api.item; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import javax.annotation.Nonnull; + +/** + * 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(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull ItemStack stack); +} diff --git a/src/main/java/moze_intel/projecte/api/item/IExtraFunction.java b/src/main/java/moze_intel/projecte/api/item/IExtraFunction.java new file mode 100644 index 000000000..dbf54783e --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/item/IExtraFunction.java @@ -0,0 +1,23 @@ +package moze_intel.projecte.api.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumHand; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * 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 + * @param hand The hand this stack was in, or null if the call was not from the player's hands + * @return Whether the operation succeeded + */ + boolean doExtraFunction(@Nonnull ItemStack stack, @Nonnull EntityPlayer player, @Nullable EnumHand hand); +} diff --git a/src/main/java/moze_intel/projecte/api/item/IItemCharge.java b/src/main/java/moze_intel/projecte/api/item/IItemCharge.java new file mode 100644 index 000000000..766dd125a --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/item/IItemCharge.java @@ -0,0 +1,31 @@ +package moze_intel.projecte.api.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumHand; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * 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(@Nonnull 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 + * @param hand The hand this stack was in, or null if the call was not from the player's hands + * @return Whether the operation succeeded + */ + boolean changeCharge(@Nonnull EntityPlayer player, @Nonnull ItemStack stack, @Nullable EnumHand hand); +} diff --git a/src/main/java/moze_intel/projecte/api/item/IItemEmc.java b/src/main/java/moze_intel/projecte/api/item/IItemEmc.java new file mode 100644 index 000000000..613996935 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/item/IItemEmc.java @@ -0,0 +1,46 @@ +package moze_intel.projecte.api.item; + +import net.minecraft.item.ItemStack; + +import javax.annotation.Nonnull; + +/** + * 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(@Nonnull 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(@Nonnull 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(@Nonnull 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(@Nonnull ItemStack stack); +} diff --git a/src/main/java/moze_intel/projecte/api/item/IModeChanger.java b/src/main/java/moze_intel/projecte/api/item/IModeChanger.java new file mode 100644 index 000000000..e76d2d3bc --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/item/IModeChanger.java @@ -0,0 +1,31 @@ +package moze_intel.projecte.api.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumHand; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * 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(@Nonnull 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 + * @param hand The hand this stack was in, or null if the call was not from the player's hands + * @return Whether the operation succeeded + */ + boolean changeMode(@Nonnull EntityPlayer player, @Nonnull ItemStack stack, @Nullable EnumHand hand); +} diff --git a/src/main/java/moze_intel/projecte/api/item/IPedestalItem.java b/src/main/java/moze_intel/projecte/api/item/IPedestalItem.java new file mode 100644 index 000000000..25d3b39fa --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/item/IPedestalItem.java @@ -0,0 +1,35 @@ +package moze_intel.projecte.api.item; + +import net.minecraft.client.resources.I18n; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import javax.annotation.Nonnull; +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 { + + @SideOnly(Side.CLIENT) + String TOOLTIPDISABLED = TextFormatting.RED + I18n.format("pe.pedestal.item_disabled"); + + /*** + * Called on both client and server each time an active DMPedestalTile ticks with this item inside + */ + void updateInPedestal(@Nonnull World world, @Nonnull BlockPos pos); + + /*** + * Called clientside when inside the pedestal gui to add special function descriptions + * @return Brief strings describing the item's function in an activated pedestal + */ + @SideOnly(Side.CLIENT) + @Nonnull + List getPedestalDescription(); +} diff --git a/src/main/java/moze_intel/projecte/api/item/IProjectileShooter.java b/src/main/java/moze_intel/projecte/api/item/IProjectileShooter.java new file mode 100644 index 000000000..b359d579f --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/item/IProjectileShooter.java @@ -0,0 +1,23 @@ +package moze_intel.projecte.api.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumHand; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * 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 + * @param hand The hand this stack was in, or null if the call was not from the player's hands + * @return If the projectile was actually fired + */ + boolean shootProjectile(@Nonnull EntityPlayer player, @Nonnull ItemStack stack, @Nullable EnumHand hand); +} diff --git a/src/main/java/moze_intel/projecte/api/package-info.java b/src/main/java/moze_intel/projecte/api/package-info.java new file mode 100644 index 000000000..e050204df --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/package-info.java @@ -0,0 +1,8 @@ +/** + * Increment apiVersion every time the API changes. + * (Adding methods, removing methods, changing method signatures, etc.) + */ +@API(owner = "ProjectE", apiVersion = "1.10.2-1.0.0", provides = "ProjectEAPI") +package moze_intel.projecte.api; + +import net.minecraftforge.fml.common.API; diff --git a/src/main/java/moze_intel/projecte/api/proxy/IBlacklistProxy.java b/src/main/java/moze_intel/projecte/api/proxy/IBlacklistProxy.java new file mode 100644 index 000000000..c68fe20d5 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/proxy/IBlacklistProxy.java @@ -0,0 +1,42 @@ +package moze_intel.projecte.api.proxy; + +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import javax.annotation.Nonnull; + +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(@Nonnull Class 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(@Nonnull Class 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(@Nonnull Class 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(@Nonnull ItemStack stack); +} diff --git a/src/main/java/moze_intel/projecte/api/proxy/IConversionProxy.java b/src/main/java/moze_intel/projecte/api/proxy/IConversionProxy.java new file mode 100644 index 000000000..afcde1e26 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/proxy/IConversionProxy.java @@ -0,0 +1,65 @@ +package moze_intel.projecte.api.proxy; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import javax.annotation.Nonnull; +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: + *

    + *
  • {@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.
  • + *
  • {@link Block} - Same as calling it with {@code new ItemStack(block)}. Uses the Id and metadata = 0
  • + *
  • {@link Item} - Same as calling it with {@code new ItemStack(item)}. Uses the Id and metadata = 0
  • + *
  • {@link FluidStack} - {@link FluidStack#getFluid()} and {@link Fluid#getName()} will be used to identify this Fluid.
  • + *
  • {@link String} - will be interpreted as an OreDictionary name.
  • + *
  • {@link Object} - (No subclasses of {@code Object} - only {@code Object}!) can be used as a intermediate fake object for complex conversion.
  • + *
+ * 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: + *

+ *

{@code
+     * //Furnace Crafting Recipe:
+     * addConversion(1, Blocks.FURNACE, ImmutableMap.of((Object)Blocks.COBBLESTONE, 8));
+     * //alternatively:
+     * addConversion(1, Blocks.FURNACE, ImmutableMap.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.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));
+     * }
+     * 
+ * + * @param amount + * @param output + * @param ingredients + */ + void addConversion(int amount, @Nonnull Object output, @Nonnull Map ingredients); +} \ No newline at end of file diff --git a/src/main/java/moze_intel/projecte/api/proxy/IEMCProxy.java b/src/main/java/moze_intel/projecte/api/proxy/IEMCProxy.java new file mode 100644 index 000000000..e4e2013b8 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/proxy/IEMCProxy.java @@ -0,0 +1,96 @@ +package moze_intel.projecte.api.proxy; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import javax.annotation.Nonnull; +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(@Nonnull 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: + *
    + *
  • {@link ItemStack} - The Modname:unlocalizedName and Metadata will be used to identify this ItemStack (May contain a {@code Block} or {@code Item})
  • + *
  • {@link String} - will be interpreted as an OreDictionary name.
  • + *
  • {@link Object} - (No subclasses of {@code Object} - only {@code Object}!) can be used as a intermediate fake object for complex recipes.
  • + *
+ * + * @param o + * @param value + * @see IConversionProxy#addConversion(int, Object, Map) + */ + void registerCustomEMC(@Nonnull 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(@Nonnull 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(@Nonnull 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(@Nonnull 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(@Nonnull 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(@Nonnull 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(@Nonnull ItemStack stack); +} diff --git a/src/main/java/moze_intel/projecte/api/proxy/ITransmutationProxy.java b/src/main/java/moze_intel/projecte/api/proxy/ITransmutationProxy.java new file mode 100644 index 000000000..52529c2ea --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/proxy/ITransmutationProxy.java @@ -0,0 +1,37 @@ +package moze_intel.projecte.api.proxy; + +import moze_intel.projecte.api.capabilities.IKnowledgeProvider; +import net.minecraft.block.state.IBlockState; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +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 blockstate when targeting world transmutation + * @param result1 First result blockstate + * @param result2 Alternate result blockstate (when sneaking). You may pass null, in which there will be no alternate transmutation + * @return Whether the registration succeeded. It may fail if transmutations already exist for block origin + */ + boolean registerWorldTransmutation(@Nonnull IBlockState origin, @Nonnull IBlockState result1, @Nullable IBlockState result2); + + /** + * Gets an {@link IKnowledgeProvider} representing the UUID provided. + *

+ * If the provided UUID is offline, note that the returned {@link IKnowledgeProvider} is immutable! + * If called clientside, {@param playerUUID} is ignored and the client player is used instead. + * If called serverside, this must be called after the server has reached state SERVER_STARTED. + *

+ * If the provided UUID could not be found both on or offline, an {@link IKnowledgeProvider} with no knowledge is returned. + * + * @param playerUUID The UUID to query + * @return an {@link IKnowledgeProvider} representing the UUID provided, or an {@link IKnowledgeProvider} representing no knowledge if + * the requested UUID could not be found + */ + @Nonnull + IKnowledgeProvider getKnowledgeProviderFor(@Nonnull UUID playerUUID); +} diff --git a/src/main/java/moze_intel/projecte/api/state/PEStateProps.java b/src/main/java/moze_intel/projecte/api/state/PEStateProps.java new file mode 100644 index 000000000..2d37e5f82 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/state/PEStateProps.java @@ -0,0 +1,19 @@ +package moze_intel.projecte.api.state; + +import moze_intel.projecte.api.state.enums.EnumFuelType; +import moze_intel.projecte.api.state.enums.EnumMatterType; +import net.minecraft.block.BlockHorizontal; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.util.EnumFacing; + +public final class PEStateProps { + + public static final IProperty FACING = BlockHorizontal.FACING; + public static final IProperty FUEL_PROP = PropertyEnum.create("fueltype", EnumFuelType.class); + public static final IProperty TIER_PROP = PropertyEnum.create("tier", EnumMatterType.class); + + private PEStateProps() { + } + +} diff --git a/src/main/java/moze_intel/projecte/api/state/enums/EnumFuelType.java b/src/main/java/moze_intel/projecte/api/state/enums/EnumFuelType.java new file mode 100644 index 000000000..702dabe00 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/state/enums/EnumFuelType.java @@ -0,0 +1,28 @@ +package moze_intel.projecte.api.state.enums; + +import net.minecraft.util.IStringSerializable; + +import javax.annotation.Nonnull; + +public enum EnumFuelType implements IStringSerializable { + ALCHEMICAL_COAL("alchemical_coal"), + MOBIUS_FUEL("mobius_fuel"), + AETERNALIS_FUEL("aeternalis_fuel"); + + private final String name; + + EnumFuelType(String name) { + this.name = name; + } + + @Nonnull + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/moze_intel/projecte/api/state/enums/EnumMatterType.java b/src/main/java/moze_intel/projecte/api/state/enums/EnumMatterType.java new file mode 100644 index 000000000..cb958d945 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/state/enums/EnumMatterType.java @@ -0,0 +1,27 @@ +package moze_intel.projecte.api.state.enums; + +import net.minecraft.util.IStringSerializable; + +import javax.annotation.Nonnull; + +public enum EnumMatterType implements IStringSerializable { + DARK_MATTER("dark_matter"), + RED_MATTER("red_matter"); + + private final String name; + + EnumMatterType(String name) { + this.name = name; + } + + @Nonnull + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/moze_intel/projecte/api/tile/IEmcAcceptor.java b/src/main/java/moze_intel/projecte/api/tile/IEmcAcceptor.java new file mode 100644 index 000000000..80786a4f5 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/tile/IEmcAcceptor.java @@ -0,0 +1,24 @@ +package moze_intel.projecte.api.tile; + +import net.minecraft.util.EnumFacing; + +import javax.annotation.Nonnull; + +/** + * 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(@Nonnull EnumFacing side, double toAccept); +} diff --git a/src/main/java/moze_intel/projecte/api/tile/IEmcProvider.java b/src/main/java/moze_intel/projecte/api/tile/IEmcProvider.java new file mode 100644 index 000000000..c483551d1 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/tile/IEmcProvider.java @@ -0,0 +1,24 @@ +package moze_intel.projecte.api.tile; + +import net.minecraft.util.EnumFacing; + +import javax.annotation.Nonnull; + +/** + * 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(@Nonnull EnumFacing side, double toExtract); +} diff --git a/src/main/java/moze_intel/projecte/api/tile/IEmcStorage.java b/src/main/java/moze_intel/projecte/api/tile/IEmcStorage.java new file mode 100644 index 000000000..27434db64 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/tile/IEmcStorage.java @@ -0,0 +1,24 @@ +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(); +} diff --git a/src/main/java/moze_intel/projecte/api/tile/TileEmcAcceptor.java b/src/main/java/moze_intel/projecte/api/tile/TileEmcAcceptor.java new file mode 100644 index 000000000..03d924a15 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/tile/TileEmcAcceptor.java @@ -0,0 +1,19 @@ +package moze_intel.projecte.api.tile; + +import net.minecraft.util.EnumFacing; + +import javax.annotation.Nonnull; + +/** + * Reference implementation of IEMCAcceptor + * + * @author williewillus + */ +public class TileEmcAcceptor extends TileEmcBase implements IEmcAcceptor { + @Override + public double acceptEMC(@Nonnull EnumFacing side, double toAccept) { + double toAdd = Math.min(maximumEMC - currentEMC, toAccept); + addEMC(toAdd); + return toAdd; + } +} diff --git a/src/main/java/moze_intel/projecte/api/tile/TileEmcBase.java b/src/main/java/moze_intel/projecte/api/tile/TileEmcBase.java new file mode 100644 index 000000000..7507da94f --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/tile/TileEmcBase.java @@ -0,0 +1,80 @@ +package moze_intel.projecte.api.tile; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +import javax.annotation.Nonnull; + +/** + * 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; + } + } + + @Nonnull + @Override + public NBTTagCompound writeToNBT(NBTTagCompound tag) { + tag = super.writeToNBT(tag); + if (currentEMC > maximumEMC) { + currentEMC = maximumEMC; + } + tag.setDouble("EMC", currentEMC); + return tag; + } + + @Override + public void readFromNBT(NBTTagCompound tag) { + super.readFromNBT(tag); + double set = tag.getDouble("EMC"); + if (set > maximumEMC) { + set = maximumEMC; + } + currentEMC = set; + } +} diff --git a/src/main/java/moze_intel/projecte/api/tile/TileEmcHandler.java b/src/main/java/moze_intel/projecte/api/tile/TileEmcHandler.java new file mode 100644 index 000000000..62ee49279 --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/tile/TileEmcHandler.java @@ -0,0 +1,47 @@ +package moze_intel.projecte.api.tile; + +import net.minecraft.util.EnumFacing; + +import javax.annotation.Nonnull; + +/** + * 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(@Nonnull EnumFacing side, double toAccept) { + double toAdd = Math.min(maximumEMC - currentEMC, toAccept); + currentEMC += toAdd; + return toAdd; + } + + // -- IEMCProvider -- // + @Override + public double provideEMC(@Nonnull EnumFacing 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; + } +} diff --git a/src/main/java/moze_intel/projecte/api/tile/TileEmcProvider.java b/src/main/java/moze_intel/projecte/api/tile/TileEmcProvider.java new file mode 100644 index 000000000..5e0cb3b4c --- /dev/null +++ b/src/main/java/moze_intel/projecte/api/tile/TileEmcProvider.java @@ -0,0 +1,19 @@ +package moze_intel.projecte.api.tile; + +import net.minecraft.util.EnumFacing; + +import javax.annotation.Nonnull; + +/** + * Reference implementation for IEMCProvider + * + * @author williewillus + */ +public class TileEmcProvider extends TileEmcBase implements IEmcProvider { + @Override + public double provideEMC(@Nonnull EnumFacing side, double toExtract) { + double toRemove = Math.min(currentEMC, toExtract); + removeEMC(toRemove); + return toRemove; + } +}