diff --git a/extrabiomes/api/Api.java b/extrabiomes/api/Api.java new file mode 100644 index 0000000..23ca124 --- /dev/null +++ b/extrabiomes/api/Api.java @@ -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 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); + } + +} diff --git a/extrabiomes/api/BiomeManager.java b/extrabiomes/api/BiomeManager.java new file mode 100644 index 0000000..dd51e11 --- /dev/null +++ b/extrabiomes/api/BiomeManager.java @@ -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. + *

+ * NOTE: 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 alpine = Optional.absent(); + public static Optional autumnwoods = Optional.absent(); + public static Optional birchforest = Optional.absent(); + public static Optional extremejungle = Optional.absent(); + public static Optional forestedisland = Optional.absent(); + public static Optional forestedhills = Optional.absent(); + public static Optional glacier = Optional.absent(); + public static Optional greenhills = Optional.absent(); + public static Optional icewasteland = Optional.absent(); + public static Optional greenswamp = Optional.absent(); + public static Optional marsh = Optional.absent(); + public static Optional meadow = Optional.absent(); + public static Optional minijungle = Optional.absent(); + public static Optional mountaindesert = Optional.absent(); + public static Optional mountainridge = Optional.absent(); + public static Optional mountaintaiga = Optional.absent(); + public static Optional pineforest = Optional.absent(); + public static Optional rainforest = Optional.absent(); + public static Optional redwoodforest = Optional.absent(); + public static Optional redwoodlush = Optional.absent(); + public static Optional savanna = Optional.absent(); + public static Optional shrubland = Optional.absent(); + public static Optional snowforest = Optional.absent(); + public static Optional snowyrainforest = Optional.absent(); + public static Optional temperaterainforest = Optional.absent(); + public static Optional tundra = Optional.absent(); + public static Optional wasteland = Optional.absent(); + public static Optional woodlands = Optional.absent(); + + protected static Optional 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 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 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 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 chooseBiomeRandomGen( + GenType genType, Random rand, BiomeGenBase biome); + + protected abstract Collection getBiomeCollection(); + + protected abstract int getBiomeTotalWeight(GenType genType, + BiomeGenBase biome); +} diff --git a/extrabiomes/api/Biomes.java b/extrabiomes/api/Biomes.java new file mode 100644 index 0000000..d90be19 --- /dev/null +++ b/extrabiomes/api/Biomes.java @@ -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 + * Optional value will not be present. + */ + public static Optional 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]); + } + +} diff --git a/extrabiomes/api/DiscoverWorldTypesEvent.java b/extrabiomes/api/DiscoverWorldTypesEvent.java new file mode 100644 index 0000000..836e9f4 --- /dev/null +++ b/extrabiomes/api/DiscoverWorldTypesEvent.java @@ -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 worldTypes; + + public DiscoverWorldTypesEvent(Collection 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); + } +} diff --git a/extrabiomes/api/PluginEvent.java b/extrabiomes/api/PluginEvent.java new file mode 100644 index 0000000..e27b21e --- /dev/null +++ b/extrabiomes/api/PluginEvent.java @@ -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 {} + +} diff --git a/extrabiomes/api/Stuff.java b/extrabiomes/api/Stuff.java new file mode 100644 index 0000000..6d9a042 --- /dev/null +++ b/extrabiomes/api/Stuff.java @@ -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 scarecrow = Optional.absent(); + public static Optional paste = Optional.absent(); + + public static Optional planks = Optional.absent(); + public static Optional quickSand = Optional.absent(); + public static Optional slabRedRock = Optional.absent(); + public static Optional slabRedRockDouble = Optional.absent(); + public static Optional slabWood = Optional.absent(); + public static Optional slabWoodDouble = Optional.absent(); + public static Optional stairsAcacia = Optional.absent(); + public static Optional stairsFir = Optional.absent(); + public static Optional stairsRedCobble = Optional.absent(); + public static Optional stairsRedRockBrick = Optional.absent(); + public static Optional stairsRedwood = Optional.absent(); + public static Optional wall = Optional.absent(); + +} diff --git a/extrabiomes/api/UseLogTurnerEvent.java b/extrabiomes/api/UseLogTurnerEvent.java new file mode 100644 index 0000000..3a83927 --- /dev/null +++ b/extrabiomes/api/UseLogTurnerEvent.java @@ -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; + } +} diff --git a/extrabiomes/api/events/GetBiomeIDEvent.java b/extrabiomes/api/events/GetBiomeIDEvent.java new file mode 100644 index 0000000..b67fb62 --- /dev/null +++ b/extrabiomes/api/events/GetBiomeIDEvent.java @@ -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: + * + *

