package de.ellpeck.naturesaura.api; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.container.IAuraContainer; import de.ellpeck.naturesaura.api.aura.item.IAuraRecharge; import de.ellpeck.naturesaura.api.aura.type.BasicAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.misc.ILevelData; import de.ellpeck.naturesaura.api.misc.WeatherType; import de.ellpeck.naturesaura.api.misc.WeightedOre; import de.ellpeck.naturesaura.api.multiblock.IMultiblock; import de.ellpeck.naturesaura.api.multiblock.Matcher; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Tuple; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.CapabilityToken; import org.apache.commons.lang3.tuple.Pair; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Supplier; /** * The main class of the Nature's Aura API. This is where you can find recipe * lists and the {@link IInternalHooks} instance, which can be used to hook into * internal mod functions not exposed to the API. */ public final class NaturesAuraAPI { public static final String MOD_ID = "naturesaura"; /** * A map of all the block states that the Botanist's Pickaxe can convert * into their mossy variations. Contains mossy brick and mossy cobblestone * by default, along with all blocks specified in the config file */ public static final BiMap BOTANIST_PICKAXE_CONVERSIONS = HashBiMap.create(); /** * A map of all {@link IAuraType} instances which are types of Aura present * in different types of levels. {@link BasicAuraType} instances can be * easily registered using {@link BasicAuraType#register()}. */ public static final Map AURA_TYPES = new HashMap<>(); public static final BasicAuraType TYPE_OVERWORLD = new BasicAuraType(new ResourceLocation(MOD_ID, "overworld"), Level.OVERWORLD, 0x89cc37, 0).register(); public static final BasicAuraType TYPE_NETHER = new BasicAuraType(new ResourceLocation(MOD_ID, "nether"), Level.NETHER, 0x871c0c, 0).register(); public static final BasicAuraType TYPE_END = new BasicAuraType(new ResourceLocation(MOD_ID, "end"), Level.END, 0x302624, 0).register(); public static final BasicAuraType TYPE_OTHER = new BasicAuraType(new ResourceLocation(MOD_ID, "other"), null, 0x2fa8a0, Integer.MIN_VALUE).register(); /** * A map of all {@link IDrainSpotEffect} suppliers which are effects that * happen passively at every spot that Aura has been drained from in the * level. These effects include things like vegetational increase and * natural decay. To register your own drain spot effects, just add a * supplier for them to this map, and they will automatically be executed * once a second for every drain spot currently loaded. */ public static final Map> DRAIN_SPOT_EFFECTS = new HashMap<>(); /** * A map of all effect powder type. The integer the effect is registered to * is the color that the powder and its effect should have. To check if a * powder is active in any given area, use {@link IInternalHooks#isEffectPowderActive(Level, * BlockPos, ResourceLocation)} */ public static final Map EFFECT_POWDERS = new HashMap<>(); /** * A map of all {@link IMultiblock} objects which are multiblock structures * that can easily be looped through and checked, and also easily created * using the multiblock maker debug tool. */ public static final Map MULTIBLOCKS = new HashMap<>(); /** * A list of all {@link WeightedOre} objects that represent ores that can * spawn inside of stone blocks in the overworld */ public static final List OVERWORLD_ORES = new ArrayList<>(); /** * A list of all {@link WeightedOre} objects that represent ores that can * spawn inside netherrack blocks in the nether */ public static final List NETHER_ORES = new ArrayList<>(); /** * A map of all the entities' registry names to the amounts of aura they * each generate in the projectile generator */ public static final Map, Integer> PROJECTILE_GENERATIONS = new HashMap<>(); /** * A map of all the items that cause the {@link WeatherType} to be changed * using the weather changer */ public static final Map WEATHER_CHANGER_CONVERSIONS = new HashMap<>(); /** * The capability for any item or block that stores Aura in the form of an * {@link IAuraContainer} */ public static final Capability CAP_AURA_CONTAINER = CapabilityManager.get(new CapabilityToken<>() { }); /** * The capability for any item that can be recharged from an Aura storage * container like the Aura Cache in the form of {@link IAuraRecharge} by a * player holding it in their hand */ public static final Capability CAP_AURA_RECHARGE = CapabilityManager.get(new CapabilityToken<>() { }); /** * The capability that any chunk in a level has to store Aura in it. As this * is only applicable to chunks and all chunks in the level automatically * get assigned this capability, using it directly is not necessary for * addon developers. To retrieve this capability from any chunk, use the * helper method {@link IAuraChunk#getAuraChunk(net.minecraft.world.level.Level, * BlockPos)}. */ public static final Capability CAP_AURA_CHUNK = CapabilityManager.get(new CapabilityToken<>() { }); /** * The capability that any level has to store Nature's Aura specific data in * it. To retrieve this capability from any level, use the helper methods * {@link ILevelData#getLevelData(net.minecraft.world.level.Level)} or * {@link ILevelData#getOverworldData(net.minecraft.world.level.Level)}. */ public static final Capability CAP_LEVEL_DATA = CapabilityManager.get(new CapabilityToken<>() { }); private static final IInternalHooks INSTANCE; static { try { INSTANCE = (IInternalHooks) Class.forName("de.ellpeck.naturesaura.InternalHooks").getConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } /** * This method returns the active {@link IInternalHooks} instance which can * be used to hook into the mod's internal functionalities. * * @return The active {@link IInternalHooks} instance */ public static IInternalHooks instance() { return INSTANCE; } /** * @see #instance() */ public interface IInternalHooks { /** * Helper method to extract aura from an {@link IAuraContainer} in the * supplied player's inventory or baubles slots. The method returns true * if the aura could be extracted. Note that, if the player is in * creative mode, this method will always return true and no extraction * will take place. * * @param player The player * @param amount The amount to extract * @param simulate If the extraction should be simulated * @return If the extraction was successful */ boolean extractAuraFromPlayer(Player player, int amount, boolean simulate); /** * Helper method to insert aura into an {@link IAuraContainer} in the * supplied player's inventory or baubles slots. The method returns true * if the aura could be inserted. * * @param player The player * @param amount The amount to insert * @param simulate If the insertion should be simulated * @return If the insertion was successful */ boolean insertAuraIntoPlayer(Player player, int amount, boolean simulate); /** * This method can be used to spawn the magic particle effect used by * Nature's Aura. It will not have an effect on the client side, so if * you want to send it from the server side, you need to create your own * packet. * * @param posX The x position * @param posY The y position * @param posZ The z position * @param motionX The x motion * @param motionY The y motion * @param motionZ The z motion * @param color The color the particle should have, in hex * @param scale The scale of the particle * @param maxAge The max age before the particle should die * @param gravity The amount of gravity the particle should have, can * be 0 * @param collision If the particle should collide with blocks * @param fade If the particle should slowly fade out or suddenly * disappear */ void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade); /** * This method can be used to spawn the magic particle effect used by * Nature's Aura. The particle will be created to spawn at the start * position and move towards the end position, dying when it reaches it. * It will not have an effect on the client side, so if you want to send * it from the server side, you need to create your own packet. * * @param startX The start x * @param startY The start y * @param startZ The start z * @param endX The end x * @param endY The end y * @param endZ The end z * @param speed The speed at which the particle should go * @param color The color of the particle * @param scale The scale of the particle */ void spawnParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale); /** * Sets wether Nature's Aura particles that are spawned will be rendered * with depth test enabled or not. Default value is true, please reset * after changing. * * @param depth Wether depth test should be enabled or not */ void setParticleDepth(boolean depth); /** * Sets the range that Nature's Aura particles that are spawned will * have to have from the player at most to actually be spawned. Default * value is 32, please reset after changing. * * @param range The range that particle spawning should have */ void setParticleSpawnRange(int range); void setParticleCulling(boolean cull); /** * This method is used to create a custom multiblock from within the * API. The multiblock will automatically be registered both to Nature's * Aura's multiblock registry and Patchouli's multiblock registry. * * @param name The name the multiblock should have * @param pattern The pattern that the multiblock should have, where * each character is mapped to a raw matcher * @param rawMatchers Each char matcher in the form of the char followed * by a matcher, either in the form of a Block, an * BlockState or a {@link Matcher}, similar to the * old way that crafting recipes work. * @return the multiblock instance */ IMultiblock createMultiblock(ResourceLocation name, String[][] pattern, Object... rawMatchers); /** * Get all the active effect powders in the given area and consume the * position and the range that they have. To register a powder with the * supplied name, use {@link #EFFECT_POWDERS} * * @param level The level * @param area The area to find powders in * @param name The registry name of the powder * @return A list of powders' positions and ranges */ List> getActiveEffectPowders(Level level, AABB area, ResourceLocation name); /** * Returns true if there is an effect powder entity active anywhere * around the given position based on the radius it has. This is a * shorthand function of {@link #getActiveEffectPowders(Level, * net.minecraft.world.phys.AABB, ResourceLocation)} that returns true * if the list is non-empty * * @param level The level * @param pos The center position * @param name The registry name of the powder * @return If the effect is currently inhibited by any inhibitors */ boolean isEffectPowderActive(Level level, BlockPos pos, ResourceLocation name); /** * @see IAuraChunk#getSpotsInArea(Level, BlockPos, int, BiConsumer) */ void getAuraSpotsInArea(Level level, BlockPos pos, int radius, BiConsumer consumer); /** * @see IAuraChunk#getSpotAmountInArea(Level, BlockPos, int) */ int getSpotAmountInArea(Level level, BlockPos pos, int radius); /** * @see IAuraChunk#getAuraInArea(Level, BlockPos, int) */ int getAuraInArea(Level level, BlockPos pos, int radius); /** * @see IAuraChunk#getAuraAndSpotAmountInArea(Level, BlockPos, int) */ Pair getAuraAndSpotAmountInArea(Level level, BlockPos pos, int radius); /** * @see IAuraChunk#triangulateAuraInArea(Level, BlockPos, int) */ int triangulateAuraInArea(Level level, BlockPos pos, int radius); /** * @see IAuraChunk#getLowestSpot(Level, BlockPos, int, BlockPos) */ BlockPos getLowestAuraDrainSpot(Level level, BlockPos pos, int radius, BlockPos defaultSpot); /** * @see IAuraChunk#getHighestSpot(Level, BlockPos, int, BlockPos) */ BlockPos getHighestAuraDrainSpot(Level level, BlockPos pos, int radius, BlockPos defaultSpot); } }