Developer API 2.6.x - GrowthcraftCE/Growthcraft-1.7 GitHub Wiki
WIP This document is a WIP
While the CoreRegistry doesn't offer much right off the bat, it is meant as a core/base for other modules and offers common functionality for the other modules.
The API is accesible via:
import growthcraft.api.core.CoreRegistry;
CoreRegistry.instance();
If you'd like to create new item effects, then you can leverage Growthcraft's IEffect API in your project, or if you'd like to extend Growthcraft with new effects.
The main interface is IEffect
, it has 4 methods:
// IEffect
void apply(World world, Entity entity, Random random, Object data);
// IDescribable
void getDescription(List<String> list);
// INBTSerializableContext
void readFromNBT(NBTTagCompound data, String name);
void writeToNBT(NBTTagCompound data, String name);
All effects SHOULD be serializable via NBT data, this is to ensure that your effect is simple enough doesn't include something that cannot be explained easily in basic data.
Stock Effects:
-
EffectAddPotionEffect
: This effect is used to add a PotionEffect to the target. -
EffectChance
: Given a chance, the effect MAY apply. -
EffectList
: Applies all effects contained. -
EffectNull
: Does nothing, and will never do anything. -
EffectRandomList
: Applies a random effect from it's contained. -
EffectRemovePotionEffect
: Opposite of EffectAddPotionEffect, this will remove a PotionEffect. -
EffectWeightedRandomList
: Similar to EffectRandomList, but requires weights for each effect present.
Effects are meant to be composed of other effects, such as wrapping an EffectList
in a EffectChance
.
Effect descriptions have a similar function when applied, lets say you have an EffectChance
, which applies an EffectList
, its description could look like this:
25% of applying (
Potion Effect #1
Potion Effect #2
)
You could further place that EffectChance
into an EffectRandomList
along with an EffectRemovePotionEffect
:
Randomly applies one of (
25% of applying (
Potion Effect #1
Potion Effect #2
)
OR
Removes "Poison"
)
By creating a simple interface and smaller primitives, the system allows the creation of complex effects using smaller parts. The best part, the call signature never changes:
myAwesomeEffect.apply(world, entity, world.rand, null);
Doesn't matter if myAwesomeEffect
, is EffectNull
or EffectUberAwesomeThingThatWouldBringYourServerToItsKnees
.
In order to reload serialized effects, all effects are registered here:
final IEffectRegistry efr = CoreRegistry.instance().getEffectsRegistry();
// An example of how to register your effect.
efr.register("my_custom_effect", EffectMyCustomEffect.class);
The BeesRegistry allows you to manipulate the Growthcraft|Bees side of things, such as adding new bees, honey combs and flowers.
If you want to make booze, brew up something, ferment something, or in general mess around with the Growthcraft|Cellar, then you are looking into the CellarRegistry.
The API is accessible via:
import growthcraft.api.cellar.CellarRegistry;
CellarRegistry.instance();
So, you would like to add some nice booze to the Growthcraft registry, fear not its not that hard!
All you need is Growthcraft
(as in the the Growthcraft core
) and Growthcraft|Cellar
to get started.
import growthcraft.api.cellar.booze.BoozeEffect;
import growthcraft.api.cellar.booze.BoozeEntry;
import growthcraft.api.cellar.booze.BoozeTag;
import growthcraft.api.cellar.booze.effect.EffectTipsy;
import growthcraft.api.cellar.booze.BoozeRegistry;
import growthcraft.api.cellar.CellarRegistry;
import growthcraft.api.core.effect.EffectList;
...
final BoozeRegistry br = CellarRegistry.instance().booze();
br.registerBooze(yourBooze);
That's it your done. HOWEVER, ensure that your booze is registered to the Forge fluid registry first, or else, ALL HELL WILL BREAK LOOSE. Growthcraft will fail with an exception, we refuse to register any fluid that isn't in the FluidRegistry.
So you've registered your booze, and you'd like to leverage the rest of the API.
When you register a Booze, you also get a BoozeEntry (which automatically gives you a BoozeEffect and therefore the IEffect API, neat ain't it)
final BoozeEntry be = br.getBoozeEntry(booze);
final BoozeEffect boozeEffect = be.getEffect();
// Note you can also fetch the effect directly using br.getEffect(booze);
A BoozeEffect is composed of 2 effects, the first being the EffectTipsy
which adds the tipsy effect to the target, this is normally null by default, being "no tipsy effect", the second effect, is an EffectList
, this is where you add your own effects to the booze.
final EffectList effectList = beff.getEffects();
// BoozeEffect also offers some convenience methods for creating special PotionEffect entries
beff.addPotionEntry(potionInstance, time, level);
// This adds a new EffectAddPotionEffect using a BoozePotionEffectFactory
BoozePotionEffectFactory
is a implementation of the IPotionEffectFactory
interface, which is used by EffectAddPotionEffect
to create PotionEffects, simple enough right?
Booze entries also have tags.
Now tags are VERY important for booze, since they can have complex effects, which make it hard to find out what they are, we have BoozeTags
.
Growthcraft identifies booze characteristics via its tags, (even if they are misleading sometimes).
For example if a Booze has the FERMENTED
tag, then Growthcraft knows that its a fermented booze, and therefore prevents it from being used for creating yeast, instead a Booze must be tagged with YOUNG
in order to be used for creating yeast.
Tags have no Hard rule, just don't do something like FERMENTED and YOUNG
, which makes no sense.
// Tagging your booze
br.addTags(myYoungBooze, BoozeTag.YOUNG);
br.addTags(myFermentedBooze, BoozeTag.FERMENTED);
br.addTags(myPotentBooze, BoozeTag.FERMENTED, BoozeTag.POTENT);
// Checking tags
br.hasTags(myYoungBooze, BoozeTag.YOUNG); // true
br.hasTags(myYoungBooze, BoozeTag.YOUNG, BoozeTag.FERMENTED); // false
br.hasTags(myPotentBooze, BoozeTag.POTENT); // true
br.hasTags(myPotentBooze, BoozeTag.FERMENTED, BoozeTag.POTENT); // true
When you tag your booze accordingly, you also get the benefits of other helper methods, such as generating Thaumcraft Aspects for your Booze Entries, however that is a topic for later.
You can always define your own tags by creating a new BoozeTag, seriously
final BoozeTag EPIC = new BoozeTag("epic");
br.addTags(myEpicBooze, EPIC);
DO NOT CREATE A NEW BOOZETAG PER BOOZE. While we have no reason to enforce it, its a good idea to have a reusable tag to reduce memory usage.
In addition you can get the Tags LocalizedName
, which is pulled from grc.booze.tag.name
, for our EPIC tag, it would be grc.booze.tag.epic
, yes, it uses the name you passed in.
Tags are great and all, but they also serve a secondary function.
BoozeTag.POTENT.setModifierFunction(new ModifierPotent());
Yes, modifier functions, these functions are used to dynamically manipulate Booze Potion Effects, while you could just define each and every potion effect yourself, you can also just set your entire booze array to the base level of the Potion Effect and let the modifier functions scale them for you.
For example, if you added regeneration
to your booze effects at level 1, and you tag it with POTENT
, then your booze will be scaled to Level 2
.
We use multiple boozes with this, you set all of them to the same thing potion and the modifier function will scale them for you, so EXTENDED
booze will have their time doubled, and POTENT
will have their level increased, HYPER_EXTENDED
, will have the effect of POTENT
and EXTENDED
. POISONED
will tell Growthcraft that the booze is dangerous, but it doesn't have a modifier function.
Modifier functions only change level
and time
, if you want your booze to be poisoned
you must poison it yourself.
For example, Growthcraft|Nether
has Vile Slop, which is considered a POISONED
booze, however it applies negative buffs instead, it is only marked as POISONED
because it used Nether Rash
as its fermenting item.
All in, the Booze API is only 1 layer of the Growthcraft Cellar APIs.
The API is accessible via:
import growthcraft.api.cellar.CellarRegistry;
// optional if you want to grab the registry instance
import growthcraft.api.cellar.brewing.IBrewingRegistry;
final IBrewingRegistry brewingRegistry = CellarRegistry.instance().brewing();
The API is accessible via:
import growthcraft.api.cellar.CellarRegistry;
// optional if you want to grab the registry instance
import growthcraft.api.cellar.fermenting.IFermentingRegistry;
final IFermentingRegistry brewingRegistry = CellarRegistry.instance().brewing();
Adding new recipes for the Fruit Press is done via the Pressing Registry, accessible via:
import growthcraft.api.cellar.CellarRegistry;
import growthcraft.api.cellar.pressing.IPressingRegistry;
final IPressingRegistry reg = CellarRegistry.instance().pressing();
IPressingRegistry
has 3 methods
addRecipe
Adds new recipes to the registry
/**
* Add a new Pressing Recipe
*
* @param inputItem - an ItemStack, or ANY IMultiItemStack (OreItemStacks, MultiItemStacks)
* @param result - the output fluid
* @param time - how long does the item press in ticks
* @param residue - optional residue produced by the press
*/
void addRecipe(@Nonnull Object inputItem, @Nonnull FluidStack result, int time, @Nullable Residue residue);
/**
* @param src - the input item stack
* @return recipe if found or null
*/
PressingRecipe getPressingRecipe(ItemStack src);
NOTE getPressingRecipe will fail if the given stack size is smaller than the recipe item.
/**
* @param src - the input item stack
* @return true, a recipe exists; otherwise false
*/
boolean hasPressingRecipe(ItemStack src);
The API is accessible via:
import growthcraft.api.milk.MilkRegistry;
MilkRegistry.instance();
This
If you'd like to add new items to the Growthcraft|Fishtrap, this is the place to be.
The API is accessible via:
import growthcraft.api.fishtrap.FishTrapRegistry;
FishTrapRegistry.instance();