Added APIs, moved Nitro Creeper to Natura

master
mDiyo 2013-05-30 19:55:32 -07:00
parent 3bbd6a6947
commit 8a3dac472d
82 changed files with 4302 additions and 234 deletions

46
extrabiomes/api/Api.java Normal file
View File

@ -0,0 +1,46 @@
/**
* This work is licensed under the Creative Commons
* Attribution-ShareAlike 3.0 Unported License. To view a copy of this
* license, visit http://creativecommons.org/licenses/by-sa/3.0/.
*/
package extrabiomes.api;
import net.minecraftforge.event.EventBus;
import com.google.common.base.Optional;
/*
* @author ScottKillen
*/
public class Api {
private static final EventBus eventBus = new EventBus();
protected static Optional<EventBus> pluginBus = Optional.of(new EventBus());
public static EventBus getExtrabiomesXLEventBus() {
return eventBus;
}
/**
* @return true if ExtrtabiomesXL is installed and active
* @deprecated Use {@link #isExtrabiomesXLActive()} instead
*/
@Deprecated
public static boolean isActive() {
return isExtrabiomesXLActive();
}
/**
* @return true if ExtrtabiomesXL is installed and active
*/
@SuppressWarnings("deprecation")
public static boolean isExtrabiomesXLActive() {
return BiomeManager.isActive();
}
public static void registerPlugin(Object plugin) {
if (pluginBus.isPresent()) pluginBus.get().register(plugin);
}
}

View File

@ -0,0 +1,197 @@
/**
* This work is licensed under the Creative Commons
* Attribution-ShareAlike 3.0 Unported License. To view a copy of this
* license, visit http://creativecommons.org/licenses/by-sa/3.0/.
*/
package extrabiomes.api;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collection;
import java.util.Random;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.gen.feature.WorldGenerator;
import com.google.common.base.Optional;
/**
* Allows direct access to Extrabiome's biomes. This class' members will
* be populated during the @Init event. If a biome is absent after the
* Init event, then the Extrabiomes mod is not active or not installed.
* <p>
* <b>NOTE:</b> Make sure to only reference members of this class in the
* PostInit event or later.
*
* @author ScottKillen
*
*/
// The BiomeManager will be removed following release 3.6.0. Use extrabiomes.api.Biomes instead
@Deprecated
public abstract class BiomeManager {
protected enum GenType {
TREE, GRASS;
}
public static Optional<? extends BiomeGenBase> alpine = Optional.absent();
public static Optional<? extends BiomeGenBase> autumnwoods = Optional.absent();
public static Optional<? extends BiomeGenBase> birchforest = Optional.absent();
public static Optional<? extends BiomeGenBase> extremejungle = Optional.absent();
public static Optional<? extends BiomeGenBase> forestedisland = Optional.absent();
public static Optional<? extends BiomeGenBase> forestedhills = Optional.absent();
public static Optional<? extends BiomeGenBase> glacier = Optional.absent();
public static Optional<? extends BiomeGenBase> greenhills = Optional.absent();
public static Optional<? extends BiomeGenBase> icewasteland = Optional.absent();
public static Optional<? extends BiomeGenBase> greenswamp = Optional.absent();
public static Optional<? extends BiomeGenBase> marsh = Optional.absent();
public static Optional<? extends BiomeGenBase> meadow = Optional.absent();
public static Optional<? extends BiomeGenBase> minijungle = Optional.absent();
public static Optional<? extends BiomeGenBase> mountaindesert = Optional.absent();
public static Optional<? extends BiomeGenBase> mountainridge = Optional.absent();
public static Optional<? extends BiomeGenBase> mountaintaiga = Optional.absent();
public static Optional<? extends BiomeGenBase> pineforest = Optional.absent();
public static Optional<? extends BiomeGenBase> rainforest = Optional.absent();
public static Optional<? extends BiomeGenBase> redwoodforest = Optional.absent();
public static Optional<? extends BiomeGenBase> redwoodlush = Optional.absent();
public static Optional<? extends BiomeGenBase> savanna = Optional.absent();
public static Optional<? extends BiomeGenBase> shrubland = Optional.absent();
public static Optional<? extends BiomeGenBase> snowforest = Optional.absent();
public static Optional<? extends BiomeGenBase> snowyrainforest = Optional.absent();
public static Optional<? extends BiomeGenBase> temperaterainforest = Optional.absent();
public static Optional<? extends BiomeGenBase> tundra = Optional.absent();
public static Optional<? extends BiomeGenBase> wasteland = Optional.absent();
public static Optional<? extends BiomeGenBase> woodlands = Optional.absent();
protected static Optional<? extends BiomeManager> instance = Optional.absent();
/**
* This method allows the addition of grasses to custom biomes by
* weight.
*
* @param biome
* the biomes to add the tree to.
* @param grassGen
* the grass generator
* @param weight
* the relative probabilty of picking this grass to
* generate. To establish a relative priority, some
* function should be applied to the current total weight
* for a biome.
*/
public static void addWeightedGrassGenForBiome(BiomeGenBase biome,
WorldGenerator grassGen, int weight)
{
checkArgument(instance.isPresent(),
"Cannot add weighted grass gens until after API is initialized.");
checkNotNull(biome, "Biome is required.");
checkNotNull(grassGen, "Grass generator is required.");
checkArgument(weight > 0, "Weight must be greater than zero.");
instance.get().addBiomeGen(GenType.GRASS, biome, grassGen,
weight);
}
/**
* This method allows the addition of trees to custom biomes by
* weight.
*
* @param biome
* the biomes to add the tree to.
* @param treeGen
* the tree generator
* @param weight
* the relative probabilty of picking this tree to
* generate. To establish a relative priority, some
* function should be applied to the current total weight
* for a biome.
*/
public static void addWeightedTreeGenForBiome(BiomeGenBase biome,
WorldGenerator treeGen, int weight)
{
checkArgument(instance.isPresent(),
"Cannot add weighted tree gens until after API is initialized.");
checkNotNull(biome, "Biome is required.");
checkNotNull(treeGen, "Tree Generator is required.");
checkArgument(weight > 0, "Weight must be greater than zero.");
instance.get()
.addBiomeGen(GenType.TREE, biome, treeGen, weight);
}
/**
* Returns a random choice from the weighted list of grass
* generators
*
* @param biome
* The biome for which to select a grass gen
* @return the selected grass generator.
*/
public static Optional<? extends WorldGenerator> chooseRandomGrassGenforBiome(
Random rand, BiomeGenBase biome)
{
return instance.get().chooseBiomeRandomGen(GenType.GRASS, rand,
biome);
}
/**
* Returns a random choice from the weighted list of tree generators
*
* @param biome
* The biome for which to select a tree gen
* @return the selected tree generator.
*/
public static Optional<? extends WorldGenerator> chooseRandomTreeGenforBiome(
Random rand, BiomeGenBase biome)
{
return instance.get().chooseBiomeRandomGen(GenType.TREE, rand,
biome);
}
/**
* @return An immutable collection of this mod's biomes.
*/
public static Collection<BiomeGenBase> getBiomes() {
checkArgument(instance.isPresent(),
"Biome list not available until after API is initialized.");
return instance.get().getBiomeCollection();
}
/**
* @param biome
* The biome for which to calculate the total weight.
* @return the total weight of all grassGen choices for a given
* biome
*/
public static int getTotalGrassWeightForBiome(BiomeGenBase biome) {
checkNotNull(biome, "Biome is required.");
return instance.get().getBiomeTotalWeight(GenType.GRASS, biome);
}
/**
* @param biome
* The biome for which to calculate the total weight.
* @return the total weight of all treeGen choices for a given biome
*/
public static int getTotalTreeWeightForBiome(BiomeGenBase biome) {
checkNotNull(biome, "Biome is required.");
return instance.get().getBiomeTotalWeight(GenType.TREE, biome);
}
static boolean isActive() {
return instance.isPresent();
}
protected abstract void addBiomeGen(GenType genType,
BiomeGenBase biome, WorldGenerator treeGen, int weight);
protected abstract Optional<? extends WorldGenerator> chooseBiomeRandomGen(
GenType genType, Random rand, BiomeGenBase biome);
protected abstract Collection<BiomeGenBase> getBiomeCollection();
protected abstract int getBiomeTotalWeight(GenType genType,
BiomeGenBase biome);
}

View File

@ -0,0 +1,39 @@
/**
* This work is licensed under the Creative Commons
* Attribution-ShareAlike 3.0 Unported License. To view a copy of this
* license, visit http://creativecommons.org/licenses/by-sa/3.0/.
*/
package extrabiomes.api;
import net.minecraft.world.biome.BiomeGenBase;
import com.google.common.base.Optional;
import extrabiomes.api.events.GetBiomeIDEvent;
/**
* Provides access to custom biomes. Reference implementation.
*
* @author Scott
*
*/
public abstract class Biomes {
/**
* Retrieves a custom biome
*
* @param targetBiome
* The string name of the targertBiome. See
* {@link GetBiomeIDEvent#targetBiome} for valid values.
* @return The requested biome. If the biome does not exist, the
* <code>Optional</code> value will not be present.
*/
public static Optional<BiomeGenBase> getBiome(String targetBiome) {
final GetBiomeIDEvent event = new GetBiomeIDEvent(targetBiome);
Api.getExtrabiomesXLEventBus().post(event);
if (event.biomeID <= 0) return Optional.absent();
return Optional.of(BiomeGenBase.biomeList[event.biomeID]);
}
}

View File

@ -0,0 +1,38 @@
/**
* This work is licensed under the Creative Commons
* Attribution-ShareAlike 3.0 Unported License. To view a copy of this
* license, visit http://creativecommons.org/licenses/by-sa/3.0/.
*/
package extrabiomes.api;
import java.util.Collection;
import net.minecraft.world.WorldType;
import net.minecraftforge.event.Event;
/**
* This event fires on the ExtrabiomesXL event bus when biomes are added
* to WorldTypes.
*/
public class DiscoverWorldTypesEvent extends Event {
private final Collection<WorldType> worldTypes;
public DiscoverWorldTypesEvent(Collection<WorldType> worldTypes) {
this.worldTypes = worldTypes;
}
/**
* Adds a WorldType to the list of WorldTypes to which ExtrabiomesXL
* will add its enabled biomes.
*
* @param worldType
* The WorldType to Add
* @return true if worldType was successfully added
*/
public boolean addWorldType(WorldType worldType) {
if (worldTypes.contains(worldType)) return false;
return worldTypes.add(worldType);
}
}

View File

@ -0,0 +1,31 @@
/**
* This work is licensed under the Creative Commons
* Attribution-ShareAlike 3.0 Unported License. To view a copy of this
* license, visit http://creativecommons.org/licenses/by-sa/3.0/.
*/
package extrabiomes.api;
import net.minecraftforge.event.Event;
/**
* These events are fired during FML @PostInit to manage plugins
*/
public class PluginEvent extends Event {
/**
* Fired before any ExtrabiomesXL plugin is initialized
*/
public static class Pre extends PluginEvent {}
/**
* Fired to initialize ExtrabiomesXL plugins
*/
public static class Init extends PluginEvent {}
/**
* Fired after every ExtrabiomesXL plugin is initialized
*/
public static class Post extends PluginEvent {}
}

View File

@ -0,0 +1,34 @@
package extrabiomes.api;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import com.google.common.base.Optional;
/**
* This class contains all of the custom items and blocks.
*
* @author ScottKillen
*
*/
public enum Stuff {
INSTANCE;
public static Optional<? extends Item> scarecrow = Optional.absent();
public static Optional<? extends Item> paste = Optional.absent();
public static Optional<? extends Block> planks = Optional.absent();
public static Optional<? extends Block> quickSand = Optional.absent();
public static Optional<? extends Block> slabRedRock = Optional.absent();
public static Optional<? extends Block> slabRedRockDouble = Optional.absent();
public static Optional<? extends Block> slabWood = Optional.absent();
public static Optional<? extends Block> slabWoodDouble = Optional.absent();
public static Optional<? extends Block> stairsAcacia = Optional.absent();
public static Optional<? extends Block> stairsFir = Optional.absent();
public static Optional<? extends Block> stairsRedCobble = Optional.absent();
public static Optional<? extends Block> stairsRedRockBrick = Optional.absent();
public static Optional<? extends Block> stairsRedwood = Optional.absent();
public static Optional<? extends Block> wall = Optional.absent();
}

View File

@ -0,0 +1,44 @@
/**
* This work is licensed under the Creative Commons
* Attribution-ShareAlike 3.0 Unported License. To view a copy of this
* license, visit http://creativecommons.org/licenses/by-sa/3.0/.
*/
package extrabiomes.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.entity.player.PlayerEvent;
@Cancelable
public class UseLogTurnerEvent extends PlayerEvent {
public final ItemStack current;
public final World world;
public final int x;
public final int y;
public final int z;
private boolean handled = false;
public UseLogTurnerEvent(EntityPlayer player, ItemStack current,
World world, int x, int y, int z)
{
super(player);
this.current = current;
this.world = world;
this.x = x;
this.y = y;
this.z = z;
}
public boolean isHandled() {
return handled;
}
public void setHandled() {
handled = true;
}
}

View File

@ -0,0 +1,61 @@
/**
* This work is licensed under the Creative Commons
* Attribution-ShareAlike 3.0 Unported License. To view a copy of this
* license, visit http://creativecommons.org/licenses/by-sa/3.0/.
*/
package extrabiomes.api.events;
import net.minecraftforge.event.Event;
/**
* Used by the API to retrieve a biomeID
*
* @author Scott
*
*/
public class GetBiomeIDEvent extends Event {
/**
* Valid values:
*
* <pre>
* ALPINE
* AUTUMNWOODS
* BIRCHFOREST
* EXTREMEJUNGLE
* FORESTEDHILLS
* FORESTEDISLAND
* GLACIER
* GREENHILLS
* GREENSWAMP
* ICEWASTELAND
* MARSH
* MEADOW
* MINIJUNGLE
* MOUNTAINDESERT
* MOUNTAINRIDGE
* MOUNTAINTAIGA
* PINEFOREST
* RAINFOREST
* REDWOODFOREST
* REDWOODLUSH
* SAVANNA
* SHRUBLAND
* SNOWYFOREST
* SNOWYRAINFOREST
* TEMPORATERAINFOREST
* TUNDRA
* WASTELAND
* WOODLANDS
* </pre>
*/
public final String targetBiome;
public int biomeID;
public GetBiomeIDEvent(String targetBiome) {
this.targetBiome = targetBiome;
}
}

107
ic2/api/Direction.java Normal file
View File

@ -0,0 +1,107 @@
package ic2.api;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
/**
* Represents the 6 possible directions along the axis of a block.
*/
public enum Direction {
/**
* -X
*/
XN(0),
/**
* +X
*/
XP(1),
/**
* -Y
*/
YN(2), //MC-Code starts with 0 here
/**
* +Y
*/
YP(3), // 1...
/**
* -Z
*/
ZN(4),
/**
* +Z
*/
ZP(5);
Direction(int dir) {
this.dir = dir;
}
/*public CoordinateTuple ApplyToCoordinates(CoordinateTuple coordinates) {
CoordinateTuple ret = new CoordinateTuple(coordinates);
ret.coords[dir/2] += GetSign();
return ret;
}*/
/**
* Get the tile entity next to a tile entity following this direction.
*
* @param tileEntity tile entity to check
* @return Adjacent tile entity or null if none exists
*/
public TileEntity applyToTileEntity(TileEntity tileEntity) {
int coords[] = { tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord };
coords[dir/2] += getSign();
if (tileEntity.worldObj != null && tileEntity.worldObj.blockExists(coords[0], coords[1], coords[2])) {
return tileEntity.worldObj.getBlockTileEntity(coords[0], coords[1], coords[2]);
} else {
return null;
}
}
/**
* Get the inverse of this direction (XN -> XP, XP -> XN, etc.)
*
* @return Inverse direction
*/
public Direction getInverse() {
int inverseDir = dir - getSign();
for (Direction direction : directions) {
if (direction.dir == inverseDir) return direction;
}
return this;
}
/**
* Convert this direction to a Minecraft side value.
*
* @return Minecraft side value
*/
public int toSideValue() {
return (dir + 4) % 6;
}
/**
* Determine direction sign (N for negative or P for positive).
*
* @return -1 if the direction is negative, +1 if the direction is positive
*/
private int getSign() {
return (dir % 2) * 2 - 1;
}
public ForgeDirection toForgeDirection() {
return ForgeDirection.getOrientation(toSideValue());
}
private int dir;
private static final Direction[] directions = Direction.values();
}

View File

