Compare commits

...

27 Commits

Author SHA1 Message Date
yueh f44cddf8d5 Splitted coremod into a container and loading plugin. 2017-07-23 15:37:39 +02:00
thatsIch e3bf52ff7b Merge pull request #2846 from suttonwilliamd/fix-LR-badge
Fixed "Latest Release" badge in readme.md
2017-07-13 22:55:56 +02:00
William 07913af4f8 Fixed "Latest Release" badge in readme.md
Spaces translate to %20 in URLs
2017-03-23 21:16:59 -04:00
yueh 1760113cd4 Fixes #2768: Incorrect return value when charging items via Tesla. (#2771) 2017-01-31 12:17:32 +01:00
yueh 12b05275f2 Fixes #2750: Added missing RF Integration Modules. (#2770)
* Fixes #2750: Added missing RF Integration Modules.

Readded the integration modules for both RF integrations.
These are necessary to correctly enable RF support as well as act as
fallback to disable it automatically on missing interfaces.

* Unittests and improved logging for integration modules.

Added a unittest to ensure an integration types instaniates an integration
module without throwing any exception.
Improved the logging should this ever happen at runtime again.
2017-01-31 12:17:03 +01:00
yueh c720584e49 Fixes #2729: Fix transformer regression introduced during FG downtime. (#2730)
Added a unittest to verify the necessary string returns match the actual
existing classes, in case something screws up the refactoring.
2016-12-31 18:25:16 +01:00
yueh ab89278274 Replaces old fluid handlers with the new capability based ones. (#2727)
* Changed ME Chest and P2P tunnels to use fluid capabilities.
* Renamed all occurrences of liquid to fluids.
2016-12-31 16:01:29 +01:00
yueh 7c5f777e41 Fixes #2713: Call super#onBlockActivated() for wrench interaction. (#2728) 2016-12-31 16:00:45 +01:00
yueh 8b0637d05d Fixes IDE not correctly cleaning up the list of staged files. 2016-12-31 15:21:25 +01:00
yueh 497f1c9ace Fixes #2714: Use a concurrent list to back NetworkList (#2715) 2016-12-29 15:51:17 +01:00
yueh 2ab0528015 Fixes #2724: Use capitalized oredict name for dyes, not uppercase. 2016-12-29 15:50:02 +01:00
yueh 589730bfad Fixes #2707: Calculuate the correct AABB for a rotated skychest. 2016-12-17 23:47:42 +01:00
yueh 8700a79ca6 Fixes #2684: Avoid transforming charged quartz when dead. 2016-12-17 23:04:35 +01:00
yueh a14cf2204d Fixes anchor rendering (#2698)
* Fixes #2680: Use a shorter cable anchor model when blocked by a facade.
* Fixes #2664: Prevent anchors from creating intersection.

Replaced the simple List<ResourceLocation> for the static models with a
new container also indicating a solid part, which can be used to prevent
the creation of an intersection.
2016-12-14 22:37:10 +01:00
yueh 8bed7f223e TheOneProbe integration (#2696)
Displayed information is equal to current the WAILA integration.

Added a preInit stage to IIntegrationModule.
Added a factory method to IntegrationType to avoid touching
IntegrationNode for every new integration.

Fixes #2650
2016-12-14 22:36:40 +01:00
yueh db85419702 Restructured registry packages (#2703)
Moved larger registries together with their related classes instead of putting unrelated classes into the same package.
2016-12-14 22:35:52 +01:00
yueh fb79fd284d Replaced Watcher using Collection with a more fitting interface (#2693)
Replaced the watchers for energy, storage and crafting with a more fitting interface compared to a common collection.

Fixes #229
2016-12-14 18:30:49 +01:00
yueh e3305c1963 Update Forge to latest RB
Updated JEI
2016-12-14 17:46:16 +01:00
yueh a3c85b4a59 Fixes #2699: Do not trust the stackSize in case of internal changes.
An external inventory might change the stacksize of the slot we currently
are extracting from. Thus we have to cache the initial stackSize for a later
calculation of the extracted amount per slot.
As other inventories might NOT change the stacksize after a modification,
we can not use the stack reaching 0 as conditions to break.
2016-12-14 11:25:49 +01:00
yueh a2b20f1d67 Fixes #2689: Do not pass our own blockstate to the adjacent block. 2016-12-08 21:29:46 +01:00
yueh 86908b1ae6 Fixes #2647: Prevent crafting status from crashing due to missing network. 2016-12-08 13:07:25 +01:00
dshadowwolf 6bf52b0b0f Fixes constant reequip animation on portable cells/terminals (#2690)
Fix for portable cell and wireless terminal going into re-equip animations when GUI is open.
2016-12-08 12:34:41 +01:00
yueh eb1e86cacb Refactored GrinderRegistry. (#2644)
* Refactored GrinderRegistry.

Changed IGrinderRegistry#getRecipes to return an unmodifiable collection.
Added a way to remove recipes explicitly instead the internal list.
Added a cache to lookup recipes instead of iterating a list.

Renamed IGrinderEntry to IGrinderRecipe
Made IGrindRecipe immutable for easy caching.

Improved GrinderLogging and Exception Handling
JEI Workaround as it expects a List instead Collection.

* Added blacklist of explicit oredict names for the grindstone.

This can be used should the automatic recipe generation create unintended
loopholes.
2016-12-02 23:47:50 +01:00
yueh c405e725b2 Fixes #2667: Use new IC2 item names for P2P attunement. 2016-12-02 22:16:29 +01:00
yueh d377af9a69 Fixes #2675: Set fullBlock correctly afterwards.
Reduces the visibility of some methods as these should be access through the public methods of Block or the overridden ones.
Removes now useless getCheckedSubBlocks.
2016-12-02 22:15:56 +01:00
yueh 12dbd17320 Fixes #2666: Restore inventory after powerloss and still avoid dupes. 2016-12-01 16:17:46 +01:00
yueh 5028c8025b Fixes #2669: Missing particle texture for pylons. 2016-12-01 10:56:01 +01:00
168 changed files with 3389 additions and 1820 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
[![Travis](https://img.shields.io/travis/AppliedEnergistics/Applied-Energistics-2.svg?maxAge=2592000&style=flat-square)](https://travis-ci.org/AppliedEnergistics/Applied-Energistics-2)
[![Latest Release](https://img.shields.io/github/release/AppliedEnergistics/Applied-Energistics-2.svg?label=Latest Release&style=flat-square)](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases)
[![Latest Release](https://img.shields.io/github/release/AppliedEnergistics/Applied-Energistics-2.svg?label=Latest%20Release&style=flat-square)](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases)
# Applied Energistics 2
+1 -1
View File
@@ -68,7 +68,7 @@ jar {
}
minecraft {
coreMod = "appeng.coremod.AppEngCore"
coreMod = "appeng.coremod.AppEngLoadingPlugin"
version = minecraft_version + "-" + forge_version
+3 -2
View File
@@ -9,7 +9,7 @@ aebasename=appliedenergistics2
#########################################################
minecraft_version=1.10.2
mcp_mappings=snapshot_20161111
forge_version=12.18.2.2139
forge_version=12.18.3.2185
#########################################################
# Installable #
@@ -19,6 +19,7 @@ waila_version=1.7.0-B3_1.9.4
#########################################################
# Provided APIs #
#########################################################
jei_version=3.13.3.373
jei_version=3.13.6.391
tesla_version=1.10.2-1.2.1.50
ic2_version=2.6.99-ex110
top_version=1.10-1.3.3-41
+7
View File
@@ -38,6 +38,11 @@ repositories {
name = "IC2 repo"
url = "http://maven.ic2.player.to"
}
maven { // TheOneProbe
name 'tterrag maven'
url "http://maven.tterrag.com/"
}
}
configurations {
@@ -48,12 +53,14 @@ dependencies {
// installable runtime dependencies
mods "mcp.mobius.waila:Waila:${waila_version}"
mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev"
mods "mcjty.theoneprobe:TheOneProbe:${top_version}"
// compile against provided APIs
compileOnly "mezz.jei:jei_${minecraft_version}:${jei_version}:api"
compileOnly "mcp.mobius.waila:Waila:${waila_version}"
compileOnly "net.darkhax.tesla:Tesla:${tesla_version}"
compileOnly "net.industrial-craft:industrialcraft-2:${ic2_version}:api"
compileOnly "mcjty.theoneprobe:TheOneProbe:${top_version}:api"
// at runtime, use the full JEI jar
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
+13 -1
View File
@@ -31,7 +31,7 @@ task deinstallWaila(type: Delete) {
delete fileTree(dir: minecraft.runDir + "/mods", include: "*Waila*.jar")
}
// IC²
// IC2
task installIC2(type: Copy, dependsOn: "deinstallIC2") {
from { configurations.mods }
include "**/*industrialcraft-2*.jar"
@@ -41,3 +41,15 @@ task installIC2(type: Copy, dependsOn: "deinstallIC2") {
task deinstallIC2(type: Delete) {
delete fileTree(dir: minecraft.runDir + "/mods", include: "*industrialcraft-2*.jar")
}
// TOP
task installTop(type: Copy, dependsOn: "deinstallTop") {
from { configurations.mods }
include "**/*TheOneProbe*.jar"
into file(minecraft.runDir + "/mods")
}
task deinstallTop(type: Delete) {
delete fileTree(dir: minecraft.runDir + "/mods", include: "*TheOneProbe*.jar")
}
@@ -76,7 +76,7 @@ public interface IParts
IItemDefinition p2PTunnelItems();
IItemDefinition p2PTunnelLiquids();
IItemDefinition p2PTunnelFluids();
IItemDefinition p2PTunnelEU();
@@ -24,13 +24,17 @@
package appeng.api.features;
import java.util.Optional;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
/**
* Registration Records for {@link IGrinderRegistry}
*/
public interface IGrinderEntry
public interface IGrinderRecipe
{
/**
@@ -38,66 +42,40 @@ public interface IGrinderEntry
*
* @return input that the grinder will accept.
*/
@Nonnull
ItemStack getInput();
/**
* lets you change the grinder recipe by changing its input.
*
* @param input input item
*/
void setInput( ItemStack input );
/**
* gets the current output
*
* @return output that the grinder will produce
*/
@Nonnull
ItemStack getOutput();
/**
* allows you to change the output.
* gets the current output
*
* @param output output item
* @return output that the grinder will produce
*/
void setOutput( ItemStack output );
@Nonnull
Optional<ItemStack> getOptionalOutput();
/**
* gets the current output
*
* @return output that the grinder will produce
*/
ItemStack getOptionalOutput();
/**
* gets the current output
*
* @return output that the grinder will produce
*/
ItemStack getSecondOptionalOutput();
/**
* stack, and 0.0-1.0 chance that it will be generated.
*
* @param output output item
* @param chance generation chance
*/
void setOptionalOutput( ItemStack output, float chance );
Optional<ItemStack> getSecondOptionalOutput();
/**
* 0.0 - 1.0 the chance that the optional output will be generated.
*
* @return chance of optional output
*/
@Nonnull
float getOptionalChance();
/**
* stack, and 0.0-1.0 chance that it will be generated.
*
* @param output second optional output item
* @param chance second optional output chance
*/
void setSecondOptionalOutput( ItemStack output, float chance );
/**
* 0.0 - 1.0 the chance that the optional output will be generated.
*
@@ -106,16 +84,10 @@ public interface IGrinderEntry
float getSecondOptionalChance();
/**
* Energy cost, in turns.
* Amount of turns required to process the item.
*
* @return number of turns it takes to produce the output from the input.
*/
int getEnergyCost();
int getRequiredTurns();
/**
* Allows you to adjust the number of turns
*
* @param c number of turns to produce output.
*/
void setEnergyCost( int c );
}
@@ -24,7 +24,10 @@
package appeng.api.features;
import java.util.List;
import java.util.Collection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
@@ -36,51 +39,90 @@ public interface IGrinderRegistry
{
/**
* Current list of registered recipes, you can modify this if you want too.
* An immutable list of the currently registered recipes.
*
* @return currentlyRegisteredRecipes
*/
List<IGrinderEntry> getRecipes();
@Nonnull
Collection<IGrinderRecipe> getRecipes();
/**
* add a new recipe the easy way, in &#8594; out, how many turns., duplicates will not be added.
* Add a new recipe with a single input and output and how many turns it requires.
*
* Will ignore duplicate recipes with the same input item.
*
* @param in input
* @param out output
* @param turns amount of turns to turn the input into the output
* @param in The {@link ItemStack} to grind.
* @param out The {@link ItemStack} to output.
* @param turns Amount of turns to turn the input into the output, with turns > 0.
*/
void addRecipe( ItemStack in, ItemStack out, int turns );
void addRecipe( @Nonnull ItemStack in, @Nonnull ItemStack out, int turns );
/**
* Add a new recipe with an input, output and a single optional output.
*
* Will ignore duplicate recipes with the same input item.
*
* @param in The {@link ItemStack} to grind.
* @param out The {@link ItemStack} to output.
* @param optional The optional {@link ItemStack} to output of a certain chance.
* @param chance Chance to get the optional output within 0.0 - 1.0
* @param turns Amount of turns to turn the input into the output, with turns > 0.
*/
void addRecipe( @Nonnull ItemStack in, @Nonnull ItemStack out, @Nonnull ItemStack optional, float chance, int turns );
/**
* add a new recipe with optional outputs, duplicates will not be added.
*
* Will ignore duplicate recipes with the same input item.
*
* @param in input
* @param out output
* @param optional optional output
* @param chance chance to get the optional output within 0.0 - 1.0
* @param turns amount of turns to turn the input into the outputs
*/
void addRecipe( ItemStack in, ItemStack out, ItemStack optional, float chance, int turns );
/**
* add a new recipe with optional outputs, duplicates will not be added.
*
* @param in input
* @param out output
* @param optional optional output
* @param chance chance to get the optional output within 0.0 - 1.0
* @param optional2 second optional output
* @param in The {@link ItemStack} to grind.
* @param out The {@link ItemStack} to output.
* @param optional The first optional {@link ItemStack} to output of a certain chance.
* @param chance Chance to get the first optional output within 0.0 - 1.0
* @param optional2 The second optional {@link ItemStack} to output of a certain chance.
* @param chance2 chance to get the second optional output within 0.0 - 1.0
* @param turns amount of turns to turn the input into the outputs
* @param turns Amount of turns to turn the input into the output, with turns > 0.
*
*/
void addRecipe( ItemStack in, ItemStack out, ItemStack optional, float chance, ItemStack optional2, float chance2, int turns );
void addRecipe( @Nonnull ItemStack in, @Nonnull ItemStack out, @Nonnull ItemStack optional, float chance, @Nonnull ItemStack optional2, float chance2, int turns );
/**
* Remove the specific from the recipe list.
*
* @param recipe The recipe to be removed.
* @return true, if it was removed
*/
boolean removeRecipe( @Nonnull IGrinderRecipe recipe );
/**
* Searches for a recipe for a given input, and returns it.
*
* @param input input
* @param input The {@link ItemStack} to be grinded.
*
* @return identified recipe or null
*/
IGrinderEntry getRecipeForInput( ItemStack input );
@Nullable
IGrinderRecipe getRecipeForInput( @Nonnull ItemStack input );
/**
* Allows do add a custom ratio from an ore to dust when being grinded.
*
* The default ratio is 1 ore to 2 dusts.
*
* These have to be added before any recipe is registered. Otherwise it will use the default value.
*
* @param oredictName The name of the ore;
* @param ratio The amount, must be > 0;
*/
void addDustRatio( @Nonnull String oredictName, int ratio );
/**
* Remove a custom ratio for a specific ore name.
*
* Will use the default of 2 value afterwards.
*
* @param oredictName The name of the ore;
*/
boolean removeDustRatio( @Nonnull String oredictName );
}
@@ -24,12 +24,36 @@
package appeng.api.networking.crafting;
import java.util.Collection;
import appeng.api.storage.data.IAEStack;
public interface ICraftingWatcher extends Collection<IAEStack>
/**
* DO NOT IMPLEMENT.
*
* Will be injected when adding an {@link ICraftingWatcherHost} to a grid.
*/
public interface ICraftingWatcher
{
/**
* Add a specific {@link IAEStack} to watch.
*
* Supports multiple values, duplicate ones will not be added.
*
* @param stack
* @return true, if successfully added.
*/
boolean add( IAEStack<?> stack );
/**
* Remove a specific {@link IAEStack} from the watcher.
*
* @param stack
* @return true, if successfully removed.
*/
boolean remove( IAEStack<?> stack );
/**
* Removes all watched stacks and resets the watcher to a clean state.
*/
void reset();
}
@@ -24,10 +24,34 @@
package appeng.api.networking.energy;
import java.util.Collection;
public interface IEnergyWatcher extends Collection<Double>
/**
* DO NOT IMPLEMENT.
*
* Will be injected when adding an {@link IEnergyWatcherHost} to a grid.
*/
public interface IEnergyWatcher
{
/**
* Add a specific threshold to watch.
*
* Supports multiple values, duplicate ones will not be added.
*
* @param amount
* @return true, if successfully added.
*/
boolean add( double amount );
/**
* Remove a specific threshold from the watcher.
*
* @param amount
* @return true, if successfully removed.
*/
boolean remove( double amount );
/**
* Removes all thresholds and resets the watcher to a clean state.
*/
void reset();
}
@@ -24,12 +24,36 @@
package appeng.api.networking.storage;
import java.util.Collection;
import appeng.api.storage.data.IAEStack;
public interface IStackWatcher extends Collection<IAEStack>
/**
* DO NOT IMPLEMENT.
*
* Will be injected when adding an {@link IStackWatcherHost} to a grid.
*/
public interface IStackWatcher
{
/**
* Add a specific {@link IAEStack} to watch.
*
* Supports multiple values, duplicate ones will not be added.
*
* @param stack
* @return true, if successfully added.
*/
boolean add( IAEStack<?> stack );
/**
* Remove a specific {@link IAEStack} from the watcher.
*
* @param stack
* @return true, if successfully removed.
*/
boolean remove( IAEStack<?> stack );
/**
* Removes all watched stacks and resets the watcher to a clean state.
*/
void reset();
}
+19 -10
View File
@@ -25,10 +25,11 @@ package appeng.api.parts;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
@@ -39,7 +40,6 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
@@ -71,7 +71,8 @@ public interface IPart extends IBoxProvider, ICustomCableConnection
ItemStack getItemStack( PartItemStack type );
/**
* Render dynamic portions of this part, as part of the cable bus TESR. This part has to return true for {@link #requireDynamicRender()} in order for
* Render dynamic portions of this part, as part of the cable bus TESR. This part has to return true for
* {@link #requireDynamicRender()} in order for
* this method to be called.
*/
@SideOnly( Side.CLIENT )
@@ -267,8 +268,10 @@ public interface IPart extends IBoxProvider, ICustomCableConnection
boolean canBePlacedOn( BusSupport what );
/**
* This method is used when a chunk is rebuilt to determine how this part should be rendered. The returned models should represent the
* part oriented north. They will be automatically rotated to match the part's actual orientation. Tint indices 1-4 can be used in the
* This method is used when a chunk is rebuilt to determine how this part should be rendered. The returned models
* should represent the
* part oriented north. They will be automatically rotated to match the part's actual orientation. Tint indices 1-4
* can be used in the
* models to access the parts color.
*
* <dl>
@@ -279,18 +282,23 @@ public interface IPart extends IBoxProvider, ICustomCableConnection
* <dt>Tint Index 3</dt>
* <dd>The {@link AEColor#whiteVariant bright variant color} of the cable that this part is attached to.</dd>
* <dt>Tint Index 4</dt>
* <dd>A color variant that is between the cable's {@link AEColor#mediumVariant color} and its {@link AEColor#whiteVariant bright variant}.</dd>
* <dd>A color variant that is between the cable's {@link AEColor#mediumVariant color} and its
* {@link AEColor#whiteVariant bright variant}.</dd>
* </dl>
*
* <b>Important:</b> All models must have been registered via the {@link IPartModels} API before use.
*/
default List<ResourceLocation> getStaticModels()
@Nonnull
default IPartModel getStaticModels()
{
return Collections.emptyList();
return new IPartModel()
{
};
}
/**
* Implement this method if your part exposes capabilitys. Any requests for capabilities on the cable bus will be forwarded to parts on the appropriate
* Implement this method if your part exposes capabilitys. Any requests for capabilities on the cable bus will be
* forwarded to parts on the appropriate
* side.
*
* @see TileEntity#hasCapability(Capability, EnumFacing)
@@ -303,7 +311,8 @@ public interface IPart extends IBoxProvider, ICustomCableConnection
}
/**
* Implement this method if your part exposes capabilitys. Any requests for capabilities on the cable bus will be forwarded to parts on the appropriate
* Implement this method if your part exposes capabilitys. Any requests for capabilities on the cable bus will be
* forwarded to parts on the appropriate
* side.
*
* @see TileEntity#getCapability(Capability, EnumFacing)
@@ -0,0 +1,65 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 - 2015 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.parts;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.util.ResourceLocation;
/**
* A container to store a collection of {@link ResourceLocation} as models for a part as well as other properties.
*/
public interface IPartModel
{
/**
* A solid {@link IPartModel} indicates that the rendering requires a cable connection, which will also result in
* creating an intersection for the cable.
*
* This should be true for pretty much all parts.
*
* @return true for a solid part.
*/
default boolean requireCableConnection()
{
return true;
}
/**
* A collection of {@link ResourceLocation} used as models for a part.
*
* @return a collection of models, never null.
*/
@Nonnull
default List<ResourceLocation> getModels()
{
return Collections.emptyList();
}
}
+89 -100
View File
@@ -31,10 +31,8 @@ import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
@@ -65,12 +63,6 @@ public abstract class AEBaseBlock extends Block
protected AxisAlignedBB boundingBox = FULL_BLOCK_AABB;
@Override
public boolean isVisuallyOpaque()
{
return this.isOpaque() && this.isFullSize();
}
protected AEBaseBlock( final Material mat )
{
super( mat );
@@ -96,13 +88,15 @@ public abstract class AEBaseBlock extends Block
this.setLightLevel( 0 );
this.setHardness( 2.2F );
this.setHarvestLevel( "pickaxe", 0 );
// Workaround as vanilla sets it way too early.
this.fullBlock = this.isFullSize();
}
@Override
public String toString()
public final boolean isVisuallyOpaque()
{
String regName = getRegistryName() != null ? getRegistryName().getResourcePath() : "unregistered";
return getClass().getSimpleName() + "[" + regName + "]";
return this.isOpaque() && this.isFullSize();
}
@Override
@@ -111,31 +105,12 @@ public abstract class AEBaseBlock extends Block
return new BlockStateContainer( this, this.getAEStates() );
}
protected IProperty[] getAEStates()
{
return new IProperty[0];
}
public boolean isOpaque()
{
return this.isOpaque;
}
@Override
public boolean isNormalCube( IBlockState state )
public final boolean isNormalCube( IBlockState state )
{
return this.isFullSize() && this.isOpaque();
}
protected ICustomCollision getCustomCollision( final World w, final BlockPos pos )
{
if( this instanceof ICustomCollision )
{
return (ICustomCollision) this;
}
return null;
}
@Override
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )
{
@@ -210,7 +185,8 @@ public abstract class AEBaseBlock extends Block
if( br != null )
{
br = new AxisAlignedBB( br.minX + pos.getX(), br.minY + pos.getY(), br.minZ + pos.getZ(), br.maxX + pos.getX(), br.maxY + pos.getY(), br.maxZ + pos.getZ() );
br = new AxisAlignedBB( br.minX + pos.getX(), br.minY + pos.getY(), br.minZ + pos.getZ(), br.maxX + pos.getX(), br.maxY + pos
.getY(), br.maxZ + pos.getZ() );
return br;
}
}
@@ -241,7 +217,8 @@ public abstract class AEBaseBlock extends Block
}
else
{
b = new AxisAlignedBB( b.minX + pos.getX(), b.minY + pos.getY(), b.minZ + pos.getZ(), b.maxX + pos.getX(), b.maxY + pos.getY(), b.maxZ + pos.getZ() );
b = new AxisAlignedBB( b.minX + pos.getX(), b.minY + pos.getY(), b.minZ + pos.getZ(), b.maxX + pos.getX(), b.maxY + pos.getY(), b.maxZ + pos
.getZ() );
}
return b;
@@ -303,19 +280,6 @@ public abstract class AEBaseBlock extends Block
return super.collisionRayTrace( state, w, pos, a, b );
}
public boolean onActivated( final World w, final BlockPos pos, final EntityPlayer player, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ )
{
return false;
}
@Override
@SideOnly( Side.CLIENT )
@SuppressWarnings( "unchecked" )
public final void getSubBlocks( final Item item, final CreativeTabs tabs, final List itemStacks )
{
this.getCheckedSubBlocks( item, tabs, itemStacks );
}
@Override
public boolean hasComparatorInputOverride( IBlockState state )
{
@@ -329,21 +293,11 @@ public abstract class AEBaseBlock extends Block
}
@Override
public boolean isNormalCube( IBlockState state, final IBlockAccess world, final BlockPos pos )
public final boolean isNormalCube( IBlockState state, final IBlockAccess world, final BlockPos pos )
{
return this.isFullSize();
}
public IOrientable getOrientable( final IBlockAccess w, final BlockPos pos )
{
if( this instanceof IOrientableBlock )
{
IOrientableBlock orientable = (IOrientableBlock) this;
return orientable.getOrientable( w, pos );
}
return null;
}
@Override
public boolean rotateBlock( final World w, final BlockPos pos, final EnumFacing axis )
{
@@ -378,50 +332,24 @@ public abstract class AEBaseBlock extends Block
return super.rotateBlock( w, pos, axis );
}
protected boolean hasCustomRotation()
{
return false;
}
protected void customRotateBlock( final IOrientable rotatable, final EnumFacing axis )
{
}
public boolean isValidOrientation( final World w, final BlockPos pos, final EnumFacing forward, final EnumFacing up )
{
return true;
}
@Override
public EnumFacing[] getValidRotations( final World w, final BlockPos pos )
{
return new EnumFacing[0];
}
@SideOnly( Side.CLIENT )
public void getCheckedSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
{
super.getSubBlocks( item, tabs, itemStacks );
}
public String getUnlocalizedName( final ItemStack is )
{
return this.getUnlocalizedName();
}
@Override
public void addInformation( final ItemStack is, final EntityPlayer player, final List<String> lines, final boolean advancedItemTooltips )
{
}
public boolean hasSubtypes()
public boolean onActivated( final World w, final BlockPos pos, final EntityPlayer player, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ )
{
return this.hasSubtypes;
return false;
}
public EnumFacing mapRotation( final IOrientable ori, final EnumFacing dir )
public final EnumFacing mapRotation( final IOrientable ori, final EnumFacing dir )
{
// case DOWN: return bottomIcon;
// case UP: return blockIcon;
@@ -486,36 +414,97 @@ public abstract class AEBaseBlock extends Block
return null;
}
public boolean isFullSize()
@Override
public String toString()
{
return this.isFullSize;
String regName = getRegistryName() != null ? getRegistryName().getResourcePath() : "unregistered";
return getClass().getSimpleName() + "[" + regName + "]";
}
public boolean setFullSize( final boolean isFullSize )
protected String getUnlocalizedName( final ItemStack is )
{
this.isFullSize = isFullSize;
return isFullSize;
return this.getUnlocalizedName();
}
public boolean setOpaque( final boolean isOpaque )
protected boolean hasCustomRotation()
{
return false;
}
protected void customRotateBlock( final IOrientable rotatable, final EnumFacing axis )
{
}
protected IOrientable getOrientable( final IBlockAccess w, final BlockPos pos )
{
if( this instanceof IOrientableBlock )
{
IOrientableBlock orientable = (IOrientableBlock) this;
return orientable.getOrientable( w, pos );
}
return null;
}
protected boolean isValidOrientation( final World w, final BlockPos pos, final EnumFacing forward, final EnumFacing up )
{
return true;
}
protected ICustomCollision getCustomCollision( final World w, final BlockPos pos )
{
if( this instanceof ICustomCollision )
{
return (ICustomCollision) this;
}
return null;
}
protected IProperty[] getAEStates()
{
return new IProperty[0];
}
protected boolean isOpaque()
{
return this.isOpaque;
}
protected boolean setOpaque( final boolean isOpaque )
{
this.isOpaque = isOpaque;
return isOpaque;
}
public boolean isInventory()
protected boolean hasSubtypes()
{
return this.isInventory;
return this.hasSubtypes;
}
public void setInventory( final boolean isInventory )
{
this.isInventory = isInventory;
}
public void setHasSubtypes( final boolean hasSubtypes )
protected void setHasSubtypes( final boolean hasSubtypes )
{
this.hasSubtypes = hasSubtypes;
}
protected boolean isFullSize()
{
return this.isFullSize;
}
protected boolean setFullSize( final boolean isFullSize )
{
this.isFullSize = isFullSize;
return isFullSize;
}
protected boolean isInventory()
{
return this.isInventory;
}
protected void setInventory( final boolean isInventory )
{
this.isInventory = isInventory;
}
}
@@ -85,7 +85,7 @@ public class BlockCraftingMonitor extends BlockCraftingUnit
@Override
@SideOnly( Side.CLIENT )
public void getCheckedSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
public void getSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
{
itemStacks.add( new ItemStack( this, 1, 0 ) );
}
@@ -149,6 +149,7 @@ public class BlockCraftingUnit extends AEBaseTileBlock
public boolean onBlockActivated( final World w, final BlockPos pos, final IBlockState state, final EntityPlayer p, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ )
{
final TileCraftingTile tg = this.getTileEntity( w, pos );
if( tg != null && !p.isSneaking() && tg.isFormed() && tg.isActive() )
{
if( Platform.isClient() )
@@ -160,7 +161,7 @@ public class BlockCraftingUnit extends AEBaseTileBlock
return true;
}
return false;
return super.onBlockActivated( w, pos, state, p, hand, heldItem, side, hitX, hitY, hitZ );
}
public enum CraftingUnitType
@@ -107,6 +107,7 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
Platform.openGUI( p, tg, AEPartLocation.fromFacing( side ), GuiBridge.GUI_MAC );
return true;
}
return false;
return super.onBlockActivated( w, pos, state, p, hand, heldItem, side, hitX, hitY, hitZ );
}
}
@@ -22,6 +22,7 @@ package appeng.block.misc;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -22,6 +22,7 @@ package appeng.block.networking;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
@@ -376,7 +377,7 @@ public class BlockCableBus extends AEBaseTileBlock
@Override
@SideOnly( Side.CLIENT )
public void getCheckedSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
public void getSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
{
// do nothing
}
@@ -63,9 +63,9 @@ public class BlockEnergyCell extends AEBaseTileBlock
@Override
@SideOnly( Side.CLIENT )
public void getCheckedSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
public void getSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
{
super.getCheckedSubBlocks( item, tabs, itemStacks );
super.getSubBlocks( item, tabs, itemStacks );
final ItemStack charged = new ItemStack( this, 1 );
final NBTTagCompound tag = Platform.openNbtData( charged );
@@ -21,6 +21,7 @@ package appeng.block.networking;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.properties.IProperty;
@@ -46,6 +47,7 @@ import appeng.helpers.ICustomCollision;
import appeng.tile.networking.TileWireless;
import appeng.util.Platform;
public class BlockWireless extends AEBaseTileBlock implements ICustomCollision
{
@@ -62,7 +64,6 @@ public class BlockWireless extends AEBaseTileBlock implements ICustomCollision
}
}
public static final PropertyEnum<State> STATE = PropertyEnum.create( "state", State.class );
public BlockWireless()
@@ -112,13 +113,9 @@ public class BlockWireless extends AEBaseTileBlock implements ICustomCollision
@Override
public boolean onBlockActivated( final World w, final BlockPos pos, final IBlockState state, final EntityPlayer player, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ )
{
if( player.isSneaking() )
{
return false;
}
final TileWireless tg = this.getTileEntity( w, pos );
if( tg != null )
if( tg != null && !player.isSneaking() )
{
if( Platform.isServer() )
{
@@ -126,7 +123,8 @@ public class BlockWireless extends AEBaseTileBlock implements ICustomCollision
}
return true;
}
return false;
return super.onBlockActivated( w, pos, state, player, hand, heldItem, side, hitX, hitY, hitZ );
}
@Override
@@ -94,7 +94,7 @@ public class BlockPaint extends AEBaseTileBlock
@Override
@SideOnly( Side.CLIENT )
public void getCheckedSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
public void getSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
{
// do nothing
}
@@ -4,6 +4,7 @@ package appeng.block.paint;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import com.google.common.base.Function;
@@ -4,6 +4,7 @@ package appeng.block.qnb;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.base.Function;
@@ -53,7 +53,7 @@ public class BlockMatrixFrame extends AEBaseBlock implements ICustomCollision
@Override
@SideOnly( Side.CLIENT )
public void getCheckedSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
public void getSubBlocks( final Item item, final CreativeTabs tabs, final List<ItemStack> itemStacks )
{
// do nothing
}
@@ -47,6 +47,10 @@ import appeng.util.Platform;
public class BlockSkyChest extends AEBaseTileBlock implements ICustomCollision
{
private static final double AABB_OFFSET_BOTTOM = .0625d;
private static final double AABB_OFFSET_SIDES = 0;
private static final double AABB_OFFSET_TOP = .125d;
public enum SkyChestType
{
STONE, BLOCK
@@ -71,7 +75,6 @@ public class BlockSkyChest extends AEBaseTileBlock implements ICustomCollision
return EnumBlockRenderType.ENTITYBLOCK_ANIMATED;
}
@Override
public boolean onActivated( final World w, final BlockPos pos, final EntityPlayer player, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ )
{
@@ -85,6 +88,21 @@ public class BlockSkyChest extends AEBaseTileBlock implements ICustomCollision
@Override
public Iterable<AxisAlignedBB> getSelectedBoundingBoxesFromPool( final World w, final BlockPos pos, final Entity thePlayer, final boolean b )
{
final AxisAlignedBB aabb = computeAABB( w, pos );
return Collections.singletonList( aabb );
}
@Override
public void addCollidingBlockToList( final World w, final BlockPos pos, final AxisAlignedBB bb, final List<AxisAlignedBB> out, final Entity e )
{
final AxisAlignedBB aabb = computeAABB( w, pos );
out.add( aabb );
}
private AxisAlignedBB computeAABB( final World w, final BlockPos pos )
{
final TileSkyChest sk = this.getTileEntity( w, pos );
EnumFacing o = EnumFacing.UP;
@@ -94,17 +112,19 @@ public class BlockSkyChest extends AEBaseTileBlock implements ICustomCollision
o = sk.getUp();
}
final double offsetX = o.getFrontOffsetX() == 0 ? 0.06 : 0.0;
final double offsetY = o.getFrontOffsetY() == 0 ? 0.06 : 0.0;
final double offsetZ = o.getFrontOffsetZ() == 0 ? 0.06 : 0.0;
final double offsetX = o.getFrontOffsetX() == 0 ? AABB_OFFSET_BOTTOM : AABB_OFFSET_SIDES;
final double offsetY = o.getFrontOffsetY() == 0 ? AABB_OFFSET_BOTTOM : AABB_OFFSET_SIDES;
final double offsetZ = o.getFrontOffsetZ() == 0 ? AABB_OFFSET_BOTTOM : AABB_OFFSET_SIDES;
final double sc = 0.06;
return Collections.singletonList( new AxisAlignedBB( Math.max( 0.0, offsetX - o.getFrontOffsetX() * sc ), Math.max( 0.0, offsetY - o.getFrontOffsetY() * sc ), Math.max( 0.0, offsetZ - o.getFrontOffsetZ() * sc ), Math.min( 1.0, ( 1.0 - offsetX ) - o.getFrontOffsetX() * sc ), Math.min( 1.0, ( 1.0 - offsetY ) - o.getFrontOffsetY() * sc ), Math.min( 1.0, ( 1.0 - offsetZ ) - o.getFrontOffsetZ() * sc ) ) );
}
// x/z needs to be multiplied by -1, thus we simply add not substract.
final double minX = Math.max( 0.0, offsetX + o.getFrontOffsetX() * AABB_OFFSET_TOP );
final double minY = Math.max( 0.0, offsetY - o.getFrontOffsetY() * AABB_OFFSET_TOP );
final double minZ = Math.max( 0.0, offsetZ + o.getFrontOffsetZ() * AABB_OFFSET_TOP );
@Override
public void addCollidingBlockToList( final World w, final BlockPos pos, final AxisAlignedBB bb, final List<AxisAlignedBB> out, final Entity e )
{
out.add( new AxisAlignedBB( 0.05, 0.05, 0.05, 0.95, 0.95, 0.95 ) );
final double maxX = Math.min( 1.0, ( 1.0 - offsetX ) + o.getFrontOffsetX() * AABB_OFFSET_TOP );
final double maxY = Math.min( 1.0, ( 1.0 - offsetY ) - o.getFrontOffsetY() * AABB_OFFSET_TOP );
final double maxZ = Math.min( 1.0, ( 1.0 - offsetZ ) + o.getFrontOffsetZ() * AABB_OFFSET_TOP );
return new AxisAlignedBB( minX, minY, minZ, maxX, maxY, maxZ );
}
}
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
@@ -54,7 +54,6 @@ import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.widgets.GuiScrollbar;
@@ -22,6 +22,7 @@ package appeng.client.me;
import java.util.ArrayList;
import java.util.Collections;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
@@ -21,6 +21,7 @@ package appeng.client.render;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
@@ -22,6 +22,7 @@ package appeng.client.render;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
@@ -25,6 +25,8 @@ import java.util.EnumMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
@@ -41,6 +43,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.property.IExtendedBlockState;
import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.block.networking.BlockCableBus;
@@ -81,8 +84,9 @@ public class CableBusBakedModel implements IBakedModel
List<BakedQuad> quads = new ArrayList<>();
// The core parts of the cable will only be rendered in the CUTOUT layer. TRANSLUCENT is used only for translucent facades further down below.
if ( layer == BlockRenderLayer.CUTOUT )
// The core parts of the cable will only be rendered in the CUTOUT layer. TRANSLUCENT is used only for
// translucent facades further down below.
if( layer == BlockRenderLayer.CUTOUT )
{
// First, handle the cable at the center of the cable bus
addCableQuads( renderState, quads );
@@ -90,13 +94,13 @@ public class CableBusBakedModel implements IBakedModel
// Then handle attachments
for( EnumFacing facing : EnumFacing.values() )
{
List<ResourceLocation> models = renderState.getAttachments().get( facing );
if( models == null )
final IPartModel partModel = renderState.getAttachments().get( facing );
if( partModel == null )
{
continue;
}
for( ResourceLocation model : models )
for( ResourceLocation model : partModel.getModels() )
{
IBakedModel bakedModel = partModels.get( model );
@@ -122,8 +126,7 @@ public class CableBusBakedModel implements IBakedModel
renderState.getBoundingBoxes(),
renderState.getAttachments().keySet(),
rand,
quads
);
quads );
return quads;
}
@@ -131,25 +134,30 @@ public class CableBusBakedModel implements IBakedModel
// Determines whether a cable is connected to exactly two sides that are opposite each other
private static boolean isStraightLine( AECableType cableType, EnumMap<EnumFacing, AECableType> sides )
{
Iterator<EnumFacing> it = sides.keySet().iterator();
final Iterator<Entry<EnumFacing, AECableType>> it = sides.entrySet().iterator();
if( !it.hasNext() )
{
return false; // No connections
}
EnumFacing firstSide = it.next();
AECableType firstType = sides.get( firstSide );
final Entry<EnumFacing, AECableType> nextConnection = it.next();
final EnumFacing firstSide = nextConnection.getKey();
final AECableType firstType = nextConnection.getValue();
if( !it.hasNext() )
{
return false; // Only a single connection
}
if( firstSide.getOpposite() != it.next() )
if( firstSide.getOpposite() != it.next().getKey() )
{
return false; // Connected to two sides that are not opposite each other
}
if (it.hasNext()) {
if( it.hasNext() )
{
return false; // Must not have any other connection points
}
AECableType secondType = sides.get( firstSide.getOpposite() );
final AECableType secondType = sides.get( firstSide.getOpposite() );
// Certain cable types have restrictions on when they're rendered as a straight connection
switch( cableType )
@@ -176,8 +184,8 @@ public class CableBusBakedModel implements IBakedModel
// If the connection is straight, no busses are attached, and no covered core has been forced (in case of glass
// cables), then render the cable as a simplified straight line.
boolean noAttachments = renderState.getAttachments().isEmpty();
if( isStraightLine( cableType, connectionTypes ) && noAttachments )
boolean noAttachments = !renderState.getAttachments().values().stream().anyMatch( IPartModel::requireCableConnection );
if( noAttachments && isStraightLine( cableType, connectionTypes ) )
{
EnumFacing facing = connectionTypes.keySet().iterator().next();
@@ -227,11 +235,12 @@ public class CableBusBakedModel implements IBakedModel
}
// Render all outgoing connections using the appropriate type
for( EnumFacing facing : connectionTypes.keySet() )
for( final Entry<EnumFacing, AECableType> connection : connectionTypes.entrySet() )
{
AECableType connectionType = connectionTypes.get( facing );
boolean cableBusAdjacent = renderState.getCableBusAdjacent().contains( facing );
int channels = renderState.getChannelsOnSide().get( facing );
final EnumFacing facing = connection.getKey();
final AECableType connectionType = connection.getValue();
final boolean cableBusAdjacent = renderState.getCableBusAdjacent().contains( facing );
final int channels = renderState.getChannelsOnSide().get( facing );
switch( cableType )
{
@@ -269,9 +278,9 @@ public class CableBusBakedModel implements IBakedModel
// If no core is present, just use the first part that comes into play
for( EnumFacing side : renderState.getAttachments().keySet() )
{
List<ResourceLocation> models = renderState.getAttachments().get( side );
IPartModel partModel = renderState.getAttachments().get( side );
for( ResourceLocation model : models )
for( ResourceLocation model : partModel.getModels() )
{
IBakedModel bakedModel = partModels.get( model );
@@ -282,9 +291,11 @@ public class CableBusBakedModel implements IBakedModel
TextureAtlasSprite particleTexture = bakedModel.getParticleTexture();
// If a part sub-model has no particle texture (indicated by it being the missing texture), don't add it,
// If a part sub-model has no particle texture (indicated by it being the missing texture), don't
// add
// it,
// so we don't get ugly missing texture break particles.
if ( textureMap.getMissingSprite() != particleTexture )
if( textureMap.getMissingSprite() != particleTexture )
{
result.add( particleTexture );
}
@@ -25,9 +25,9 @@ import java.util.EnumSet;
import java.util.List;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
@@ -60,7 +60,7 @@ public class CableBusRenderState
// connections contains a corresponding entry.
private EnumMap<EnumFacing, Integer> channelsOnSide = new EnumMap<>( EnumFacing.class );
private EnumMap<EnumFacing, List<ResourceLocation>> attachments = new EnumMap<>( EnumFacing.class );
private EnumMap<EnumFacing, IPartModel> attachments = new EnumMap<>( EnumFacing.class );
// For each attachment, this contains the distance from the edge until which a cable connection should be drawn
private EnumMap<EnumFacing, Integer> attachmentConnections = new EnumMap<>( EnumFacing.class );
@@ -68,7 +68,8 @@ public class CableBusRenderState
// Contains the facade to use for each side that has a facade attached
private EnumMap<EnumFacing, FacadeRenderState> facades = new EnumMap<>( EnumFacing.class );
// Contains the bounding boxes of all parts on the cable bus to allow facades to cut out holes for the parts. This list is only populated if there are
// Contains the bounding boxes of all parts on the cable bus to allow facades to cut out holes for the parts. This
// list is only populated if there are
// facades on this cable bus
private List<AxisAlignedBB> boundingBoxes = new ArrayList<>();
@@ -132,7 +133,7 @@ public class CableBusRenderState
this.cableBusAdjacent = cableBusAdjacent;
}
public EnumMap<EnumFacing, List<ResourceLocation>> getAttachments()
public EnumMap<EnumFacing, IPartModel> getAttachments()
{
return attachments;
}
@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import javax.vecmath.Vector4f;
import com.google.common.base.Preconditions;
@@ -26,6 +26,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.vecmath.Vector3f;
@@ -2,6 +2,7 @@ package appeng.client.render.crafting;
import java.util.List;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
@@ -21,6 +21,7 @@ package appeng.client.render.model;
import java.util.ArrayList;
import java.util.List;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
@@ -4,6 +4,7 @@ package appeng.client.render.model;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
@@ -32,6 +32,7 @@ import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
import com.google.common.base.Charsets;
@@ -233,7 +233,7 @@ class SpatialPylonBakedModel implements IBakedModel
@Override
public TextureAtlasSprite getParticleTexture()
{
return null;
return this.textures.get( SpatialPylonTextureType.DIM );
}
@Override
@@ -31,6 +31,7 @@ import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.storage.ITerminalHost;
import appeng.container.guisync.GuiSync;
import appeng.util.Platform;
public class ContainerCraftingStatus extends ContainerCraftingCPU
@@ -52,50 +53,53 @@ public class ContainerCraftingStatus extends ContainerCraftingCPU
@Override
public void detectAndSendChanges()
{
final ICraftingGrid cc = this.getNetwork().getCache( ICraftingGrid.class );
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
int matches = 0;
boolean changed = false;
for( final ICraftingCPU c : cpuSet )
if( Platform.isServer() && this.getNetwork() != null )
{
boolean found = false;
for( final CraftingCPURecord ccr : this.cpus )
{
if( ccr.getCpu() == c )
{
found = true;
}
}
final ICraftingGrid cc = this.getNetwork().getCache( ICraftingGrid.class );
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
final boolean matched = this.cpuMatches( c );
if( matched )
{
matches++;
}
if( found == !matched )
{
changed = true;
}
}
if( changed || this.cpus.size() != matches )
{
this.cpus.clear();
int matches = 0;
boolean changed = false;
for( final ICraftingCPU c : cpuSet )
{
if( this.cpuMatches( c ) )
boolean found = false;
for( final CraftingCPURecord ccr : this.cpus )
{
this.cpus.add( new CraftingCPURecord( c.getAvailableStorage(), c.getCoProcessors(), c ) );
if( ccr.getCpu() == c )
{
found = true;
}
}
final boolean matched = this.cpuMatches( c );
if( matched )
{
matches++;
}
if( found == !matched )
{
changed = true;
}
}
this.sendCPUs();
}
if( changed || this.cpus.size() != matches )
{
this.cpus.clear();
for( final ICraftingCPU c : cpuSet )
{
if( this.cpuMatches( c ) )
{
this.cpus.add( new CraftingCPURecord( c.getAvailableStorage(), c.getCoProcessors(), c ) );
}
}
this.noCPU = this.cpus.isEmpty();
this.sendCPUs();
}
this.noCPU = this.cpus.isEmpty();
}
super.detectAndSendChanges();
}
+19 -2
View File
@@ -24,8 +24,11 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import com.google.common.collect.Sets;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
@@ -99,6 +102,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
// Grindstone
private String[] grinderOres = Stream.of( ORES_VANILLA, ORES_AE, ORES_COMMON, ORES_MISC ).flatMap( Stream::of ).toArray( String[]::new );
private Set<String> grinderBlackList;
private double oreDoublePercentage = 90.0;
// Batteries
@@ -153,8 +157,16 @@ public final class AEConfig extends Configuration implements IConfigurableObject
this.removeCrashingItemsOnLoad = this.get( "general", "removeCrashingItemsOnLoad", false,
"Will auto-remove items that crash when being loaded from storage. This will destroy those items instead of crashing the game!" ).getBoolean();
this.grinderOres = this.get( "GrindStone", "grinderOres", this.grinderOres ).getStringList();
this.oreDoublePercentage = this.get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage ).getDouble( this.oreDoublePercentage );
this.setCategoryComment( "GrindStone",
"Creates recipe of the following pattern automatically: '1 oreTYPE => 2 dustTYPE' and '(1 ingotTYPE or 1 crystalTYPE or 1 gemTYPE) => 1 dustTYPE'" );
this.grinderOres = this.get( "GrindStone", "grinderOres", this.grinderOres, "The list of types to handle. Specify without a prefix like ore or dust." )
.getStringList();
this.grinderBlackList = Sets.newHashSet(
this.get( "GrindStone", "blacklist", new String[] {}, "Blacklists the exact oredict name from being handled by any recipe." )
.getStringList() );
this.oreDoublePercentage = this
.get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage, "Chance to actually get an output with stacksize > 1." )
.getDouble( this.oreDoublePercentage );
this.settings.registerSetting( Settings.SEARCH_TOOLTIPS, YesNo.YES );
this.settings.registerSetting( Settings.TERMINAL_STYLE, TerminalStyle.TALL );
@@ -632,6 +644,11 @@ public final class AEConfig extends Configuration implements IConfigurableObject
return grinderOres;
}
public Set<String> getGrinderBlackList()
{
return this.grinderBlackList;
}
public double getOreDoublePercentage()
{
return oreDoublePercentage;
+3 -3
View File
@@ -290,11 +290,11 @@ public final class AELog
*
* @param message String to be logged
*/
public static void grinder( @Nonnull final String message )
public static void grinder( @Nonnull final String message, final Object... params )
{
if( AEConfig.instance().isFeatureEnabled( AEFeature.GRINDER_LOGGING ) )
{
log( Level.DEBUG, "grinder: " + message );
log( Level.DEBUG, "grinder: " + message, params );
}
}
@@ -307,7 +307,7 @@ public final class AELog
{
if( AEConfig.instance().isFeatureEnabled( AEFeature.INTEGRATION_LOGGING ) )
{
debug( exception );
error( exception );
}
}
+1
View File
@@ -22,6 +22,7 @@ package appeng.core;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import com.google.common.base.Stopwatch;
+3 -2
View File
@@ -22,6 +22,7 @@ package appeng.core;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import com.google.common.base.Preconditions;
@@ -57,8 +58,8 @@ import appeng.api.parts.IPartHelper;
import appeng.capabilities.Capabilities;
import appeng.core.features.AEFeature;
import appeng.core.features.registries.P2PTunnelRegistry;
import appeng.core.features.registries.entries.BasicCellHandler;
import appeng.core.features.registries.entries.CreativeCellHandler;
import appeng.core.features.registries.cell.BasicCellHandler;
import appeng.core.features.registries.cell.CreativeCellHandler;
import appeng.core.localization.GuiText;
import appeng.core.localization.PlayerMessages;
import appeng.core.stats.PlayerStatsRegistration;
@@ -61,7 +61,7 @@ public final class ApiParts implements IParts
private final IItemDefinition p2PTunnelME;
private final IItemDefinition p2PTunnelRedstone;
private final IItemDefinition p2PTunnelItems;
private final IItemDefinition p2PTunnelLiquids;
private final IItemDefinition p2PTunnelFluids;
private final IItemDefinition p2PTunnelEU;
// private final IItemDefinition p2PTunnelRF;
private final IItemDefinition p2PTunnelLight;
@@ -112,7 +112,7 @@ public final class ApiParts implements IParts
this.p2PTunnelME = new DamagedItemDefinition( "part.tunnel.me", itemPart.createPart( PartType.P2PTunnelME ) );
this.p2PTunnelRedstone = new DamagedItemDefinition( "part.tunnel.redstone", itemPart.createPart( PartType.P2PTunnelRedstone ) );
this.p2PTunnelItems = new DamagedItemDefinition( "part.tunnel.item", itemPart.createPart( PartType.P2PTunnelItems ) );
this.p2PTunnelLiquids = new DamagedItemDefinition( "part.tunnel.fluid", itemPart.createPart( PartType.P2PTunnelLiquids ) );
this.p2PTunnelFluids = new DamagedItemDefinition( "part.tunnel.fluid", itemPart.createPart( PartType.P2PTunnelFluids ) );
this.p2PTunnelEU = new DamagedItemDefinition( "part.tunnel.eu", itemPart.createPart( PartType.P2PTunnelEU ) );
// this.p2PTunnelRF = new DamagedItemDefinition( itemMultiPart.createPart( PartType.P2PTunnelRF ) );
this.p2PTunnelLight = new DamagedItemDefinition( "part.tunnel.light", itemPart.createPart( PartType.P2PTunnelLight ) );
@@ -281,9 +281,9 @@ public final class ApiParts implements IParts
}
@Override
public IItemDefinition p2PTunnelLiquids()
public IItemDefinition p2PTunnelFluids()
{
return this.p2PTunnelLiquids;
return this.p2PTunnelFluids;
}
@Override
@@ -118,7 +118,7 @@ public enum AEFeature
P2P_TUNNEL_ITEMS( "P2PTunnelItems", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_REDSTONE( "P2PTunnelRedstone", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_EU( "P2PTunnelEU", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_LIQUIDS( "P2PTunnelLiquids", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_FLUIDS( "P2PTunnelFluids", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_LIGHT( "P2PTunnelLight", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_OPEN_COMPUTERS( "P2PTunnelOpenComputers", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_PRESSURE( "P2PTunnelPressure", Constants.CATEGORY_P2P_TUNNELS ),
@@ -1,299 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import appeng.api.features.IGrinderEntry;
import appeng.api.features.IGrinderRegistry;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.features.registries.entries.AppEngGrinderRecipe;
import appeng.recipes.ores.IOreListener;
import appeng.recipes.ores.OreDictionaryHandler;
import appeng.util.Platform;
public final class GrinderRecipeManager implements IGrinderRegistry, IOreListener
{
private final List<IGrinderEntry> recipes;
private final Map<ItemStack, String> ores;
private final Map<ItemStack, String> ingots;
private final Map<String, ItemStack> dusts;
public GrinderRecipeManager()
{
this.recipes = new ArrayList<IGrinderEntry>();
this.ores = new HashMap<ItemStack, String>();
this.ingots = new HashMap<ItemStack, String>();
this.dusts = new HashMap<String, ItemStack>();
this.addOre( "Coal", new ItemStack( Items.COAL ) );
this.addOre( "Charcoal", new ItemStack( Items.COAL, 1, 1 ) );
this.addOre( "NetherQuartz", new ItemStack( Blocks.QUARTZ_ORE ) );
this.addIngot( "NetherQuartz", new ItemStack( Items.QUARTZ ) );
this.addOre( "Gold", new ItemStack( Blocks.GOLD_ORE ) );
this.addIngot( "Gold", new ItemStack( Items.GOLD_INGOT ) );
this.addOre( "Iron", new ItemStack( Blocks.IRON_ORE ) );
this.addIngot( "Iron", new ItemStack( Items.IRON_INGOT ) );
this.addOre( "Obsidian", new ItemStack( Blocks.OBSIDIAN ) );
this.addIngot( "Ender", new ItemStack( Items.ENDER_PEARL ) );
this.addIngot( "EnderPearl", new ItemStack( Items.ENDER_PEARL ) );
this.addIngot( "Wheat", new ItemStack( Items.WHEAT ) );
OreDictionaryHandler.INSTANCE.observe( this );
}
@Override
public List<IGrinderEntry> getRecipes()
{
this.log( "API - getRecipes" );
return this.recipes;
}
@Override
public void addRecipe( final ItemStack in, final ItemStack out, final int cost )
{
if( in == null || out == null )
{
this.log( "Invalid Grinder Recipe Specified." );
return;
}
this.log( "Allow Grinding of " + Platform.getItemDisplayName( in ) + " to " + Platform.getItemDisplayName( out ) + " for " + cost );
this.injectRecipe( new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), cost ) );
}
@Override
public void addRecipe( final ItemStack in, final ItemStack out, final ItemStack optional, final float chance, final int cost )
{
if( in == null || ( optional == null && out == null ) )
{
this.log( "Invalid Grinder Recipe Specified." );
return;
}
this.log( "Allow Grinding of " + Platform.getItemDisplayName( in ) + " to " + Platform.getItemDisplayName( out ) + " with optional " + Platform.getItemDisplayName( optional ) + " for " + cost );
this.injectRecipe( new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), this.copy( optional ), chance, cost ) );
}
@Override
public void addRecipe( final ItemStack in, final ItemStack out, final ItemStack optional, final float chance, final ItemStack optional2, final float chance2, final int cost )
{
if( in == null || ( optional == null && out == null && optional2 == null ) )
{
this.log( "Invalid Grinder Recipe Specified." );
return;
}
this.log( "Allow Grinding of " + Platform.getItemDisplayName( in ) + " to " + Platform.getItemDisplayName( out ) + " with optional " + Platform.getItemDisplayName( optional ) + " for " + cost );
this.injectRecipe( new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), this.copy( optional ), this.copy( optional2 ), chance, chance2, cost ) );
}
private void injectRecipe( final AppEngGrinderRecipe appEngGrinderRecipe )
{
for( final IGrinderEntry gr : this.recipes )
{
if( Platform.itemComparisons().isSameItem( gr.getInput(), appEngGrinderRecipe.getInput() ) )
{
return;
}
}
this.recipes.add( appEngGrinderRecipe );
}
private ItemStack copy( final ItemStack is )
{
if( is != null )
{
return is.copy();
}
return null;
}
@Override
public IGrinderEntry getRecipeForInput( final ItemStack input )
{
this.log( "Looking up recipe for " + Platform.getItemDisplayName( input ) );
if( input != null )
{
for( final IGrinderEntry r : this.recipes )
{
if( Platform.itemComparisons().isEqualItem( input, r.getInput() ) )
{
this.log( "Recipe for " + input.getUnlocalizedName() + " found " + Platform.getItemDisplayName( r.getOutput() ) );
return r;
}
}
this.log( "Could not find recipe for " + Platform.getItemDisplayName( input ) );
}
return null;
}
private void log( final String o )
{
AELog.grinder( o );
}
private int getDustToOreRatio( final String name )
{
if( name.equals( "Obsidian" ) )
{
return 1;
}
if( name.equals( "Charcoal" ) )
{
return 1;
}
if( name.equals( "Coal" ) )
{
return 1;
}
return 2;
}
private void addOre( final String name, final ItemStack item )
{
if( item == null )
{
return;
}
this.log( "Adding Ore - " + name + " : " + Platform.getItemDisplayName( item ) );
this.ores.put( item, name );
if( this.dusts.containsKey( name ) )
{
final ItemStack is = this.dusts.get( name ).copy();
final int ratio = this.getDustToOreRatio( name );
if( ratio > 1 )
{
final ItemStack extra = is.copy();
extra.stackSize = ratio - 1;
this.addRecipe( item, is, extra, (float) ( AEConfig.instance().getOreDoublePercentage() / 100.0 ), 8 );
}
else
{
this.addRecipe( item, is, 8 );
}
}
}
private void addIngot( final String name, final ItemStack item )
{
if( item == null )
{
return;
}
this.log( "Adding Ingot - " + name + " : " + Platform.getItemDisplayName( item ) );
this.ingots.put( item, name );
if( this.dusts.containsKey( name ) )
{
this.addRecipe( item, this.dusts.get( name ), 4 );
}
}
private void addDust( final String name, final ItemStack item )
{
if( item == null )
{
return;
}
if( this.dusts.containsKey( name ) )
{
this.log( "Rejecting Dust - " + name + " : " + Platform.getItemDisplayName( item ) );
return;
}
this.log( "Adding Dust - " + name + " : " + Platform.getItemDisplayName( item ) );
this.dusts.put( name, item );
for( final Entry<ItemStack, String> d : this.ores.entrySet() )
{
if( name.equals( d.getValue() ) )
{
final ItemStack is = item.copy();
is.stackSize = 1;
final int ratio = this.getDustToOreRatio( name );
if( ratio > 1 )
{
final ItemStack extra = is.copy();
extra.stackSize = ratio - 1;
this.addRecipe( d.getKey(), is, extra, (float) ( AEConfig.instance().getOreDoublePercentage() / 100.0 ), 8 );
}
else
{
this.addRecipe( d.getKey(), is, 8 );
}
}
}
for( final Entry<ItemStack, String> d : this.ingots.entrySet() )
{
if( name.equals( d.getValue() ) )
{
this.addRecipe( d.getKey(), item, 4 );
}
}
}
@Override
public void oreRegistered( final String name, final ItemStack item )
{
if( name.startsWith( "ore" ) || name.startsWith( "crystal" ) || name.startsWith( "gem" ) || name.startsWith( "ingot" ) || name.startsWith( "dust" ) )
{
for( final String ore : AEConfig.instance().getGrinderOres() )
{
if( name.equals( "ore" + ore ) )
{
this.addOre( ore, item );
}
else if( name.equals( "crystal" + ore ) || name.equals( "ingot" + ore ) || name.equals( "gem" + ore ) )
{
this.addIngot( ore, item );
}
else if( name.equals( "dust" + ore ) )
{
this.addDust( ore, item );
}
}
}
}
}
@@ -34,6 +34,9 @@ import appeng.api.movable.IMovableRegistry;
import appeng.api.networking.IGridCacheRegistry;
import appeng.api.parts.IPartModels;
import appeng.api.storage.ICellRegistry;
import appeng.core.features.registries.cell.CellRegistry;
import appeng.core.features.registries.grinder.GrinderRecipeManager;
import appeng.core.features.registries.inscriber.InscriberRegistry;
/**
@@ -16,7 +16,7 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries.entries;
package appeng.core.features.registries.cell;
import net.minecraft.entity.player.EntityPlayer;
@@ -16,7 +16,7 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries;
package appeng.core.features.registries.cell;
import java.util.ArrayList;
@@ -16,7 +16,7 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries.entries;
package appeng.core.features.registries.cell;
import net.minecraft.entity.player.EntityPlayer;
@@ -1,146 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries.entries;
import net.minecraft.item.ItemStack;
import appeng.api.features.IGrinderEntry;
public class AppEngGrinderRecipe implements IGrinderEntry
{
private ItemStack in;
private ItemStack out;
private float optionalChance;
private ItemStack optionalOutput;
private float optionalChance2;
private ItemStack optionalOutput2;
private int energy;
public AppEngGrinderRecipe( final ItemStack a, final ItemStack b, final int cost )
{
this.in = a;
this.out = b;
this.energy = cost;
}
public AppEngGrinderRecipe( final ItemStack a, final ItemStack b, final ItemStack c, final float chance, final int cost )
{
this.in = a;
this.out = b;
this.optionalOutput = c;
this.optionalChance = chance;
this.energy = cost;
}
public AppEngGrinderRecipe( final ItemStack a, final ItemStack b, final ItemStack c, final ItemStack d, final float chance, final float chance2, final int cost )
{
this.in = a;
this.out = b;
this.optionalOutput = c;
this.optionalChance = chance;
this.optionalOutput2 = d;
this.optionalChance2 = chance2;
this.energy = cost;
}
@Override
public ItemStack getInput()
{
return this.in;
}
@Override
public void setInput( final ItemStack i )
{
this.in = i.copy();
}
@Override
public ItemStack getOutput()
{
return this.out;
}
@Override
public void setOutput( final ItemStack o )
{
this.out = o.copy();
}
@Override
public ItemStack getOptionalOutput()
{
return this.optionalOutput;
}
@Override
public ItemStack getSecondOptionalOutput()
{
return this.optionalOutput2;
}
@Override
public void setOptionalOutput( final ItemStack output, final float chance )
{
this.optionalOutput = output.copy();
this.optionalChance = chance;
}
@Override
public float getOptionalChance()
{
return this.optionalChance;
}
@Override
public void setSecondOptionalOutput( final ItemStack output, final float chance )
{
this.optionalChance2 = chance;
this.optionalOutput2 = output.copy();
}
@Override
public float getSecondOptionalChance()
{
return this.optionalChance2;
}
@Override
public int getEnergyCost()
{
return this.energy;
}
@Override
public void setEnergyCost( final int c )
{
this.energy = c;
}
}
@@ -0,0 +1,108 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries.grinder;
import java.util.Optional;
import net.minecraft.item.ItemStack;
import appeng.api.features.IGrinderRecipe;
public class AppEngGrinderRecipe implements IGrinderRecipe
{
private final ItemStack in;
private final ItemStack out;
private final float optionalChance;
private final Optional<ItemStack> optionalOutput;
private final float optionalChance2;
private final Optional<ItemStack> optionalOutput2;
private final int turns;
AppEngGrinderRecipe( final ItemStack input, final ItemStack output, final int cost )
{
this( input, output, null, null, 0, 0, cost );
}
AppEngGrinderRecipe( final ItemStack input, final ItemStack output, final ItemStack optional, final float chance, final int cost )
{
this( input, output, optional, null, chance, 0, cost );
}
AppEngGrinderRecipe( final ItemStack input, final ItemStack output, final ItemStack optional1, final ItemStack optional2, final float chance1, final float chance2, final int cost )
{
this.in = input;
this.out = output;
this.optionalOutput = Optional.ofNullable( optional1 );
this.optionalChance = chance1;
this.optionalOutput2 = Optional.ofNullable( optional2 );
this.optionalChance2 = chance2;
this.turns = cost;
}
@Override
public ItemStack getInput()
{
return this.in;
}
@Override
public ItemStack getOutput()
{
return this.out;
}
@Override
public Optional<ItemStack> getOptionalOutput()
{
return this.optionalOutput;
}
@Override
public Optional<ItemStack> getSecondOptionalOutput()
{
return this.optionalOutput2;
}
@Override
public float getOptionalChance()
{
return this.optionalChance;
}
@Override
public float getSecondOptionalChance()
{
return this.optionalChance2;
}
@Override
public int getRequiredTurns()
{
return this.turns;
}
}
@@ -0,0 +1,396 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries.grinder;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import appeng.api.features.IGrinderRecipe;
import appeng.api.features.IGrinderRegistry;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.recipes.ores.IOreListener;
import appeng.recipes.ores.OreDictionaryHandler;
import appeng.util.Platform;
public final class GrinderRecipeManager implements IGrinderRegistry, IOreListener
{
private final Map<CacheKey, IGrinderRecipe> recipes;
private final Map<ItemStack, String> ores;
private final Map<ItemStack, String> ingots;
private final Map<String, ItemStack> dusts;
private final Map<String, Integer> dustToOreRatio;
public GrinderRecipeManager()
{
this.recipes = Maps.newHashMap();
this.ores = Maps.newHashMap();
this.ingots = Maps.newHashMap();
this.dusts = Maps.newHashMap();
this.dustToOreRatio = Maps.newHashMap();
this.addDustRatio( "Obsidian", 1 );
this.addDustRatio( "Charcoal", 1 );
this.addDustRatio( "Coal", 1 );
this.addOre( "Coal", new ItemStack( Items.COAL ) );
this.addOre( "Charcoal", new ItemStack( Items.COAL, 1, 1 ) );
this.addOre( "NetherQuartz", new ItemStack( Blocks.QUARTZ_ORE ) );
this.addIngot( "NetherQuartz", new ItemStack( Items.QUARTZ ) );
this.addOre( "Gold", new ItemStack( Blocks.GOLD_ORE ) );
this.addIngot( "Gold", new ItemStack( Items.GOLD_INGOT ) );
this.addOre( "Iron", new ItemStack( Blocks.IRON_ORE ) );
this.addIngot( "Iron", new ItemStack( Items.IRON_INGOT ) );
this.addOre( "Obsidian", new ItemStack( Blocks.OBSIDIAN ) );
this.addIngot( "Ender", new ItemStack( Items.ENDER_PEARL ) );
this.addIngot( "EnderPearl", new ItemStack( Items.ENDER_PEARL ) );
this.addIngot( "Wheat", new ItemStack( Items.WHEAT ) );
OreDictionaryHandler.INSTANCE.observe( this );
}
@Override
public Collection<IGrinderRecipe> getRecipes()
{
return Collections.unmodifiableCollection( this.recipes.values() );
}
@Override
public void addRecipe( final ItemStack in, final ItemStack out, final int cost )
{
Preconditions.checkNotNull( in, "Null is not accepted as input itemstack." );
Preconditions.checkNotNull( out, "Null is not accepted as output itemstack." );
Preconditions.checkArgument( cost > 0, "Turns must be > 0" );
this.log( "Allow Grinding of '%1$s' to '%2$s' for %3$d turn", Platform.getItemDisplayName( in ), Platform.getItemDisplayName( out ), cost );
this.injectRecipe( new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), cost ) );
}
@Override
public void addRecipe( final ItemStack in, final ItemStack out, final ItemStack optional, final float chance, final int cost )
{
Preconditions.checkNotNull( in, "Null is not accepted as input itemstack." );
Preconditions.checkNotNull( out, "Null is not accepted as output itemstack." );
Preconditions.checkNotNull( optional, "Null is not accepted as optional itemstack." );
Preconditions.checkArgument( chance >= 0.0 && chance <= 1.0, "chance must be within 0.0 - 1.0." );
Preconditions.checkArgument( cost > 0, "Turns must be > 0" );
this.log( "Allow Grinding of '%1$s' to '%2$s' with optional '%3$s' @ %4$.2f for %5$d", Platform.getItemDisplayName( in ),
Platform.getItemDisplayName( out ), Platform.getItemDisplayName( optional ), chance, cost );
this.injectRecipe( new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), this.copy( optional ), chance, cost ) );
}
@Override
public void addRecipe( final ItemStack in, final ItemStack out, final ItemStack optional1, final float chance1, final ItemStack optional2, final float chance2, final int cost )
{
Preconditions.checkNotNull( in, "Null is not accepted as input itemstack." );
Preconditions.checkNotNull( out, "Null is not accepted as output itemstack." );
Preconditions.checkNotNull( optional1, "Null is not accepted as optional itemstack." );
Preconditions.checkArgument( chance1 >= 0.0 && chance1 <= 1.0, "chance must be within 0.0 - 1.0." );
Preconditions.checkNotNull( optional2, "Null is not accepted as optional2 itemstack." );
Preconditions.checkArgument( chance2 >= 0.0 && chance2 <= 1.0, "chance2 must be within 0.0 - 1.0." );
Preconditions.checkArgument( cost > 0, "Turns must be > 0" );
this.log( "Allow Grinding of '%1$s' to '%2$s' with optional '%3$s' @ %4$.2f and optional2 '%5$s' @ %6$.2f for %7$d", Platform.getItemDisplayName( in ),
Platform.getItemDisplayName( out ), Platform.getItemDisplayName( optional1 ), chance1, Platform.getItemDisplayName( optional2 ), chance2,
cost );
this.injectRecipe(
new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), this.copy( optional1 ), this.copy( optional2 ), chance1, chance2, cost ) );
}
@Override
public boolean removeRecipe( IGrinderRecipe recipe )
{
Preconditions.checkNotNull( recipe, "Cannot remove null as recipe." );
final CacheKey key = new CacheKey( recipe.getInput() );
final IGrinderRecipe removedRecipe = this.recipes.remove( key );
this.log( "Removed Grinding of '%1%s'", Platform.getItemDisplayName( recipe.getInput() ) );
return removedRecipe != null;
}
@Override
public IGrinderRecipe getRecipeForInput( final ItemStack input )
{
this.log( "Looking up recipe for '%1$s'", Platform.getItemDisplayName( input ) );
if( input == null )
{
return null;
}
final IGrinderRecipe recipe = this.recipes.get( new CacheKey( input ) );
if( recipe == null )
{
return null;
}
this.log( "Recipe for '%1$s' found '%2$s'", input.getUnlocalizedName(), Platform.getItemDisplayName( recipe.getOutput() ) );
return recipe;
}
@Override
public void addDustRatio( String oredictName, int ratio )
{
Preconditions.checkNotNull( oredictName );
Preconditions.checkArgument( ratio > 0 );
this.log( "Added ratio for '%1$s' of %2$d", oredictName, ratio );
this.dustToOreRatio.put( oredictName, ratio );
}
@Override
public boolean removeDustRatio( String oredictName )
{
Preconditions.checkNotNull( oredictName );
this.log( "Removed ratio for '%1$s'", oredictName );
return this.dustToOreRatio.remove( oredictName ) != null;
}
@Override
public void oreRegistered( final String name, final ItemStack item )
{
if( !AEConfig.instance().getGrinderBlackList().contains( name ) && ( name.startsWith( "ore" ) || name.startsWith( "crystal" ) || name
.startsWith( "gem" ) || name.startsWith( "ingot" ) || name.startsWith( "dust" ) ) )
{
for( final String ore : AEConfig.instance().getGrinderOres() )
{
if( name.equals( "ore" + ore ) )
{
this.addOre( ore, item );
}
else if( name.equals( "crystal" + ore ) || name.equals( "ingot" + ore ) || name.equals( "gem" + ore ) )
{
this.addIngot( ore, item );
}
else if( name.equals( "dust" + ore ) )
{
this.addDust( ore, item );
}
}
}
}
private void injectRecipe( final AppEngGrinderRecipe appEngGrinderRecipe )
{
final CacheKey cacheKey = new CacheKey( appEngGrinderRecipe.getInput() );
if( this.recipes.containsKey( cacheKey ) )
{
this.log( "Tried to add duplicate recipe for '%1$s'", Platform.getItemDisplayName( appEngGrinderRecipe.getInput() ) );
return;
}
this.recipes.put( cacheKey, appEngGrinderRecipe );
}
private ItemStack copy( final ItemStack is )
{
if( is != null )
{
return is.copy();
}
return null;
}
private int getDustToOreRatio( final String name )
{
return this.dustToOreRatio.getOrDefault( name, 2 );
}
private void addOre( final String name, final ItemStack item )
{
if( item == null )
{
return;
}
this.log( "Adding Ore: '%1$s'", Platform.getItemDisplayName( item ) );
this.ores.put( item, name );
if( this.dusts.containsKey( name ) )
{
final ItemStack is = this.dusts.get( name ).copy();
final int ratio = this.getDustToOreRatio( name );
if( ratio > 1 )
{
final ItemStack extra = is.copy();
extra.stackSize = ratio - 1;
this.addRecipe( item, is, extra, (float) ( AEConfig.instance().getOreDoublePercentage() / 100.0 ), 8 );
}
else
{
this.addRecipe( item, is, 8 );
}
}
}
private void addIngot( final String name, final ItemStack item )
{
if( item == null )
{
return;
}
this.log( "Adding Ingot: '%1$s'", Platform.getItemDisplayName( item ) );
this.ingots.put( item, name );
if( this.dusts.containsKey( name ) )
{
this.addRecipe( item, this.dusts.get( name ), 4 );
}
}
private void addDust( final String name, final ItemStack item )
{
if( item == null )
{
return;
}
if( this.dusts.containsKey( name ) )
{
this.log( "Rejecting Dust: '%1$s'", Platform.getItemDisplayName( item ) );
return;
}
this.log( "Adding Dust: '%1$s'", Platform.getItemDisplayName( item ) );
this.dusts.put( name, item );
for( final Entry<ItemStack, String> d : this.ores.entrySet() )
{
if( name.equals( d.getValue() ) )
{
final ItemStack is = item.copy();
is.stackSize = 1;
final int ratio = this.getDustToOreRatio( name );
if( ratio > 1 )
{
final ItemStack extra = is.copy();
extra.stackSize = ratio - 1;
this.addRecipe( d.getKey(), is, extra, (float) ( AEConfig.instance().getOreDoublePercentage() / 100.0 ), 8 );
}
else
{
this.addRecipe( d.getKey(), is, 8 );
}
}
}
for( final Entry<ItemStack, String> d : this.ingots.entrySet() )
{
if( name.equals( d.getValue() ) )
{
this.addRecipe( d.getKey(), item, 4 );
}
}
}
private void log( final String o, Object... params )
{
AELog.grinder( o, params );
}
private static class CacheKey
{
private final Item item;
private final int damage;
CacheKey( ItemStack input )
{
Preconditions.checkNotNull( input );
Preconditions.checkNotNull( input.getItem() );
this.item = input.getItem();
this.damage = input.getItemDamage();
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + damage;
result = prime * result + ( ( item == null ) ? 0 : item.hashCode() );
return result;
}
@Override
public boolean equals( Object obj )
{
if( this == obj )
{
return true;
}
if( obj == null || getClass() != obj.getClass() )
{
return false;
}
CacheKey other = (CacheKey) obj;
if( damage != other.damage )
{
return false;
}
if( item == null )
{
if( other.item != null )
{
return false;
}
}
else if( item != other.item )
{
return false;
}
return true;
}
}
}
@@ -16,7 +16,7 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries.entries;
package appeng.core.features.registries.inscriber;
import java.util.Collection;
@@ -38,7 +38,7 @@ import appeng.api.features.InscriberProcessType;
*/
public class InscriberInscribeRecipe extends InscriberRecipe
{
public InscriberInscribeRecipe( @Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot )
InscriberInscribeRecipe( @Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot )
{
super( inputs, output, top, bot, InscriberProcessType.INSCRIBE );
}
@@ -16,7 +16,7 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries.entries;
package appeng.core.features.registries.inscriber;
import java.util.ArrayList;
@@ -57,7 +57,7 @@ public class InscriberRecipe implements IInscriberRecipe
@Nonnull
private final InscriberProcessType type;
public InscriberRecipe( @Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot, @Nonnull final InscriberProcessType type )
InscriberRecipe( @Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot, @Nonnull final InscriberProcessType type )
{
this.inputs = new ArrayList<ItemStack>( inputs.size() );
this.inputs.addAll( inputs );
@@ -16,7 +16,7 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.features.registries;
package appeng.core.features.registries.inscriber;
import java.util.ArrayList;
@@ -35,7 +35,6 @@ import appeng.api.features.IInscriberRecipe;
import appeng.api.features.IInscriberRecipeBuilder;
import appeng.api.features.IInscriberRegistry;
import appeng.api.features.InscriberProcessType;
import appeng.core.features.registries.entries.InscriberRecipe;
/**
@@ -34,11 +34,11 @@ import appeng.core.sync.packets.PacketCompressedNBT;
import appeng.core.sync.packets.PacketConfigButton;
import appeng.core.sync.packets.PacketCraftRequest;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketJEIRecipe;
import appeng.core.sync.packets.PacketLightning;
import appeng.core.sync.packets.PacketMEInventoryUpdate;
import appeng.core.sync.packets.PacketMatterCannon;
import appeng.core.sync.packets.PacketMockExplosion;
import appeng.core.sync.packets.PacketJEIRecipe;
import appeng.core.sync.packets.PacketNewStorageDimension;
import appeng.core.sync.packets.PacketPaintedEntity;
import appeng.core.sync.packets.PacketPartPlacement;
@@ -19,10 +19,6 @@
package appeng.coremod;
import java.util.Map;
import javax.annotation.Nullable;
import com.google.common.eventbus.EventBus;
import net.minecraftforge.fml.common.DummyModContainer;
@@ -31,18 +27,15 @@ import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.ModMetadata;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.relauncher.FMLRelaunchLog;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin.MCVersion;
import appeng.core.AEConfig;
@MCVersion( "1.10.2" )
public final class AppEngCore extends DummyModContainer implements IFMLLoadingPlugin
public final class AppEngCoreContainer extends DummyModContainer
{
private final ModMetadata metadata = new ModMetadata();
public AppEngCore()
public AppEngCoreContainer()
{
FMLRelaunchLog.info( "[AppEng] Core Init" );
this.metadata.autogenerated = false;
@@ -61,37 +54,6 @@ public final class AppEngCore extends DummyModContainer implements IFMLLoadingPl
{
}
@Override
public String[] getASMTransformerClass()
{
return new String[] { "appeng.coremod.asm.ASMIntegration" };
}
@Override
public String getModContainerClass()
{
return "appeng.coremod.AppEngCore";
}
@Nullable
@Override
public String getSetupClass()
{
return null;
}
@Override
public void injectData( final Map<String, Object> data )
{
}
@Override
public String getAccessTransformerClass()
{
return null;
}
@Override
public ModMetadata getMetadata()
{
@@ -0,0 +1,64 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.coremod;
import java.util.Map;
import javax.annotation.Nullable;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
@IFMLLoadingPlugin.MCVersion( "1.10.2" )
@IFMLLoadingPlugin.TransformerExclusions( { "appeng.coremod." } )
public class AppEngLoadingPlugin implements IFMLLoadingPlugin
{
@Override
public String[] getASMTransformerClass()
{
return new String[] { "appeng.coremod.transformer.IntegrationTransformer" };
}
@Override
public String getModContainerClass()
{
return "appeng.coremod.AppEngCoreContainer";
}
@Nullable
@Override
public String getSetupClass()
{
return null;
}
@Override
public void injectData( final Map<String, Object> data )
{
}
@Override
public String getAccessTransformerClass()
{
return null;
}
}
@@ -68,7 +68,7 @@ public final class MissingCoreMod extends CustomModLoadingErrorDisplayException
this.drawCenteredString( fontRenderer, "In a developer environment add the following too your args,", errorScreen.width / 2, offset, COLOR_WHITE );
offset += SCREEN_OFFSET;
this.drawCenteredString( fontRenderer, "-Dfml.coreMods.load=appeng.coremod.AppEngCore", errorScreen.width / 2, offset, SHADOW_WHITE );
this.drawCenteredString( fontRenderer, "-Dfml.coreMods.load=appeng.coremod.AppEngCoreContainer", errorScreen.width / 2, offset, SHADOW_WHITE );
}
else
{
@@ -16,7 +16,7 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.coremod.asm;
package appeng.coremod.transformer;
import java.util.Iterator;
@@ -41,37 +41,22 @@ import appeng.integration.IntegrationType;
@Reflected
public final class ASMIntegration implements IClassTransformer
public final class IntegrationTransformer implements IClassTransformer
{
@Reflected
public ASMIntegration()
public IntegrationTransformer()
{
/**
* Side, Display Name, ModID ClassPostFix
*/
for( final IntegrationType type : IntegrationType.values() )
{
IntegrationRegistry.INSTANCE.add( type );
}
// integrationModules.add( IntegrationSide.BOTH, "Thermal Expansion", "ThermalExpansion", IntegrationType.TE );
// integrationModules.add( IntegrationSide.BOTH, "Mystcraft", "Mystcraft", IntegrationType.Mystcraft );
// integrationModules.add( IntegrationSide.BOTH, "Greg Tech", "gregtech_addon", IntegrationType.GT );
// integrationModules.add( IntegrationSide.BOTH, "Universal Electricity", null, IntegrationType.UE );
// integrationModules.add( IntegrationSide.BOTH, "Logistics Pipes", "LogisticsPipes|Main", IntegrationType.LP );
// integrationModules.add( IntegrationSide.BOTH, "Better Storage", IntegrationType.betterstorage );
// integrationModules.add( IntegrationSide.BOTH, "Forestry", "Forestry", IntegrationType.Forestry );
// integrationModules.add( IntegrationSide.BOTH, "Mekanism", "Mekanism", IntegrationType.Mekanism );
}
@Nullable
@Override
public byte[] transform( final String name, final String transformedName, final byte[] basicClass )
{
if( basicClass == null || transformedName.startsWith( "appeng.coremod" ) )
if( basicClass == null )
{
return basicClass;
}
@@ -19,11 +19,9 @@
package appeng.crafting;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import javax.annotation.Nonnull;
import java.util.Set;
import appeng.api.networking.crafting.ICraftingWatcher;
import appeng.api.networking.crafting.ICraftingWatcherHost;
@@ -39,7 +37,7 @@ public class CraftingWatcher implements ICraftingWatcher
private final CraftingGridCache gsc;
private final ICraftingWatcherHost host;
private final HashSet<IAEStack> myInterests = new HashSet<IAEStack>();
private final Set<IAEStack> myInterests = new HashSet<IAEStack>();
public CraftingWatcher( final CraftingGridCache cache, final ICraftingWatcherHost host )
{
@@ -52,45 +50,6 @@ public class CraftingWatcher implements ICraftingWatcher
return this.host;
}
@Override
public int size()
{
return this.myInterests.size();
}
@Override
public boolean isEmpty()
{
return this.myInterests.isEmpty();
}
@Override
public boolean contains( final Object o )
{
return this.myInterests.contains( o );
}
@Nonnull
@Override
public Iterator<IAEStack> iterator()
{
return new ItemWatcherIterator( this, this.myInterests.iterator() );
}
@Nonnull
@Override
public Object[] toArray()
{
return this.myInterests.toArray();
}
@Nonnull
@Override
public <T> T[] toArray( @Nonnull final T[] a )
{
return this.myInterests.toArray( a );
}
@Override
public boolean add( final IAEStack e )
{
@@ -103,100 +62,20 @@ public class CraftingWatcher implements ICraftingWatcher
}
@Override
public boolean remove( final Object o )
public boolean remove( final IAEStack o )
{
return this.myInterests.remove( o ) && this.gsc.getInterestManager().remove( (IAEStack) o, this );
}
@Override
public boolean containsAll( @Nonnull final Collection<?> c )
{
return this.myInterests.containsAll( c );
}
@Override
public boolean addAll( @Nonnull final Collection<? extends IAEStack> c )
{
boolean didChange = false;
for( final IAEStack o : c )
{
didChange = this.add( o ) || didChange;
}
return didChange;
}
@Override
public boolean removeAll( @Nonnull final Collection<?> c )
{
boolean didSomething = false;
for( final Object o : c )
{
didSomething = this.remove( o ) || didSomething;
}
return didSomething;
}
@Override
public boolean retainAll( @Nonnull final Collection<?> c )
{
boolean changed = false;
final Iterator<IAEStack> i = this.iterator();
while( i.hasNext() )
{
if( !c.contains( i.next() ) )
{
i.remove();
changed = true;
}
}
return changed;
}
@Override
public void clear()
public void reset()
{
final Iterator<IAEStack> i = this.myInterests.iterator();
while( i.hasNext() )
{
this.gsc.getInterestManager().remove( i.next(), this );
i.remove();
}
}
private class ItemWatcherIterator implements Iterator<IAEStack>
{
private final CraftingWatcher watcher;
private final Iterator<IAEStack> interestIterator;
private IAEStack myLast;
public ItemWatcherIterator( final CraftingWatcher parent, final Iterator<IAEStack> i )
{
this.watcher = parent;
this.interestIterator = i;
}
@Override
public boolean hasNext()
{
return this.interestIterator.hasNext();
}
@Override
public IAEStack next()
{
return this.myLast = this.interestIterator.next();
}
@Override
public void remove()
{
CraftingWatcher.this.gsc.getInterestManager().remove( this.myLast, this.watcher );
this.interestIterator.remove();
}
}
}
@@ -2,6 +2,7 @@ package appeng.decorative.slab;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
@@ -95,15 +95,17 @@ public class BlockQuartzGlass extends AEBaseBlock
{
BlockPos adjacentPos = pos.offset( side );
final Material mat = w.getBlockState( adjacentPos ).getBlock().getMaterial( state );
final Material mat = w.getBlockState( adjacentPos ).getMaterial();
if( mat == Material.GLASS || mat == AEGlassMaterial.INSTANCE )
{
if( w.getBlockState( adjacentPos ).getBlock().getRenderType( state ) == this.getRenderType( state ) )
if( w.getBlockState( adjacentPos ).getRenderType() == this.getRenderType( state ) )
{
return false;
}
}
return super.shouldSideBeRendered( state, w, pos, side );
return w.getBlockState( pos ).shouldSideBeRendered( w, adjacentPos, side );
}
@Override
@@ -64,7 +64,7 @@ public final class EntityChargedQuartz extends AEBaseEntityItem
{
super.onUpdate();
if( !AEConfig.instance().isFeatureEnabled( AEFeature.IN_WORLD_FLUIX ) )
if( this.isDead || !AEConfig.instance().isFeatureEnabled( AEFeature.IN_WORLD_FLUIX ) )
{
return;
}
@@ -74,14 +74,16 @@ public final class EntityChargedQuartz extends AEBaseEntityItem
CommonHelper.proxy.spawnEffect( EffectType.Lightning, this.worldObj, this.posX, this.posY, this.posZ, null );
this.delay = 0;
}
this.delay++;
final int j = MathHelper.floor_double( this.posX );
final int i = MathHelper.floor_double( (this.getEntityBoundingBox().minY + this.getEntityBoundingBox().maxY) / 2.0D );
final int i = MathHelper.floor_double( ( this.getEntityBoundingBox().minY + this.getEntityBoundingBox().maxY ) / 2.0D );
final int k = MathHelper.floor_double( this.posZ );
IBlockState state = this.worldObj.getBlockState( new BlockPos( j, i, k ) );
final Material mat = state.getBlock().getMaterial( state );
if( Platform.isServer() && mat.isLiquid() )
{
this.transformTime++;
@@ -25,6 +25,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableSet;
@@ -27,6 +27,10 @@ public interface IIntegrationModule
return true;
}
default void preInit() throws Throwable
{
}
default void init() throws Throwable
{
}
@@ -25,9 +25,6 @@ import net.minecraftforge.fml.common.ModAPIManager;
import appeng.api.exceptions.ModNotInstalled;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.integration.modules.ic2.IC2Module;
import appeng.integration.modules.jei.JEIModule;
import appeng.integration.modules.waila.WailaModule;
final class IntegrationNode
@@ -80,7 +77,8 @@ final class IntegrationNode
final ModAPIManager apiManager = ModAPIManager.INSTANCE;
boolean enabled = this.modID == null || Loader.isModLoaded( this.modID ) || apiManager.hasAPI( this.modID );
AEConfig.instance().addCustomCategoryComment( "ModIntegration", "Valid Values are 'AUTO', 'ON', or 'OFF' - defaults to 'AUTO' ; Suggested that you leave this alone unless your experiencing an issue, or wish to disable the integration for a reason." );
AEConfig.instance().addCustomCategoryComment( "ModIntegration",
"Valid Values are 'AUTO', 'ON', or 'OFF' - defaults to 'AUTO' ; Suggested that you leave this alone unless your experiencing an issue, or wish to disable the integration for a reason." );
final String mode = AEConfig.instance().get( "ModIntegration", this.displayName.replace( " ", "" ), "AUTO" ).getString();
if( mode.toUpperCase().equals( "ON" ) )
@@ -94,24 +92,14 @@ final class IntegrationNode
if( enabled )
{
switch( type )
{
case IC2:
this.mod = Integrations.setIc2( new IC2Module() );
break;
case JEI:
this.mod = Integrations.setJei( new JEIModule() );
break;
case Waila:
this.mod = new WailaModule();
break;
}
this.mod = type.createInstance();
}
else
{
throw new ModNotInstalled( this.modID );
}
this.mod.preInit();
this.setState( IntegrationStage.INIT );
break;
@@ -19,27 +19,71 @@
package appeng.integration;
import appeng.integration.modules.ic2.IC2Module;
import appeng.integration.modules.jei.JEIModule;
import appeng.integration.modules.rf.RFItemModule;
import appeng.integration.modules.rf.RFTileModule;
import appeng.integration.modules.theoneprobe.TheOneProbeModule;
import appeng.integration.modules.waila.WailaModule;
public enum IntegrationType
{
IC2( IntegrationSide.BOTH, "Industrial Craft 2", "IC2" ),
IC2( IntegrationSide.BOTH, "Industrial Craft 2", "IC2" )
{
@Override
public IIntegrationModule createInstance()
{
return Integrations.setIc2( new IC2Module() );
}
},
RC( IntegrationSide.BOTH, "Railcraft", "Railcraft" ),
RF( IntegrationSide.BOTH, "RedstoneFlux Power - Tiles", "CoFHAPI" )
{
RF( IntegrationSide.BOTH, "RedstoneFlux Power - Tiles", "CoFHAPI" ),
@Override
public IIntegrationModule createInstance()
{
return new RFTileModule();
}
},
RFItem( IntegrationSide.BOTH, "RedstoneFlux Power - Items", "CoFHAPI" ),
RFItem( IntegrationSide.BOTH, "RedstoneFlux Power - Items", "CoFHAPI" )
{
MFR( IntegrationSide.BOTH, "Mine Factory Reloaded", "MineFactoryReloaded" ),
@Override
public IIntegrationModule createInstance()
{
return new RFItemModule();
}
},
Waila( IntegrationSide.BOTH, "Waila", "Waila" ),
Waila( IntegrationSide.BOTH, "Waila", "Waila" )
{
@Override
public IIntegrationModule createInstance()
{
return new WailaModule();
}
},
InvTweaks( IntegrationSide.CLIENT, "Inventory Tweaks", "inventorytweaks" ),
JEI( IntegrationSide.CLIENT, "Just Enough Items", "JEI" )
{
@Override
public IIntegrationModule createInstance()
{
return Integrations.setJei( new JEIModule() );
}
},
JEI( IntegrationSide.CLIENT, "Just Enough Items", "JEI" ),
Mekanism( IntegrationSide.BOTH, "Mekanism", "Mekanism" ),
OpenComputers( IntegrationSide.BOTH, "OpenComputers", "OpenComputers" );
THE_ONE_PROBE( IntegrationSide.BOTH, "TheOneProbe", "theoneprobe" )
{
@Override
public IIntegrationModule createInstance()
{
return new TheOneProbeModule();
}
};
public final IntegrationSide side;
public final String dspName;
@@ -52,4 +96,9 @@ public enum IntegrationType
this.modID = modid;
}
public IIntegrationModule createInstance()
{
throw new MissingIntegrationModuleException( this.name() );
}
}
@@ -0,0 +1,32 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration;
public class MissingIntegrationModuleException extends RuntimeException
{
private static final long serialVersionUID = 1927357647297008228L;
public MissingIntegrationModuleException( String name )
{
super( "Missing integration module for type '" + name + "'." );
}
}
@@ -36,9 +36,13 @@ import appeng.tile.powersink.IExternalPowerSink;
public class IC2Module implements IIC2
{
private static final String[] IC2_CABLE_TYPES = { "copper", "glass", "gold", "iron", "tin", "detector", "splitter" };
public IC2Module()
{
IntegrationHelper.testClassExistence( this, ic2.api.energy.tile.IEnergyTile.class );
IntegrationHelper.testClassExistence( this, ic2.api.item.IC2Items.class );
IntegrationHelper.testClassExistence( this, ic2.api.recipe.Recipes.class );
IntegrationHelper.testClassExistence( this, ic2.api.recipe.RecipeInputItemStack.class );
}
@@ -46,22 +50,21 @@ public class IC2Module implements IIC2
public void postInit()
{
final IP2PTunnelRegistry reg = AEApi.instance().registries().p2pTunnel();
reg.addNewAttunement( this.getItem( "copperCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "insulatedCopperCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "goldCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "insulatedGoldCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "ironCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "insulatedIronCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "insulatedTinCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "glassFiberCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "tinCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "detectorCableItem" ), TunnelType.IC2_POWER );
reg.addNewAttunement( this.getItem( "splitterCableItem" ), TunnelType.IC2_POWER );
for( String string : IC2_CABLE_TYPES )
{
reg.addNewAttunement( this.getCable( string ), TunnelType.IC2_POWER );
}
}
private ItemStack getItem( final String name )
private ItemStack getItem( final String name, String variant )
{
return ic2.api.item.IC2Items.getItem( name );
return ic2.api.item.IC2Items.getItem( name, variant );
}
private ItemStack getCable( final String type )
{
return this.getItem( "cable", "type:" + type );
}
/**
@@ -21,6 +21,7 @@ package appeng.integration.modules.jei;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import com.google.common.base.Splitter;
@@ -22,16 +22,16 @@ package appeng.integration.modules.jei;
import mezz.jei.api.recipe.IRecipeHandler;
import mezz.jei.api.recipe.IRecipeWrapper;
import appeng.api.features.IGrinderEntry;
import appeng.api.features.IGrinderRecipe;
class GrinderRecipeHandler implements IRecipeHandler<IGrinderEntry>
class GrinderRecipeHandler implements IRecipeHandler<IGrinderRecipe>
{
@Override
public Class<IGrinderEntry> getRecipeClass()
public Class<IGrinderRecipe> getRecipeClass()
{
return IGrinderEntry.class;
return IGrinderRecipe.class;
}
@Override
@@ -41,19 +41,19 @@ class GrinderRecipeHandler implements IRecipeHandler<IGrinderEntry>
}
@Override
public String getRecipeCategoryUid( IGrinderEntry recipe )
public String getRecipeCategoryUid( IGrinderRecipe recipe )
{
return GrinderRecipeCategory.UID;
}
@Override
public IRecipeWrapper getRecipeWrapper( IGrinderEntry recipe )
public IRecipeWrapper getRecipeWrapper( IGrinderRecipe recipe )
{
return new GrinderRecipeWrapper( recipe );
}
@Override
public boolean isRecipeValid( IGrinderEntry recipe )
public boolean isRecipeValid( IGrinderRecipe recipe )
{
return true;
}
@@ -31,15 +31,15 @@ import net.minecraft.item.ItemStack;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeWrapper;
import appeng.api.features.IGrinderEntry;
import appeng.api.features.IGrinderRecipe;
class GrinderRecipeWrapper extends BlankRecipeWrapper
{
private final IGrinderEntry recipe;
private final IGrinderRecipe recipe;
GrinderRecipeWrapper( IGrinderEntry recipe )
GrinderRecipeWrapper( IGrinderRecipe recipe )
{
this.recipe = recipe;
}
@@ -50,14 +50,8 @@ class GrinderRecipeWrapper extends BlankRecipeWrapper
ingredients.setInput( ItemStack.class, recipe.getInput() );
List<ItemStack> outputs = new ArrayList<>( 3 );
outputs.add( recipe.getOutput() );
if( recipe.getOptionalOutput() != null )
{
outputs.add( recipe.getOptionalOutput() );
}
if( recipe.getSecondOptionalOutput() != null )
{
outputs.add( recipe.getSecondOptionalOutput() );
}
recipe.getOptionalOutput().ifPresent( outputs::add );
recipe.getSecondOptionalOutput().ifPresent( outputs::add );
ingredients.setOutputs( ItemStack.class, outputs );
}
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -70,8 +71,10 @@ public class JEIPlugin extends BlankModPlugin
registerDescriptions( definitions, registry );
// Allow recipe transfer from JEI to crafting and pattern terminal
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), VanillaRecipeCategoryUid.CRAFTING );
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ), VanillaRecipeCategoryUid.CRAFTING );
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ),
VanillaRecipeCategoryUid.CRAFTING );
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ),
VanillaRecipeCategoryUid.CRAFTING );
}
private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
@@ -130,7 +133,7 @@ public class JEIPlugin extends BlankModPlugin
return;
}
registry.addRecipes( AEApi.instance().registries().grinder().getRecipes() );
registry.addRecipes( Lists.newArrayList( AEApi.instance().registries().grinder().getRecipes() ) );
registry.addRecipeHandlers( new GrinderRecipeHandler() );
registry.addRecipeCategories( new GrinderRecipeCategory( registry.getJeiHelpers().getGuiHelper() ) );
registry.addRecipeCategoryCraftingItem( grindstone, GrinderRecipeCategory.UID );
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayer;
@@ -0,0 +1,32 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.rf;
import appeng.integration.IIntegrationModule;
import appeng.integration.IntegrationHelper;
public class RFItemModule implements IIntegrationModule
{
public RFItemModule()
{
IntegrationHelper.testClassExistence( this, cofh.api.energy.IEnergyContainerItem.class );
}
}
@@ -0,0 +1,32 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.rf;
import appeng.integration.IIntegrationModule;
import appeng.integration.IntegrationHelper;
public class RFTileModule implements IIntegrationModule
{
public RFTileModule()
{
IntegrationHelper.testClassExistence( this, cofh.api.energy.IEnergyReceiver.class );
}
}
@@ -0,0 +1,86 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe;
import java.util.List;
import java.util.Optional;
import com.google.common.collect.Lists;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.IProbeInfoProvider;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.parts.IPart;
import appeng.core.AppEng;
import appeng.integration.modules.theoneprobe.part.ChannelInfoProvider;
import appeng.integration.modules.theoneprobe.part.IPartProbInfoProvider;
import appeng.integration.modules.theoneprobe.part.P2PStateInfoProvider;
import appeng.integration.modules.theoneprobe.part.PartAccessor;
import appeng.integration.modules.theoneprobe.part.PowerStateInfoProvider;
import appeng.integration.modules.theoneprobe.part.StorageMonitorInfoProvider;
public final class PartInfoProvider implements IProbeInfoProvider
{
private final List<IPartProbInfoProvider> providers;
private final PartAccessor accessor = new PartAccessor();
public PartInfoProvider()
{
final IPartProbInfoProvider channel = new ChannelInfoProvider();
final IPartProbInfoProvider power = new PowerStateInfoProvider();
final IPartProbInfoProvider storageMonitor = new StorageMonitorInfoProvider();
final IPartProbInfoProvider p2p = new P2PStateInfoProvider();
this.providers = Lists.newArrayList( channel, power, p2p, storageMonitor );
}
@Override
public String getID()
{
return AppEng.MOD_ID + ":PartInfoProvider";
}
@Override
public void addProbeInfo( ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
final TileEntity te = world.getTileEntity( data.getPos() );
final Optional<IPart> maybePart = this.accessor.getMaybePart( te, data );
if( maybePart.isPresent() )
{
final IPart part = maybePart.get();
for( final IPartProbInfoProvider provider : this.providers )
{
provider.addProbeInfo( part, mode, probeInfo, player, world, blockState, data );
}
}
}
}
@@ -0,0 +1,51 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe;
import com.google.common.base.Function;
import net.minecraftforge.fml.common.event.FMLInterModComms;
import mcjty.theoneprobe.api.ITheOneProbe;
import appeng.integration.IIntegrationModule;
import appeng.integration.modules.theoneprobe.config.AEConfigProvider;
public class TheOneProbeModule implements IIntegrationModule, Function<ITheOneProbe, Void>
{
@Override
public void preInit() throws Throwable
{
FMLInterModComms.sendFunctionMessage( "theoneprobe", "getTheOneProbe", this.getClass().getName() );
}
@Override
public Void apply( ITheOneProbe input )
{
input.registerProbeConfigProvider( new AEConfigProvider() );
input.registerProvider( new TileInfoProvider() );
input.registerProvider( new PartInfoProvider() );
return null;
}
}
@@ -0,0 +1,66 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe;
import java.util.Locale;
import net.minecraft.util.text.translation.I18n;
public enum TheOneProbeText
{
CRAFTING,
DEVICE_ONLINE,
DEVICE_OFFLINE,
DEVICE_MISSING_CHANNEL,
P2P_UNLINKED,
P2P_INPUT_ONE_OUTPUT,
P2P_INPUT_MANY_OUTPUTS,
P2P_OUTPUT,
LOCKED,
UNLOCKED,
SHOWING,
CONTAINS,
CHANNELS,
STORED_ENERGY;
private final String root;
TheOneProbeText()
{
this.root = "theoneprobe.appliedenergistics2";
}
public String getLocal()
{
return I18n.translateToLocal( this.getUnlocalized() );
}
public String getUnlocalized()
{
return this.root + '.' + this.name().toLowerCase( Locale.ENGLISH );
}
}
@@ -0,0 +1,80 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe;
import java.util.List;
import com.google.common.collect.Lists;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.IProbeInfoProvider;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.core.AppEng;
import appeng.integration.modules.theoneprobe.tile.ChargerInfoProvider;
import appeng.integration.modules.theoneprobe.tile.CraftingMonitorInfoProvider;
import appeng.integration.modules.theoneprobe.tile.ITileProbInfoProvider;
import appeng.integration.modules.theoneprobe.tile.PowerStateInfoProvider;
import appeng.integration.modules.theoneprobe.tile.PowerStorageInfoProvider;
import appeng.tile.AEBaseTile;
public final class TileInfoProvider implements IProbeInfoProvider
{
private final List<ITileProbInfoProvider> providers;
public TileInfoProvider()
{
final ITileProbInfoProvider charger = new ChargerInfoProvider();
final ITileProbInfoProvider energyCell = new CraftingMonitorInfoProvider();
final ITileProbInfoProvider craftingBlock = new PowerStateInfoProvider();
final ITileProbInfoProvider craftingMonitor = new PowerStorageInfoProvider();
this.providers = Lists.newArrayList( charger, energyCell, craftingBlock, craftingMonitor );
}
@Override
public String getID()
{
return AppEng.MOD_ID + ":TileInfoProvider";
}
@Override
public void addProbeInfo( ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
final TileEntity tile = world.getTileEntity( data.getPos() );
if( tile instanceof AEBaseTile )
{
final AEBaseTile aeBaseTile = (AEBaseTile) tile;
for( final ITileProbInfoProvider provider : this.providers )
{
provider.addProbeInfo( aeBaseTile, mode, probeInfo, player, world, blockState, data );
}
}
}
}
@@ -0,0 +1,53 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.config;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeConfig;
import mcjty.theoneprobe.api.IProbeConfigProvider;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeHitEntityData;
import appeng.tile.AEBaseTile;
public class AEConfigProvider implements IProbeConfigProvider
{
@Override
public void getProbeConfig( IProbeConfig config, EntityPlayer player, World world, Entity entity, IProbeHitEntityData data )
{
// Still no AE entities.
}
@Override
public void getProbeConfig( IProbeConfig config, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( world.getTileEntity( data.getPos() ) instanceof AEBaseTile )
{
config.setRFMode( 0 );
}
}
}
@@ -0,0 +1,66 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.parts.IPart;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.parts.networking.PartCableSmart;
import appeng.parts.networking.PartDenseCable;
public class ChannelInfoProvider implements IPartProbInfoProvider
{
@Override
public void addProbeInfo( IPart part, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( part instanceof PartDenseCable || part instanceof PartCableSmart )
{
final int usedChannels;
final int maxChannels = ( part instanceof PartDenseCable ) ? 32 : 8;
if( part.getGridNode().isActive() )
{
final NBTTagCompound tmp = new NBTTagCompound();
part.writeToNBT( tmp );
usedChannels = tmp.getByte( "usedChannels" );
}
else
{
usedChannels = 0;
}
final String formattedChannelString = String.format( TheOneProbeText.CHANNELS.getLocal(), usedChannels, maxChannels );
probeInfo.text( formattedChannelString );
}
}
}
@@ -0,0 +1,45 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.IProbeInfoProvider;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.parts.IPart;
/**
* Similar to {@link IProbeInfoProvider}, but already providing the {@link IPart} being looked at.
*
*/
public interface IPartProbInfoProvider
{
/**
* @see IProbeInfoProvider#addProbeInfo(ProbeMode, IProbeInfo, EntityPlayer, World, IBlockState, IProbeHitData)
*/
void addProbeInfo( IPart part, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data );
}
@@ -0,0 +1,115 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import com.google.common.collect.Iterators;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.parts.IPart;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.me.GridAccessException;
import appeng.parts.p2p.PartP2PTunnel;
public class P2PStateInfoProvider implements IPartProbInfoProvider
{
private static final int STATE_UNLINKED = 0;
private static final int STATE_OUTPUT = 1;
private static final int STATE_INPUT = 2;
public static final String TAG_P2P_STATE = "p2p_state";
@Override
public void addProbeInfo( IPart part, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( part instanceof PartP2PTunnel )
{
final PartP2PTunnel tunnel = (PartP2PTunnel) part;
// The default state
int state = STATE_UNLINKED;
int outputCount = 0;
if( !tunnel.isOutput() )
{
outputCount = getOutputCount( tunnel );
if( outputCount > 0 )
{
// Only set it to INPUT if we know there are any outputs
state = STATE_INPUT;
}
}
else
{
final PartP2PTunnel input = tunnel.getInput();
if( input != null )
{
state = STATE_OUTPUT;
}
}
switch( state )
{
case STATE_UNLINKED:
probeInfo.text( TheOneProbeText.P2P_UNLINKED.getLocal() );
break;
case STATE_OUTPUT:
probeInfo.text( TheOneProbeText.P2P_OUTPUT.getLocal() );
break;
case STATE_INPUT:
probeInfo.text( getOutputText( outputCount ) );
break;
}
}
}
private static int getOutputCount( PartP2PTunnel tunnel )
{
try
{
return Iterators.size( tunnel.getOutputs().iterator() );
}
catch( GridAccessException e )
{
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText( int outputs )
{
if( outputs <= 1 )
{
return TheOneProbeText.P2P_INPUT_ONE_OUTPUT.getLocal();
}
else
{
return String.format( TheOneProbeText.P2P_INPUT_MANY_OUTPUTS.getLocal(), outputs );
}
}
}
@@ -0,0 +1,55 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import java.util.Optional;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import mcjty.theoneprobe.api.IProbeHitData;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHost;
import appeng.api.parts.SelectedPart;
public final class PartAccessor
{
public Optional<IPart> getMaybePart( final TileEntity te, final IProbeHitData data )
{
if( te instanceof IPartHost )
{
BlockPos pos = data.getPos();
final Vec3d position = data.getHitVec().addVector( -pos.getX(), -pos.getY(), -pos.getZ() );
final IPartHost host = (IPartHost) te;
final SelectedPart sp = host.selectPart( position );
if( sp.part != null )
{
return Optional.of( sp.part );
}
}
return Optional.empty();
}
}
@@ -0,0 +1,71 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.parts.IPart;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
public class PowerStateInfoProvider implements IPartProbInfoProvider
{
@Override
public void addProbeInfo( IPart part, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( part instanceof IPowerChannelState )
{
final IPowerChannelState state = (IPowerChannelState) part;
final String tooltip = this.getToolTip( state.isActive(), state.isPowered() );
probeInfo.text( tooltip );
}
}
private String getToolTip( final boolean isActive, final boolean isPowered )
{
final String result;
if( isActive && isPowered )
{
result = TheOneProbeText.DEVICE_ONLINE.getLocal();
}
else if( isPowered )
{
result = TheOneProbeText.DEVICE_MISSING_CHANNEL.getLocal();
}
else
{
result = TheOneProbeText.DEVICE_OFFLINE.getLocal();
}
return result;
}
}
@@ -0,0 +1,66 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.part;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.implementations.parts.IPartStorageMonitor;
import appeng.api.parts.IPart;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
public class StorageMonitorInfoProvider implements IPartProbInfoProvider
{
@Override
public void addProbeInfo( IPart part, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( part instanceof IPartStorageMonitor )
{
final IPartStorageMonitor monitor = (IPartStorageMonitor) part;
final IAEStack<?> displayed = monitor.getDisplayed();
final boolean isLocked = monitor.isLocked();
if( displayed instanceof IAEItemStack )
{
final IAEItemStack ais = (IAEItemStack) displayed;
probeInfo.text( TheOneProbeText.SHOWING.getLocal() + ": " + ais.getItemStack().getDisplayName() );
}
else if( displayed instanceof IAEFluidStack )
{
final IAEFluidStack ais = (IAEFluidStack) displayed;
probeInfo.text( TheOneProbeText.SHOWING.getLocal() + ": " + ais.getFluid().getLocalizedName( ais.getFluidStack() ) );
}
probeInfo.text( isLocked ? TheOneProbeText.LOCKED.getLocal() : TheOneProbeText.UNLOCKED.getLocal() );
}
}
}
@@ -0,0 +1,61 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.ElementAlignment;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.tile.AEBaseTile;
import appeng.tile.misc.TileCharger;
public class ChargerInfoProvider implements ITileProbInfoProvider
{
@Override
public void addProbeInfo( AEBaseTile tile, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( tile instanceof TileCharger )
{
final TileCharger charger = (TileCharger) tile;
final IInventory chargerInventory = charger.getInternalInventory();
final ItemStack chargingItem = chargerInventory.getStackInSlot( 0 );
if( chargingItem != null )
{
final String currentInventory = chargingItem.getDisplayName();
final IProbeInfo centerAlignedHorizontalLayout = probeInfo
.horizontal( probeInfo.defaultLayoutStyle().alignment( ElementAlignment.ALIGN_CENTER ) );
centerAlignedHorizontalLayout.item( chargingItem );
centerAlignedHorizontalLayout.text( currentInventory );
}
}
}
}
@@ -0,0 +1,64 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.ElementAlignment;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.storage.data.IAEItemStack;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.tile.AEBaseTile;
import appeng.tile.crafting.TileCraftingMonitorTile;
public class CraftingMonitorInfoProvider implements ITileProbInfoProvider
{
@Override
public void addProbeInfo( AEBaseTile tile, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( tile instanceof TileCraftingMonitorTile )
{
final TileCraftingMonitorTile monitor = (TileCraftingMonitorTile) tile;
final IAEItemStack displayStack = monitor.getJobProgress();
if( displayStack != null )
{
final ItemStack itemStack = displayStack.getItemStack();
final String itemName = itemStack.getDisplayName();
final String formattedCrafting = String.format( TheOneProbeText.CRAFTING.getLocal(), itemName );
final IProbeInfo centerAlignedHorizontalLayout = probeInfo
.horizontal( probeInfo.defaultLayoutStyle().alignment( ElementAlignment.ALIGN_CENTER ) );
centerAlignedHorizontalLayout.item( itemStack );
centerAlignedHorizontalLayout.text( formattedCrafting );
}
}
}
}
@@ -0,0 +1,44 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.IProbeInfoProvider;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.tile.AEBaseTile;
/**
* Similar to {@link IProbeInfoProvider}, but already providing the {@link AEBaseTile} being looked at.
*
*/
public interface ITileProbInfoProvider
{
/**
* @see IProbeInfoProvider#addProbeInfo(ProbeMode, IProbeInfo, EntityPlayer, World, IBlockState, IProbeHitData)
*/
void addProbeInfo( AEBaseTile tile, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data );
}
@@ -0,0 +1,64 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.implementations.IPowerChannelState;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.tile.AEBaseTile;
public class PowerStateInfoProvider implements ITileProbInfoProvider
{
@Override
public void addProbeInfo( AEBaseTile tile, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( tile instanceof IPowerChannelState )
{
final IPowerChannelState state = (IPowerChannelState) tile;
final boolean isActive = state.isActive();
final boolean isPowered = state.isPowered();
if( isActive && isPowered )
{
probeInfo.text( TheOneProbeText.DEVICE_ONLINE.getLocal() );
}
else if( isPowered )
{
probeInfo.text( TheOneProbeText.DEVICE_MISSING_CHANNEL.getLocal() );
}
else
{
probeInfo.text( TheOneProbeText.DEVICE_OFFLINE.getLocal() );
}
}
}
}
@@ -0,0 +1,66 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.theoneprobe.tile;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import mcjty.theoneprobe.api.IProbeHitData;
import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.api.ProbeMode;
import appeng.api.networking.energy.IAEPowerStorage;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.tile.AEBaseTile;
import appeng.util.Platform;
public class PowerStorageInfoProvider implements ITileProbInfoProvider
{
@Override
public void addProbeInfo( AEBaseTile tile, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
{
if( tile instanceof IAEPowerStorage )
{
final IAEPowerStorage storage = (IAEPowerStorage) tile;
final double maxPower = storage.getAEMaxPower();
if( maxPower > 0 )
{
final long internalCurrentPower = (long) ( storage.getAECurrentPower() * 100 );
if( internalCurrentPower >= 0 )
{
final long internalMaxPower = (long) ( 100 * maxPower );
final String formatCurrentPower = Platform.formatPowerLong( internalCurrentPower, false );
final String formatMaxPower = Platform.formatPowerLong( internalMaxPower, false );
final String formattedString = String.format( TheOneProbeText.STORED_ENERGY.getLocal(), formatCurrentPower, formatMaxPower );
probeInfo.text( formattedString );
}
}
}
}
}
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -1,3 +1,4 @@
package appeng.items.parts;
@@ -11,6 +12,7 @@ import java.util.List;
import net.minecraft.util.ResourceLocation;
import appeng.api.parts.IPartModel;
import appeng.core.AELog;
@@ -22,7 +24,7 @@ class PartModelsHelper
static List<ResourceLocation> createModels( Class<?> clazz )
{
List<ResourceLocation> locations = new ArrayList<>( );
List<ResourceLocation> locations = new ArrayList<>();
// Check all static fields for used models
Field[] fields = clazz.getDeclaredFields();
@@ -33,7 +35,6 @@ class PartModelsHelper
continue;
}
if( !Modifier.isStatic( field.getModifiers() ) )
{
AELog.error( "The @PartModels annotation can only be used on static fields or methods. Was seen on: " + field );
@@ -80,8 +81,8 @@ class PartModelsHelper
Class<?> returnType = method.getReturnType();
if( !ResourceLocation.class.isAssignableFrom( returnType ) && !Collection.class.isAssignableFrom( returnType ) )
{
AELog.error( "The @PartModels annotation can only be used on static methods that return a ResourceLocation or Collection of "
+ "ResourceLocations. Was seen on: " + method );
AELog.error(
"The @PartModels annotation can only be used on static methods that return a ResourceLocation or Collection of " + "ResourceLocations. Was seen on: " + method );
continue;
}
@@ -119,18 +120,23 @@ class PartModelsHelper
{
locations.add( (ResourceLocation) value );
}
else if( value instanceof IPartModel )
{
locations.addAll( ( (IPartModel) value ).getModels() );
}
else if( value instanceof Collection )
{
// Check that each object is a ResourceLocation
// Check that each object is an IPartModel
Collection values = (Collection) value;
for( Object candidate : values )
{
if ( !( candidate instanceof ResourceLocation )) {
if( !( candidate instanceof IPartModel ) )
{
AELog.error( "List of locations obtained from {} contains a non resource location: {}", source, candidate );
continue;
}
locations.add( (ResourceLocation) candidate );
locations.addAll( ( (IPartModel) candidate ).getModels() );
}
}
}
@@ -59,10 +59,10 @@ import appeng.parts.networking.PartCableGlass;
import appeng.parts.networking.PartCableSmart;
import appeng.parts.networking.PartDenseCable;
import appeng.parts.networking.PartQuartzFiber;
import appeng.parts.p2p.PartP2PFluids;
import appeng.parts.p2p.PartP2PIC2Power;
import appeng.parts.p2p.PartP2PItems;
import appeng.parts.p2p.PartP2PLight;
import appeng.parts.p2p.PartP2PLiquids;
import appeng.parts.p2p.PartP2PRedstone;
import appeng.parts.p2p.PartP2PTunnelME;
import appeng.parts.reporting.PartConversionMonitor;
@@ -226,8 +226,8 @@ public enum PartType
}
},
P2PTunnelLiquids( 463, "p2p_tunnel_liquids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIQUIDS ), EnumSet
.noneOf( IntegrationType.class ), PartP2PLiquids.class, GuiText.FluidTunnel )
P2PTunnelFluids( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet
.noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel )
{
@Override
String getUnlocalizedName()

Some files were not shown because too many files have changed in this diff Show More