+     *     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
+     * 
+ */ + public final String targetBiome; + public int biomeID; + + public GetBiomeIDEvent(String targetBiome) { + this.targetBiome = targetBiome; + } + +} diff --git a/ic2/api/Direction.java b/ic2/api/Direction.java new file mode 100644 index 0000000..751375a --- /dev/null +++ b/ic2/api/Direction.java @@ -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(); +} + diff --git a/ic2/api/crops/BaseSeed.java b/ic2/api/crops/BaseSeed.java new file mode 100644 index 0000000..11286b4 --- /dev/null +++ b/ic2/api/crops/BaseSeed.java @@ -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; + } +} diff --git a/ic2/api/crops/CropCard.java b/ic2/api/crops/CropCard.java new file mode 100644 index 0000000..1d1d171 --- /dev/null +++ b/ic2/api/crops/CropCard.java @@ -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[]; +} diff --git a/ic2/api/crops/Crops.java b/ic2/api/crops/Crops.java new file mode 100644 index 0000000..e054b1f --- /dev/null +++ b/ic2/api/crops/Crops.java @@ -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); +} diff --git a/ic2/api/crops/ICropTile.java b/ic2/api/crops/ICropTile.java new file mode 100644 index 0000000..4084c50 --- /dev/null +++ b/ic2/api/crops/ICropTile.java @@ -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); +} diff --git a/ic2/api/energy/EnergyNet.java b/ic2/api/energy/EnergyNet.java new file mode 100644 index 0000000..724aa9b --- /dev/null +++ b/ic2/api/energy/EnergyNet.java @@ -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; +} + diff --git a/ic2/api/energy/event/EnergyTileEvent.java b/ic2/api/energy/event/EnergyTileEvent.java new file mode 100644 index 0000000..c8faea4 --- /dev/null +++ b/ic2/api/energy/event/EnergyTileEvent.java @@ -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; + } +} + diff --git a/ic2/api/energy/event/EnergyTileLoadEvent.java b/ic2/api/energy/event/EnergyTileLoadEvent.java new file mode 100644 index 0000000..b80d45b --- /dev/null +++ b/ic2/api/energy/event/EnergyTileLoadEvent.java @@ -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); + } +} + diff --git a/ic2/api/energy/event/EnergyTileSourceEvent.java b/ic2/api/energy/event/EnergyTileSourceEvent.java new file mode 100644 index 0000000..80c230c --- /dev/null +++ b/ic2/api/energy/event/EnergyTileSourceEvent.java @@ -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; + } +} + diff --git a/ic2/api/energy/event/EnergyTileUnloadEvent.java b/ic2/api/energy/event/EnergyTileUnloadEvent.java new file mode 100644 index 0000000..5e04637 --- /dev/null +++ b/ic2/api/energy/event/EnergyTileUnloadEvent.java @@ -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); + } +} + diff --git a/ic2/api/energy/tile/IEnergyAcceptor.java b/ic2/api/energy/tile/IEnergyAcceptor.java new file mode 100644 index 0000000..c4bb85b --- /dev/null +++ b/ic2/api/energy/tile/IEnergyAcceptor.java @@ -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); +} + diff --git a/ic2/api/energy/tile/IEnergyConductor.java b/ic2/api/energy/tile/IEnergyConductor.java new file mode 100644 index 0000000..2bfc8b6 --- /dev/null +++ b/ic2/api/energy/tile/IEnergyConductor.java @@ -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(); +} + diff --git a/ic2/api/energy/tile/IEnergyEmitter.java b/ic2/api/energy/tile/IEnergyEmitter.java new file mode 100644 index 0000000..367349f --- /dev/null +++ b/ic2/api/energy/tile/IEnergyEmitter.java @@ -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); +} + diff --git a/ic2/api/energy/tile/IEnergySink.java b/ic2/api/energy/tile/IEnergySink.java new file mode 100644 index 0000000..19013c1 --- /dev/null +++ b/ic2/api/energy/tile/IEnergySink.java @@ -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(); +} + diff --git a/ic2/api/energy/tile/IEnergySource.java b/ic2/api/energy/tile/IEnergySource.java new file mode 100644 index 0000000..d008648 --- /dev/null +++ b/ic2/api/energy/tile/IEnergySource.java @@ -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(); +} + diff --git a/ic2/api/energy/tile/IEnergyTile.java b/ic2/api/energy/tile/IEnergyTile.java new file mode 100644 index 0000000..182e10d --- /dev/null +++ b/ic2/api/energy/tile/IEnergyTile.java @@ -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(); +} + diff --git a/ic2/api/energy/usage.txt b/ic2/api/energy/usage.txt new file mode 100644 index 0000000..b01b3c0 --- /dev/null +++ b/ic2/api/energy/usage.txt @@ -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. + diff --git a/ic2/api/event/PaintEvent.java b/ic2/api/event/PaintEvent.java new file mode 100644 index 0000000..add12fa --- /dev/null +++ b/ic2/api/event/PaintEvent.java @@ -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; + } +} diff --git a/ic2/api/event/RetextureEvent.java b/ic2/api/event/RetextureEvent.java new file mode 100644 index 0000000..c80bcf8 --- /dev/null +++ b/ic2/api/event/RetextureEvent.java @@ -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; + } +} diff --git a/ic2/api/item/ElectricItem.java b/ic2/api/item/ElectricItem.java new file mode 100644 index 0000000..051a76b --- /dev/null +++ b/ic2/api/item/ElectricItem.java @@ -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; +} + diff --git a/ic2/api/item/IBoxable.java b/ic2/api/item/IBoxable.java new file mode 100644 index 0000000..deb9f48 --- /dev/null +++ b/ic2/api/item/IBoxable.java @@ -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); +} diff --git a/ic2/api/item/ICustomElectricItem.java b/ic2/api/item/ICustomElectricItem.java new file mode 100644 index 0000000..8c1baea --- /dev/null +++ b/ic2/api/item/ICustomElectricItem.java @@ -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); +} diff --git a/ic2/api/item/IElectricItem.java b/ic2/api/item/IElectricItem.java new file mode 100644 index 0000000..adaf3b7 --- /dev/null +++ b/ic2/api/item/IElectricItem.java @@ -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); +} + diff --git a/ic2/api/item/IMetalArmor.java b/ic2/api/item/IMetalArmor.java new file mode 100644 index 0000000..16ffd24 --- /dev/null +++ b/ic2/api/item/IMetalArmor.java @@ -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); +} diff --git a/ic2/api/item/ITerraformingBP.java b/ic2/api/item/ITerraformingBP.java new file mode 100644 index 0000000..58f7e2f --- /dev/null +++ b/ic2/api/item/ITerraformingBP.java @@ -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); +} diff --git a/ic2/api/item/ItemWrapper.java b/ic2/api/item/ItemWrapper.java new file mode 100644 index 0000000..58f8073 --- /dev/null +++ b/ic2/api/item/ItemWrapper.java @@ -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 boxableItems = ArrayListMultimap.create(); + private static final Multimap 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; + } +} diff --git a/ic2/api/item/Items.java b/ic2/api/item/Items.java new file mode 100644 index 0000000..0d3f753 --- /dev/null +++ b/ic2/api/item/Items.java @@ -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; +} + diff --git a/ic2/api/network/INetworkClientTileEntityEventListener.java b/ic2/api/network/INetworkClientTileEntityEventListener.java new file mode 100644 index 0000000..ed3ea38 --- /dev/null +++ b/ic2/api/network/INetworkClientTileEntityEventListener.java @@ -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); +} + diff --git a/ic2/api/network/INetworkDataProvider.java b/ic2/api/network/INetworkDataProvider.java new file mode 100644 index 0000000..c3f283e --- /dev/null +++ b/ic2/api/network/INetworkDataProvider.java @@ -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 getNetworkedFields(); +} + diff --git a/ic2/api/network/INetworkItemEventListener.java b/ic2/api/network/INetworkItemEventListener.java new file mode 100644 index 0000000..02ce470 --- /dev/null +++ b/ic2/api/network/INetworkItemEventListener.java @@ -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); +} + diff --git a/ic2/api/network/INetworkTileEntityEventListener.java b/ic2/api/network/INetworkTileEntityEventListener.java new file mode 100644 index 0000000..fbb4753 --- /dev/null +++ b/ic2/api/network/INetworkTileEntityEventListener.java @@ -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); +} + diff --git a/ic2/api/network/INetworkUpdateListener.java b/ic2/api/network/INetworkUpdateListener.java new file mode 100644 index 0000000..09414ae --- /dev/null +++ b/ic2/api/network/INetworkUpdateListener.java @@ -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); +} + diff --git a/ic2/api/network/NetworkHelper.java b/ic2/api/network/NetworkHelper.java new file mode 100644 index 0000000..0981daf --- /dev/null +++ b/ic2/api/network/NetworkHelper.java @@ -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; +} + diff --git a/ic2/api/reactor/IC2Reactor.java b/ic2/api/reactor/IC2Reactor.java new file mode 100644 index 0000000..512c4ff --- /dev/null +++ b/ic2/api/reactor/IC2Reactor.java @@ -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"; + } +} diff --git a/ic2/api/reactor/IReactor.java b/ic2/api/reactor/IReactor.java new file mode 100644 index 0000000..7a32187 --- /dev/null +++ b/ic2/api/reactor/IReactor.java @@ -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(); +} diff --git a/ic2/api/reactor/IReactorChamber.java b/ic2/api/reactor/IReactorChamber.java new file mode 100644 index 0000000..1b9f2c9 --- /dev/null +++ b/ic2/api/reactor/IReactorChamber.java @@ -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(); +} diff --git a/ic2/api/reactor/IReactorComponent.java b/ic2/api/reactor/IReactorComponent.java new file mode 100644 index 0000000..5170e94 --- /dev/null +++ b/ic2/api/reactor/IReactorComponent.java @@ -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); +} diff --git a/ic2/api/recipe/ICraftingRecipeManager.java b/ic2/api/recipe/ICraftingRecipeManager.java new file mode 100644 index 0000000..756eaf6 --- /dev/null +++ b/ic2/api/recipe/ICraftingRecipeManager.java @@ -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); +} diff --git a/ic2/api/recipe/IListRecipeManager.java b/ic2/api/recipe/IListRecipeManager.java new file mode 100644 index 0000000..5c0d306 --- /dev/null +++ b/ic2/api/recipe/IListRecipeManager.java @@ -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 { + /** + * 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 getStacks(); +} diff --git a/ic2/api/recipe/IMachineRecipeManager.java b/ic2/api/recipe/IMachineRecipeManager.java new file mode 100644 index 0000000..9adaeb8 --- /dev/null +++ b/ic2/api/recipe/IMachineRecipeManager.java @@ -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 { + /** + * 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 getRecipes(); +} diff --git a/ic2/api/recipe/Recipes.java b/ic2/api/recipe/Recipes.java new file mode 100644 index 0000000..7c36237 --- /dev/null +++ b/ic2/api/recipe/Recipes.java @@ -0,0 +1,38 @@ +package ic2.api.recipe; + +import net.minecraft.item.ItemStack; + +/** + * General recipe registry. + * + * @author Richard + */ +public class Recipes { + public static IMachineRecipeManager macerator; + public static IMachineRecipeManager extractor; + public static IMachineRecipeManager compressor; + + /** + * Reference amplifier values: + * + * 5000: Scrap + * 45000: Scrapbox + */ + public static IMachineRecipeManager 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 scrapboxDrops; + public static IListRecipeManager recyclerBlacklist; + + public static ICraftingRecipeManager advRecipes; +} diff --git a/ic2/api/tile/ExplosionWhitelist.java b/ic2/api/tile/ExplosionWhitelist.java new file mode 100644 index 0000000..01322b6 --- /dev/null +++ b/ic2/api/tile/ExplosionWhitelist.java @@ -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 whitelist = new HashSet(); +} + diff --git a/ic2/api/tile/IEnergyStorage.java b/ic2/api/tile/IEnergyStorage.java new file mode 100644 index 0000000..79f3011 --- /dev/null +++ b/ic2/api/tile/IEnergyStorage.java @@ -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); +} diff --git a/ic2/api/tile/IWrenchable.java b/ic2/api/tile/IWrenchable.java new file mode 100644 index 0000000..b82c6ff --- /dev/null +++ b/ic2/api/tile/IWrenchable.java @@ -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); +} + diff --git a/mods/tinker/tconstruct/TConstruct.java b/mods/tinker/tconstruct/TConstruct.java index 8ba9e09..a34c1f7 100644 --- a/mods/tinker/tconstruct/TConstruct.java +++ b/mods/tinker/tconstruct/TConstruct.java @@ -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 { diff --git a/mods/tinker/tconstruct/client/TProxyClient.java b/mods/tinker/tconstruct/client/TProxyClient.java index 3d89be1..fddc50c 100644 --- a/mods/tinker/tconstruct/client/TProxyClient.java +++ b/mods/tinker/tconstruct/client/TProxyClient.java @@ -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)); diff --git a/mods/tinker/tconstruct/common/TContent.java b/mods/tinker/tconstruct/common/TContent.java index 1ffd2a2..f3fc52f 100644 --- a/mods/tinker/tconstruct/common/TContent.java +++ b/mods/tinker/tconstruct/common/TContent.java @@ -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 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); } diff --git a/mods/tinker/tconstruct/entity/BlueSlime.java b/mods/tinker/tconstruct/entity/BlueSlime.java index 9197c9d..1a8f68c 100644 --- a/mods/tinker/tconstruct/entity/BlueSlime.java +++ b/mods/tinker/tconstruct/entity/BlueSlime.java @@ -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); + } } } diff --git a/mods/tinker/tconstruct/entity/NitroCreeper.java b/mods/tinker/tconstruct/entity/NitroCreeper.java deleted file mode 100644 index 209d2ee..0000000 --- a/mods/tinker/tconstruct/entity/NitroCreeper.java +++ /dev/null @@ -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; - }*/ -} diff --git a/mods/tinker/tconstruct/items/TitleIcon.java b/mods/tinker/tconstruct/items/TitleIcon.java index 4de8ef3..2207c03 100644 --- a/mods/tinker/tconstruct/items/TitleIcon.java +++ b/mods/tinker/tconstruct/items/TitleIcon.java @@ -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) { diff --git a/mods/tinker/tconstruct/plugins/minefactoryreloaded/MineFactoryReloaded.java b/mods/tinker/tconstruct/plugins/minefactoryreloaded/MineFactoryReloaded.java index c4ca83a..fa1a9aa 100644 --- a/mods/tinker/tconstruct/plugins/minefactoryreloaded/MineFactoryReloaded.java +++ b/mods/tinker/tconstruct/plugins/minefactoryreloaded/MineFactoryReloaded.java @@ -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; diff --git a/mods/tinker/tconstruct/skill/SkillBase.java b/mods/tinker/tconstruct/skill/SkillBase.java new file mode 100644 index 0000000..f80949c --- /dev/null +++ b/mods/tinker/tconstruct/skill/SkillBase.java @@ -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; + } +} diff --git a/mods/tinker/tconstruct/util/PHConstruct.java b/mods/tinker/tconstruct/util/PHConstruct.java index 8d4f871..52d0fbb 100644 --- a/mods/tinker/tconstruct/util/PHConstruct.java +++ b/mods/tinker/tconstruct/util/PHConstruct.java @@ -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; diff --git a/mods/tinker/tconstruct/util/TEventHandler.java b/mods/tinker/tconstruct/util/TEventHandler.java index 084816b..f4b8512 100644 --- a/mods/tinker/tconstruct/util/TEventHandler.java +++ b/mods/tinker/tconstruct/util/TEventHandler.java @@ -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); } } diff --git a/mods/tinker/textures/mob/creeperunstable.png b/mods/tinker/textures/mob/creeperunstable.png deleted file mode 100644 index 93fa310..0000000 Binary files a/mods/tinker/textures/mob/creeperunstable.png and /dev/null differ diff --git a/powercrystals/minefactoryreloaded/api/FertilizerType.java b/powercrystals/minefactoryreloaded/api/FertilizerType.java new file mode 100644 index 0000000..15e8bfb --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/FertilizerType.java @@ -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, +} \ No newline at end of file diff --git a/powercrystals/minefactoryreloaded/api/IDeepStorageUnit.java b/powercrystals/minefactoryreloaded/api/IDeepStorageUnit.java new file mode 100644 index 0000000..ec6c1be --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IDeepStorageUnit.java @@ -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(); +} diff --git a/powercrystals/minefactoryreloaded/api/IFactoryFertilizable.java b/powercrystals/minefactoryreloaded/api/IFactoryFertilizable.java new file mode 100644 index 0000000..1374d59 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IFactoryFertilizable.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/IFactoryFertilizer.java b/powercrystals/minefactoryreloaded/api/IFactoryFertilizer.java new file mode 100644 index 0000000..08589c1 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IFactoryFertilizer.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/IFactoryFruit.java b/powercrystals/minefactoryreloaded/api/IFactoryFruit.java new file mode 100644 index 0000000..65ed9f9 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IFactoryFruit.java @@ -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 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); +} diff --git a/powercrystals/minefactoryreloaded/api/IFactoryPlantable.java b/powercrystals/minefactoryreloaded/api/IFactoryPlantable.java new file mode 100644 index 0000000..29bc7fb --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IFactoryPlantable.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/IFactoryRanchable.java b/powercrystals/minefactoryreloaded/api/IFactoryRanchable.java new file mode 100644 index 0000000..23fec3b --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IFactoryRanchable.java @@ -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 ranch(World world, EntityLiving entity, IInventory rancher); +} diff --git a/powercrystals/minefactoryreloaded/api/ILiquidDrinkHandler.java b/powercrystals/minefactoryreloaded/api/ILiquidDrinkHandler.java new file mode 100644 index 0000000..2ab4a58 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/ILiquidDrinkHandler.java @@ -0,0 +1,8 @@ +package powercrystals.minefactoryreloaded.api; + +import net.minecraft.entity.player.EntityPlayer; + +public interface ILiquidDrinkHandler +{ + public void onDrink(EntityPlayer player); +} diff --git a/powercrystals/minefactoryreloaded/api/IMobEggHandler.java b/powercrystals/minefactoryreloaded/api/IMobEggHandler.java new file mode 100644 index 0000000..a322f92 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IMobEggHandler.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/IRandomMobProvider.java b/powercrystals/minefactoryreloaded/api/IRandomMobProvider.java new file mode 100644 index 0000000..b03d6f0 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IRandomMobProvider.java @@ -0,0 +1,11 @@ +package powercrystals.minefactoryreloaded.api; + +import java.util.List; + +import net.minecraft.world.World; + + +public interface IRandomMobProvider +{ + public List getRandomMobs(World world); +} \ No newline at end of file diff --git a/powercrystals/minefactoryreloaded/api/ISafariNetHandler.java b/powercrystals/minefactoryreloaded/api/ISafariNetHandler.java new file mode 100644 index 0000000..3700179 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/ISafariNetHandler.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/ISyringe.java b/powercrystals/minefactoryreloaded/api/ISyringe.java new file mode 100644 index 0000000..5521d45 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/ISyringe.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/IToolHammer.java b/powercrystals/minefactoryreloaded/api/IToolHammer.java new file mode 100644 index 0000000..09ce777 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IToolHammer.java @@ -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 +{ +} diff --git a/powercrystals/minefactoryreloaded/api/IToolHammerAdvanced.java b/powercrystals/minefactoryreloaded/api/IToolHammerAdvanced.java new file mode 100644 index 0000000..9c45234 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/IToolHammerAdvanced.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/RandomMob.java b/powercrystals/minefactoryreloaded/api/RandomMob.java new file mode 100644 index 0000000..063699d --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/RandomMob.java @@ -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; + } +} diff --git a/powercrystals/minefactoryreloaded/api/rednet/IConnectableRedNet.java b/powercrystals/minefactoryreloaded/api/rednet/IConnectableRedNet.java new file mode 100644 index 0000000..50ece4c --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/rednet/IConnectableRedNet.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/rednet/IRedNetLogicCircuit.java b/powercrystals/minefactoryreloaded/api/rednet/IRedNetLogicCircuit.java new file mode 100644 index 0000000..0bbbeeb --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/rednet/IRedNetLogicCircuit.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/rednet/IRedNetNetworkContainer.java b/powercrystals/minefactoryreloaded/api/rednet/IRedNetNetworkContainer.java new file mode 100644 index 0000000..5e27b1f --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/rednet/IRedNetNetworkContainer.java @@ -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); +} diff --git a/powercrystals/minefactoryreloaded/api/rednet/RedNetConnectionType.java b/powercrystals/minefactoryreloaded/api/rednet/RedNetConnectionType.java new file mode 100644 index 0000000..58b08a4 --- /dev/null +++ b/powercrystals/minefactoryreloaded/api/rednet/RedNetConnectionType.java @@ -0,0 +1,10 @@ +package powercrystals.minefactoryreloaded.api.rednet; + +public enum RedNetConnectionType +{ + None, + CableSingle, + PlateSingle, + CableAll, + PlateAll +}