@ -0,0 +1,56 @@
package ic2.api.crops;
/**
* Base agriculture seed. Used to determine the state of a plant once it is planted from an item.
*/
public class BaseSeed {
/**
* Plant ID.
*/
public int id;
/**
* Plant size.
*/
public int size;
/**
* Plant growth stat.
*/
public int statGrowth;
/**
* Plant gain stat.
*/
public int statGain;
/**
* Plant resistance stat.
*/
public int statResistance;
/**
* For internal usage only.
*/
public int stackSize;
/**
* Create a BaseSeed object.
*
* @param id plant ID
* @param size plant size
* @param statGrowth plant growth stat
* @param statGain plant gain stat
* @param statResistance plant resistance stat
* @param stackSize for internal usage only
*/
public BaseSeed(int id, int size, int statGrowth, int statGain, int statResistance, int stackSize) {
super();
this.id = id;
this.size = size;
this.statGrowth = statGrowth;
this.statGain = statGain;
this.statResistance = statResistance;
this.stackSize = stackSize;
}
}

366
ic2/api/crops/CropCard.java Normal file
View File

@ -0,0 +1,366 @@
package ic2.api.crops;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* Base agriculture crop.
*
* Any crop extending this can be registered using registerCrop to be added into the game.
*/
public abstract class CropCard
{
/**
* Plant name. Will be displayed to the player.
*
* @return Plant name
*/
public abstract String name();
/**
* Your name here, will be shown in "Discovered by:" when analyzing seeds.
*
* @return Your name
*/
public String discoveredBy() {return "Alblaka";}
/**
* Description of your plant. Keep it short, a few characters per line for up to two lines.
* Default is showing attributes of your plant, 2 per line.
*
* @param i line to get, starting from 0
* @return The line
*/
public String desc(int i)
{
String[] att = attributes();
if (att == null || att.length==0) return "";
if (i == 0)
{
String s = att[0];
if (att.length >= 2)
{
s+=", "+att[1];
if (att.length >= 3) s+=",";
}
return s;
}
else
{
if (att.length < 3) return "";
String s = att[2];
if (att.length >= 4) s+=", "+att[3];
return s;
}
}
/**
* Tier of the plant. Ranges from 1 to 16, 0 is Weed.
* Valuable and powerful crops have higher tiers, useless and weak ones have lower tiers.
*
* @return Tier
*/
public abstract int tier();
/**
* Describe the plant through a set of stats, influencing breeding.
* Plants sharing stats and attributes will tend to cross-breed more often.
*
* Stats:
* - 0: Chemistry (Industrial uses based on chemical plant components)
* - 1: Consumable (Food, potion ingredients, stuff meant to be eaten or similarly used)
* - 2: Defensive (Plants with defense capabilities (damaging, explosive, chemical) or special abilities in general)
* - 3: Colorful (How colorful/aesthetically/beautiful is the plant, like dye-plants or plants without actual effects)
* - 4: Weed (Is this plant weed-like and rather unwanted/quick-spreading? Rare super-breed plants should have low values here)
*
* @param n index of the requested stat
* @return The requested value of the stats
*/
public abstract int stat(int n);
/**
* Additional attributes of the plant, also influencing breeding.
* Plants sharing stats and attributes will tend to cross-breed more often.
*
* @return Attributes as an array of strings
*/
public abstract String[] attributes();
/**
* Determine the max crop size.
*
* Currently only used for texture allocation.
*/
public abstract int maxSize();
/**
* Instantiate your Icons here.
*
* This method will get called by IC2, don't call it yourself.
*/
@SideOnly(Side.CLIENT)
public void registerSprites(IconRegister iconRegister) {
textures = new Icon[maxSize()];
for (int i = 1; i <= textures.length; i++) {
textures[i-1] = iconRegister.registerIcon("ic2:crop/blockCrop."+name()+"."+i);
}
}
/**
* Sprite the crop is meant to be rendered with.
*
* @param crop reference to ICropTile
* @return 0-255, representing the sprite index on the crop's spritesheet.
*/
@SideOnly(Side.CLIENT)
public Icon getSprite(ICropTile crop) {
if (crop.getSize() <= 0 || crop.getSize() > textures.length) return null;
return textures[crop.getSize() - 1];
}
/**
* Get the crop's spritesheet.
* Per default crops_0.png of ic2-sprites
* @return Texture file path
*/
public String getTextureFile() {
return "/ic2/sprites/crops_0.png";
}
/**
* Amount of growth points needed to increase the plant's size.
* Default is 200 * tier.
*/
public int growthDuration(ICropTile crop)
{
return tier()*200;
}
/**
* Check whether the plant can grow further.
*
* Consider:
* - Humidity, nutrients and air quality
* - Current size
* - Light level
* - Special biomes or conditions, accessible through crop.worldObj
*
* This method will be called upon empty upgraded crops to check whether a neighboring plant can cross onto it! Don't check if the size is greater than 0 and if the ID is real.
*
* @param crop reference to ICropTile
* @return Whether the crop can grow
*/
public abstract boolean canGrow(ICropTile crop);
/**
* Calculate the influence for the plant to grow based on humidity, nutrients and air.
* Normal behavior is rating the three stats "normal", with each of them ranging from 0-30.
* Basic rule: Assume everything returns 10. All together must equal 30. Add the factors to your likings, for example (humidity*0.7)+(nutrients*0.9)+(air*1.4)
*
* Default is humidity + nutrients + air (no factors).
*
* @param crop reference to ICropTile
* @param humidity ground humidity, influenced by hydration
* @param nutrients nutrient quality in ground, based on fertilizers
* @param air air quality, influences by open gardens and less crops surrounding this one
* @return 0-30
*/
public int weightInfluences(ICropTile crop, float humidity, float nutrients, float air)
{
return (int) (humidity+nutrients+air);
}
/**
* Used to determine whether the plant can crossbreed with another crop.
* Default is allow crossbreeding if the size is greater or equal than 3.
*
* @param crop crop to crossbreed with
*/
public boolean canCross(ICropTile crop)
{
return crop.getSize() >= 3;
}
/**
* Called when the plant is rightclicked by a player.
* Default action is harvesting.
*
* @param crop reference to ICropTile
* @param player player rightclicking the crop
* @return Whether the plant has changed
*/
public boolean rightclick(ICropTile crop, EntityPlayer player)
{
return crop.harvest(true);
}
/**
* Check whether the crop can be harvested.
*
* @param crop reference to ICropTile
* @return Whether the crop can be harvested in its current state.
*/
public abstract boolean canBeHarvested(ICropTile crop);
/**
* Base chance for dropping the plant's gains, specify values greater than 1 for multiple drops.
* Default is 0.95^tier.
*
* @return Chance to drop the gains
*/
public float dropGainChance()
{
float base = 1F;
for (int i = 0; i < tier(); i++) {base*=0.95;}
return base;
}
/**
* Item obtained from harvesting the plant.
*
* @param crop reference to ICropTile
* @return Item obtained
*/
public abstract ItemStack getGain(ICropTile crop);
/**
* Get the size of the plant after harvesting.
* Default is 1.
*
* @param crop reference to ICropTile
* @return Plant size after harvesting
*/
public byte getSizeAfterHarvest(ICropTile crop) {return 1;}
/**
* Called when the plant is leftclicked by a player.
* Default action is picking the plant.
*
* @param crop reference to ICropTile
* @param player player leftclicked the crop
* @return Whether the plant has changed
*/
public boolean leftclick(ICropTile crop, EntityPlayer player)
{
return crop.pick(true);
}
/**
* Base chance for dropping seeds when the plant is picked.
* Default is 0.5*0.8^tier with a bigger chance for sizes greater than 2 and absolutely no chance for size 0.
*
* @param crop reference to ICropTile
* @return Chance to drop the seeds
*/
public float dropSeedChance(ICropTile crop)
{
if (crop.getSize() == 1) return 0;
float base = 0.5F;
if (crop.getSize() == 2) base/=2F;
for (int i = 0; i < tier(); i++) {base*=0.8;}
return base;
}
/**
* Obtain seeds dropped when the plant is picked.
* Multiple drops of the returned ItemStack can occur.
* Default action is generating a seed from this crop.
*
* @param crop reference to ICropTile
* @return Seeds
*/
public ItemStack getSeeds(ICropTile crop)
{
return crop.generateSeeds(crop.getID(), crop.getGrowth(), crop.getGain(), crop.getResistance(), crop.getScanLevel());
}
/**
* Called when a neighbor block to the crop has changed.
*
* @param crop reference to ICropTile
*/
public void onNeighbourChange(ICropTile crop){}
/**
* Check if the crop should emit redstone.
*
* @return Whether the crop should emit redstone
*/
public int emitRedstone(ICropTile crop){return 0;}
/**
* Called when the crop is destroyed.
*
* @param crop reference to ICropTile
*/
public void onBlockDestroyed(ICropTile crop){}
/**
* Get the light value emitted by the plant.
*
* @param crop reference to ICropTile
* @return Light value emitted
*/
public int getEmittedLight(ICropTile crop) {return 0;}
/**
* Default is true if the entity is an EntityLiving in jumping or sprinting state.
*
* @param crop reference to ICropTile
* @param entity entity colliding
* @return Whether trampling calculation should happen, return false if the plant is no longer valid.
*/
public boolean onEntityCollision(ICropTile crop, Entity entity)
{
if (entity instanceof EntityLiving)
{
return ((EntityLiving)entity).isSprinting();
}
return false;
}
/**
* Called every time the crop ticks.
* Should be called every 256 ticks or around 13 seconds.
*
* @param crop reference to ICropTile
*/
public void tick(ICropTile crop) {}
/**
* Check whether this plant spreads weed to surrounding tiles.
* Default is true if the plant has a high growth stat (or is weeds) and size greater or equal than 2.
*
* @param crop reference to ICropTile
* @return Whether the plant spreads weed
*/
public boolean isWeed(ICropTile crop)
{
return crop.getSize()>=2 && (crop.getID()==0 || crop.getGrowth()>=24);
}
/**
* Get this plant's ID.
*
* @return ID of this CropCard or -1 if it's not registered
*/
public final int getId()
{
return Crops.instance.getIdFor(this);
}
@SideOnly(Side.CLIENT)
protected Icon textures[];
}

103
ic2/api/crops/Crops.java Normal file
View File

@ -0,0 +1,103 @@
package ic2.api.crops;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.item.ItemStack;
import net.minecraft.world.biome.BiomeGenBase;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* General management of the crop system.
*/
public abstract class Crops {
public static Crops instance;
/**
* Adds a crop humidity and nutrient biome bonus.
*
* 0 indicates no bonus and negative values indicate a penalty.
*
* @param biome Biome to apply the bonus in
* @param humidityBonus Humidity stat bonus
* @param nutrientsBonus Nutrient stat bonus
*/
public abstract void addBiomeBonus(BiomeGenBase biome, int humidityBonus, int nutrientsBonus);
/**
* Gets the humidity bonus for a biome.
*
* @param biome Biome to check
* @return Humidity bonus or 0 if none
*/
public abstract int getHumidityBiomeBonus(BiomeGenBase biome);
/**
* Gets the nutrient bonus for a biome.
*
* @param biome Biome to check
* @return Nutrient bonus or 0 if none
*/
public abstract int getNutrientBiomeBonus(BiomeGenBase biome);
/**
* Returns the list of registered crops.
*
* @return Registered crops by ID
*/
public abstract CropCard[] getCropList();
/**
* Auto-assign an ID to a plant and register it.
* Usage of this method is not recommended! Other plants could take your IDs and cause your plants to turn into other plants.
*
* @param crop plant to register
* @return The ID assigned to the plant
*/
public abstract short registerCrop(CropCard crop);
/**
* Attempt to register a plant to an ID.
* If the ID is taken, the crop will not be registered and a console print will notify the user.
*
* @param crop plant to register
* @param i ID to register the plant to
* @return Whether the crop was registered
*/
public abstract boolean registerCrop(CropCard crop, int i);
/**
* Registers a base seed, an item used to plant a crop.
*
* @param stack item
* @param id plant ID
* @param size initial size
* @param growth initial growth stat
* @param gain initial gain stat
* @param resistance initial resistance stat
* @return True if successful
*/
public abstract boolean registerBaseSeed(ItemStack stack, int id, int size, int growth, int gain, int resistance);
/**
* Finds a base seed from the given item.
*
* @return Base seed or null if none found
*/
public abstract BaseSeed getBaseSeed(ItemStack stack);
/**
* Execute registerSprites for all registered crop cards.
*
* This method will get called by IC2, don't call it yourself.
*/
@SideOnly(Side.CLIENT)
public abstract void startSpriteRegistration(IconRegister iconRegister);
/**
* Returns the ID for the given crop.
*
* @param crop Crop to look up
* @return ID, or -1 if not found
*/
public abstract int getIdFor(CropCard crop);
}

View File

@ -0,0 +1,253 @@
package ic2.api.crops;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
/**
* Interface implemented by the crop tile entity.
*/
public interface ICropTile {
/**
* Get the crop's plant ID.
*
* @return Plant ID, or -1 if there is no plant currently on the crop
*/
public short getID();
/**
* Set the crop's plant ID.
*
* @param id Plant ID, or -1 for no plant
*/
public void setID(short id);
/**
* Get the crop's plant size.
*
* @return Plant size, starting with 1 and maximum varies depending on plant
*/
public byte getSize();
/**
* Set the crop's plant size.
*
* @param size Plant size
*/
public void setSize(byte size);
/**
* Get the crop's plant growth stat.
* Higher values indicate faster growth.
*
* @return Plant growth stat
*/
public byte getGrowth();
/**
* Set the crop's plant growth stat.
*
* @param growth Plant growth stat
*/
public void setGrowth(byte growth);
/**
* Get the crop's plant gain stat.
* Higher values indicate more drops.
*
* @return Plant gain stat
*/
public byte getGain();
/**
* Set the crop's plant gain stat.
*
* @param gain Plant gain stat
*/
public void setGain(byte gain);
/**
* Get the crop's plant resistance stat.
* Higher values indicate more resistance against trampling.
*
* @return Plant resistance stat
*/
public byte getResistance();
/**
* Set the crop's plant resistance stat.
*
* @param resistance Plant resistance stat
*/
public void setResistance(byte resistance);
/**
* Get the crop's plant scan level.
* Increases every time the seed is analyzed.
*
* @return Plant scan level
*/
public byte getScanLevel();
/**
* Set the crop's plant scan level.
*
* @param scanLevel Plant scan level
*/
public void setScanLevel(byte scanLevel);
/**
* Get the crop's plant custom data, stored alongside the crop.
* Can be modified in place.
*
* @return Plant custom data
*/
public NBTTagCompound getCustomData();
/**
* Get the crop's nutrient storage.
* Ranges from 0 to 100.
*
* @return Crop nutrient storage
*/
public int getNutrientStorage();
/**
* Set the crop's nutrient storage.
*
* @param nutrientStorage Crop nutrient storage
*/
public void setNutrientStorage(int nutrientStorage);
/**
* Get the crop's hydration storage.
* 0 indicates nothing, 1-10 indicate water hydration and 11-100 for hydration cells.
*
* @return Crop hydration storage
*/
public int getHydrationStorage();
/**
* Set the crop's hydration storage.
*
* @param hydrationStorage Crop hydration storage
*/
public void setHydrationStorage(int hydrationStorage);
/**
* Get the crop's Weed-Ex storage.
*
* @return Crop Weed-Ex storage
*/
public int getWeedExStorage();
/**
* Set the crop's Weed-Ex storage.
*
* @param weedExStorage Crop Weed-Ex storage
*/
public void setWeedExStorage(int weedExStorage);
/**
* Get the crop's humidity.
* Ranges from 0 (dry) to 10 (humid).
* Updates every couple of seconds or when an update is requested.
*
* @see #updateState()
*
* @return Crop humidity level
*/
public byte getHumidity();
/**
* Get the crop's nutrient level.
* Ranges from 0 (empty) to 10 (full).
* Updates every couple of seconds or when an update is requested.
*
* @see #updateState()
*
* @return Crop nutrient level
*/
public byte getNutrients();
/**
* Get the crop's air quality.
* Ranges from 0 (cluttered) to 10 (fresh).
* Updates every couple of seconds or when an update is requested.
*
* @see #updateState()
*
* @return Crop air quality
*/
public byte getAirQuality();
/**
* Get the crop's world.
*
* @return Crop world
*/
public World getWorld();
/**
* Get the crop's location.
*
* @return Crop location
*/
public ChunkCoordinates getLocation();
/**
* Get the crop's light level.
*
* @return Crop light level
*/
public int getLightLevel();
/**
* Pick the crop, removing and giving seeds for the plant.
*
* @param manual whether it was done by hand (not automated)
* @return true if successfully picked
*/
public boolean pick(boolean manual);
/**
* Harvest the crop, turning it into gain and resetting its size.
*
* @param manual whether it one by hand (not automated)
* @return true if successfully harvested
*/
public boolean harvest(boolean manual);
/**
* Fully clears the crop without dropping anything.
*/
public void reset();
/**
* Request a texture and lighting update.
*/
public void updateState();
/**
* Check if a block is under the farmland containing the crop.
* Searches up to 2 blocks below the farmland or an air space, whichever appears first.
*
* @param block block to search
* @return Whether the block was found
*/
public boolean isBlockBelow(Block block);
/**
* Generate plant seeds with the given parameters.
*
* @param plant plant ID
* @param growth plant growth stat
* @param gain plant gain stat
* @param resis plant resistance stat
* @param scan plant scan level
* @return Plant seed item
*/
public ItemStack generateSeeds(short plant, byte growth, byte gain, byte resis, byte scan);
}

View File

@ -0,0 +1,175 @@
package ic2.api.energy;
import java.lang.reflect.Method;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import ic2.api.energy.tile.IEnergySource;
/**
* Provides access to the energy network.
*/
public final class EnergyNet {
/**
* Gets the EnergyNet instance for the specified world.
*
* @param world world
* @return EnergyNet instance for the world
*/
public static EnergyNet getForWorld(World world) {
try {
if (EnergyNet_getForWorld == null) EnergyNet_getForWorld = Class.forName(getPackage() + ".core.EnergyNet").getMethod("getForWorld", World.class);
return new EnergyNet(EnergyNet_getForWorld.invoke(null, world));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private EnergyNet(Object energyNetInstance) {
this.energyNetInstance = energyNetInstance;
}
/**
* Add a tile entity to the energy network.
* The tile entity has to be valid and initialized.
*
* @param addedTileEntity tile entity to add
*
* @deprecated use EnergyTileLoadEvent instead
*/
@Deprecated
public void addTileEntity(TileEntity addedTileEntity) {
try {
if (EnergyNet_addTileEntity == null) EnergyNet_addTileEntity = Class.forName(getPackage() + ".core.EnergyNet").getMethod("addTileEntity", TileEntity.class);
EnergyNet_addTileEntity.invoke(energyNetInstance, addedTileEntity);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Removes a tile entity from the energy network.
* The tile entity has to be still valid.
*
* @param removedTileEntity tile entity to remove
*
* @deprecated use EnergyTileUnloadEvent instead
*/
@Deprecated
public void removeTileEntity(TileEntity removedTileEntity) {
try {
if (EnergyNet_removeTileEntity == null) EnergyNet_removeTileEntity = Class.forName(getPackage() + ".core.EnergyNet").getMethod("removeTileEntity", TileEntity.class);
EnergyNet_removeTileEntity.invoke(energyNetInstance, removedTileEntity);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Emit energy from an energy source to the energy network.
*
* @param energySource energy source to emit energy from
* @param amount amount of energy to emit in EU
* @return Leftover (unused) power
*
* @deprecated use EnergyTileSourceEvent instead
*/
@Deprecated
public int emitEnergyFrom(IEnergySource energySource, int amount) {
try {
if (EnergyNet_emitEnergyFrom == null) EnergyNet_emitEnergyFrom = Class.forName(getPackage() + ".core.EnergyNet").getMethod("emitEnergyFrom", IEnergySource.class, Integer.TYPE);
return ((Integer) EnergyNet_emitEnergyFrom.invoke(energyNetInstance, energySource, amount)).intValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Get the amount of energy currently being conducted by a conductor.
* Call this twice with a delay to get the average conducted power by doing (call2 - call1) / 2.
*
* @param tileEntity conductor
*
* @deprecated use getTotalEnergyEmitted and getTotalEnergySunken instead
*/
@Deprecated
public long getTotalEnergyConducted(TileEntity tileEntity) {
try {
if (EnergyNet_getTotalEnergyConducted == null) EnergyNet_getTotalEnergyConducted = Class.forName(getPackage() + ".core.EnergyNet").getMethod("getTotalEnergyConducted", TileEntity.class);
return ((Long) EnergyNet_getTotalEnergyConducted.invoke(energyNetInstance, tileEntity)).longValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* determine how much energy has been emitted by the EnergyEmitter specified
*
* @note call this twice with x ticks delay to get the avg. emitted power p = (call2 - call1) / x EU/tick
*
* @param tileEntity energy emitter
*/
public long getTotalEnergyEmitted(TileEntity tileEntity) {
try {
if (EnergyNet_getTotalEnergyEmitted == null) EnergyNet_getTotalEnergyEmitted = Class.forName(getPackage() + ".core.EnergyNet").getMethod("getTotalEnergyEmitted", TileEntity.class);
return ((Long) EnergyNet_getTotalEnergyEmitted.invoke(energyNetInstance, tileEntity)).longValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* determine how much energy has been sunken by the EnergySink specified
*
* @note call this twice with x ticks delay to get the avg. sunken power p = (call2 - call1) / x EU/tick
*
* @param tileEntity energy emitter
*/
public long getTotalEnergySunken(TileEntity tileEntity) {
try {
if (EnergyNet_getTotalEnergySunken == null) EnergyNet_getTotalEnergySunken = Class.forName(getPackage() + ".core.EnergyNet").getMethod("getTotalEnergySunken", TileEntity.class);
return ((Long) EnergyNet_getTotalEnergySunken.invoke(energyNetInstance, tileEntity)).longValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Get the base IC2 package name, used internally.
*
* @return IC2 package name, if unable to be determined defaults to ic2
*/
private static String getPackage() {
Package pkg = EnergyNet.class.getPackage();
if (pkg != null) {
String packageName = pkg.getName();
return packageName.substring(0, packageName.length() - ".api.energy".length());
}
return "ic2";
}
/**
* Instance of the energy network.
*/
Object energyNetInstance;
private static Method EnergyNet_getForWorld;
private static Method EnergyNet_addTileEntity;
private static Method EnergyNet_removeTileEntity;
private static Method EnergyNet_emitEnergyFrom;
private static Method EnergyNet_getTotalEnergyConducted;
private static Method EnergyNet_getTotalEnergyEmitted;
private static Method EnergyNet_getTotalEnergySunken;
}

View File

@ -0,0 +1,17 @@
package ic2.api.energy.event;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.event.world.WorldEvent;
import ic2.api.energy.tile.IEnergyTile;
public class EnergyTileEvent extends WorldEvent {
public final IEnergyTile energyTile;
public EnergyTileEvent(IEnergyTile energyTile) {
super(((TileEntity) energyTile).worldObj);
this.energyTile = energyTile;
}
}

View File

@ -0,0 +1,24 @@
package ic2.api.energy.event;
import ic2.api.energy.tile.IEnergyTile;
/**
* Event announcing new energy tiles.
*
* This event notifies subscribers of loaded energy tiles, e.g. after getting
* loaded through the chunk they are in or after being placed down by the
* player or another deployer mechanism.
*
* Every energy tile which wants to get connected to the IC2 Energy Network has
* to either post this event or alternatively call EnergyNet.addTileEntity().
*
* You may use this event to build a static representation of energy tiles for
* your own energy grid implementation if you need to. It's not required if you
* always lookup energy paths on demand.
*/
public class EnergyTileLoadEvent extends EnergyTileEvent {
public EnergyTileLoadEvent(IEnergyTile energyTile) {
super(energyTile);
}
}

View File

@ -0,0 +1,33 @@
package ic2.api.energy.event;
import ic2.api.energy.tile.IEnergySource;
/**
* Event announcing an energy source operation.
*
* This event notifies subscribers of energy sources trying to push energy into
* an energy grid.
*
* The amount field indicates the maximum amount of energy left to be
* distributed. You have to substract the amount of energy you accepted from
* 'amount'.
*
* The IEnergySource posting this event has to check 'amount' to see how much
* energy has not been used up and adjust its output buffer accordingly
* (usually buffer -= 'initial amount' - 'amount after posting the event')
*/
public class EnergyTileSourceEvent extends EnergyTileEvent {
/**
* Amount of energy provided by the energy source.
*
* amount needs to be adjusted to show the remaining unused energy.
*/
public int amount;
public EnergyTileSourceEvent(IEnergySource energySource, int amount) {
super(energySource);
this.amount = amount;
}
}

View File

@ -0,0 +1,25 @@
package ic2.api.energy.event;
import ic2.api.energy.tile.IEnergyTile;
/**
* Event announcing terminated energy tiles.
*
* This event notifies subscribers of unloaded energy tiles, e.g. after getting
* unloaded through the chunk they are in or after being destroyed by the
* player or another block pick/destruction mechanism.
*
* Every energy tile which wants to get disconnected from the IC2 Energy
* Network has to either post this event or alternatively call
* EnergyNet.removeTileEntity().
*
* You may use this event to build a static representation of energy tiles for
* your own energy grid implementation if you need to. It's not required if you
* always lookup energy paths on demand.
*/
public class EnergyTileUnloadEvent extends EnergyTileEvent {
public EnergyTileUnloadEvent(IEnergyTile energyTile) {
super(energyTile);
}
}

View File

@ -0,0 +1,22 @@
package ic2.api.energy.tile;
import net.minecraft.tileentity.TileEntity;
import ic2.api.Direction;
/**
* For internal usage only.
*
* @see IEnergySink
* @see IEnergyConductor
*/
public interface IEnergyAcceptor extends IEnergyTile {
/**
* Determine if this acceptor can accept current from an adjacent emitter in a direction.
*
* @param emitter energy emitter
* @param direction direction the energy is being received from
*/
boolean acceptsEnergyFrom(TileEntity emitter, Direction direction);
}

View File

@ -0,0 +1,51 @@
package ic2.api.energy.tile;
/**
* Tile entities which conduct energy pulses without buffering (mostly cables) have to implement this
* interface.
*/
public interface IEnergyConductor extends IEnergyAcceptor, IEnergyEmitter {
/**
* Energy loss for the conductor in EU per block.
*
* @return Energy loss
*/
double getConductionLoss();
/**
* Amount of energy the insulation will handle before shocking nearby players and mobs.
*
* @return Insulation energy absorption in EU
*/
int getInsulationEnergyAbsorption();
/**
* Amount of energy the insulation will handle before it is destroyed.
* Ensure that this value is greater than the insulation energy absorption + 64.
*
* @return Insulation-destroying energy in EU
*/
int getInsulationBreakdownEnergy();
/**
* Amount of energy the conductor will handle before it melts.
*
* @return Conductor-destroying energy in EU
*/
int getConductorBreakdownEnergy();
/**
* Remove the conductor's insulation if the insulation breakdown energy was exceeded.
*
* @see #getInsulationBreakdownEnergy()
*/
void removeInsulation();
/**
* Remove the conductor if the conductor breakdown energy was exceeded.
*
* @see #getConductorBreakdownEnergy()
*/
void removeConductor();
}

View File

@ -0,0 +1,23 @@
package ic2.api.energy.tile;
import net.minecraft.tileentity.TileEntity;
import ic2.api.Direction;
/**
* For internal usage only.
*
* @see IEnergySource
* @see IEnergyConductor
*/
public interface IEnergyEmitter extends IEnergyTile {
/**
* Determine if this emitter can emit energy to an adjacent receiver.
*
* @param receiver receiver
* @param direction direction the receiver is from the emitter
* @return Whether energy should be emitted
*/
boolean emitsEnergyTo(TileEntity receiver, Direction direction);
}

View File

@ -0,0 +1,41 @@
package ic2.api.energy.tile;
import ic2.api.Direction;
/**
* Allows a tile entity (mostly a machine) to receive energy.
*/
public interface IEnergySink extends IEnergyAcceptor {
/**
* Determine how much energy the sink accepts.
*
* This value is unrelated to getMaxSafeInput().
*
* Make sure that injectEnergy() does accepts energy if demandsEnergy() returns anything > 0.
*
* @return max accepted input in eu
*/
int demandsEnergy();
/**
* Transfer energy to the sink.
*
* @param directionFrom direction from which the energy comes from
* @param amount energy to be transferred
* @return Energy not consumed (leftover)
*/
int injectEnergy(Direction directionFrom, int amount);
/**
* Determine the amount of eu which can be safely injected into the specific energy sink without exploding.
*
* Typical values are 32 for LV, 128 for MV, 512 for HV and 2048 for EV. A value of Integer.MAX_VALUE indicates no
* limit.
*
* This value is unrelated to demandsEnergy().
*
* @return max safe input in eu
*/
int getMaxSafeInput();
}

View File

@ -0,0 +1,15 @@
package ic2.api.energy.tile;
/**
* Allows a tile entity (mostly a generator) to emit energy.
*/
public interface IEnergySource extends IEnergyEmitter {
/**
* Maximum energy output provided by the source.
* If unsure, use Integer.MAX_VALUE.
*
* @return Maximum energy output
*/
int getMaxEnergyOutput();
}

View File

@ -0,0 +1,18 @@
package ic2.api.energy.tile;
/**
* For internal usage only.
*
* @see IEnergySink
* @see IEnergySource
* @see IEnergyConductor
*/
public interface IEnergyTile {
/**
* Determine if this tile entity has been added to the energy network
*
* @return Whether the tile entity has been added
*/
boolean isAddedToEnergyNet();
}

101
ic2/api/energy/usage.txt Normal file
View File

@ -0,0 +1,101 @@
-----------------------------------------------------
-- How to implement your own energy network blocks --
-----------------------------------------------------
There are currently three different types of energy network blocks:
- energy sources, e.g. generators or the output side of a storage block/transformer
- energy sinks, e.g. machines or the input side of a storage block/transformer
- conductors, e.g. cables
Note that storage blocks or transformers are both sources and sinks.
All those blocks have to have a tile entity which has to implement the interface corresponding to
its function and also post events to the Forge event bus.
The energy generation, distribution and consumption is strictly limited to the simulating (server)
side, use the proper side checks before posting the related events. One possibility is to check for
FMLCommonHandler.instance().getEffectiveSide().isClient() being false.
The energy network works by sources pushing energy into the grid through EnergyTileSourceEvent,
conductors will carry the energy to sinks which will then receive it through injectEnergy().
-- EnergyTileLoadEvent --
For all energy network tiles (sources, sinks, conductors) you have to post an EnergyTileLoadEvent.
The event has to be posted as soon as the implementing tile entity is fully loaded, usually after
loading the chunk which contains it or after the user placing the block.
The energy net implementation will use the event to add it to its energy grid map, taking it into
account for further energy transfers.
You can detect the loading by either using the 1st iteration of updateEntity() or by waiting for
the next world tick after TileEntity.validate(). The 2nd approach is obviously more sophisticated
and requires to use some tick queuing mechanism.
The event can by posted as following:
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
-- EnergyTileUnloadEvent --
Another event every energy tile has to post is the EnergyTileUnloadEvent.
The event has to be posted as soon as the implementing tile entity is being unloaded, either by
unloading the containing chunk or by destroying the block containing it.
It's possible to detect the unloading by triggering on both the beginning of
TileEntity.invalidate() and the beginning of TileEntity.onChunkUnload().
It is important that the tile entity is still properly linked to the world while posting the unload
event, otherwise the energy net can't find all affected connections.
-- energy source --
An energy source has to post the following events:
- EnergyTileLoadEvent on load
- EnergyTileUnloadEvent on unload
- EnergyTileSourceEvent whenever it wants to send energy
Additionally the interface IEnergySource has to be implemented.
The EnergyTileSourceEvent contains a field amount, which should be evaluated after having posted
the event. The value determines how much energy couldn't be delivered somewhere.
-- energy sink --
An energy sink has to post the following events:
- EnergyTileLoadEvent on load
- EnergyTileUnloadEvent on unload
Additionally the interface IEnergySink has to be implemented.
The method demandsEnergy() will be called fairly often and should be implemented with performance
in mind. It's usually recommended to always fill some small internal buffer regardless of other
conditions, e.g. even if an enabling redstone signal is off.
-- energy conductor --
An energy conductor has to post the following events:
- EnergyTileLoadEvent on load
- EnergyTileUnloadEvent on unload
Additionally the interface IEnergyConductor has to be implemented.
--------------------------------------------------
-- How to implement/add your own energy network --
--------------------------------------------------
If you want to create an alternative way of distributing energy, e.g. to have different
distribution rules or to use energy networks provided by other mods, you can register to the energy
tile events and use the interfaces to handle the energy distribution yourself. It's no longer
required to use conversion blocks.
IC2's EnergyNet itself is built on top of the api events and interfaces, providing their default
use case.
Note that is you have a pull-type energy network which lets the sinks retrieve energy from the
sources instead of IC2's method of pushing energy from the sources to the sinks, you'll currently
have to monitor the energy sinks regularly for their energy demand and start/stop pulling energy
accordingly. The load and unload events will tell you when to start/stop monitoring demandsEnergy.

View File

@ -0,0 +1,30 @@
package ic2.api.event;
import net.minecraft.world.World;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.world.WorldEvent;
@Cancelable
public class PaintEvent extends WorldEvent {
// target block
public final int x;
public final int y;
public final int z;
public final int side;
// color to paint the block
public final int color;
// set to true to confirm the operation
public boolean painted = false;
public PaintEvent(World world, int x, int y, int z, int side, int color) {
super(world);
this.x = x;
this.y = y;
this.z = z;
this.side = side;
this.color = color;
}
}

View File

@ -0,0 +1,35 @@
package ic2.api.event;
import net.minecraft.world.World;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.world.WorldEvent;
@Cancelable
public class RetextureEvent extends WorldEvent {
// target block
public final int x;
public final int y;
public final int z;
public final int side;
// referenced block (to grab the texture from)
public final int referencedBlockId;
public final int referencedMeta;
public final int referencedSide;
// set to true to confirm the operation
public boolean applied = false;
public RetextureEvent(World world, int x, int y, int z, int side, int referencedBlockId, int referencedMeta, int referencedSide) {
super(world);
this.x = x;
this.y = y;
this.z = z;
this.side = side;
this.referencedBlockId = referencedBlockId;
this.referencedMeta = referencedMeta;
this.referencedSide = referencedSide;
}
}

View File

@ -0,0 +1,134 @@
package ic2.api.item;
import java.lang.reflect.Method;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* Allows for charging, discharging and using electric items (IElectricItem).
*
* The charge or remaining capacity of an item can be determined by calling charge/discharge with
* ignoreTransferLimit and simulate set to true.
*/
public final class ElectricItem {
/**
* Charge an item with a specified amount of energy
*
* @param itemStack electric item's stack
* @param amount amount of energy to charge in EU
* @param tier tier of the charging device, has to be at least as high as the item to charge
* @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
* @param simulate don't actually change the item, just determine the return value
* @return Energy transferred into the electric item
*/
public static int charge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate) {
try {
if (ElectricItem_charge == null) ElectricItem_charge = Class.forName(getPackage() + ".core.item.ElectricItem").getMethod("charge", ItemStack.class, Integer.TYPE, Integer.TYPE, Boolean.TYPE, Boolean.TYPE);
return (Integer) ElectricItem_charge.invoke(null, itemStack, amount, tier, ignoreTransferLimit, simulate);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Discharge an item by a specified amount of energy
*
* @param itemStack electric item's stack
* @param amount amount of energy to charge in EU
* @param tier tier of the discharging device, has to be at least as high as the item to discharge
* @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
* @param simulate don't actually discharge the item, just determine the return value
* @return Energy retrieved from the electric item
*/
public static int discharge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate) {
try {
if (ElectricItem_discharge == null) ElectricItem_discharge = Class.forName(getPackage() + ".core.item.ElectricItem").getMethod("discharge", ItemStack.class, Integer.TYPE, Integer.TYPE, Boolean.TYPE, Boolean.TYPE);
return (Integer) ElectricItem_discharge.invoke(null, itemStack, amount, tier, ignoreTransferLimit, simulate);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Determine if the specified electric item has at least a specific amount of EU.
* This is supposed to be used in the item code during operation, for example if you want to implement your own electric item.
* BatPacks are not taken into account.
*
* @param itemStack electric item's stack
* @param amount minimum amount of energy required
* @return true if there's enough energy
*/
public static boolean canUse(ItemStack itemStack, int amount) {
try {
if (ElectricItem_canUse == null) ElectricItem_canUse = Class.forName(getPackage() + ".core.item.ElectricItem").getMethod("canUse", ItemStack.class, Integer.TYPE);
return (Boolean) ElectricItem_canUse.invoke(null, itemStack, amount);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Try to retrieve a specific amount of energy from an Item, and if applicable, a BatPack.
* This is supposed to be used in the item code during operation, for example if you want to implement your own electric item.
*
* @param itemStack electric item's stack
* @param amount amount of energy to discharge in EU
* @param player player holding the item
* @return true if the operation succeeded
*/
public static boolean use(ItemStack itemStack, int amount, EntityPlayer player) {
try {
if (ElectricItem_use == null) ElectricItem_use = Class.forName(getPackage() + ".core.item.ElectricItem").getMethod("use", ItemStack.class, Integer.TYPE, EntityPlayer.class);
return (Boolean) ElectricItem_use.invoke(null, itemStack, amount, player);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Charge an item from the BatPack a player is wearing.
* This is supposed to be used in the item code during operation, for example if you want to implement your own electric item.
* use() already contains this functionality.
*
* @param itemStack electric item's stack
* @param player player holding the item
*/
public static void chargeFromArmor(ItemStack itemStack, EntityPlayer player) {
try {
if (ElectricItem_chargeFromArmor == null) ElectricItem_chargeFromArmor = Class.forName(getPackage() + ".core.item.ElectricItem").getMethod("chargeFromArmor", ItemStack.class, EntityPlayer.class);
ElectricItem_chargeFromArmor.invoke(null, itemStack, player);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Get the base IC2 package name, used internally.
*
* @return IC2 package name, if unable to be determined defaults to ic2
*/
private static String getPackage() {
Package pkg = ElectricItem.class.getPackage();
if (pkg != null) {
String packageName = pkg.getName();
return packageName.substring(0, packageName.length() - ".api.item".length());
}
return "ic2";
}
private static Method ElectricItem_charge;
private static Method ElectricItem_discharge;
private static Method ElectricItem_canUse;
private static Method ElectricItem_use;
private static Method ElectricItem_chargeFromArmor;
}

View File

@ -0,0 +1,18 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
/**
* Provides custom toolbox storage behavior for items.
*
* The normal condition for storing an item in a toolbox is having a maximum stack size of 1.
*/
public interface IBoxable {
/**
* Determine whether an item can be stored in a toolbox or not.
*
* @param itemstack item to be stored
* @return Whether to store the item in the toolbox or not
*/
public abstract boolean canBeStoredInToolbox(ItemStack itemstack);
}

View File

@ -0,0 +1,64 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
/**
* Provides the ability to store energy on the implementing item.
*
* This interface is a special version of IElectricItem which delegates the implementation of
* charge(), discharge() and canUse() to the implementing Item.
*
* The default implementation (when not using ICustomElectricItem) does the following:
* - store and retrieve the charge
* - handle charging, taking amount, tier, transfer limit and simulate into account
* - replace item IDs if appropriate (getChargedItemId() and getEmptyItemId())
* - update and manage the damage value for the visual charge indicator
*
* @note ICustomElectricItem must not call the ElectricItem methods charge, discharge or canUse
*/
public interface ICustomElectricItem extends IElectricItem {
/**
* Charge an item with a specified amount of energy
*
* @param itemStack electric item's stack
* @param amount amount of energy to charge in EU
* @param tier tier of the charging device, has to be at least as high as the item to charge
* @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
* @param simulate don't actually change the item, just determine the return value
* @return Energy transferred into the electric item
*/
public int charge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate);
/**
* Discharge an item by a specified amount of energy
*
* @param itemStack electric item's stack
* @param amount amount of energy to charge in EU
* @param tier tier of the discharging device, has to be at least as high as the item to discharge
* @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
* @param simulate don't actually discharge the item, just determine the return value
* @return Energy retrieved from the electric item
*/
public int discharge(ItemStack itemStack, int amount, int tier, boolean ignoreTransferLimit, boolean simulate);
/**
* Determine if the specified electric item has at least a specific amount of EU.
* This is supposed to be used in the item code during operation, for example if you want to implement your own electric item.
* BatPacks are not taken into account.
*
* @param itemStack electric item's stack
* @param amount minimum amount of energy required
* @return true if there's enough energy
*/
public boolean canUse(ItemStack itemStack, int amount);
/**
* Determine whether to show the charge tool tip with NEI or other means.
*
* Return false if IC2's handler is incompatible, you want to implement your own or you don't
* want to display the charge at all.
*
* @return true to show the tool tip (x/y EU)
*/
public boolean canShowChargeToolTip(ItemStack itemStack);
}

View File

@ -0,0 +1,54 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
/**
* Provides the ability to store energy on the implementing item.
*
* The item should have a maximum damage of 13.
*/
public interface IElectricItem {
/**
* Determine if the item can be used in a machine or as an armor part to supply energy.
*
* @return Whether the item can supply energy
*/
boolean canProvideEnergy(ItemStack itemStack);
/**
* Get the item ID to use for a charge energy greater than 0.
*
* @return Item ID to use
*/
int getChargedItemId(ItemStack itemStack);
/**
* Get the item ID to use for a charge energy of 0.
*
* @return Item ID to use
*/
int getEmptyItemId(ItemStack itemStack);
/**
* Get the item's maximum charge energy in EU.
*
* @return Maximum charge energy
*/
int getMaxCharge(ItemStack itemStack);
/**
* Get the item's tier, lower tiers can't send energy to higher ones.
* Batteries are Tier 1, Energy Crystals are Tier 2, Lapotron Crystals are Tier 3.
*
* @return Item's tier
*/
int getTier(ItemStack itemStack);
/**
* Get the item's transfer limit in EU per transfer operation.
*
* @return Transfer limit
*/
int getTransferLimit(ItemStack itemStack);
}

View File

@ -0,0 +1,20 @@
package ic2.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* Armor items implementing this can be considered metal armor.
*
* Currently used for determining which boots can be used to slide up a magnetic pole.
*/
public interface IMetalArmor {
/**
* Determine if the given armor piece is metal armor.
*
* @param itemstack Armor piece as worn by the player
* @param player The player
* @return Whether the armor piece is metal armor
*/
public boolean isMetalArmor(ItemStack itemstack, EntityPlayer player);
}

View File

@ -0,0 +1,35 @@
package ic2.api.item;
import net.minecraft.world.World;
/**
* Allows an item to act as a terraformer blueprint.
*/
public interface ITerraformingBP
{
/**
* Get the energy consumption per operation of the blueprint.
*
* @return Energy consumption in EU
*/
public abstract int getConsume();
/**
* Get the maximum range of the blueprint.
* Should be a divisor of 5.
*
* @return Maximum range in blocks
*/
public abstract int getRange();
/**
* Perform the terraforming operation.
*
* @param world world to terraform
* @param x X position to terraform
* @param z Z position to terraform
* @param yCoord Y position of the terraformer
* @return Whether the operation was successful and the terraformer should consume energy.
*/
public abstract boolean terraform(World world, int x, int z, int yCoord);
}

View File

@ -0,0 +1,50 @@
package ic2.api.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
/**
* Wrapper for inserting interfaces into items you don't own.
*
* @author Richard
*/
public class ItemWrapper {
private static final Multimap<Item, IBoxable> boxableItems = ArrayListMultimap.create();
private static final Multimap<Item, IMetalArmor> metalArmorItems = ArrayListMultimap.create();
public static void registerBoxable(Item item, IBoxable boxable) {
boxableItems.put(item, boxable);
}
public static boolean canBeStoredInToolbox(ItemStack stack) {
Item item = stack.getItem();
// use customs first to allow for overriding behavior
for (IBoxable boxable : boxableItems.get(item)) {
if (boxable.canBeStoredInToolbox(stack)) return true;
}
if (item instanceof IBoxable && ((IBoxable) item).canBeStoredInToolbox(stack)) return true;
return false;
}
public static void registerMetalArmor(Item item, IMetalArmor armor) {
metalArmorItems.put(item, armor);
}
public static boolean isMetalArmor(ItemStack stack, EntityPlayer player) {
Item item = stack.getItem();
// use customs first to allow for overriding behavior
for (IMetalArmor metalArmor : metalArmorItems.get(item)) {
if (metalArmor.isMetalArmor(stack, player)) return true;
}
if (item instanceof IMetalArmor && ((IMetalArmor) item).isMetalArmor(stack, player)) return true;
return false;
}
}

407
ic2/api/item/Items.java Normal file
View File

@ -0,0 +1,407 @@
package ic2.api.item;
import net.minecraft.item.ItemStack;
/**
* Provides access to IC2 blocks and items.
*
* Some items can be acquired through the ore dictionary which is the recommended way.
* The items are initialized while IC2 is being loaded - try to use ModsLoaded() or load your mod after IC2.
* Some blocks/items can be disabled by a config setting, so it's recommended to check if they're null first.
*
* Getting the associated Block/Item for an ItemStack x:
* Blocks: Block.blocksList[x.itemID]
* Items: x.getItem()
*/
public final class Items {
/**
* Get an ItemStack for a specific item name, example: Items.getItem("resin")
* See the list below for item names.
* Make sure to copy() the ItemStack if you want to modify it.
*
* @param name item name
* @return The item or null if the item does not exist or an error occurred
*/
public static ItemStack getItem(String name) {
try {
if (Ic2Items == null) Ic2Items = Class.forName(getPackage() + ".core.Ic2Items");
Object ret = Ic2Items.getField(name).get(null);
if (ret instanceof ItemStack) {
return (ItemStack) ret;
} else {
return null;
}
} catch (Exception e) {
System.out.println("IC2 API: Call getItem failed for "+name);
return null;
}
}
/* Possible values:
----- blocks -----
ores
copperOre Copper Ore block, currently not meta sensitive, meta in ItemStack set to 0, ore dictionary: oreCopper, null with enableWorldGenOreCopper=false
tinOre Tin Ore block, currently not meta sensitive, meta in ItemStack set to 0, ore dictionary: oreTin, null with enableWorldGenOreTin=false
uraniumOre Tin Ore block, currently not meta sensitive, meta in ItemStack set to 0, ore dictionary: oreUranium, null with enableWorldGenOreUranium=false
rubber related
Rubber wood block, meta reflects the state, meta in ItemStack set to 0, ore dictionary: woodRubber (with meta 0), null with enableWorldGenTreeRubber=false
dropped (as an item) -> metadata 0
block, no resin spot -> metadata 0 or 1
block, wet resin spot -> metadata 2-5 (according to the side)
block, dry resin spot -> metadata 8-11 (wet state + 6)
rubberWood
rubberLeaves Rubber Leaves block, currently not meta sensitive, meta in ItemStack set to 0, null with enableWorldGenTreeRubber=false
rubberSapling Rubber Sapling block, currently not meta sensitive, meta in ItemStack set to 0, null with enableWorldGenTreeRubber=false
resinSheet Resin Sheet block, currently not meta sensitive
rubberTrampoline Rubber Trampoline block, meta reflects internal state, meta in ItemStack set to 0
building/storage
ironFence Iron Fence block, currently not meta sensitive
reinforcedStone Reinforced Stone block, currently not meta sensitive
reinforcedGlass Reinforced Glass block, currently not meta sensitive
reinforcedDoorBlock Reinforced Door block, meta reflects the state (see vanilla doors), meta in ItemStack set to 0
constructionFoam Construction Foam block, currently not meta sensitive
constructionFoamWall Construction Foam Wall block, meta = color, implements IPaintableBlock
scaffold Scaffold block, meta reflects internal physical model data
bronzeBlock Bronze block, meta sensitive
copperBlock Copper block, meta sensitive
tinBlock Tin block, meta sensitive
uraniumBlock Uranium block, meta sensitive
cables (when placed as a block, inventory items are different TE implements IEnergyConductor)
copperCableBlock Copper Cable block, meta sensitive
insulatedCopperCableBlock Insulated Copper Cable block, meta sensitive
goldCableBlock Gold Cable block, meta sensitive
insulatedGoldCableBlock Insulated Gold Cable block, meta sensitive
doubleInsulatedGoldCableBlock Double Insulated Gold Cable block, meta sensitive
ironCableBlock Iron Cable block, meta sensitive
insulatedIronCableBlock Insulated Iron Cable block, meta sensitive
doubleInsulatedIronCableBlock Double Insulated Iron Cable block, meta sensitive
trippleInsulatedIronCableBlock Tripple Insulated Iron Cable block, meta sensitive
glassFiberCableBlock Glass Fiber Cable block, meta sensitive
tinCableBlock Tin Cable block, meta sensitive
detectorCableBlock Detector Cable block, meta sensitive
splitterCableBlock Splitter Cable block, meta sensitive
generators + related (TE implements IEnergySource ex. reactorChamber)
generator Generator block, meta sensitive
geothermalGenerator Geothermal Generator block, meta sensitive
waterMill Water Mill block, meta sensitive
solarPanel Solar Panel block, meta sensitive
windMill Wind Mill block, meta sensitive
nuclearReactor Nuclear Reactor block, meta sensitive
reactorChamber Reactor Chamber block, currently not meta sensitive
energy storages (TE implements IEnergySource and IEnergyConductor)
batBox BatBox block, meta sensitive
mfeUnit MFE Unit block, meta sensitive
mfsUnit MFS Unit block, meta sensitive
transformers (TE implements IEnergySource and IEnergyConductor)
lvTransformer LV Transformer block, meta sensitive
mvTransformer MV Transformer block, meta sensitive
hvTransformer HV Transformer block, meta sensitive
machines + related (TE implements IEnergySink ex. machine, miningPipe, miningPipeTip)
machine Machine block, meta sensitive
advancedMachine Advanced Machine block, meta sensitive
ironFurnace Iron Furnace block, meta sensitive
electroFurnace Electro Furnace block, meta sensitive
macerator Macerator block, meta sensitive
extractor Extractor block, meta sensitive
compressor Compressor block, meta sensitive
canner Canner block, meta sensitive
miner Miner block, meta sensitive
pump Pump block, meta sensitive
magnetizer Magnetizer block, meta sensitive
electrolyzer Electrolyzer block, meta sensitive
recycler Recycler block, meta sensitive
inductionFurnace Induction Furnace block, meta sensitive
massFabricator Mass Fabricator block, meta sensitive
terraformer Terraformer block, meta sensitive
teleporter Teleporter block, meta sensitive
teslaCoil Tesla Coil block, meta sensitive
luminator Passive (dark) Luminator block, meta = facing
activeLuminator Active (bright) Luminator block, meta = facing
miningPipe Mining Pipe block, currently not meta sensitive, meta in ItemStack set to 0
miningPipeTip Mining Pipe Tip block, currently not meta sensitive, meta in ItemStack set to 0
personal blocks
personalSafe Personal Safe block, meta sensitive
tradeOMat Trade-O-Mat block, meta sensitive
energyOMat Energy-O-Mat block, meta sensitive
explosives
industrialTnt Industrial TNT block, currently not meta sensitive
nuke Nuke block, currently not meta sensitive
dynamiteStick Dynamite Stick block, meta = placement, meta in ItemStack set to 0
dynamiteStickWithRemote Dynamite Stick with Remote block, meta = placement, meta in ItemStack set to 0
Agriculture Stuff
crop Crop Block, empty, not meta sensitive
----- items -----
rubber + related
resin Resin item, currently not meta sensitive
rubber Rubber item, currently not meta sensitive, ore dictionary: itemRubber
ore drops
uraniumDrop Uranium Drop item, currently not meta sensitive, ore dictionary: itemDropUranium
dusts
bronzeDust Bronze Dust item, currently not meta sensitive
clayDust Clay Dust item, currently not meta sensitive
coalDust Coal Dust item, currently not meta sensitive
copperDust Copper Dust item, currently not meta sensitive
goldDust Gold Dust item, currently not meta sensitive
ironDust Iron Dust item, currently not meta sensitive
silverDust Silver Dust item, currently not meta sensitive
smallIronDust Small Iron Dust item, currently not meta sensitive
tinDust Tin Dust item, currently not meta sensitive
hydratedCoalDust Hydrated Coal Dust item, currently not meta sensitive
ingots
refinedIronIngot Refined Iron Ingot item, currently not meta sensitive, ore dictionary: ingotRefinedIron
copperIngot Copper Ingot item, currently not meta sensitive, ore dictionary: ingotCopper
tinIngot Tin Ingot item, currently not meta sensitive, ore dictionary: ingotTin
bronzeIngot Bronze Ingot item, currently not meta sensitive, ore dictionary: ingotBronze
mixedMetalIngot Mixed Metal Ingot item, currently not meta sensitive
uraniumIngot Uranium Ingot item, currently not meta sensitive, ore dictionary: ingotUranium
tools/weapons (without electric tools)
treetap Treetap item, meta = damage value
wrench Wrench item, meta = damage value
cutter Insulation Cutter item, meta = damage value
constructionFoamSprayer Construction Foam Sprayer item, meta = charges (as of v1.45)
bronzePickaxe Bronze Pickaxe item, meta = damage value
bronzeAxe Bronze Axe item, meta = damage value
bronzeSword Bronze Sword item, meta = damage value
bronzeShovel Bronze Shovel item, meta = damage value
bronzeHoe Bronze Hoe item, meta = damage value
el. tools/devices/weapons
miningDrill Mining Drill item, meta = visual charge indicator, implements IElectricItem
diamondDrill Diamond Tipped Mining Drill item, meta = visual charge indicator, implements IElectricItem
chainsaw Chainsaw item, meta = visual charge indicator, implements IElectricItem
electricWrench Electric Wrench item, meta = visual charge indicator, implements IElectricItem
electricTreetap Electric Treetap item, meta = visual charge indicator, implements IElectricItem
miningLaser Mining Laser item, meta = visual charge indicator, implements IElectricItem
ecMeter EC-Mater item, currently not meta sensitive
odScanner Ore Density Scanner item, meta = damage value for charge level, implements IElectricItem
ovScanner Ore Value Scanner item, meta = visual charge indicator, implements IElectricItem
frequencyTransmitter Frequency Transmitter item, currently not meta sensitive
nanoSaber Idle Nano Saber item, meta = visual charge indicator, implements IElectricItem
enabledNanoSaber Enabled Nano Saber item, meta = visual charge indicator, implements IElectricItem
armor/wearable
rubberBoots Rubber Boots item, meta = damage value
bronzeHelmet Bronze Helmet Armor item, meta = damage value
bronzeChestplate Bronze Chestplate Armor item, meta = damage value
bronzeLeggings Bronze Leggings Armor item, meta = damage value
bronzeBoots Bronze Boots Armor item, meta = damage value
compositeArmor Composite Armor item, meta = damage value for charge level
nanoHelmet Nano Helmet Armor item, meta = visual charge indicator, implements IElectricItem
nanoBodyarmor Nano Bodyarmor item, meta = visual charge indicator, implements IElectricItem
nanoLeggings Nano Leggings Armor item, meta = visual charge indicator, implements IElectricItem
nanoBoots Nano Boots Armor item, meta = visual charge indicator, implements IElectricItem
quantumHelmet Quantum Helmet Armor item, meta = visual charge indicator, implements IElectricItem
quantumBodyarmor Quantum Bodyarmor item, meta = visual charge indicator, implements IElectricItem
quantumLeggings Quantum Leggings Armor item, meta = visual charge indicator, implements IElectricItem
quantumBoots Quantum Boots Armor item, meta = visual charge indicator, implements IElectricItem
jetpack Jetpack item, meta = damage value for fuel level
electricJetpack Electric Jetpack item, meta = visual charge indicator, implements IElectricItem
batPack BatPack item, meta = visual charge indicator, implements IElectricItem, can provide energy
lapPack LapPack item, meta = visual charge indicator, implements IElectricItem, can provide energy
cfPack CF Pack item, meta = charges (as of v1.45)
solarHelmet Solar Helmet item, currently not meta sensitive
staticBoots Static Boots item, currently not meta sensitive
batteries
reBattery Empty RE Battery item, currently not meta sensitive, implements IElectricItem
chargedReBattery RE Battery item, meta = visual charge indicator, implements IElectricItem, can provide energy
energyCrystal Energy Crystal item, meta = visual charge indicator, implements IElectricItem, can provide energy
lapotronCrystal Lapotron Crystal item, meta = visual charge indicator, implements IElectricItem, can provide energy
suBattery SU Battery item, currently not meta sensitive
cables
copperCableItem Copper Cable item, meta sensitive
insulatedCopperCableItem Insulated Copper Cable item, meta sensitive
goldCableItem Gold Cable item, meta sensitive
insulatedGoldCableItem Insulated Gold Cable item, meta sensitive
doubleInsulatedGoldCableItem Double Insulated Gold Cable item, meta sensitive
ironCableItem Iron Cable item, meta sensitive
insulatedIronCableItem Insulated Iron Cable item, meta sensitive
doubleInsulatedIronCableItem Double Insulated Iron Cable item, meta sensitive
trippleInsulatedIronCableItem Tripple Insulated Iron Cable item, meta sensitive
glassFiberCableItem Glass Fiber Cable item, meta sensitive
tinCableItem Tin Cable item, meta sensitive
detectorCableItem Detector Cable item, meta sensitive
splitterCableItem Splitter Cable item, meta sensitive
cells/containers (without reactor components)
cell Empty Cell item, currently not meta sensitive
lavaCell Lava Cell item, currently not meta sensitive
hydratedCoalCell Hydrated Coal Cell item, currently not meta sensitive
bioCell Bio Cell item, currently not meta sensitive
coalfuelCell Coalfuel Cell item, currently not meta sensitive
biofuelCell Biofuel Cell item, currently not meta sensitive
waterCell Water Cell item, currently not meta sensitive
electrolyzedWaterCell Electrolyzed Water Cell item, currently not meta sensitive
fuelCan Empty Fuel Can item, currently not meta sensitive
filledFuelCan Fuel Can item, meta = fuel value (as of v1.45)
tinCan Empty Tin Can item, currently not meta sensitive
filledTinCan Filled Tin Can item, currently not meta sensitive
reactor components
uraniumCell Uranium Cell item, meta = damage value
coolingCell Cooling Cell item, meta = damage value
depletedIsotopeCell Depleted Isotope Cell item, meta = damage value
reEnrichedUraniumCell Re-Enriched Uranium Cell item, currently not meta sensitive
nearDepletedUraniumCell Near-Depleted Uranium Cell item, currently not meta sensitive
integratedReactorPlating Integrated Reactor Plating item, meta = damage value
integratedHeatDisperser Integrated Heat Disperser item, meta = damage value
terraformer blueprints
terraformerBlueprint Empty Terraformer Blueprint item, currently not meta sensitive
cultivationTerraformerBlueprint Cultivation Terraformer Blueprint item, currently not meta sensitive
irrigationTerraformerBlueprint Irrigation Terraformer Blueprint item, currently not meta sensitive
chillingTerraformerBlueprint Chilling Terraformer Blueprint item, currently not meta sensitive
desertificationTerraformerBlueprint Desertification Terraformer Blueprint item, currently not meta sensitive
flatificatorTerraformerBlueprint Flatificator Terraformer Blueprint item, currently not meta sensitive
mushroomTerraformerBlueprint Mushroom Terraformer Blueprint item, currently not meta sensitive
diamond chain
coalBall Coal Ball item, currently not meta sensitive
compressedCoalBall Compressed Coal Ball item, currently not meta sensitive
coalChunk Coal Chunk item, currently not meta sensitive
industrialDiamond Industrial Diamond item, currently not meta sensitive, DEPRECATED
recycler chain
scrap Scrap item, currently not meta sensitive
scrapBox Scrap Box item, currently not meta sensitive
fuel production chain
hydratedCoalClump Hydrated Coal Clump item, currently not meta sensitive
plantBall Plant Ball item, currently not meta sensitive
compressedPlantBall Compressed Plant Ball item, currently not meta sensitive
painting
painter Painter item, currently not meta sensitive
blackPainter Black Painter item, meta = damage value
redPainter Red Painter item, meta = damage value
greenPainter Green Painter item, meta = damage value
brownPainter Brown Painter item, meta = damage value
bluePainter Blue Painter item, meta = damage value
purplePainter Purple Painter item, meta = damage value
cyanPainter Cyan Painter item, meta = damage value
lightGreyPainter Light Grey Painter item, meta = damage value
darkGreyPainter Dark Grey Painter item, meta = damage value
pinkPainter Pink Painter item, meta = damage value
limePainter Lime Painter item, meta = damage value
yellowPainter Yellow Painter item, meta = damage value
cloudPainter Cloud Painter item, meta = damage value
magentaPainter Magenta Painter item, meta = damage value
orangePainter Orange Painter item, meta = damage value
whitePainter White Painter item, meta = damage value
explosives + related
dynamite Throwable Dynamite item, currently not meta sensitive
stickyDynamite Throwable Sticky Dynamite item, currently not meta sensitive
remote Dynamite Remote item, currently not meta sensitive
misc intermediate recipe ingredients
electronicCircuit Electronic Circuit item, currently not meta sensitive
advancedCircuit Advanced Circuit item, currently not meta sensitive
advancedAlloy Advanced Alloy item, currently not meta sensitive
carbonFiber Raw Carbon Fiber item, currently not meta sensitive
carbonMesh Raw Carbon Mesh item, currently not meta sensitive
carbonPlate Carbon Plate item, currently not meta sensitive
matter UU-Matter item, currently not meta sensitive
iridiumOre Iridium Ore item, currently not meta sensitive
iridiumPlate Iridium Plate item, currently not meta sensitive
upgrade modules
overclockerUpgrade overclocker upgrade item, meta sensitive
transformerUpgrade transformer upgrade item, meta sensitive
energyStorageUpgrade energy storage upgrade item, meta sensitive
misc
coin Coin item, currently not meta sensitive
reinforcedDoor Reinforced Door item, currently not meta sensitive
constructionFoamPellet Construction Foam Pellet item, currently not meta sensitive
cropSeed Crop seeds, stuff stored in NBT, don't use for crafting recipes!
cropnalyzer Cropnalyzer handheld device
fertilizer Basic IC2Item, used to provide nutrients toCropBlocks
hydratingCell Cell used to hydrate Crops, meta = Content, 0 = Full, 9999 = Near empty
electricHoe Electric Hoe, meta = charge level
solarHelmet Solar Helmet item, currently not meta sensitive
terraWart Terra Wart item, cures potion effects
weedEx Weed-EX can, meta = uses left
*/
/**
* Get the base IC2 package name, used internally.
*
* @return IC2 package name, if unable to be determined defaults to ic2
*/
private static String getPackage() {
Package pkg = Items.class.getPackage();
if (pkg != null) {
String packageName = pkg.getName();
return packageName.substring(0, packageName.length() - ".api.item".length());
}
return "ic2";
}
private static Class<?> Ic2Items;
}

View File

@ -0,0 +1,17 @@
package ic2.api.network;
import net.minecraft.entity.player.EntityPlayer;
/**
* Allows a tile entity to receive network events received from clients.
*/
public interface INetworkClientTileEntityEventListener {
/**
* Called when a network event is received.
*
* @param player client which sent the event
* @param event event ID
*/
void onNetworkEvent(EntityPlayer player, int event);
}

View File

@ -0,0 +1,18 @@
package ic2.api.network;
import java.util.List;
/**
* Tile entities which want to synchronized specific fields between client and server have to implement this.
*
* The fields don't update themselves, a field update must be sent every time a synchronized field changes.
*/
public interface INetworkDataProvider {
/**
* Get the list of synchronized fields.
*
* @return Names of the synchronized fields
*/
List<String> getNetworkedFields();
}

View File

@ -0,0 +1,18 @@
package ic2.api.network;
import net.minecraft.entity.player.EntityPlayer;
/**
* Allows an item to receive network events received from the server.
*/
public interface INetworkItemEventListener {
/**
* Called when a network event is received.
*
* @param metaData item metadata
* @param player player containing the item
* @param event event ID
*/
void onNetworkEvent(int metaData, EntityPlayer player, int event);
}

View File

@ -0,0 +1,14 @@
package ic2.api.network;
/**
* Allows a tile entity to receive network events received from the server.
*/
public interface INetworkTileEntityEventListener {
/**
* Called when a network event is received.
*
* @param event Event ID
*/
void onNetworkEvent(int event);
}

View File

@ -0,0 +1,14 @@
package ic2.api.network;
/**
* Allows a tile entity to receive field sync updates received from the server.
*/
public interface INetworkUpdateListener {
/**
* Called when a field is synchronized.
*
* @param field field synchronized
*/
void onNetworkUpdate(String field);
}

View File

@ -0,0 +1,243 @@
package ic2.api.network;
import java.lang.reflect.Method;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
/**
* Provides methods to initiate events and synchronize tile entity fields in SMP.
*
* The methods are transparent between singleplayer and multiplayer - if a method is called in
* singleplayer, the associated callback will be locally executed. The implementation is different
* between the client and server versions of IC2.
*
* You'll usually want to use the server->client methods defined here to synchronize information
* which is needed by the clients outside the GUI, such as rendering the block, playing sounds or
* producing effects. Anything which is only visible inside the GUI should be synchronized through
* the Container class associated to the GUI in Container.updateProgressBar().
*/
public final class NetworkHelper {
// server -> client
/**
* Schedule a TileEntity's field to be updated to the clients in range.
*
* The updater will query the field's value during the next update, updates happen usually
* every 2 ticks. If low latency is important use initiateTileEntityEvent instead.
*
* IC2's network updates have to get triggered every time, it doesn't continuously poll/send
* the field value. Just call updateTileEntityField after every change to a field which needs
* network synchronization.
*
* The following field data types are currently supported:
* - int, int[], short, short[], byte, byte[], long, long[]
* - float, float[], double, double[]
* - boolean, boolean[]
* - String, String[]
* - ItemStack
* - NBTBase (includes NBTTagCompound)
* - Block, Item, Achievement, Potion, Enchantment
* - ChunkCoordinates, ChunkCoordIntPair
* - TileEntity (does not sync the actual tile entity, instead looks up the tile entity by its position in the client world)
* - World (does not sync the actual world, instead looks up the world by its dimension ID)
*
* Once the update has been processed by the client, it'll call onNetworkUpdate on the client-
* side TileEntity if it implements INetworkUpdateListener.
*
* If this method is being executed on the client (i.e. Singleplayer), it'll just call
* INetworkUpdateListener.onNetworkUpdate (if implemented by the te).
*
* @param te TileEntity to update
* @param field Name of the field to update
*/
public static void updateTileEntityField(TileEntity te, String field) {
try {
if (NetworkManager_updateTileEntityField == null) NetworkManager_updateTileEntityField = Class.forName(getPackage() + ".core.network.NetworkManager").getMethod("updateTileEntityField", TileEntity.class, String.class);
if (instance == null) instance = getInstance();
NetworkManager_updateTileEntityField.invoke(instance, te, field);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Immediately send an event for the specified TileEntity to the clients in range.
*
* If this method is being executed on the client (i.e. Singleplayer), it'll just call
* INetworkTileEntityEventListener.onNetworkEvent (if implemented by the te).
*
* @param te TileEntity to notify, should implement INetworkTileEntityEventListener
* @param event Arbitrary integer to represent the event, choosing the values is up to you
* @param limitRange Limit the notification range to (currently) 20 blocks instead of the
* tracking distance if true
*/
public static void initiateTileEntityEvent(TileEntity te, int event, boolean limitRange) {
try {
if (NetworkManager_initiateTileEntityEvent == null) NetworkManager_initiateTileEntityEvent = Class.forName(getPackage() + ".core.network.NetworkManager").getMethod("initiateTileEntityEvent", TileEntity.class, Integer.TYPE, Boolean.TYPE);
if (instance == null) instance = getInstance();
NetworkManager_initiateTileEntityEvent.invoke(instance, te, event, limitRange);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Immediately send an event for the specified Item to the clients in range.
*
* The item should implement INetworkItemEventListener to receive the event.
*
* If this method is being executed on the client (i.e. Singleplayer), it'll just call
* INetworkItemEventListener.onNetworkEvent (if implemented by the item).
*
* @param player EntityPlayer holding the item
* @param itemStack ItemStack containing the item
* @param event Arbitrary integer to represent the event, choosing the values is up to you
* @param limitRange Limit the notification range to (currently) 20 blocks instead of the
* tracking distance if true
*/
public static void initiateItemEvent(EntityPlayer player, ItemStack itemStack, int event, boolean limitRange) {
try {
if (NetworkManager_initiateItemEvent == null) NetworkManager_initiateItemEvent = Class.forName(getPackage() + ".core.network.NetworkManager").getMethod("initiateItemEvent", EntityPlayer.class, ItemStack.class, Integer.TYPE, Boolean.TYPE);
if (instance == null) instance = getInstance();
NetworkManager_initiateItemEvent.invoke(instance, player, itemStack, event, limitRange);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Schedule a block update (re-render) on the clients in range.
*
* If this method is being executed on the client (i.e. Singleplayer), it'll just trigger the
* block update locally.
*
* @param world World containing the block
* @param x The block's x coordinate
* @param y The block's y coordinate
* @param z The block's z coordinate
*/
public static void announceBlockUpdate(World world, int x, int y, int z) {
try {
if (NetworkManager_announceBlockUpdate == null) NetworkManager_announceBlockUpdate = Class.forName(getPackage() + ".core.network.NetworkManager").getMethod("announceBlockUpdate", World.class, Integer.TYPE, Integer.TYPE, Integer.TYPE);
if (instance == null) instance = getInstance();
NetworkManager_announceBlockUpdate.invoke(instance, world, x, y, z);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// client -> server
/**
* Ask the server to send the values of the fields specified.
*
* See updateTileEntityField for the supported field types.
*
* The implementation is currently limited to TileEntitys as data providers. The tile entity
* has to be fully initialized when executing this method (i.e. valid worldObj+coords).
*
* This method doesn't do anything if executed on the server.
*
* @param dataProvider Object implementing the INetworkDataProvider interface
*/
public static void requestInitialData(INetworkDataProvider dataProvider) {
try {
if (NetworkManager_requestInitialData == null) NetworkManager_requestInitialData = Class.forName(getPackage() + ".core.network.NetworkManager").getMethod("requestInitialData", INetworkDataProvider.class);
if (instance == null) instance = getInstance();
NetworkManager_requestInitialData.invoke(instance, dataProvider);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Immediately send an event for the specified TileEntity to the server.
*
* This method doesn't do anything if executed on the server.
*
* @param te TileEntity to notify, should implement INetworkClientTileEntityEventListener
* @param event Arbitrary integer to represent the event, choosing the values is up to you
*/
public static void initiateClientTileEntityEvent(TileEntity te, int event) {
try {
if (NetworkManager_initiateClientTileEntityEvent == null) NetworkManager_initiateClientTileEntityEvent = Class.forName(getPackage() + ".core.network.NetworkManager").getMethod("initiateClientTileEntityEvent", TileEntity.class, Integer.TYPE);
if (instance == null) instance = getInstance();
NetworkManager_initiateClientTileEntityEvent.invoke(instance, te, event);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Immediately send an event for the specified Item to the clients in range.
*
* The item should implement INetworkItemEventListener to receive the event.
*
* This method doesn't do anything if executed on the server.
*
* @param itemStack ItemStack containing the item
* @param event Arbitrary integer to represent the event, choosing the values is up to you
*/
public static void initiateClientItemEvent(ItemStack itemStack, int event) {
try {
if (NetworkManager_initiateClientItemEvent == null) NetworkManager_initiateClientItemEvent = Class.forName(getPackage() + ".core.network.NetworkManager").getMethod("initiateClientItemEvent", ItemStack.class, Integer.TYPE);
if (instance == null) instance = getInstance();
NetworkManager_initiateClientItemEvent.invoke(instance, itemStack, event);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Get the base IC2 package name, used internally.
*
* @return IC2 package name, if unable to be determined defaults to ic2
*/
private static String getPackage() {
Package pkg = NetworkHelper.class.getPackage();
if (pkg != null) {
String packageName = pkg.getName();
return packageName.substring(0, packageName.length() - ".api.network".length());
}
return "ic2";
}
/**
* Get the NetworkManager instance, used internally.
*
* @return NetworkManager instance
*/
private static Object getInstance() {
try {
return Class.forName(getPackage() + ".core.IC2").getDeclaredField("network").get(null);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
private static Object instance;
private static Method NetworkManager_updateTileEntityField;
private static Method NetworkManager_initiateTileEntityEvent;
private static Method NetworkManager_initiateItemEvent;
private static Method NetworkManager_announceBlockUpdate;
private static Method NetworkManager_requestInitialData;
private static Method NetworkManager_initiateClientTileEntityEvent;
private static Method NetworkManager_initiateClientItemEvent;
}

View File

@ -0,0 +1,34 @@
package ic2.api.reactor;
import java.lang.reflect.Field;
public class IC2Reactor {
private static Field energyGeneratorNuclear;
public static int getEUOutput() {
try {
if (energyGeneratorNuclear == null) energyGeneratorNuclear = Class.forName(getPackage() + ".core.IC2").getDeclaredField("energyGeneratorNuclear");
return energyGeneratorNuclear.getInt(null);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
/**
* Get the base IC2 package name, used internally.
*
* @return IC2 package name, if unable to be determined defaults to ic2
*/
private static String getPackage() {
Package pkg = IC2Reactor.class.getPackage();
if (pkg != null) {
String packageName = pkg.getName();
return packageName.substring(0, packageName.length() - ".api.reactor".length());
}
return "ic2";
}
}

View File

@ -0,0 +1,134 @@
package ic2.api.reactor;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* Interface implemented by the tile entity of nuclear reactors.
*/
public interface IReactor {
/**
* Get the reactor's position in the world.
*
* @return Position of the reactor
*/
public ChunkCoordinates getPosition();
/**
* Get the reactor's corresponding world.
*
* @return The reactor's world
*/
public World getWorld();
/**
* Get the reactor's heat.
*
* @return The reactor's heat
*/
public int getHeat();
/**
* Set the reactor's heat.
*
* @param heat reactor heat
*/
public void setHeat(int heat);
/**
* Increase the reactor's heat.
*
* Use negative values to decrease.
*
* @param amount amount of heat to add
* @return The reactor's heat after adding the specified amount
*/
public int addHeat(int amount);
/**
* Get the reactor's maximum heat before exploding.
*
* @return Maximum heat value
*/
public int getMaxHeat();
/**
* Set the reactor's stored maxHeat variable.
* Used by plating to increase the reactors MaxHeat capacity.
* Needs to be called during each cycle process.
*/
public void setMaxHeat(int newMaxHeat);
/**
* Get's the reactor's HEM (Heat Effect Modifier)
* Basic value is 1.0F.
* Reducing the value causes a weakening/reduction of the heat-based sideeffects of reactors
* (F.e. water evaporation, melting, damaging entitys, etc)
*
* @return HEM
*/
public float getHeatEffectModifier();
/**
* Set's the reactor's HEM
* Needs to be called during each cycle process.
*/
public void setHeatEffectModifier(float newHEM);
/**
* Get the reactor's energy output.
*
* @return Energy output, not multiplied by the base EU/t value
*/
public int getOutput();
/**
* Add's the given amount of energy to the Reactor's output.
*
* @return Energy output after adding the value, not multiplied by the base EU/t value
*/
public int addOutput(int energy);
/**
* Replaced by IC2Reactor.getEUOutput() - stays at the universal output value of 1 for compatibility
*/
@Deprecated
public int getPulsePower();
/**
* Get the item at the specified grid coordinates.
*
* @param x X position of the item
* @param y Y position of the item
* @return The item or null if there is no item
*/
public ItemStack getItemAt(int x, int y);
/**
* Set the item at the specified grid coordinates.
*
* @param x X position of the item
* @param y Y position of the item
* @param item The item to set.
*/
public void setItemAt(int x, int y, ItemStack item);
/**
* Explode the reactor.
*/
public void explode();
/**
* Get the reactor's tick rate (game ticks per reactor tick).
*
* @return Tick rate
*/
public int getTickRate();
/**
* Get whether the reactor is active and supposed to produce energy
* @return Whether the reactor is active
*/
public boolean produceEnergy();
}

View File

@ -0,0 +1,13 @@
package ic2.api.reactor;
/**
* Interface implemented by the reactor chamber tile entity.
*/
public interface IReactorChamber {
/**
* Get the chamber's reactor.
*
* @return The reactor
*/
public IReactor getReactor();
}

View File

@ -0,0 +1,97 @@
package ic2.api.reactor;
import net.minecraft.item.ItemStack;
/**
* Design custom Reactor components by implementing this Interface
* Items implementing the interface will not be ejected from Reactors in their clean-up
* and can/will be interacted with by other elements, f.e. Uranium Cells.
*
* All IC2 ReactorComponents implement and use this Interface
*
*/
public interface IReactorComponent
{
/**
* Called by reactor upon iterating through it's inventory (every cycle).
* Perform all necessary calculation/interaction here
*
* @param reactor Reference to the Reactor
* @param yourStack Reference to the specific instance of iterated ItemStack
* @param x X-coordinate of the stack in the grid
* @param y Y-coordinate of the stack in the grid
*/
public void processChamber(IReactor reactor, ItemStack yourStack, int x, int y);
/**
* Can be called by Uranium-Components who attempt to generate energy by pulsing to other components.
* Uranium-Uranium interaction (f.e.) uses this method.
* @param reactor Reference to the Reactor
* @param yourStack Reference to the specific instance of called ItemStack
* @param pulsingStack Reference to the specific instance of pulsing ItemStack
* @param youX X-coordinate of your stack in the grid
* @param youY Y-coordinate of your stack in the grid
* @param pulseX X-coordinate of pulsing stack in the grid
* @param pulseY Y-coordinate of pulsing stack in the grid
* @return true if this component reacts to the pulse (and pulse is therefore meant to produce heat)
*/
public boolean acceptUraniumPulse(IReactor reactor, ItemStack yourStack, ItemStack pulsingStack, int youX, int youY, int pulseX, int pulseY);
/**
* Called by components to determine whether your component can be heated.
* @param reactor Reference to the Reactor
* @param yourStack Reference to the specific instance of iterated ItemStack
* @param x X-coordinate of the stack in the grid
* @param y Y-coordinate of the stack in the grid
* @return true if your component can take heat
*/
public boolean canStoreHeat(IReactor reactor, ItemStack yourStack, int x, int y);
/**
* Called by heat-switches to determine how much heat to distribute into which direction.
* Please return the maximum capacity of your heat-containing component here.
* @param reactor Reference to the Reactor
* @param yourStack Reference to the specific instance of iterated ItemStack
* @param x X-coordinate of the stack in the grid
* @param y Y-coordinate of the stack in the grid
* @return Maximum heat
*/
public int getMaxHeat(IReactor reactor, ItemStack yourStack, int x, int y);
/**
* Called by heat-switches to determine how much heat to distribute into which direction.
* Please return the current amount of heat stored in this component
* @param reactor Reference to the Reactor
* @param yourStack Reference to the specific instance of iterated ItemStack
* @param x X-coordinate of the stack in the grid
* @param y Y-coordinate of the stack in the grid
* @return Current Heat
*/
public int getCurrentHeat(IReactor reactor, ItemStack yourStack, int x, int y);
/**
* Called by components to distribute heat to your component.
* Perform heating-calculations and increase your heat (dmg) level accordingly.
* This method will as well be called to REDUCE heat, by providing a negative amount.
*
* @param reactor Reference to the Reactor
* @param yourStack Reference to the specific instance of iterated ItemStack
* @param x X-coordinate of the stack in the grid
* @param y Y-coordinate of the stack in the grid
* @param heat Amount of heat to be added (may be negative to subtract heat)
* @return 0 if the 'order' was accepted, return >0 to indicate the 'remaining' heat which couldn't be absorbed (and vice versa for <0)
*/
public int alterHeat(IReactor reactor, ItemStack yourStack, int x, int y, int heat);
/**
* Called upon reactor explosion
* Alter the explosion size.
* Returning a float 0 < f < 1 will be counted as multiplier.
* Anything else will be counted as a flat addition (in case of <0 = reduction).
*
* @param reactor Reference to the Reactor
* @param yourStack Reference to the specific instance of iterated ItemStack
* @return your explosion modifier
*/
public float influenceExplosion(IReactor reactor, ItemStack yourStack);
}

View File

@ -0,0 +1,26 @@
package ic2.api.recipe;
import net.minecraft.item.ItemStack;
/**
* Recipe manager interface for crafting recipes.
*
* @author Richard
*/
public interface ICraftingRecipeManager {
/**
* Adds a shaped crafting recipe.
*
* @param output Recipe output
* @param input Recipe input format
*/
public void addRecipe(ItemStack output, Object... input);
/**
* Adds a shapeless crafting recipe.
*
* @param output Recipe output
* @param input Recipe input
*/
public void addShapelessRecipe(ItemStack output, Object... input);
}

View File

@ -0,0 +1,36 @@
package ic2.api.recipe;
import java.util.List;
import net.minecraft.item.ItemStack;
/**
* Recipe manager interface for basic lists.
*
* @author Richard
*/
public interface IListRecipeManager extends Iterable<ItemStack> {
/**
* Adds a stack to the list.
*
* @param stack Stack to add
*/
public void add(ItemStack stack);
/**
* Checks whether the specified stack is in the list.
*
* @param stack Stack to check
* @return Whether the stack is in the list
*/
public boolean contains(ItemStack stack);
/**
* Gets the list of stacks.
*
* You're a mad evil scientist if you ever modify this.
*
* @return List of stacks
*/
public List<ItemStack> getStacks();
}

View File

@ -0,0 +1,37 @@
package ic2.api.recipe;
import java.util.Map;
import net.minecraft.item.ItemStack;
/**
* Recipe manager interface for basic machines.
*
* @author Richard
*/
public interface IMachineRecipeManager<V> {
/**
* Adds a recipe to the machine.
*
* @param input Recipe input
* @param output Recipe output
*/
public void addRecipe(ItemStack input, V output);
/**
* Gets the recipe output for the given input.
*
* @param input Recipe input
* @return Recipe output, or null if none
*/
public V getOutputFor(ItemStack input, boolean adjustInput);
/**
* Gets a list of recipes.
*
* You're a mad evil scientist if you ever modify this.
*
* @return List of recipes
*/
public Map<ItemStack, V> getRecipes();
}

View File

@ -0,0 +1,38 @@
package ic2.api.recipe;
import net.minecraft.item.ItemStack;
/**
* General recipe registry.
*
* @author Richard
*/
public class Recipes {
public static IMachineRecipeManager<ItemStack> macerator;
public static IMachineRecipeManager<ItemStack> extractor;
public static IMachineRecipeManager<ItemStack> compressor;
/**
* Reference amplifier values:
*
* 5000: Scrap
* 45000: Scrapbox
*/
public static IMachineRecipeManager<Integer> matterAmplifier;
/**
* Reference scrap box chance values:
*
* 0.1: Diamond
* 0.5: Cake, Gold Helmet, Iron Ore, Gold Ore
* 1.0: Wooden tools, Soul Sand, Sign, Leather, Feather, Bone
* 1.5: Apple, Bread
* 2.0: Netherrack, Rotten Flesh
* 3.0: Grass, Gravel
* 4.0: Stick
* 5.0: Dirt, Wooden Hoe
*/
public static IMachineRecipeManager<Float> scrapboxDrops;
public static IListRecipeManager recyclerBlacklist;
public static ICraftingRecipeManager advRecipes;
}

View File

@ -0,0 +1,46 @@
package ic2.api.tile;
import java.util.*;
import net.minecraft.block.Block;
/**
* Blocks on this whitelist will not resist an explosion but won't be destroyed.
*
* The explosion code by default ignores blocks which absorb more than 1000 explosion power to
* prevent abusing personal safes, Trade-O-Mats and other blocks to serve as a cheap and
* invulnerable reactor chambers. Said blocks will not shield the explosion and won't get
* destroyed.
*/
public final class ExplosionWhitelist {
/**
* Add a block to the whitelist.
*
* @param block block to add
*/
public static void addWhitelistedBlock(Block block) {
whitelist.add(block);
}
/**
* Remove a block from the whitelist.
*
* @param block block to remove
*/
public static void removeWhitelistedBlock(Block block) {
whitelist.remove(block);
}
/**
* Check if a block is on the whitelist.
*
* @param block block to check if whitelisted
* @return Whether the block is whitelisted
*/
public static boolean isBlockWhitelisted(Block block) {
return whitelist.contains(block);
}
private static Set<Block> whitelist = new HashSet<Block>();
}

View File

@ -0,0 +1,54 @@
package ic2.api.tile;
import ic2.api.Direction;
/**
* Interface implemented by the tile entity of energy storage blocks.
*/
public interface IEnergyStorage {
/**
* Get the amount of energy currently stored in the block.
*
* @return Energy stored in the block
*/
public int getStored();
/**
* Set the amount of energy currently stored in the block.
*
* @param energy stored energy
*/
public void setStored(int energy);
/**
* Add the specified amount of energy.
*
* Use negative values to decrease.
*
* @param amount of energy to add
* @return Energy stored in the block after adding the specified amount
*/
public int addEnergy(int amount);
/**
* Get the maximum amount of energy the block can store.
*
* @return Maximum energy stored
*/
public int getCapacity();
/**
* Get the block's energy output.
*
* @return Energy output in EU/t
*/
public int getOutput();
/**
* Get whether this block can have its energy used by an adjacent teleporter.
*
* @param side side the teleporter is draining energy from
* @return Whether the block is teleporter compatible
*/
public boolean isTeleporterCompatible(Direction side);
}

View File

@ -0,0 +1,59 @@
package ic2.api.tile;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* Allows a tile entity to make use of the wrench's removal and rotation functions.
*/
public interface IWrenchable {
/**
* Determine if the wrench can be used to set the block's facing.
* Called before wrenchCanRemove().
*
* @param entityPlayer player using the wrench, may be null
* @param side block's side the wrench was clicked on
* @return Whether the wrenching was done and the wrench should be damaged
*/
boolean wrenchCanSetFacing(EntityPlayer entityPlayer, int side);
/**
* Get the block's facing.
*
* @return Block facing
*/
short getFacing();
/**
* Set the block's facing
*
* @param facing facing to set the block to
*/
void setFacing(short facing);
/**
* Determine if the wrench can be used to remove the block.
* Called if wrenchSetFacing fails.
*
* @param entityPlayer player using the wrench, may be null
* @return Whether the wrenching was done and the wrench should be damaged
*/
boolean wrenchCanRemove(EntityPlayer entityPlayer);
/**
* Determine the probability to drop the block as it is.
* The first entry in getBlockDropped will be replaced by blockid:meta if the drop is successful.
*
* @return Probability from 0 to 1
*/
float getWrenchDropRate();
/**
* Determine the item the block will drop when the wrenching is successful.
*
* @param entityPlayer player using the wrench, may be null
* @return Item to drop
*/
ItemStack getWrenchDrop(EntityPlayer entityPlayer);
}

View File

@ -37,7 +37,7 @@ import cpw.mods.fml.common.registry.VillagerRegistry;
* @dependencies: IC2 API, MFR API
*/
@Mod(modid = "TConstruct", name = "TConstruct", version = "1.5.1_1.3.dev48", dependencies = "required-after:Forge@[7.7.1.675,)")
@Mod(modid = "TConstruct", name = "TConstruct", version = "1.5.1_1.3.dev49", dependencies = "required-after:Forge@[7.7.1.675,)")
@NetworkMod(serverSideRequired = false, clientSideRequired = true, channels = { "TConstruct" }, packetHandler = mods.tinker.tconstruct.util.network.TPacketHandler.class)
public class TConstruct
{

View File

@ -9,6 +9,7 @@ import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import mods.natura.entity.NitroCreeper;
import mods.tinker.tconstruct.TConstruct;
import mods.tinker.tconstruct.blocks.logic.CastingBasinLogic;
import mods.tinker.tconstruct.blocks.logic.CastingTableLogic;
@ -56,7 +57,6 @@ import mods.tinker.tconstruct.entity.CartEntity;
import mods.tinker.tconstruct.entity.Crystal;
import mods.tinker.tconstruct.entity.FancyEntityItem;
import mods.tinker.tconstruct.entity.GolemBase;
import mods.tinker.tconstruct.entity.NitroCreeper;
import mods.tinker.tconstruct.entity.Skyla;
import mods.tinker.tconstruct.entity.SlimeClone;
import mods.tinker.tconstruct.entity.projectile.DaggerEntity;
@ -245,7 +245,6 @@ public class TProxyClient extends TProxyCommon
//Entities
RenderingRegistry.registerEntityRenderingHandler(FancyEntityItem.class, new FancyItemRender());
RenderingRegistry.registerEntityRenderingHandler(NitroCreeper.class, new RenderCreeper());
RenderingRegistry.registerEntityRenderingHandler(BlueSlime.class, new SlimeRender(new ModelSlime(16), new ModelSlime(0), 0.25F));
RenderingRegistry.registerEntityRenderingHandler(SlimeClone.class, new SlimeCloneRender(new CloneHeadModel(0), new CloneHeadModel(1f), 0.25F));
RenderingRegistry.registerEntityRenderingHandler(GolemBase.class, new GolemRender(0));

View File

@ -1,5 +1,7 @@
package mods.tinker.tconstruct.common;
import java.util.Collection;
import mods.tinker.tconstruct.TConstruct;
import mods.tinker.tconstruct.blocks.EquipBlock;
import mods.tinker.tconstruct.blocks.GravelOre;
@ -30,9 +32,7 @@ import mods.tinker.tconstruct.blocks.logic.SmelteryDrainLogic;
import mods.tinker.tconstruct.blocks.logic.SmelteryLogic;
import mods.tinker.tconstruct.blocks.logic.ToolStationLogic;
import mods.tinker.tconstruct.entity.BlueSlime;
import mods.tinker.tconstruct.entity.Crystal;
import mods.tinker.tconstruct.entity.FancyEntityItem;
import mods.tinker.tconstruct.entity.NitroCreeper;
import mods.tinker.tconstruct.entity.projectile.DaggerEntity;
import mods.tinker.tconstruct.items.CraftingItem;
import mods.tinker.tconstruct.items.DiamondApple;
@ -96,7 +96,6 @@ import mods.tinker.tconstruct.modifiers.ModRepair;
import mods.tinker.tconstruct.modifiers.TActiveOmniMod;
import mods.tinker.tconstruct.util.PHConstruct;
import mods.tinker.tconstruct.util.RecipeRemover;
import mods.tinker.tconstruct.worldgen.OverworldProvider;
import net.minecraft.block.Block;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
@ -110,7 +109,6 @@ import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraftforge.common.BiomeDictionary;
import net.minecraftforge.common.ChestGenHooks;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.liquids.LiquidContainerData;
import net.minecraftforge.liquids.LiquidContainerRegistry;
@ -123,6 +121,7 @@ import cpw.mods.fml.common.IFuelHandler;
import cpw.mods.fml.common.event.FMLInterModComms;
import cpw.mods.fml.common.registry.EntityRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import extrabiomes.api.BiomeManager;
public class TContent implements IFuelHandler
{
@ -260,13 +259,12 @@ public class TContent implements IFuelHandler
{
EntityRegistry.registerModEntity(FancyEntityItem.class, "Fancy Item", 0, TConstruct.instance, 32, 5, true);
EntityRegistry.registerModEntity(DaggerEntity.class, "Dagger", 1, TConstruct.instance, 32, 5, true);
EntityRegistry.registerModEntity(Crystal.class, "Crystal", 2, TConstruct.instance, 32, 5, true);
//EntityRegistry.registerModEntity(Crystal.class, "Crystal", 2, TConstruct.instance, 32, 5, true);
//EntityRegistry.registerModEntity(SlimeClone.class, "SlimeClone", 2, TConstruct.instance, 32, 5, true);
//EntityRegistry.registerModEntity(LaunchedPotion.class, "Launched Potion", 1, TConstruct.instance, 32, 3, true);
//EntityRegistry.registerModEntity(CartEntity.class, "Small Wagon", 1, TConstruct.instance, 32, 5, true);
//EntityRegistry.registerModEntity(Skyla.class, "Skyla", 10, TConstruct.instance, 32, 5, true);
EntityRegistry.registerModEntity(NitroCreeper.class, "UnstableCreeper", 11, TConstruct.instance, 64, 5, true);
EntityRegistry.registerModEntity(BlueSlime.class, "EdibleSlime", 12, TConstruct.instance, 64, 5, true);
//EntityRegistry.registerModEntity(MetalSlime.class, "MetalSlime", 13, TConstruct.instance, 64, 5, true);
@ -281,7 +279,7 @@ public class TContent implements IFuelHandler
BiomeGenBase[] nether = BiomeDictionary.getBiomesForType(BiomeDictionary.Type.NETHER);
if (PHConstruct.superfunWorld)
/*if (PHConstruct.superfunWorld)
{
EntityRegistry.addSpawn(NitroCreeper.class, 1000, 100, 100, EnumCreatureType.monster, plains);
EntityRegistry.addSpawn(NitroCreeper.class, 1000, 100, 100, EnumCreatureType.monster, mountain);
@ -293,12 +291,7 @@ public class TContent implements IFuelHandler
EntityRegistry.addSpawn(NitroCreeper.class, 1000, 100, 100, EnumCreatureType.monster, wasteland);
DimensionManager.unregisterProviderType(0);
DimensionManager.registerProviderType(0, OverworldProvider.class, true);
}
if (PHConstruct.redCreeper)
{
EntityRegistry.addSpawn(NitroCreeper.class, PHConstruct.redCreeperWeight, 4, 6, EnumCreatureType.monster, nether);
}
}*/
if (PHConstruct.blueSlime)
{
EntityRegistry.addSpawn(BlueSlime.class, PHConstruct.blueSlimeWeight, 4, 4, EnumCreatureType.monster, plains);
@ -310,6 +303,18 @@ public class TContent implements IFuelHandler
EntityRegistry.addSpawn(BlueSlime.class, PHConstruct.blueSlimeWeight, 4, 4, EnumCreatureType.monster, jungle);
EntityRegistry.addSpawn(BlueSlime.class, PHConstruct.blueSlimeWeight, 4, 4, EnumCreatureType.monster, wasteland);
}
try
{
Class.forName("extrabiomes.api.BiomeManager");
Collection<BiomeGenBase> ebxlCollection = BiomeManager.getBiomes();
BiomeGenBase[] ebxlBiomes = (BiomeGenBase[]) ebxlCollection.toArray();
EntityRegistry.addSpawn(BlueSlime.class, PHConstruct.blueSlimeWeight, 4, 4, EnumCreatureType.monster, ebxlBiomes);
}
catch (Exception e)
{
}
//EntityRegistry.addSpawn(MetalSlime.class, 1, 4, 4, EnumCreatureType.monster, overworldBiomes);
}

View File

@ -37,10 +37,10 @@ public class BlueSlime extends EntityLiving implements IMob, IBossDisplayData
{
super(world);
this.texture = "/mods/tinker/textures/mob/slimeedible.png";
int offset = this.rand.nextInt(199);
if (offset < 99)
int offset = this.rand.nextInt(299);
if (offset < 149)
offset = 1;
else if (offset < 198)
else if (offset < 298)
offset = 2;
else
offset = 3;
@ -443,6 +443,11 @@ public class BlueSlime extends EntityLiving implements IMob, IBossDisplayData
tags.setInteger("MiningSpeed", 800);
this.entityDropItem(toolStack, 0f);
if (rand.nextInt(10) == 0)
{
ItemStack dropStack = new ItemStack(TContent.heartCanister, 1, 1);
this.entityDropItem(dropStack, 0f);
}
}
}

View File

@ -1,202 +0,0 @@
package mods.tinker.tconstruct.entity;
import net.minecraft.block.Block;
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.monster.EntityIronGolem;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class NitroCreeper extends EntityCreeper
{
protected int fuseTime = 12;
protected int timeSinceIgnited;
protected int lastActiveTime;
public float explosionRadius = 1f;
public NitroCreeper(World world)
{
super(world);
this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0F, false));
this.texture = "/mods/tinker/textures/mob/creeperunstable.png";
this.isImmuneToFire = true;
}
/*@Override
public void initCreature ()
{
//if (this.rand.nextInt(100) == 0)
this.dataWatcher.updateObject(17, Byte.valueOf((byte)1));
}*/
public int getMaxHealth ()
{
return 20;
}
protected void fall (float distance)
{
if (!this.worldObj.isRemote)
{
if (distance > 5)
{
boolean flag = this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing");
if (this.getPowered())
{
this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 20f, flag);
}
else
{
this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 3f, false);
}
this.setDead();
}
else
super.fall(distance);
}
}
public void writeEntityToNBT (NBTTagCompound par1NBTTagCompound)
{
super.writeEntityToNBT(par1NBTTagCompound);
par1NBTTagCompound.setShort("Fuse", (short) this.fuseTime);
}
public void readEntityFromNBT (NBTTagCompound par1NBTTagCompound)
{
super.readEntityFromNBT(par1NBTTagCompound);
if (par1NBTTagCompound.hasKey("Fuse"))
{
this.fuseTime = par1NBTTagCompound.getShort("Fuse");
}
}
public void onUpdate ()
{
if (this.isEntityAlive())
{
this.lastActiveTime = this.timeSinceIgnited;
int i = this.getCreeperState();
if (i > 0 && this.timeSinceIgnited == 0)
{
this.playSound("random.fuse", 1.0F, 0.5F);
}
this.timeSinceIgnited += i;
if (this.timeSinceIgnited < 0)
{
this.timeSinceIgnited = 0;
}
int difficulty = worldObj.difficultySetting;
int lengthBoost = 4 * (3 - difficulty);
int powered = this.getPowered() ? 12 : 0;
if (this.timeSinceIgnited >= this.fuseTime + difficulty + powered)
{
this.timeSinceIgnited = this.fuseTime;
if (!this.worldObj.isRemote)
{
boolean flag = this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing");
if (powered > 0)
{
this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 20f, flag);
}
else
{
this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 3f, flag);
}
this.setDead();
}
}
}
super.onUpdate();
}
public float getCreeperFlashIntensity (float par1)
{
return ((float) this.lastActiveTime + (float) (this.timeSinceIgnited - this.lastActiveTime) * par1) / (float) (this.fuseTime - 2);
}
protected void dropFewItems (boolean par1, int par2)
{
int j = this.getDropItemId();
if (j > 0)
{
int k = this.rand.nextInt(4) + 2;
if (par2 > 0)
{
k += this.rand.nextInt(par2 + 1);
}
for (int l = 0; l < k; ++l)
{
this.dropItem(j, 1);
}
}
if (this.getPowered())
{
if (j > 0)
{
int k = this.rand.nextInt(40) + 20;
if (par2 > 0)
{
k += this.rand.nextInt(par2*6 + 1);
}
for (int l = 0; l < k; ++l)
{
this.dropItem(j, 1);
}
}
/*j = Block.tnt.blockID;
int k = this.rand.nextInt(5) + 2;
if (par2 > 0)
{
k += this.rand.nextInt(par2*3 + 1);
}
for (int l = 0; l < k; ++l)
{
this.dropItem(j, 1);
}*/
}
}
public boolean attackEntityFrom(DamageSource source, int damage)
{
if (source instanceof EntityDamageSource && ((EntityDamageSource)source).getEntity() instanceof EntityIronGolem)
{
damage = 1000;
}
return super.attackEntityFrom(source, damage);
}
/*public boolean getCanSpawnHere()
{
int i = MathHelper.floor_double(this.posX);
int j = MathHelper.floor_double(this.boundingBox.minY);
int k = MathHelper.floor_double(this.posZ);
return this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox) && this.getBlockPathWeight(i, j, k) >= 0.0F;
}*/
}

View File

@ -2,9 +2,9 @@ package mods.tinker.tconstruct.items;
import java.util.List;
import mods.natura.entity.NitroCreeper;
import mods.tinker.tconstruct.client.TProxyClient;
import mods.tinker.tconstruct.entity.BlueSlime;
import mods.tinker.tconstruct.entity.NitroCreeper;
import mods.tinker.tconstruct.library.tools.ToolCore;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IconRegister;
@ -24,9 +24,9 @@ import cpw.mods.fml.relauncher.SideOnly;
public class TitleIcon extends Item
{
int[] primaryColor = { 0x66BBE8, 0x66BBE8, 0xF73E6C };
int[] secondaryColor = { 0x1567BF, 0x1567BF, 0x9B5004 };
String[] mobNames = { "TConstruct.EdibleSlime", "TConstruct.KingSlime", "TConstruct.UnstableCreeper" };
int[] primaryColor = { 0x66BBE8, 0x66BBE8 };
int[] secondaryColor = { 0x1567BF, 0xFFEC6E };
String[] mobNames = { "TConstruct.EdibleSlime", "TConstruct.KingSlime" };
public TitleIcon(int par1)
{

View File

@ -1,10 +1,10 @@
package mods.tinker.tconstruct.plugins.minefactoryreloaded;
import mods.natura.entity.NitroCreeper;
import mods.tinker.tconstruct.common.TContent;
import mods.tinker.tconstruct.entity.BlueSlime;
import mods.tinker.tconstruct.entity.Crystal;
import mods.tinker.tconstruct.entity.MetalSlime;
import mods.tinker.tconstruct.entity.NitroCreeper;
import mods.tinker.tconstruct.entity.Skyla;
import mods.tinker.tconstruct.plugins.minefactoryreloaded.grindables.GrindableStandard;
import mods.tinker.tconstruct.plugins.minefactoryreloaded.harvestables.HarvestableOreBerry;

View File

@ -0,0 +1,34 @@
package mods.tinker.tconstruct.skill;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
/* Base skill
*
*/
public abstract class SkillBase
{
public abstract String getTextureFile();
public abstract String getSkillName();
public int chargeTime() //Ticks
{
return 0;
}
public boolean canPlayerUseSkill()
{
return true;
}
public void activateSkill(EntityPlayer player, World world)
{
}
public int getSkillCost()
{
return 0;
}
}

View File

@ -60,9 +60,7 @@ public class PHConstruct
enableTCactus = config.get("Difficulty Changes", "Enable mod cactus tools", true).getBoolean(true);
enableTBone = config.get("Difficulty Changes", "Enable mod bone tools", true).getBoolean(true);
redCreeper = config.get("Mob Spawning", "Activate Nitro Creeper Spawns", true).getBoolean(true);
blueSlime = config.get("Mob Spawning", "Activate Blue Slime Spawns", true).getBoolean(true);
redCreeperWeight = config.get("Mob Spawning", "Spawn Weight for Nitro Creeper", 8).getInt(8);
blueSlimeWeight = config.get("Mob Spawning", "Spawn Weight for Blue Slime", 8).getInt(8);
woodCrafter = config.getBlock("Wood Tool Station", 1471).getInt(1471);
@ -404,8 +402,6 @@ public class PHConstruct
public static int seaLevel;
//Mobs
public static boolean redCreeper;
public static int redCreeperWeight;
public static boolean blueSlime;
public static int blueSlimeWeight;

View File

@ -3,10 +3,10 @@ package mods.tinker.tconstruct.util;
import java.util.ArrayList;
import java.util.Random;
import mods.natura.entity.NitroCreeper;
import mods.tinker.tconstruct.TConstruct;
import mods.tinker.tconstruct.blocks.logic.LiquidTextureLogic;
import mods.tinker.tconstruct.common.TContent;
import mods.tinker.tconstruct.entity.NitroCreeper;
import mods.tinker.tconstruct.library.crafting.PatternBuilder;
import mods.tinker.tconstruct.library.crafting.Smeltery;
import mods.tinker.tconstruct.library.crafting.ToolBuilder;
@ -121,9 +121,6 @@ public class TEventHandler
{
EntityCreeper creeper = new EntityCreeper(event.entityLiving.worldObj);
spawnEntity(event.entityLiving.posX, event.entityLiving.posY+1, event.entityLiving.posZ, creeper, event.entityLiving.worldObj);
EntitySkeleton skeleton = new EntitySkeleton(event.entityLiving.worldObj);
spawnEntity(event.entityLiving.posX, event.entityLiving.posY+1, event.entityLiving.posZ, skeleton, event.entityLiving.worldObj);
skeleton.mountEntity(creeper);
creeper.mountEntity(event.entityLiving);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -0,0 +1,23 @@
package powercrystals.minefactoryreloaded.api;
/**
* @author PowerCrystals
*
* Determines what kind of action a given fertilizer can perform. Your IFactoryFertilizable instances should check this before
* performing any action to maintain future compatibility.
*/
public enum FertilizerType
{
/**
* The fertilizer will fertilize grass.
*/
Grass,
/**
* The fertilizer will grow a plant.
*/
GrowPlant,
/**
* The fertilizer will grow magical crops.
*/
GrowMagicalCrop,
}

View File

@ -0,0 +1,26 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
public interface IDeepStorageUnit
{
/**
* @return A populated ItemStack with stackSize for the full amount of materials in the DSU. May have a stackSize > getMaxStackSize().
*/
ItemStack getStoredItemType();
/**
* Sets the total amount of the item currently being stored, or zero if it wants to remove all items.
*/
void setStoredItemCount(int amount);
/**
* Sets the type of the stored item and initializes the number of stored items to count. Will overwrite any existing stored items.
*/
void setStoredItemType(int itemID, int meta, int Count);
/**
* @return The maximum number of items the DSU can hold.
*/
int getMaxStoredCount();
}

View File

@ -0,0 +1,40 @@
package powercrystals.minefactoryreloaded.api;
import java.util.Random;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a fertilizable block, and the process to fertilize it. You can assume that you will never have to check that block ID matches the one returned by
* getFertilizableBlockId().
*/
public interface IFactoryFertilizable
{
/**
* @return The block ID this instance is managing.
*/
public int getFertilizableBlockId();
/**
* @param world The world this block belongs to.
* @param x The X coordinate of this block.
* @param y The Y coordinate of this block.
* @param z The Z coordinate of this block.
* @param fertilizerType The kind of fertilizer being used.
* @return True if the block at (x,y,z) can be fertilized with the given type of fertilizer.
*/
public boolean canFertilizeBlock(World world, int x, int y, int z, FertilizerType fertilizerType);
/**
* @param world The world this block belongs to.
* @param rand A Random instance to use when fertilizing, if necessary.
* @param x The X coordinate of this block.
* @param y The Y coordinate of this block.
* @param z The Z coordinate of this block.
* @param fertilizerType The kind of fertilizer being used.
* @return True if fertilization was successful. If false, the Fertilizer will not consume a fertilizer item and will not drain power.
*/
public boolean fertilize(World world, Random rand, int x, int y, int z, FertilizerType fertilizerType);
}

View File

@ -0,0 +1,33 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* Defines a fertilizer item for use in the Fertilizer.
*/
public interface IFactoryFertilizer
{
/**
* @return The ID of this fertilizer item.
*/
int getFertilizerId();
/**
* @return The metadata of this fertilizer item.
*/
int getFertilizerMeta();
/**
* @return The type of fertilizer this is.
*/
FertilizerType getFertilizerType();
/**
* Called when a fertilization is successful. If you set the ItemStack size to 0, it will be deleted by the fertilizer.
*
* @param fertilizer The ItemStack used to fertilize.
*/
void consume(ItemStack fertilizer);
}

View File

@ -0,0 +1,69 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import java.util.Random;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* Defines a fruit entry for the Fruit Picker.
*
* @author powercrystals
*
*/
public interface IFactoryFruit
{
/**
* @return The block ID this fruit has in the world.
*/
public int getSourceBlockId();
/**
* Used to determine if this fruit can be picked (is it ripe yet, etc)
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
* @return True if the fruit can be picked
*/
public boolean canBePicked(World world, int x, int y, int z);
/**
* Called by the Fruit Picker to determine what block to replace the picked block with. Only ID and meta/damage will be used.
* At the time this method is called, the fruit still exists. Do not pass an item ID as the return value.
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
* @return The block to replace the fruit block with, or null for air.
*/
public ItemStack getReplacementBlock(World world, int x, int y, int z);
/**
* Called by the Fruit Picker before the fruit is picked.
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
*/
public void prePick(World world, int x, int y, int z);
/**
* Called by the Fruit Picker to determine what drops to generate. At the time this method is called, the fruit still exists.
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
*/
public List<ItemStack> getDrops(World world, Random rand, int x, int y, int z);
/**
* Called by the Fruit Picker after the fruit is picked.
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
*/
public void postPick(World world, int x, int y, int z);
}

View File

@ -0,0 +1,67 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a plantable object for use in the Planter.
*/
public interface IFactoryPlantable
{
/**
* @return The block or item ID this plantable is managing.
*/
public int getSeedId();
/**
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
* @return The block ID that will be placed into the world.
*/
public int getPlantedBlockId(World world, int x, int y, int z, ItemStack stack);
/**
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
* @return The block metadata that will be placed into the world.
*/
public int getPlantedBlockMetadata(World world, int x, int y, int z, ItemStack stack);
/**
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
* @return True if this plantable can be placed at the provided coordinates.
*/
public boolean canBePlantedHere(World world, int x, int y, int z, ItemStack stack);
/**
* Called before planting is performed. Used to till soil, for example.
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
*/
public void prePlant(World world, int x, int y, int z, ItemStack stack);
/**
* Called after planting is performed. Usually empty.
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
*/
public void postPlant(World world, int x, int y, int z, ItemStack stack);
}

View File

@ -0,0 +1,29 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import net.minecraft.entity.EntityLiving;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a ranchable entity for use in the Rancher.
*/
public interface IFactoryRanchable
{
/**
* @return The entity being ranched. Must be a subtype of EntityLiving.
*/
public Class<?> getRanchableEntity();
/**
* @param world The world this entity is in.
* @param entity The entity instance being ranched.
* @param rancher The rancher instance doing the ranching. Used to access the Rancher's inventory when milking cows, for example.
* @return A list of drops.
*/
public List<ItemStack> ranch(World world, EntityLiving entity, IInventory rancher);
}

View File

@ -0,0 +1,8 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.player.EntityPlayer;
public interface ILiquidDrinkHandler
{
public void onDrink(EntityPlayer player);
}

View File

@ -0,0 +1,18 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.EntityEggInfo;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* Defines a class that MFR will use to local egg info for a given mob. This is used to color the Safari Net based on the captured mob.
*/
public interface IMobEggHandler
{
/**
* @param safariNet The Safari Net that is looking for egg info.
* @return An EntityEggInfo, or null if this instance cannot handle this mob.
*/
public EntityEggInfo getEgg(ItemStack safariNet);
}

View File

@ -0,0 +1,11 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import net.minecraft.world.World;
public interface IRandomMobProvider
{
public List<RandomMob> getRandomMobs(World world);
}

View File

@ -0,0 +1,28 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* Defines an object that can display information about a captured mob in a Safari net.
*/
public interface ISafariNetHandler
{
/**
* @return The class of mob that this handler applies to.
*/
public Class<?> validFor();
/**
* @param safariNetStack The Safari Net that is requesting information.
* @param player The player holding the Safari Net.
* @param infoList The current list of information strings. Add yours to this.
* @param advancedTooltips True if the advanced tooltips option is on.
*/
@SuppressWarnings("rawtypes")
public void addInformation(ItemStack safariNetStack, EntityPlayer player, List infoList, boolean advancedTooltips);
}

View File

@ -0,0 +1,31 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.EntityLiving;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a syringe for use in the Vet machine.
*/
public interface ISyringe
{
/**
* Called when the vet is deciding if it should use this syringe.
* @param world The world instance.
* @param entity The entity being injected.
* @param syringe The syringe ItemStack.
* @return True if the entity can be injected by this syringe.
*/
public boolean canInject(World world, EntityLiving entity, ItemStack syringe);
/**
* Called to perform an injection.
* @param world The world instance.
* @param entity The entity being injected.
* @param syringe The syringe ItemStack.
* @return True if injection was successful.
*/
public boolean inject(World world, EntityLiving entity, ItemStack syringe);
}

View File

@ -0,0 +1,9 @@
package powercrystals.minefactoryreloaded.api;
/**
* @author PowerCrystals
* Defines a tool that can rotate MFR machines. Implement on an Item class. Requires no additional work on your part.
*/
public interface IToolHammer
{
}

View File

@ -0,0 +1,16 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* This interface is like IToolHammer, but is for items that change state on a per-stack basis. Implement this
* instead of IToolHammer - not both!
*
* This interface will replace IToolHammer in MC 1.6.
*/
public interface IToolHammerAdvanced
{
public boolean isActive(ItemStack stack);
}

View File

@ -0,0 +1,21 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.Entity;
import net.minecraft.util.WeightedRandomItem;
public class RandomMob extends WeightedRandomItem
{
private Entity _mob;
public RandomMob(Entity savedMob, int weight)
{
super(weight);
_mob = savedMob;
}
public Entity getMob()
{
if(_mob == null) return null;
return _mob;
}
}

View File

@ -0,0 +1,80 @@
package powercrystals.minefactoryreloaded.api.rednet;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
/**
* Defines a Block that can connect to RedNet wires. This must be implemented on your Block class.
* Note that when you implement this, the RedNet network makes several assumptions about your code -
* primarily, it will not clamp values to 0 <= x <= 15. This means you must be able to accept any
* possible integer without crashing, even negatives. It will also assume that calling the onInput(s)Changed()
* methods are sufficient, and will not issue block updates. Finally, it will never call the vanilla redstone
* output methods in All mode, and will only query the methods contained in this interface in that case. In Single
* mode, it will call onInputChanged, and will check for strong power (or weak if in Plate mode) through the vanilla
* method calls.
*/
public interface IConnectableRedNet
{
/**
* Returns the connection type of this Block. "All" types will cause getOutputValues() and onInputsChanged() to be used,
* whereas "Single" types will onInputChanged() to be called for input changes and the normal redstone power output methods
* to be called for output. If this value must be changed while the block is alive, it must perform a block update on any
* adjacent RedNet wires.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side that connection information is required for.
* @return The connection type.
*/
public RedNetConnectionType getConnectionType(World world, int x, int y, int z, ForgeDirection side);
/**
* Returns the output values of this RedNet node. This array must be 16 elements long. Only called if your block is connected in "All" mode.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side the output values are required for.
* @return The output values.
*/
public int[] getOutputValues(World world, int x, int y, int z, ForgeDirection side);
/**
* Returns the output value of this RedNet node for a given subnet. Only called if your block is connected in "All" mode.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side the output value is required for.
* @param subnet The subnet to get the output value for (0-15).
* @return The output value.
*/
public int getOutputValue(World world, int x, int y, int z, ForgeDirection side, int subnet);
/**
* Called when the input values to this block change. Only called if your block is connected in "All" mode.
* Do not issue a network value update from inside this method call; it will be ignored. Issue your updates
* on the next tick.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side the input values are being changed on.
* @param inputValues The new set of input values. This array will be 16 elements long.
*/
public void onInputsChanged(World world, int x, int y, int z, ForgeDirection side, int[] inputValues);
/**
* Called when the input value to this block changes. Only called if your block is connected in "Single" mode.
* Do not issue a network value update from inside this method call; it will be ignored. Issue your updates
* on the next tick.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side the input values are being changed on.
* @param inputValue The new input value
*/
public void onInputChanged(World world, int x, int y, int z, ForgeDirection side, int inputValue);
}

View File

@ -0,0 +1,19 @@
package powercrystals.minefactoryreloaded.api.rednet;
import net.minecraft.nbt.NBTTagCompound;
public interface IRedNetLogicCircuit
{
public int getInputCount();
public int getOutputCount();
public int[] recalculateOutputValues(long worldTime, int[] inputValues);
public String getUnlocalizedName();
public String getInputPinLabel(int pin);
public String getOutputPinLabel(int pin);
public void readFromNBT(NBTTagCompound tag);
public void writeToNBT(NBTTagCompound tag);
}

View File

@ -0,0 +1,31 @@
package powercrystals.minefactoryreloaded.api.rednet;
import net.minecraft.world.World;
/**
*
* You should not implement this yourself. Instead, use this to look for cables to notify from your IConnectableRedNet as this does not
* require a block update. This will be implemented on the cable's Block class.
*
*/
public interface IRedNetNetworkContainer
{
/**
* Tells the network to recalculate all subnets.
* @param world The world this cable is in.
* @param x The x-coordinate of this cable.
* @param x The y-coordinate of this cable.
* @param x The z-coordinate of this cable.
*/
public void updateNetwork(World world, int x, int y, int z);
/**
* Tells the network to recalculate a specific subnet.
* @param world The world this cable is in.
* @param x The x-coordinate of this cable.
* @param x The y-coordinate of this cable.
* @param x The z-coordinate of this cable.
* @param subnet The subnet to recalculate.
*/
public void updateNetwork(World world, int x, int y, int z, int subnet);
}

View File

@ -0,0 +1,10 @@
package powercrystals.minefactoryreloaded.api.rednet;
public enum RedNetConnectionType
{
None,
CableSingle,
PlateSingle,
CableAll,
PlateAll
}