Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 483049f555 | |||
| a7a65ae39d | |||
| 45878df17d | |||
| 98142d8ade | |||
| 7956872d1d | |||
| e243c8e9a2 | |||
| 641d0d40cc | |||
| 50fad685b6 | |||
| 1ad49edd76 | |||
| 7ceaa4cc3e | |||
| b70c86542b | |||
| c1197c0084 | |||
| f0d807f0a2 | |||
| 5fa2c0ab27 | |||
| 3063bd887c | |||
| fac4a8f9dc | |||
| 9d8226da19 | |||
| 33754d289d | |||
| 959672dae3 | |||
| 90c17c09a8 | |||
| e0bf7223e0 | |||
| ba9af94228 | |||
| 122b6163dc | |||
| fab42ccc75 | |||
| f5dd2c8b0a | |||
| a126112a2d | |||
| 99cda5f5a3 | |||
| 56a5363528 | |||
| be65edbd5b | |||
| fe5d9251eb | |||
| 3cf48b2291 | |||
| cc4599b5fc | |||
| c1fa77df51 | |||
| 725fa491e6 | |||
| e2a6cd1d57 | |||
| 6ddf60fab8 | |||
| 2c07acfe81 | |||
| 3749742231 | |||
| 74b9610b45 | |||
| a725779ff6 | |||
| b82df25c75 | |||
| cc9b33b473 | |||
| 5496b746ea | |||
| f80f623ccf | |||
| cba6c5500f | |||
| bc8268af94 | |||
| 297cd16702 | |||
| 41711e50b9 | |||
| 2bfb8b75e8 |
@@ -14,6 +14,7 @@
|
||||
* [Building](#building)
|
||||
* [Contribution](#contribution)
|
||||
* [API](#applied-energistics-2-api)
|
||||
* [CraftTweaker](#applied-energistics-2-crafttweaker)
|
||||
* [Localization](#applied-energistics-2-localization)
|
||||
* [Credits](#credits)
|
||||
|
||||
@@ -154,6 +155,57 @@ Where the __ are filled in with the correct version criteria; AE2 is available f
|
||||
|
||||
An example string would be `appeng:appliedenergistics2:rv2-alpha-30:dev`
|
||||
|
||||
## Applied Energistics 2 CraftTweaker
|
||||
|
||||
### Inscriber
|
||||
Add a recipe. When `inscribe` is true the bottom and top inputs are not consumed.
|
||||
|
||||
mods.appliedenergistics2.Inscriber.addRecipe(ItemStack output, ItemStack input, boolean inscribe,
|
||||
@Optional ItemStack topInput, @Optional ItemStack bottomInput );
|
||||
|
||||
Remove all recipes for this output stack.
|
||||
|
||||
mods.appliedenergistics2.Inscriber.removeRecipe(ItemStack output);
|
||||
|
||||
### Grindstone
|
||||
Add a recipe.
|
||||
|
||||
mods.appliedenergistics2.Grinder.addRecipe( ItemStack output, ItemStack input, int turns,
|
||||
@Optional ItemStack secondary1Output, @Optional float secondary1Chance,
|
||||
@Optional ItemStack secondary2Output, @Optional float secondary2Chance);
|
||||
|
||||
Remove recipes for this input.
|
||||
|
||||
mods.appliedenergistics2.Grinder.removeRecipe(ItemStack input);
|
||||
|
||||
### Spatial
|
||||
Whitelist a TileEntity class for Spatial IO.
|
||||
|
||||
mods.appliedenergistics2.Spatial.whitelistEntity( String fullEntityClassName );
|
||||
|
||||
### Attunement
|
||||
Attune a ItemStack or ModID to a specific P2P-Tunnel type. ModID's are used as fallback when no ItemStack was found.
|
||||
|
||||
mods.appliedenergistics2.Attunement.attuneME( ItemStack itemStack );
|
||||
mods.appliedenergistics2.Attunement.attuneME( String modID );
|
||||
mods.appliedenergistics2.Attunement.attuneItem( ItemStack itemStack );
|
||||
mods.appliedenergistics2.Attunement.attuneItem( String modID );
|
||||
mods.appliedenergistics2.Attunement.attuneFluid( ItemStack itemStack );
|
||||
mods.appliedenergistics2.Attunement.attuneFluid( String modID );
|
||||
mods.appliedenergistics2.Attunement.attuneRedstone( ItemStack itemStack );
|
||||
mods.appliedenergistics2.Attunement.attuneRedstone( String modID );
|
||||
mods.appliedenergistics2.Attunement.attuneRF( ItemStack itemStack );
|
||||
mods.appliedenergistics2.Attunement.attuneRF( String modID );
|
||||
mods.appliedenergistics2.Attunement.attuneIC2( ItemStack itemStack );
|
||||
mods.appliedenergistics2.Attunement.attuneIC2( String modID );
|
||||
mods.appliedenergistics2.Attunement.attuneLight( ItemStack itemStack );
|
||||
mods.appliedenergistics2.Attunement.attuneLight( String modID );
|
||||
|
||||
### Cannon
|
||||
Add ammo types for the matter cannon.
|
||||
|
||||
mods.appliedenergistics2.Cannon.registerAmmo( ItemStack itemStack, double weight );
|
||||
|
||||
## Applied Energistics 2 Localization
|
||||
|
||||
### English Text
|
||||
|
||||
+2
-1
@@ -9,7 +9,7 @@ aebasename=appliedenergistics2
|
||||
#########################################################
|
||||
minecraft_version=1.12.2
|
||||
mcp_mappings=snapshot_20171003
|
||||
forge_version=14.23.0.2491
|
||||
forge_version=14.23.1.2554
|
||||
|
||||
#########################################################
|
||||
# Installable #
|
||||
@@ -24,6 +24,7 @@ tesla_version=1.0.61
|
||||
ic2_version=2.8.19-ex112
|
||||
top_version=1.12-1.4.18-10
|
||||
cofhcore_version=1.12-4.+
|
||||
crafttweaker_version=4.0.10.310
|
||||
|
||||
#########################################################
|
||||
# Deployment #
|
||||
|
||||
@@ -58,6 +58,11 @@ repositories {
|
||||
name 'tehnut'
|
||||
url "http://tehnut.info/maven"
|
||||
}
|
||||
|
||||
maven { // CraftTweaker
|
||||
name 'jared maven'
|
||||
url "http://maven.blamejared.com/"
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
@@ -77,6 +82,7 @@ dependencies {
|
||||
compileOnly "net.industrial-craft:industrialcraft-2:${ic2_version}:api"
|
||||
compileOnly "mcjty.theoneprobe:TheOneProbe-1.12:${top_version}:api"
|
||||
compileOnly "cofh:CoFHCore:${cofhcore_version}:deobf"
|
||||
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
|
||||
|
||||
// at runtime, use the full JEI jar
|
||||
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
|
||||
|
||||
@@ -28,6 +28,7 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
|
||||
import appeng.api.config.TunnelType;
|
||||
|
||||
@@ -47,6 +48,7 @@ public interface IP2PTunnelRegistry
|
||||
*/
|
||||
void addNewAttunement( @Nonnull ItemStack trigger, @Nullable TunnelType type );
|
||||
void addNewAttunement( @Nonnull String ModId, @Nullable TunnelType type );
|
||||
void addNewAttunement( @Nonnull Capability<?> cap, @Nullable TunnelType type );
|
||||
|
||||
/**
|
||||
* returns null if no attunement can be found.
|
||||
|
||||
@@ -48,6 +48,7 @@ public interface IRecipeHandlerRegistry
|
||||
* @param name name of crafthandler
|
||||
* @param handler class of crafthandler
|
||||
*/
|
||||
@Deprecated
|
||||
void addNewCraftHandler( String name, Class<? extends ICraftHandler> handler );
|
||||
|
||||
/**
|
||||
@@ -65,11 +66,13 @@ public interface IRecipeHandlerRegistry
|
||||
* @return A recipe handler by name, returns null on failure.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
ICraftHandler getCraftHandlerFor( String name );
|
||||
|
||||
/**
|
||||
* @return a new recipe handler, which can be used to parse, and read recipe files.
|
||||
*/
|
||||
@Deprecated
|
||||
IRecipeHandler createNewRecipehandler();
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,7 +30,7 @@ import appeng.api.exceptions.MissingIngredientException;
|
||||
import appeng.api.exceptions.RecipeException;
|
||||
import appeng.api.exceptions.RegistrationException;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public interface ICraftHandler
|
||||
{
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import net.minecraft.item.ItemStack;
|
||||
import appeng.api.exceptions.MissingIngredientException;
|
||||
import appeng.api.exceptions.RegistrationException;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public interface IIngredient
|
||||
{
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ package appeng.api.recipes;
|
||||
/**
|
||||
* Represents the AE2 Recipe Loading/Reading Class
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IRecipeHandler
|
||||
{
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.io.BufferedReader;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public interface IRecipeLoader
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -43,6 +43,19 @@ import appeng.api.storage.data.IItemList;
|
||||
public interface IStorageChannel<T extends IAEStack<T>>
|
||||
{
|
||||
|
||||
/**
|
||||
* Can be used as factor for transferring stacks of a channel.
|
||||
*
|
||||
* E.g. used by IO Ports to transfer 1000 mB, not 1 mB to match the
|
||||
* item channel transferring a full bucket per operation.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
default int transferFactor()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link IItemList} of the specific type.
|
||||
*
|
||||
|
||||
@@ -37,13 +37,17 @@ import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
||||
|
||||
import appeng.block.AEBaseBlock;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.entity.EntityIds;
|
||||
import appeng.entity.EntityTinyTNTPrimed;
|
||||
import appeng.helpers.ICustomCollision;
|
||||
|
||||
@@ -54,15 +58,24 @@ public class BlockTinyTNT extends AEBaseBlock implements ICustomCollision
|
||||
public BlockTinyTNT()
|
||||
{
|
||||
super( Material.TNT );
|
||||
this.setLightOpacity( 1 );
|
||||
|
||||
this.boundingBox = new AxisAlignedBB( 0.25f, 0.0f, 0.25f, 0.75f, 0.5f, 0.75f );
|
||||
this.setFullSize( this.setOpaque( false ) );
|
||||
|
||||
this.setLightOpacity( 2 );
|
||||
this.setFullSize( false );
|
||||
this.setOpaque( false );
|
||||
|
||||
this.setSoundType( SoundType.GROUND );
|
||||
this.setHardness( 0F );
|
||||
|
||||
// TODO: 1.11
|
||||
// EntityRegistry.registerModEntity( EntityTinyTNTPrimed.class, "EntityTinyTNTPrimed", EntityIds.get(
|
||||
// EntityTinyTNTPrimed.class ), AppEng.instance(), 16, 4, true );
|
||||
EntityRegistry.registerModEntity( new ResourceLocation( AppEng.MOD_ID, EntityTinyTNTPrimed.class.getName() ), EntityTinyTNTPrimed.class,
|
||||
"EntityTinyTNTPrimed", EntityIds.get( EntityTinyTNTPrimed.class ), AppEng.instance(), 16, 4, true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube( IBlockState state )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -101,7 +101,6 @@ public class BlockCableBus extends AEBaseTileBlock
|
||||
// this will actually be overwritten later through setupTile and the
|
||||
// combined layers
|
||||
this.setTileEntity( TileCableBus.class );
|
||||
this.useNeighborBrightness = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -47,9 +47,9 @@ 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;
|
||||
private static final double AABB_OFFSET_BOTTOM = 0.00;
|
||||
private static final double AABB_OFFSET_SIDES = 0.06;
|
||||
private static final double AABB_OFFSET_TOP = 0.125;
|
||||
|
||||
public enum SkyChestType
|
||||
{
|
||||
@@ -111,18 +111,18 @@ public class BlockSkyChest extends AEBaseTileBlock implements ICustomCollision
|
||||
o = sk.getUp();
|
||||
}
|
||||
|
||||
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 offsetX = o.getFrontOffsetX() == 0 ? AABB_OFFSET_SIDES : 0.0;
|
||||
final double offsetY = o.getFrontOffsetY() == 0 ? AABB_OFFSET_SIDES : 0.0;
|
||||
final double offsetZ = o.getFrontOffsetZ() == 0 ? AABB_OFFSET_SIDES : 0.0;
|
||||
|
||||
// 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 );
|
||||
// for x/z top and bottom is swapped
|
||||
final double minX = Math.max( 0.0, offsetX + ( o.getFrontOffsetX() < 0 ? AABB_OFFSET_BOTTOM : ( o.getFrontOffsetX() * AABB_OFFSET_TOP ) ) );
|
||||
final double minY = Math.max( 0.0, offsetY + ( o.getFrontOffsetY() < 0 ? AABB_OFFSET_TOP : ( o.getFrontOffsetY() * AABB_OFFSET_BOTTOM ) ) );
|
||||
final double minZ = Math.max( 0.0, offsetZ + ( o.getFrontOffsetZ() < 0 ? AABB_OFFSET_BOTTOM : ( o.getFrontOffsetZ() * AABB_OFFSET_TOP ) ) );
|
||||
|
||||
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 );
|
||||
final double maxX = Math.min( 1.0, 1.0 - offsetX - ( o.getFrontOffsetX() < 0 ? AABB_OFFSET_TOP : ( o.getFrontOffsetX() * AABB_OFFSET_BOTTOM ) ) );
|
||||
final double maxY = Math.min( 1.0, 1.0 - offsetY - ( o.getFrontOffsetY() < 0 ? AABB_OFFSET_BOTTOM : ( o.getFrontOffsetY() * AABB_OFFSET_TOP ) ) );
|
||||
final double maxZ = Math.min( 1.0, 1.0 - offsetZ - ( o.getFrontOffsetZ() < 0 ? AABB_OFFSET_TOP : ( o.getFrontOffsetZ() * AABB_OFFSET_BOTTOM ) ) );
|
||||
|
||||
return new AxisAlignedBB( minX, minY, minZ, maxX, maxY, maxZ );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.bootstrap;
|
||||
|
||||
|
||||
import net.minecraft.advancements.ICriterionInstance;
|
||||
import net.minecraft.advancements.ICriterionTrigger;
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ICriterionTriggerRegistry
|
||||
{
|
||||
void register( ICriterionTrigger<? extends ICriterionInstance> trigger );
|
||||
}
|
||||
@@ -23,7 +23,6 @@ import java.text.NumberFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -43,70 +42,17 @@ public abstract class AEBaseMEGui extends AEBaseGui
|
||||
super( container );
|
||||
}
|
||||
|
||||
public List<String> handleItemTooltip( final ItemStack stack, final int mouseX, final int mouseY, final List<String> currentToolTip )
|
||||
{
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
final Slot s = this.getSlot( mouseX, mouseY );
|
||||
if( s instanceof SlotME )
|
||||
{
|
||||
final int BigNumber = AEConfig.instance().useTerminalUseLargeFont() ? 999 : 9999;
|
||||
|
||||
IAEItemStack myStack = null;
|
||||
|
||||
try
|
||||
{
|
||||
final SlotME theSlotField = (SlotME) s;
|
||||
myStack = theSlotField.getAEStack();
|
||||
}
|
||||
catch( final Throwable ignore )
|
||||
{
|
||||
}
|
||||
|
||||
if( myStack != null )
|
||||
{
|
||||
if( myStack.getStackSize() > BigNumber || ( myStack.getStackSize() > 1 && stack.isItemDamaged() ) )
|
||||
{
|
||||
final String local = ButtonToolTips.ItemsStored.getLocal();
|
||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( myStack.getStackSize() );
|
||||
final String format = String.format( local, formattedAmount );
|
||||
|
||||
currentToolTip.add( TextFormatting.GRAY + format );
|
||||
}
|
||||
|
||||
if( myStack.getCountRequestable() > 0 )
|
||||
{
|
||||
final String local = ButtonToolTips.ItemsRequestable.getLocal();
|
||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( myStack.getCountRequestable() );
|
||||
final String format = String.format( local, formattedAmount );
|
||||
|
||||
currentToolTip.add( TextFormatting.GRAY + format );
|
||||
}
|
||||
}
|
||||
else if( stack.getCount() > BigNumber || ( stack.getCount() > 1 && stack.isItemDamaged() ) )
|
||||
{
|
||||
final String local = ButtonToolTips.ItemsStored.getLocal();
|
||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( stack.getCount() );
|
||||
final String format = String.format( local, formattedAmount );
|
||||
|
||||
currentToolTip.add( TextFormatting.GRAY + format );
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentToolTip;
|
||||
}
|
||||
|
||||
// Vanilla version...
|
||||
// protected void drawItemStackTooltip(ItemStack stack, int x, int y)
|
||||
@Override
|
||||
protected void renderToolTip( final ItemStack stack, final int x, final int y )
|
||||
{
|
||||
final Slot s = this.getSlot( x, y );
|
||||
|
||||
if( s instanceof SlotME && !stack.isEmpty() )
|
||||
{
|
||||
final int BigNumber = AEConfig.instance().useTerminalUseLargeFont() ? 999 : 9999;
|
||||
final int bigNumber = AEConfig.instance().useTerminalUseLargeFont() ? 999 : 9999;
|
||||
|
||||
IAEItemStack myStack = null;
|
||||
final List<String> currentToolTip = this.getItemToolTip( stack );
|
||||
|
||||
try
|
||||
{
|
||||
@@ -117,33 +63,44 @@ public abstract class AEBaseMEGui extends AEBaseGui
|
||||
{
|
||||
}
|
||||
|
||||
ITooltipFlag.TooltipFlags tooltipFlag = this.mc.gameSettings.advancedItemTooltips ? ITooltipFlag.TooltipFlags.ADVANCED : ITooltipFlag.TooltipFlags.NORMAL;
|
||||
if( myStack != null )
|
||||
{
|
||||
final List<String> currentToolTip = stack.getTooltip( this.mc.player, tooltipFlag );
|
||||
|
||||
if( myStack.getStackSize() > BigNumber || ( myStack.getStackSize() > 1 && stack.isItemDamaged() ) )
|
||||
if( myStack.getStackSize() > bigNumber || ( myStack.getStackSize() > 1 && stack.isItemDamaged() ) )
|
||||
{
|
||||
currentToolTip.add( "Items Stored: " + NumberFormat.getNumberInstance( Locale.US ).format( myStack.getStackSize() ) );
|
||||
final String local = ButtonToolTips.ItemsStored.getLocal();
|
||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( myStack.getStackSize() );
|
||||
final String format = String.format( local, formattedAmount );
|
||||
|
||||
currentToolTip.add( TextFormatting.GRAY + format );
|
||||
}
|
||||
|
||||
if( myStack.getCountRequestable() > 0 )
|
||||
{
|
||||
currentToolTip.add( "Items Requestable: " + NumberFormat.getNumberInstance( Locale.US ).format( myStack.getCountRequestable() ) );
|
||||
final String local = ButtonToolTips.ItemsRequestable.getLocal();
|
||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( myStack.getCountRequestable() );
|
||||
final String format = String.format( local, formattedAmount );
|
||||
|
||||
currentToolTip.add( format );
|
||||
}
|
||||
|
||||
this.drawTooltip( x, y, currentToolTip );
|
||||
this.drawHoveringText( currentToolTip, x, y, this.fontRenderer );
|
||||
|
||||
return;
|
||||
}
|
||||
else if( stack.getCount() > BigNumber )
|
||||
else if( stack.getCount() > bigNumber )
|
||||
{
|
||||
List<String> var4 = stack.getTooltip( this.mc.player, tooltipFlag );
|
||||
var4.add( "Items Stored: " + NumberFormat.getNumberInstance( Locale.US ).format( stack.getCount() ) );
|
||||
this.drawTooltip( x, y, var4 );
|
||||
final String local = ButtonToolTips.ItemsStored.getLocal();
|
||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( stack.getCount() );
|
||||
final String format = String.format( local, formattedAmount );
|
||||
|
||||
currentToolTip.add( TextFormatting.GRAY + format );
|
||||
|
||||
this.drawHoveringText( currentToolTip, x, y, this.fontRenderer );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.renderToolTip( stack, x, y );
|
||||
// super.drawItemStackTooltip( stack, x, y );
|
||||
}
|
||||
}
|
||||
@@ -319,7 +319,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
|
||||
final Enum searchModeSetting = AEConfig.instance().getConfigManager().getSetting( Settings.SEARCH_MODE );
|
||||
|
||||
final boolean isAutoFocus = SearchBoxMode.AUTOSEARCH == searchModeSetting || SearchBoxMode.JEI_AUTOSEARCH == searchModeSetting || SearchBoxMode.AUTOSEARCH_KEEP == searchModeSetting || SearchBoxMode.JEI_AUTOSEARCH_KEEP == searchModeSetting;
|
||||
final boolean isManualFocus = SearchBoxMode.MANUAL_SEARCH == searchModeSetting || SearchBoxMode.JEI_MANUAL_SEARCH == searchModeSetting || SearchBoxMode.MANUAL_SEARCH_KEEP == searchModeSetting || SearchBoxMode.JEI_MANUAL_SEARCH_KEEP == searchModeSetting;
|
||||
final boolean isManualFocus = SearchBoxMode.MANUAL_SEARCH == searchModeSetting || SearchBoxMode.JEI_MANUAL_SEARCH == searchModeSetting || SearchBoxMode.MANUAL_SEARCH_KEEP == searchModeSetting || SearchBoxMode.JEI_MANUAL_SEARCH_KEEP == searchModeSetting;
|
||||
final boolean isKeepFilter = SearchBoxMode.AUTOSEARCH_KEEP == searchModeSetting || SearchBoxMode.JEI_AUTOSEARCH_KEEP == searchModeSetting || SearchBoxMode.MANUAL_SEARCH_KEEP == searchModeSetting || SearchBoxMode.JEI_MANUAL_SEARCH_KEEP == searchModeSetting;
|
||||
final boolean isJEIEnabled = SearchBoxMode.JEI_AUTOSEARCH == searchModeSetting || SearchBoxMode.JEI_MANUAL_SEARCH == searchModeSetting;
|
||||
|
||||
|
||||
@@ -237,10 +237,11 @@ public class GuiNetworkStatus extends AEBaseGui implements ISortSource
|
||||
this.getScrollBar().setRange( 0, ( size + 4 ) / 5 - this.rows, 1 );
|
||||
}
|
||||
|
||||
// Vanilla version...
|
||||
protected void drawItemStackTooltip( final ItemStack stack, final int x, final int y )
|
||||
@Override
|
||||
protected void renderToolTip( final ItemStack stack, final int x, final int y )
|
||||
{
|
||||
final Slot s = this.getSlot( x, y );
|
||||
|
||||
if( s instanceof SlotME && stack != null )
|
||||
{
|
||||
IAEItemStack myStack = null;
|
||||
@@ -270,7 +271,8 @@ public class GuiNetworkStatus extends AEBaseGui implements ISortSource
|
||||
this.drawTooltip( x, y, currentToolTip );
|
||||
}
|
||||
}
|
||||
// super.drawItemStackTooltip( stack, x, y );
|
||||
|
||||
super.renderToolTip( stack, x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -92,7 +92,7 @@ public class GuiSpatialIOPort extends AEBaseGui
|
||||
}
|
||||
else
|
||||
{
|
||||
this.fontRenderer.drawString( GuiText.SCSSize.getLocal() + ": " + GuiText.SCSSInvalid.getLocal(), 13, 93, 4210752 );
|
||||
this.fontRenderer.drawString( GuiText.SCSSize.getLocal() + ": " + GuiText.SCSInvalid.getLocal(), 13, 93, 4210752 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.client.render;
|
||||
|
||||
|
||||
import javax.vecmath.Matrix4f;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
|
||||
|
||||
public abstract class DelegateBakedModel implements IBakedModel
|
||||
{
|
||||
private IBakedModel baseModel;
|
||||
|
||||
protected DelegateBakedModel( IBakedModel base )
|
||||
{
|
||||
this.baseModel = base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<? extends IBakedModel, Matrix4f> handlePerspective( ItemCameraTransforms.TransformType type )
|
||||
{
|
||||
Pair<? extends IBakedModel, Matrix4f> pair = this.baseModel.handlePerspective( type );
|
||||
return Pair.of( this, pair.getValue() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return this.baseModel.getParticleTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return this.baseModel.getItemCameraTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return this.baseModel.isAmbientOcclusion();
|
||||
}
|
||||
|
||||
public IBakedModel getBaseModel()
|
||||
{
|
||||
return this.baseModel;
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,7 @@ import javax.annotation.Nullable;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -44,16 +42,13 @@ import appeng.items.parts.ItemFacade;
|
||||
* on the item stack.
|
||||
* A custom Item Override List is used to accomplish this.
|
||||
*/
|
||||
public class FacadeDispatcherBakedModel implements IBakedModel
|
||||
public class FacadeDispatcherBakedModel extends DelegateBakedModel
|
||||
{
|
||||
|
||||
private final IBakedModel baseModel;
|
||||
|
||||
private final VertexFormat format;
|
||||
|
||||
public FacadeDispatcherBakedModel( IBakedModel baseModel, VertexFormat format )
|
||||
{
|
||||
this.baseModel = baseModel;
|
||||
super( baseModel );
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@@ -64,16 +59,10 @@ public class FacadeDispatcherBakedModel implements IBakedModel
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return this.baseModel.isAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return this.baseModel.isGui3d();
|
||||
return this.getBaseModel().isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,18 +71,6 @@ public class FacadeDispatcherBakedModel implements IBakedModel
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return this.baseModel.getParticleTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return this.baseModel.getItemCameraTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
@@ -112,7 +89,8 @@ public class FacadeDispatcherBakedModel implements IBakedModel
|
||||
IBlockState state = itemFacade.getTextureBlockState( stack );
|
||||
ItemStack textureItem = itemFacade.getTextureItem( stack );
|
||||
|
||||
return new FacadeWithBlockBakedModel( FacadeDispatcherBakedModel.this.baseModel, state, textureItem, FacadeDispatcherBakedModel.this.format );
|
||||
return new FacadeWithBlockBakedModel( FacadeDispatcherBakedModel.this
|
||||
.getBaseModel(), state, textureItem, FacadeDispatcherBakedModel.this.format );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
|
||||
import appeng.core.AppEng;
|
||||
|
||||
@@ -41,10 +40,27 @@ import appeng.core.AppEng;
|
||||
*/
|
||||
public class FacadeItemModel implements IModel
|
||||
{
|
||||
|
||||
// We use this to get the default item transforms and make our lives easier
|
||||
private static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "item/facade_base" );
|
||||
|
||||
private IModel baseModel = null;
|
||||
|
||||
private IModel getBaseModel()
|
||||
{
|
||||
if( this.baseModel == null )
|
||||
{
|
||||
try
|
||||
{
|
||||
baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
return this.baseModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies()
|
||||
{
|
||||
@@ -60,17 +76,7 @@ public class FacadeItemModel implements IModel
|
||||
@Override
|
||||
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||
{
|
||||
IModel baseModel;
|
||||
try
|
||||
{
|
||||
baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
|
||||
IBakedModel bakedBaseModel = baseModel.bake( state, format, bakedTextureGetter );
|
||||
IBakedModel bakedBaseModel = this.getBaseModel().bake( state, format, bakedTextureGetter );
|
||||
|
||||
return new FacadeDispatcherBakedModel( bakedBaseModel, format );
|
||||
}
|
||||
@@ -78,6 +84,6 @@ public class FacadeItemModel implements IModel
|
||||
@Override
|
||||
public IModelState getDefaultState()
|
||||
{
|
||||
return TRSRTransformation.identity();
|
||||
return getBaseModel().getDefaultState();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@ import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
@@ -44,11 +42,8 @@ import appeng.client.render.cablebus.FacadeBuilder;
|
||||
* This is the actual baked model that will combine the north face of a given block state
|
||||
* with the base facade item model to achieve what is then actually rendered on screen.
|
||||
*/
|
||||
public class FacadeWithBlockBakedModel implements IBakedModel
|
||||
public class FacadeWithBlockBakedModel extends DelegateBakedModel
|
||||
{
|
||||
|
||||
private final IBakedModel baseModel;
|
||||
|
||||
private final IBlockState blockState;
|
||||
|
||||
private final IBakedModel textureModel;
|
||||
@@ -59,7 +54,7 @@ public class FacadeWithBlockBakedModel implements IBakedModel
|
||||
|
||||
public FacadeWithBlockBakedModel( IBakedModel baseModel, IBlockState blockState, ItemStack textureItem, VertexFormat format )
|
||||
{
|
||||
this.baseModel = baseModel;
|
||||
super( baseModel );
|
||||
this.blockState = blockState;
|
||||
this.textureItem = textureItem;
|
||||
this.textureModel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState( blockState );
|
||||
@@ -88,13 +83,7 @@ public class FacadeWithBlockBakedModel implements IBakedModel
|
||||
}
|
||||
}
|
||||
|
||||
return this.baseModel.getQuads( state, side, rand );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return this.baseModel.isAmbientOcclusion();
|
||||
return this.getBaseModel().getQuads( state, side, rand );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,18 +98,6 @@ public class FacadeWithBlockBakedModel implements IBakedModel
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return this.baseModel.getParticleTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return this.baseModel.getItemCameraTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ package appeng.client.render.cablebus;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -52,6 +53,8 @@ import appeng.block.networking.BlockCableBus;
|
||||
public class CableBusBakedModel implements IBakedModel
|
||||
{
|
||||
|
||||
private static final Map<CableBusRenderState, List<BakedQuad>> CABLE_MODEL_CACHE = new HashMap<>();
|
||||
|
||||
private final CableBuilder cableBuilder;
|
||||
|
||||
private final FacadeBuilder facadeBuilder;
|
||||
@@ -88,8 +91,15 @@ public class CableBusBakedModel implements IBakedModel
|
||||
// translucent facades further down below.
|
||||
if( layer == BlockRenderLayer.CUTOUT )
|
||||
{
|
||||
|
||||
// First, handle the cable at the center of the cable bus
|
||||
this.addCableQuads( renderState, quads );
|
||||
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent( renderState, k ->
|
||||
{
|
||||
final List<BakedQuad> model = new ArrayList<>();
|
||||
this.addCableQuads( renderState, model );
|
||||
return model;
|
||||
} );
|
||||
quads.addAll( cableModel );
|
||||
|
||||
// Then handle attachments
|
||||
for( EnumFacing facing : EnumFacing.values() )
|
||||
@@ -308,10 +318,8 @@ 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,
|
||||
// so we don't get ugly missing texture break particles.
|
||||
// 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( this.textureMap.getMissingSprite() != particleTexture )
|
||||
{
|
||||
result.add( particleTexture );
|
||||
@@ -336,7 +344,7 @@ public class CableBusBakedModel implements IBakedModel
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
@@ -153,4 +154,43 @@ public class CableBusRenderState
|
||||
return this.boundingBoxes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ( ( this.attachmentConnections == null ) ? 0 : this.attachmentConnections.hashCode() );
|
||||
result = prime * result + ( ( this.cableBusAdjacent == null ) ? 0 : this.cableBusAdjacent.hashCode() );
|
||||
result = prime * result + ( ( this.cableColor == null ) ? 0 : this.cableColor.hashCode() );
|
||||
result = prime * result + ( ( this.cableType == null ) ? 0 : this.cableType.hashCode() );
|
||||
result = prime * result + ( ( this.channelsOnSide == null ) ? 0 : this.channelsOnSide.hashCode() );
|
||||
result = prime * result + ( ( this.connectionTypes == null ) ? 0 : this.connectionTypes.hashCode() );
|
||||
result = prime * result + ( ( this.coreType == null ) ? 0 : this.coreType.hashCode() );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object obj )
|
||||
{
|
||||
if( this == obj )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if( obj == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( getClass() != obj.getClass() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final CableBusRenderState other = (CableBusRenderState) obj;
|
||||
|
||||
return this.cableColor == other.cableColor && this.cableType == other.cableType && this.coreType == other.coreType && Objects
|
||||
.equals( this.attachmentConnections, other.attachmentConnections ) && Objects.equals( this.cableBusAdjacent,
|
||||
other.cableBusAdjacent ) && Objects.equals( this.channelsOnSide, other.channelsOnSide ) && Objects.equals( this.connectionTypes,
|
||||
other.connectionTypes );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ public class CubeBuilder
|
||||
|
||||
private int color = 0xFFFFFFFF;
|
||||
|
||||
private boolean useStandardUV = false;
|
||||
|
||||
private boolean renderFullBright;
|
||||
|
||||
public CubeBuilder( VertexFormat format, List<BakedQuad> output )
|
||||
@@ -142,7 +144,9 @@ public class CubeBuilder
|
||||
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder( this.format );
|
||||
builder.setTexture( texture );
|
||||
builder.setQuadOrientation( face );
|
||||
|
||||
builder.setQuadTint( -1 );
|
||||
builder.setApplyDiffuseLighting( true );
|
||||
|
||||
UvVector uv = new UvVector();
|
||||
|
||||
// The user might have set specific UV coordinates for this face
|
||||
@@ -154,6 +158,10 @@ public class CubeBuilder
|
||||
uv.u2 = texture.getInterpolatedU( customUv.z );
|
||||
uv.v2 = texture.getInterpolatedV( customUv.w );
|
||||
}
|
||||
else if( this.useStandardUV )
|
||||
{
|
||||
uv = this.getStandardUv( face, texture, x1, y1, z1, x2, y2, z2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
uv = this.getDefaultUv( face, texture, x1, y1, z1, x2, y2, z2 );
|
||||
@@ -199,8 +207,7 @@ public class CubeBuilder
|
||||
break;
|
||||
}
|
||||
|
||||
int[] vertexData = builder.build().getVertexData();
|
||||
this.output.add( new BakedQuad( vertexData, -1, face, texture, true, this.format ) );
|
||||
this.output.add( builder.build() );
|
||||
}
|
||||
|
||||
private UvVector getDefaultUv( EnumFacing face, TextureAtlasSprite texture, float x1, float y1, float z1, float x2, float y2, float z2 )
|
||||
@@ -251,6 +258,51 @@ public class CubeBuilder
|
||||
return uv;
|
||||
}
|
||||
|
||||
private UvVector getStandardUv( EnumFacing face, TextureAtlasSprite texture, float x1, float y1, float z1, float x2, float y2, float z2 )
|
||||
{
|
||||
UvVector uv = new UvVector();
|
||||
switch( face )
|
||||
{
|
||||
case DOWN:
|
||||
uv.u1 = texture.getInterpolatedU( x1 * 16 );
|
||||
uv.v1 = texture.getInterpolatedV( 16 - z1 * 16 );
|
||||
uv.u2 = texture.getInterpolatedU( x2 * 16 );
|
||||
uv.v2 = texture.getInterpolatedV( 16 - z2 * 16 );
|
||||
break;
|
||||
case UP:
|
||||
uv.u1 = texture.getInterpolatedU( x1 * 16 );
|
||||
uv.v1 = texture.getInterpolatedV( z1 * 16 );
|
||||
uv.u2 = texture.getInterpolatedU( x2 * 16 );
|
||||
uv.v2 = texture.getInterpolatedV( z2 * 16 );
|
||||
break;
|
||||
case NORTH:
|
||||
uv.u1 = texture.getInterpolatedU( 16 - x1 * 16 );
|
||||
uv.v1 = texture.getInterpolatedV( 16 - y1 * 16 );
|
||||
uv.u2 = texture.getInterpolatedU( 16 - x2 * 16 );
|
||||
uv.v2 = texture.getInterpolatedV( 16 - y2 * 16 );
|
||||
break;
|
||||
case SOUTH:
|
||||
uv.u1 = texture.getInterpolatedU( x1 * 16 );
|
||||
uv.v1 = texture.getInterpolatedV( 16 - y1 * 16 );
|
||||
uv.u2 = texture.getInterpolatedU( x2 * 16 );
|
||||
uv.v2 = texture.getInterpolatedV( 16 - y2 * 16 );
|
||||
break;
|
||||
case WEST:
|
||||
uv.u1 = texture.getInterpolatedU( z1 * 16 );
|
||||
uv.v1 = texture.getInterpolatedV( 16 - y1 * 16 );
|
||||
uv.u2 = texture.getInterpolatedU( z2 * 16 );
|
||||
uv.v2 = texture.getInterpolatedV( 16 - y2 * 16 );
|
||||
break;
|
||||
case EAST:
|
||||
uv.u1 = texture.getInterpolatedU( 16 - z2 * 16 );
|
||||
uv.v1 = texture.getInterpolatedV( 16 - y1 * 16 );
|
||||
uv.u2 = texture.getInterpolatedU( 16 - z1 * 16 );
|
||||
uv.v2 = texture.getInterpolatedV( 16 - y2 * 16 );
|
||||
break;
|
||||
}
|
||||
return uv;
|
||||
}
|
||||
|
||||
// uv.u1, uv.v1
|
||||
private void putVertexTL( UnpackedBakedQuad.Builder builder, EnumFacing face, float x, float y, float z, UvVector uv )
|
||||
{
|
||||
@@ -484,6 +536,15 @@ public class CubeBuilder
|
||||
this.uvRotations[facing.ordinal()] = (byte) rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* CubeBuilder uses UV optimized for cables by default.
|
||||
* This switches to standard UV coordinates.
|
||||
*/
|
||||
public void useStandardUV()
|
||||
{
|
||||
this.useStandardUV = true;
|
||||
}
|
||||
|
||||
public List<BakedQuad> getOutput()
|
||||
{
|
||||
return this.output;
|
||||
|
||||
@@ -175,6 +175,7 @@ public class FacadeBuilder
|
||||
|
||||
// Reset to no color multiplicator
|
||||
builder.setColorRGB( 0xFFFFFF );
|
||||
builder.useStandardUV();
|
||||
|
||||
// We only render the stilt if we don't intersect with any part directly, and if there's no part on our side
|
||||
if( renderStilt && busBounds == null && layer == BlockRenderLayer.CUTOUT )
|
||||
@@ -438,22 +439,22 @@ public class FacadeBuilder
|
||||
|
||||
private static AxisAlignedBB getFacadeBox( EnumFacing side, boolean thinFacades )
|
||||
{
|
||||
int thickness = thinFacades ? 1 : 2;
|
||||
double thickness = ( thinFacades ? 1 : 2 ) / 16.0;
|
||||
|
||||
switch( side )
|
||||
{
|
||||
case DOWN:
|
||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, ( thickness ) / 16.0, 1.0 );
|
||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, thickness, 1.0 );
|
||||
case EAST:
|
||||
return new AxisAlignedBB( ( 16.0 - thickness ) / 16.0, 0.0, 0.0, 1.0, 1.0, 1.0 );
|
||||
return new AxisAlignedBB( 1.0 - thickness, 0.0, 0.0, 1.0, 1.0, 1.0 );
|
||||
case NORTH:
|
||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, ( thickness ) / 16.0 );
|
||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, thickness );
|
||||
case SOUTH:
|
||||
return new AxisAlignedBB( 0.0, 0.0, ( 16.0 - thickness ) / 16.0, 1.0, 1.0, 1.0 );
|
||||
return new AxisAlignedBB( 0.0, 0.0, 1.0 - thickness, 1.0, 1.0, 1.0 );
|
||||
case UP:
|
||||
return new AxisAlignedBB( 0.0, ( 16.0 - thickness ) / 16.0, 0.0, 1.0, 1.0, 1.0 );
|
||||
return new AxisAlignedBB( 0.0, 1.0 - thickness, 0.0, 1.0, 1.0, 1.0 );
|
||||
case WEST:
|
||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, ( thickness ) / 16.0, 1.0, 1.0 );
|
||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, thickness, 1.0, 1.0 );
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unsupported face: " + side );
|
||||
}
|
||||
|
||||
@@ -19,14 +19,11 @@
|
||||
package appeng.container;
|
||||
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -37,8 +34,6 @@ import net.minecraft.inventory.IContainerListener;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.PlayerInvWrapper;
|
||||
@@ -73,7 +68,7 @@ import appeng.container.slot.SlotPlayerInv;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketInventoryAction;
|
||||
import appeng.core.sync.packets.PacketPartialItem;
|
||||
import appeng.core.sync.packets.PacketTargetItemStack;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
import appeng.helpers.InventoryAction;
|
||||
@@ -93,7 +88,6 @@ public abstract class AEBaseContainer extends Container
|
||||
private final TileEntity tileEntity;
|
||||
private final IPart part;
|
||||
private final IGuiItemObject obj;
|
||||
private final List<PacketPartialItem> dataChunks = new LinkedList<>();
|
||||
private final HashMap<Integer, SyncData> syncData = new HashMap<>();
|
||||
private boolean isContainerValid = true;
|
||||
private String customName;
|
||||
@@ -175,47 +169,6 @@ public abstract class AEBaseContainer extends Container
|
||||
this.prepareSync();
|
||||
}
|
||||
|
||||
public void postPartial( final PacketPartialItem packetPartialItem )
|
||||
{
|
||||
this.dataChunks.add( packetPartialItem );
|
||||
if( packetPartialItem.getPageCount() == this.dataChunks.size() )
|
||||
{
|
||||
this.parsePartials();
|
||||
}
|
||||
}
|
||||
|
||||
private void parsePartials()
|
||||
{
|
||||
int total = 0;
|
||||
for( final PacketPartialItem ppi : this.dataChunks )
|
||||
{
|
||||
total += ppi.getSize();
|
||||
}
|
||||
|
||||
final byte[] buffer = new byte[total];
|
||||
int cursor = 0;
|
||||
|
||||
for( final PacketPartialItem ppi : this.dataChunks )
|
||||
{
|
||||
cursor = ppi.write( buffer, cursor );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final NBTTagCompound data = CompressedStreamTools.readCompressed( new ByteArrayInputStream( buffer ) );
|
||||
if( data != null )
|
||||
{
|
||||
this.setTargetStack( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( new ItemStack( data ) ) );
|
||||
}
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
|
||||
this.dataChunks.clear();
|
||||
}
|
||||
|
||||
public IAEItemStack getTargetStack()
|
||||
{
|
||||
return this.clientRequestedTargetItem;
|
||||
@@ -235,47 +188,7 @@ public abstract class AEBaseContainer extends Container
|
||||
return;
|
||||
}
|
||||
|
||||
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
final NBTTagCompound item = new NBTTagCompound();
|
||||
|
||||
if( stack != null )
|
||||
{
|
||||
stack.writeToNBT( item );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CompressedStreamTools.writeCompressed( item, stream );
|
||||
|
||||
final int maxChunkSize = 30000;
|
||||
final List<byte[]> miniPackets = new LinkedList<>();
|
||||
|
||||
final byte[] data = stream.toByteArray();
|
||||
|
||||
final ByteArrayInputStream bis = new ByteArrayInputStream( data, 0, stream.size() );
|
||||
while( bis.available() > 0 )
|
||||
{
|
||||
final int nextBLock = bis.available() > maxChunkSize ? maxChunkSize : bis.available();
|
||||
final byte[] nextSegment = new byte[nextBLock];
|
||||
bis.read( nextSegment );
|
||||
miniPackets.add( nextSegment );
|
||||
}
|
||||
bis.close();
|
||||
stream.close();
|
||||
|
||||
int page = 0;
|
||||
for( final byte[] packet : miniPackets )
|
||||
{
|
||||
final PacketPartialItem ppi = new PacketPartialItem( page, miniPackets.size(), packet );
|
||||
page++;
|
||||
NetworkHandler.instance().sendToServer( ppi );
|
||||
}
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
return;
|
||||
}
|
||||
NetworkHandler.instance().sendToServer( new PacketTargetItemStack( (AEItemStack) stack ) );
|
||||
}
|
||||
|
||||
this.clientRequestedTargetItem = stack == null ? null : stack.copy();
|
||||
|
||||
@@ -120,28 +120,23 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres
|
||||
|
||||
if( s == this.middle )
|
||||
{
|
||||
for( final ItemStack optional : AEApi.instance().registries().inscriber().getOptionals() )
|
||||
IItemDefinition press = AEApi.instance().definitions().materials().namePress();
|
||||
if( press.isSameAs( top ) || press.isSameAs( bot ) )
|
||||
{
|
||||
if( Platform.itemComparisons().isSameItem( optional, is ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return !press.isSameAs( is );
|
||||
}
|
||||
|
||||
boolean matches = false;
|
||||
boolean found = false;
|
||||
|
||||
for( final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes() )
|
||||
{
|
||||
final boolean matchA = ( top.isEmpty() && !recipe.getTopOptional().isPresent() ) || ( Platform.itemComparisons().isSameItem( top,
|
||||
recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) ) && // and...
|
||||
( ( bot.isEmpty() && !recipe.getBottomOptional().isPresent() ) || ( Platform.itemComparisons().isSameItem( bot,
|
||||
recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) ) );
|
||||
|
||||
final boolean matchB = ( bot.isEmpty() && !recipe.getTopOptional().isPresent() ) || ( Platform.itemComparisons().isSameItem( bot,
|
||||
recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) ) && // and...
|
||||
( ( top.isEmpty() && !recipe.getBottomOptional().isPresent() ) || ( Platform.itemComparisons().isSameItem( top,
|
||||
recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) ) );
|
||||
final boolean matchA = !top
|
||||
.isEmpty() && ( Platform.itemComparisons().isSameItem( top, recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) || Platform
|
||||
.itemComparisons()
|
||||
.isSameItem( top, recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) );
|
||||
final boolean matchB = !bot
|
||||
.isEmpty() && ( Platform.itemComparisons().isSameItem( bot, recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) || Platform
|
||||
.itemComparisons()
|
||||
.isSameItem( bot, recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) );
|
||||
|
||||
if( matchA || matchB )
|
||||
{
|
||||
@@ -150,21 +145,19 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres
|
||||
{
|
||||
if( Platform.itemComparisons().isSameItem( is, option ) )
|
||||
{
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( matches && !found )
|
||||
if( matches )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( s == this.top && !bot.isEmpty() ) || ( s == this.bottom && !top.isEmpty() ) )
|
||||
else if( ( s == this.top && !bot.isEmpty() ) || ( s == this.bottom && !top.isEmpty() ) )
|
||||
{
|
||||
ItemStack otherSlot = ItemStack.EMPTY;
|
||||
ItemStack otherSlot;
|
||||
if( s == this.top )
|
||||
{
|
||||
otherSlot = this.bottom.getStack();
|
||||
@@ -182,28 +175,24 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres
|
||||
}
|
||||
|
||||
// everything else
|
||||
boolean isValid = false;
|
||||
for( final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes() )
|
||||
{
|
||||
if( Platform.itemComparisons().isSameItem( recipe.getTopOptional().orElse( ItemStack.EMPTY ), otherSlot ) )
|
||||
boolean isValid = false;
|
||||
if( Platform.itemComparisons().isSameItem( otherSlot, recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) )
|
||||
{
|
||||
isValid = Platform.itemComparisons().isSameItem( is, recipe.getBottomOptional().orElse( ItemStack.EMPTY ) );
|
||||
}
|
||||
else if( Platform.itemComparisons().isSameItem( recipe.getBottomOptional().orElse( ItemStack.EMPTY ), otherSlot ) )
|
||||
else if( Platform.itemComparisons().isSameItem( otherSlot, recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) )
|
||||
{
|
||||
isValid = Platform.itemComparisons().isSameItem( is, recipe.getTopOptional().orElse( ItemStack.EMPTY ) );
|
||||
}
|
||||
|
||||
if( isValid )
|
||||
{
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !isValid )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -172,7 +172,7 @@ public class SlotRestrictedInput extends AppEngSlot
|
||||
|
||||
for( final ItemStack optional : AEApi.instance().registries().inscriber().getOptionals() )
|
||||
{
|
||||
if( Platform.itemComparisons().isSameItem( optional, i ) )
|
||||
if( Platform.itemComparisons().isSameItem( i, optional ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import appeng.core.crash.CrashInfo;
|
||||
import appeng.core.crash.IntegrationCrashEnhancement;
|
||||
import appeng.core.crash.ModCrashEnhancement;
|
||||
import appeng.core.features.AEFeature;
|
||||
import appeng.core.stats.AdvancementTriggers;
|
||||
import appeng.core.sync.GuiBridge;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
@@ -141,6 +142,11 @@ public final class AppEng
|
||||
return this.registration.storageDimensionID;
|
||||
}
|
||||
|
||||
public AdvancementTriggers getAdvancementTriggers()
|
||||
{
|
||||
return this.registration.advancementTriggers;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
private void preInit( final FMLPreInitializationEvent event )
|
||||
{
|
||||
@@ -183,6 +189,8 @@ public final class AppEng
|
||||
AppEng.proxy.preinit();
|
||||
}
|
||||
|
||||
IntegrationRegistry.INSTANCE.preInit();
|
||||
|
||||
if( versionCheckerConfig.isVersionCheckingEnabled() )
|
||||
{
|
||||
final VersionChecker versionChecker = new VersionChecker( versionCheckerConfig );
|
||||
|
||||
@@ -20,6 +20,8 @@ package appeng.core;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -27,6 +29,9 @@ import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.advancements.ICriterionInstance;
|
||||
import net.minecraft.advancements.ICriterionTrigger;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.ItemMeshDefinition;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
@@ -49,6 +54,7 @@ import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.relauncher.ReflectionHelper;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
@@ -72,6 +78,7 @@ import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.networking.ticking.ITickManager;
|
||||
import appeng.api.parts.IPartHelper;
|
||||
import appeng.api.recipes.IRecipeHandler;
|
||||
import appeng.bootstrap.ICriterionTriggerRegistry;
|
||||
import appeng.bootstrap.IModelRegistry;
|
||||
import appeng.bootstrap.components.IBlockRegistrationComponent;
|
||||
import appeng.bootstrap.components.IInitComponent;
|
||||
@@ -88,7 +95,9 @@ 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;
|
||||
import appeng.core.stats.AdvancementTriggers;
|
||||
import appeng.core.stats.PartItemPredicate;
|
||||
import appeng.core.stats.Stats;
|
||||
import appeng.core.worlddata.SpatialDimensionManager;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.items.materials.ItemMaterial;
|
||||
@@ -131,6 +140,7 @@ final class Registration
|
||||
DimensionType storageDimensionType;
|
||||
int storageDimensionID;
|
||||
Biome storageBiome;
|
||||
AdvancementTriggers advancementTriggers;
|
||||
|
||||
private File recipeDirectory;
|
||||
private CustomRecipeConfig customRecipeConfig;
|
||||
@@ -286,9 +296,9 @@ final class Registration
|
||||
registries.matterCannon().registerAmmo( ammoStack, weight );
|
||||
} );
|
||||
|
||||
final PlayerStatsRegistration registration = new PlayerStatsRegistration( MinecraftForge.EVENT_BUS, AEConfig.instance() );
|
||||
registration.registerAchievementHandlers();
|
||||
registration.registerAchievements();
|
||||
PartItemPredicate.register();
|
||||
Stats.register();
|
||||
this.advancementTriggers = new AdvancementTriggers( new CriterionTrigggerRegistry() );
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@@ -581,4 +591,29 @@ final class Registration
|
||||
}
|
||||
}
|
||||
|
||||
private static class CriterionTrigggerRegistry implements ICriterionTriggerRegistry
|
||||
{
|
||||
private Method method;
|
||||
|
||||
CriterionTrigggerRegistry()
|
||||
{
|
||||
this.method = ReflectionHelper.findMethod( CriteriaTriggers.class, "register", "func_192118_a", ICriterionTrigger.class );
|
||||
method.setAccessible( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register( ICriterionTrigger<? extends ICriterionInstance> trigger )
|
||||
{
|
||||
try
|
||||
{
|
||||
method.invoke( null, trigger );
|
||||
}
|
||||
catch( IllegalAccessException | IllegalArgumentException | InvocationTargetException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class ApiGrid implements IGridHelper
|
||||
Preconditions.checkNotNull( a );
|
||||
Preconditions.checkNotNull( b );
|
||||
|
||||
return new GridConnection( a, b, AEPartLocation.INTERNAL );
|
||||
return GridConnection.create( a, b, AEPartLocation.INTERNAL );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -160,6 +160,12 @@ public class ApiStorage implements IStorageHelper
|
||||
private static final class FluidStorageChannel implements IFluidStorageChannel
|
||||
{
|
||||
|
||||
@Override
|
||||
public int transferFactor()
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEFluidStack> createList()
|
||||
{
|
||||
@@ -195,7 +201,7 @@ public class ApiStorage implements IStorageHelper
|
||||
Preconditions.checkNotNull( request );
|
||||
Preconditions.checkNotNull( src );
|
||||
|
||||
return null;
|
||||
return Platform.poweredExtraction( energy, cell, request, src );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -206,7 +212,7 @@ public class ApiStorage implements IStorageHelper
|
||||
Preconditions.checkNotNull( input );
|
||||
Preconditions.checkNotNull( src );
|
||||
|
||||
return input;
|
||||
return Platform.poweredInsert( energy, cell, input, src );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,10 +106,12 @@ import appeng.core.features.BlockDefinition;
|
||||
import appeng.core.features.registries.PartModels;
|
||||
import appeng.debug.BlockChunkloader;
|
||||
import appeng.debug.BlockCubeGenerator;
|
||||
import appeng.debug.BlockEnergyGenerator;
|
||||
import appeng.debug.BlockItemGen;
|
||||
import appeng.debug.BlockPhantomNode;
|
||||
import appeng.debug.TileChunkLoader;
|
||||
import appeng.debug.TileCubeGenerator;
|
||||
import appeng.debug.TileEnergyGenerator;
|
||||
import appeng.debug.TileItemGen;
|
||||
import appeng.debug.TilePhantomNode;
|
||||
import appeng.decorative.slab.BlockSlabCommon;
|
||||
@@ -236,6 +238,7 @@ public final class ApiBlocks implements IBlocks
|
||||
private final IBlockDefinition chunkLoader;
|
||||
private final IBlockDefinition phantomNode;
|
||||
private final IBlockDefinition cubeGenerator;
|
||||
private final IBlockDefinition energyGenerator;
|
||||
|
||||
public ApiBlocks( FeatureFactory registry, PartModels partModels )
|
||||
{
|
||||
@@ -526,6 +529,11 @@ public final class ApiBlocks implements IBlocks
|
||||
.tileEntity( new TileEntityDefinition( TileCubeGenerator.class ) )
|
||||
.useCustomItemModel()
|
||||
.build();
|
||||
this.energyGenerator = registry.block( "debug_energy_gen", BlockEnergyGenerator::new )
|
||||
.features( AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE )
|
||||
.tileEntity( new TileEntityDefinition( TileEnergyGenerator.class ) )
|
||||
.useCustomItemModel()
|
||||
.build();
|
||||
}
|
||||
|
||||
private static IBlockDefinition makeSlab( String slabId, String doubleSlabId, FeatureFactory registry, IBlockDefinition blockDef )
|
||||
@@ -1014,4 +1022,9 @@ public final class ApiBlocks implements IBlocks
|
||||
{
|
||||
return this.cubeGenerator;
|
||||
}
|
||||
|
||||
public IBlockDefinition energyGenerator()
|
||||
{
|
||||
return energyGenerator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,13 +337,13 @@ public final class ApiItems implements IItems
|
||||
@Override
|
||||
public IItemDefinition biometricCard()
|
||||
{
|
||||
return this.chargedStaff;
|
||||
return this.biometricCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition chargedStaff()
|
||||
{
|
||||
return this.memoryCard;
|
||||
return this.chargedStaff;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,7 @@ package appeng.core.features.registries;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@@ -30,6 +31,8 @@ import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -49,6 +52,7 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
|
||||
private final Map<ItemStack, TunnelType> tunnels = new HashMap<>( INITIAL_CAPACITY );
|
||||
private final Map<String, TunnelType> modIdTunnels = new HashMap<>( INITIAL_CAPACITY );
|
||||
private final Map<Capability<?>, TunnelType> capTunnels = new HashMap<>( INITIAL_CAPACITY );
|
||||
|
||||
public void configure()
|
||||
{
|
||||
@@ -159,6 +163,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
this.addNewAttunement( parts.cableDenseSmart().stack( c, 1 ), TunnelType.ME );
|
||||
}
|
||||
|
||||
/**
|
||||
* attune based caps
|
||||
*/
|
||||
this.addNewAttunement( Capabilities.FORGE_ENERGY, TunnelType.FE_POWER );
|
||||
this.addNewAttunement( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, TunnelType.FLUID );
|
||||
|
||||
/**
|
||||
* attune based on the ItemStack's modId
|
||||
*/
|
||||
@@ -186,6 +196,16 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
this.modIdTunnels.put( modId, type );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNewAttunement( @Nonnull final Capability<?> cap, @Nullable final TunnelType type )
|
||||
{
|
||||
if( type == null || cap == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.capTunnels.put( cap, type );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNewAttunement( @Nonnull final ItemStack trigger, @Nullable final TunnelType type )
|
||||
{
|
||||
@@ -203,39 +223,40 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
{
|
||||
if( !trigger.isEmpty() )
|
||||
{
|
||||
// if( FluidRegistry.isContainer( trigger ) )
|
||||
// {
|
||||
// return TunnelType.FLUID;
|
||||
// }
|
||||
|
||||
for( final ItemStack is : this.tunnels.keySet() )
|
||||
// First match exact items
|
||||
for( final Entry<ItemStack, TunnelType> entry : this.tunnels.entrySet() )
|
||||
{
|
||||
final ItemStack is = entry.getKey();
|
||||
|
||||
if( is.getItem() == trigger.getItem() && is.getItemDamage() == OreDictionary.WILDCARD_VALUE )
|
||||
{
|
||||
return this.tunnels.get( is );
|
||||
return entry.getValue();
|
||||
}
|
||||
|
||||
if( ItemStack.areItemsEqual( is, trigger ) )
|
||||
{
|
||||
return this.tunnels.get( is );
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// Try by ModId next
|
||||
for( final String modId : this.modIdTunnels.keySet() )
|
||||
{
|
||||
if( trigger.getItem().getRegistryName() != null && trigger.getItem().getRegistryName().getResourceDomain().equals( modId ) )
|
||||
{
|
||||
return this.modIdTunnels.get( modId );
|
||||
}
|
||||
}
|
||||
|
||||
// Next, check if the Item you're holding supports Forge Energy
|
||||
// Next, check if the Item you're holding supports any registered capability
|
||||
for( EnumFacing face : EnumFacing.VALUES )
|
||||
{
|
||||
if( trigger.hasCapability( Capabilities.FORGE_ENERGY, face ) )
|
||||
for( Entry<Capability<?>, TunnelType> entry : this.capTunnels.entrySet() )
|
||||
{
|
||||
return TunnelType.FE_POWER;
|
||||
if( trigger.hasCapability( entry.getKey(), face ) )
|
||||
{
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use the mod id as last option.
|
||||
for( final Entry<String, TunnelType> entry : this.modIdTunnels.entrySet() )
|
||||
{
|
||||
if( trigger.getItem().getRegistryName() != null && trigger.getItem().getRegistryName().getResourceDomain().equals( entry.getKey() ) )
|
||||
{
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ public enum GuiText
|
||||
RequiredPower,
|
||||
Efficiency,
|
||||
SCSSize,
|
||||
SCSSInvalid,
|
||||
SCSInvalid,
|
||||
InWorldCrafting,
|
||||
|
||||
inWorldFluix,
|
||||
|
||||
@@ -1,73 +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.stats;
|
||||
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
/**
|
||||
* handles the achievement when an {@link net.minecraft.item.Item} is crafted by a player.
|
||||
* The achievement is only added if its a real {@link net.minecraft.entity.player.EntityPlayer}.
|
||||
*
|
||||
* @author thatsIch
|
||||
* @since rv2
|
||||
*/
|
||||
public class AchievementCraftingHandler
|
||||
{
|
||||
private final PlayerDifferentiator differentiator;
|
||||
|
||||
public AchievementCraftingHandler( final PlayerDifferentiator differentiator )
|
||||
{
|
||||
this.differentiator = differentiator;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onPlayerCraftingEvent( final PlayerEvent.ItemCraftedEvent event )
|
||||
{
|
||||
if( this.differentiator.isNoPlayer( event.player ) || event.crafting.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( final Achievements achievement : Achievements.values() )
|
||||
{
|
||||
switch( achievement.getType() )
|
||||
{
|
||||
case Craft:
|
||||
if( Platform.itemComparisons().isSameItem( achievement.getStack(), event.crafting ) )
|
||||
{
|
||||
achievement.addToPlayer( event.player );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case CraftItem:
|
||||
if( achievement.getStack() != null && achievement.getStack().getItem().getClass() == event.crafting.getItem().getClass() )
|
||||
{
|
||||
achievement.addToPlayer( event.player );
|
||||
return;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +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.stats;
|
||||
|
||||
|
||||
/**
|
||||
* Hierarchy of the AE2 achievements
|
||||
*
|
||||
* @author thatsIch
|
||||
* @since rv2
|
||||
*/
|
||||
public class AchievementHierarchy
|
||||
{
|
||||
/**
|
||||
* Setup hierarchy through assigning parents.
|
||||
*/
|
||||
void registerAchievementHierarchy()
|
||||
{
|
||||
// Achievements.Presses.setParent( Achievements.Compass );
|
||||
//
|
||||
// Achievements.Fluix.setParent( Achievements.ChargedQuartz );
|
||||
//
|
||||
// Achievements.Charger.setParent( Achievements.Fluix );
|
||||
//
|
||||
// Achievements.CrystalGrowthAccelerator.setParent( Achievements.Charger );
|
||||
//
|
||||
// Achievements.GlassCable.setParent( Achievements.Charger );
|
||||
//
|
||||
// Achievements.SpatialIOExplorer.setParent( Achievements.SpatialIO );
|
||||
//
|
||||
// Achievements.IOPort.setParent( Achievements.StorageCell );
|
||||
//
|
||||
// Achievements.PatternTerminal.setParent( Achievements.CraftingTerminal );
|
||||
//
|
||||
// Achievements.Controller.setParent( Achievements.Networking1 );
|
||||
//
|
||||
// Achievements.Networking2.setParent( Achievements.Controller );
|
||||
//
|
||||
// Achievements.Networking3.setParent( Achievements.Networking2 );
|
||||
//
|
||||
// Achievements.P2P.setParent( Achievements.Controller );
|
||||
//
|
||||
// Achievements.Recursive.setParent( Achievements.Controller );
|
||||
}
|
||||
}
|
||||
@@ -1,64 +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.stats;
|
||||
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
/**
|
||||
* handles the achievement when an {@link net.minecraft.item.Item} is picked up by a player.
|
||||
* The achievement is only added if its a real {@link net.minecraft.entity.player.EntityPlayer}.
|
||||
*
|
||||
* @author thatsIch
|
||||
* @since rv2
|
||||
*/
|
||||
public class AchievementPickupHandler
|
||||
{
|
||||
private final PlayerDifferentiator differentiator;
|
||||
|
||||
public AchievementPickupHandler( final PlayerDifferentiator differentiator )
|
||||
{
|
||||
this.differentiator = differentiator;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onItemPickUp( final PlayerEvent.ItemPickupEvent event )
|
||||
{
|
||||
if( this.differentiator.isNoPlayer( event.player ) || event.pickedUp == null || event.pickedUp.getItem().isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack is = event.pickedUp.getItem();
|
||||
|
||||
for( final Achievements achievement : Achievements.values() )
|
||||
{
|
||||
if( achievement.getType() == AchievementType.Pickup && Platform.itemComparisons().isSameItem( achievement.getStack(), is ) )
|
||||
{
|
||||
achievement.addToPlayer( event.player );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,173 +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.stats;
|
||||
|
||||
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.definitions.IItemDefinition;
|
||||
import appeng.api.util.AEColor;
|
||||
import appeng.api.util.AEColoredItemDefinition;
|
||||
|
||||
|
||||
public enum Achievements
|
||||
{
|
||||
// done
|
||||
Compass( -2, -4, AEApi.instance().definitions().blocks().skyCompass(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
Presses( -2, -2, AEApi.instance().definitions().materials().logicProcessorPress(), AchievementType.Custom ),
|
||||
|
||||
// done
|
||||
SpatialIO( -4, -4, AEApi.instance().definitions().blocks().spatialIOPort(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
SpatialIOExplorer( -4, -2, AEApi.instance().definitions().items().spatialCell128(), AchievementType.Custom ),
|
||||
|
||||
// done
|
||||
StorageCell( -6, -4, AEApi.instance().definitions().items().cell64k(), AchievementType.CraftItem ),
|
||||
|
||||
// done
|
||||
IOPort( -6, -2, AEApi.instance().definitions().blocks().iOPort(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
CraftingTerminal( -8, -4, AEApi.instance().definitions().parts().craftingTerminal(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
PatternTerminal( -8, -2, AEApi.instance().definitions().parts().patternTerminal(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
ChargedQuartz( 0, -4, AEApi.instance().definitions().materials().certusQuartzCrystalCharged(), AchievementType.Pickup ),
|
||||
|
||||
// done
|
||||
Fluix( 0, -2, AEApi.instance().definitions().materials().fluixCrystal(), AchievementType.Pickup ),
|
||||
|
||||
// done
|
||||
Charger( 0, 0, AEApi.instance().definitions().blocks().charger(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
CrystalGrowthAccelerator( -2, 0, AEApi.instance().definitions().blocks().quartzGrowthAccelerator(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
GlassCable( 2, 0, AEApi.instance().definitions().parts().cableGlass(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
Networking1( 4, -6, AEApi.instance().definitions().parts().cableCovered(), AchievementType.Custom ),
|
||||
|
||||
// done
|
||||
Controller( 4, -4, AEApi.instance().definitions().blocks().controller(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
Networking2( 4, 0, AEApi.instance().definitions().parts().cableSmart(), AchievementType.Custom ),
|
||||
|
||||
// done
|
||||
Networking3( 4, 2, AEApi.instance().definitions().parts().cableDenseSmart(), AchievementType.Custom ),
|
||||
|
||||
// done
|
||||
P2P( 2, -2, AEApi.instance().definitions().parts().p2PTunnelME(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
Recursive( 6, -2, AEApi.instance().definitions().blocks().iface(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
CraftingCPU( 6, 0, AEApi.instance().definitions().blocks().craftingStorage64k(), AchievementType.CraftItem ),
|
||||
|
||||
// done
|
||||
Facade( 6, 2, AEApi.instance().definitions().items().facade(), AchievementType.CraftItem ),
|
||||
|
||||
// done
|
||||
NetworkTool( 8, 0, AEApi.instance().definitions().items().networkTool(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
PortableCell( 8, 2, AEApi.instance().definitions().items().portableCell(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
StorageBus( 10, 0, AEApi.instance().definitions().parts().storageBus(), AchievementType.Craft ),
|
||||
|
||||
// done
|
||||
QNB( 10, 2, AEApi.instance().definitions().blocks().quantumLink(), AchievementType.Craft );
|
||||
|
||||
private final ItemStack stack;
|
||||
private final AchievementType type;
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
private Advancement parent;
|
||||
private Advancement stat;
|
||||
|
||||
Achievements( final int x, final int y, final AEColoredItemDefinition which, final AchievementType type )
|
||||
{
|
||||
this.stack = ( which != null ) ? which.stack( AEColor.TRANSPARENT, 1 ) : ItemStack.EMPTY;
|
||||
this.type = type;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
Achievements( final int x, final int y, final IItemDefinition which, final AchievementType type )
|
||||
{
|
||||
this.stack = which.maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
this.type = type;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
Achievements( final int x, final int y, final ItemStack which, final AchievementType type )
|
||||
{
|
||||
this.stack = which;
|
||||
this.type = type;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
void setParent( final Achievements parent )
|
||||
{
|
||||
this.parent = parent.getAchievement();
|
||||
}
|
||||
|
||||
public Advancement getAchievement()
|
||||
{
|
||||
// if( this.stat == null && !this.getStack().isEmpty() )
|
||||
// {
|
||||
// this.stat = new Advancement( "achievement.ae2." + this.name(), "ae2." + this.name(), this.x, this.y,
|
||||
// this.getStack(), this.parent );
|
||||
// this.stat.registerStat();
|
||||
// }
|
||||
|
||||
return this.stat;
|
||||
}
|
||||
|
||||
public void addToPlayer( final EntityPlayer player )
|
||||
{
|
||||
// player.addStat( this.getAchievement(), 1 );
|
||||
}
|
||||
|
||||
AchievementType getType()
|
||||
{
|
||||
return this.type;
|
||||
}
|
||||
|
||||
ItemStack getStack()
|
||||
{
|
||||
return this.stack;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.stats;
|
||||
|
||||
|
||||
import appeng.bootstrap.ICriterionTriggerRegistry;
|
||||
|
||||
|
||||
public class AdvancementTriggers
|
||||
{
|
||||
private AppEngAdvancementTrigger networkApprentice = new AppEngAdvancementTrigger( "network_apprentice" );
|
||||
private AppEngAdvancementTrigger networkEngineer = new AppEngAdvancementTrigger( "network_engineer" );
|
||||
private AppEngAdvancementTrigger networkAdmin = new AppEngAdvancementTrigger( "network_admin" );
|
||||
private AppEngAdvancementTrigger spatialExplorer = new AppEngAdvancementTrigger( "spatial_explorer" );
|
||||
|
||||
public AdvancementTriggers( ICriterionTriggerRegistry registry )
|
||||
{
|
||||
registry.register( networkApprentice );
|
||||
registry.register( networkEngineer );
|
||||
registry.register( networkAdmin );
|
||||
registry.register( spatialExplorer );
|
||||
}
|
||||
|
||||
public IAdvancementTrigger getNetworkApprentice()
|
||||
{
|
||||
return this.networkApprentice;
|
||||
}
|
||||
|
||||
public IAdvancementTrigger getNetworkEngineer()
|
||||
{
|
||||
return this.networkEngineer;
|
||||
}
|
||||
|
||||
public IAdvancementTrigger getNetworkAdmin()
|
||||
{
|
||||
return this.networkAdmin;
|
||||
}
|
||||
|
||||
public IAdvancementTrigger getSpatialExplorer()
|
||||
{
|
||||
return this.spatialExplorer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.stats;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.advancements.ICriterionTrigger;
|
||||
import net.minecraft.advancements.PlayerAdvancements;
|
||||
import net.minecraft.advancements.critereon.AbstractCriterionInstance;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import appeng.core.AppEng;
|
||||
|
||||
|
||||
public class AppEngAdvancementTrigger implements ICriterionTrigger<AppEngAdvancementTrigger.Instance>, IAdvancementTrigger
|
||||
{
|
||||
private final ResourceLocation ID;
|
||||
private final Map<PlayerAdvancements, AppEngAdvancementTrigger.Listeners> listeners = new HashMap<>();
|
||||
|
||||
public AppEngAdvancementTrigger( String parString )
|
||||
{
|
||||
super();
|
||||
ID = new ResourceLocation( AppEng.MOD_ID, parString );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId()
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( PlayerAdvancements playerAdvancementsIn, ICriterionTrigger.Listener<AppEngAdvancementTrigger.Instance> listener )
|
||||
{
|
||||
AppEngAdvancementTrigger.Listeners l = this.listeners.get( playerAdvancementsIn );
|
||||
|
||||
if( l == null )
|
||||
{
|
||||
l = new AppEngAdvancementTrigger.Listeners( playerAdvancementsIn );
|
||||
this.listeners.put( playerAdvancementsIn, l );
|
||||
}
|
||||
|
||||
l.add( listener );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( PlayerAdvancements playerAdvancementsIn, ICriterionTrigger.Listener<AppEngAdvancementTrigger.Instance> listener )
|
||||
{
|
||||
AppEngAdvancementTrigger.Listeners l = this.listeners.get( playerAdvancementsIn );
|
||||
|
||||
if( l != null )
|
||||
{
|
||||
l.remove( listener );
|
||||
|
||||
if( l.isEmpty() )
|
||||
{
|
||||
this.listeners.remove( playerAdvancementsIn );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllListeners( PlayerAdvancements playerAdvancementsIn )
|
||||
{
|
||||
this.listeners.remove( playerAdvancementsIn );
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppEngAdvancementTrigger.Instance deserializeInstance( JsonObject json, JsonDeserializationContext context )
|
||||
{
|
||||
return new AppEngAdvancementTrigger.Instance( this.getId() );
|
||||
}
|
||||
|
||||
public void trigger( EntityPlayerMP parPlayer )
|
||||
{
|
||||
AppEngAdvancementTrigger.Listeners l = this.listeners.get( parPlayer.getAdvancements() );
|
||||
|
||||
if( l != null )
|
||||
{
|
||||
l.trigger( parPlayer );
|
||||
}
|
||||
}
|
||||
|
||||
public static class Instance extends AbstractCriterionInstance
|
||||
{
|
||||
public Instance( ResourceLocation parID )
|
||||
{
|
||||
super( parID );
|
||||
}
|
||||
|
||||
public boolean test()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class Listeners
|
||||
{
|
||||
private final PlayerAdvancements playerAdvancements;
|
||||
private final Set<ICriterionTrigger.Listener<AppEngAdvancementTrigger.Instance>> listeners = new HashSet<>();
|
||||
|
||||
Listeners( PlayerAdvancements playerAdvancementsIn )
|
||||
{
|
||||
this.playerAdvancements = playerAdvancementsIn;
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return this.listeners.isEmpty();
|
||||
}
|
||||
|
||||
public void add( ICriterionTrigger.Listener<AppEngAdvancementTrigger.Instance> listener )
|
||||
{
|
||||
this.listeners.add( listener );
|
||||
}
|
||||
|
||||
public void remove( ICriterionTrigger.Listener<AppEngAdvancementTrigger.Instance> listener )
|
||||
{
|
||||
this.listeners.remove( listener );
|
||||
}
|
||||
|
||||
public void trigger( EntityPlayerMP player )
|
||||
{
|
||||
List<ICriterionTrigger.Listener<AppEngAdvancementTrigger.Instance>> list = null;
|
||||
|
||||
for( ICriterionTrigger.Listener<AppEngAdvancementTrigger.Instance> listener : this.listeners )
|
||||
{
|
||||
if( listener.getCriterionInstance().test() )
|
||||
{
|
||||
if( list == null )
|
||||
{
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
|
||||
list.add( listener );
|
||||
}
|
||||
}
|
||||
|
||||
if( list != null )
|
||||
{
|
||||
for( ICriterionTrigger.Listener<AppEngAdvancementTrigger.Instance> l : list )
|
||||
{
|
||||
l.grantCriterion( this.playerAdvancements );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
* Copyright (c) 2013 - 2017, 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
|
||||
@@ -19,9 +19,11 @@
|
||||
package appeng.core.stats;
|
||||
|
||||
|
||||
public enum AchievementType
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public interface IAdvancementTrigger
|
||||
{
|
||||
|
||||
Craft, CraftItem, Pickup, Custom
|
||||
|
||||
void trigger( EntityPlayerMP parPlayer );
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.stats;
|
||||
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.JsonUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.advancements.critereon.ItemPredicates;
|
||||
|
||||
import appeng.core.AppEng;
|
||||
import appeng.items.parts.ItemPart;
|
||||
import appeng.items.parts.PartType;
|
||||
|
||||
|
||||
public class PartItemPredicate extends ItemPredicate
|
||||
{
|
||||
private final PartType partType;
|
||||
|
||||
public PartItemPredicate( String partName )
|
||||
{
|
||||
this.partType = PartType.valueOf( partName.toUpperCase() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test( ItemStack item )
|
||||
{
|
||||
if( ItemPart.instance != null && item.getItem() == ItemPart.instance )
|
||||
{
|
||||
return ItemPart.instance.getTypeByStack( item ) == this.partType;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ItemPredicate deserialize( JsonObject jsonobject )
|
||||
{
|
||||
if( jsonobject.has( "part" ) )
|
||||
{
|
||||
return new PartItemPredicate( JsonUtils.getString( jsonobject, "part" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ItemPredicate.ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public static void register()
|
||||
{
|
||||
ItemPredicates.register( new ResourceLocation( AppEng.MOD_ID, "part" ), PartItemPredicate::deserialize );
|
||||
}
|
||||
}
|
||||
@@ -1,115 +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.stats;
|
||||
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.EventBus;
|
||||
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.features.AEFeature;
|
||||
|
||||
|
||||
/**
|
||||
* Registers any items a player is picking up or is crafting.
|
||||
* Registered items are added to the player stats.
|
||||
* This will only happen if the {@link AEFeature#ACHIEVEMENTS} feature is enabled.
|
||||
*/
|
||||
public class PlayerStatsRegistration
|
||||
{
|
||||
/**
|
||||
* {@link net.minecraftforge.fml.common.eventhandler.EventBus} to which the handlers might get posted to depending
|
||||
* if the feature is enabled
|
||||
*/
|
||||
private final EventBus bus;
|
||||
|
||||
/**
|
||||
* is true if the {@link appeng.core.features.AEFeature#ACHIEVEMENTS} is enabled in the
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
private final boolean isAchievementFeatureEnabled;
|
||||
|
||||
/**
|
||||
* Constructs this with an {@link net.minecraftforge.fml.common.eventhandler.EventBus} and
|
||||
* {@link appeng.core.AEConfig}.
|
||||
*
|
||||
* @param bus {@see #bus}
|
||||
* @param config {@link appeng.core.AEConfig} which is used to determine if the
|
||||
* {@link appeng.core.features.AEFeature#ACHIEVEMENTS} is enabled
|
||||
*/
|
||||
public PlayerStatsRegistration( final EventBus bus, final AEConfig config )
|
||||
{
|
||||
this.bus = bus;
|
||||
this.isAchievementFeatureEnabled = config.isFeatureEnabled( AEFeature.ACHIEVEMENTS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the {@link appeng.core.stats.AchievementCraftingHandler} and
|
||||
* {@link appeng.core.stats.AchievementPickupHandler} to the {@link #bus} if {@link #isAchievementFeatureEnabled} is
|
||||
* true.
|
||||
*/
|
||||
public void registerAchievementHandlers()
|
||||
{
|
||||
if( this.isAchievementFeatureEnabled )
|
||||
{
|
||||
final PlayerDifferentiator differentiator = new PlayerDifferentiator();
|
||||
final AchievementCraftingHandler craftingHandler = new AchievementCraftingHandler( differentiator );
|
||||
final AchievementPickupHandler pickupHandler = new AchievementPickupHandler( differentiator );
|
||||
|
||||
this.bus.register( craftingHandler );
|
||||
this.bus.register( pickupHandler );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the {@link appeng.core.stats.AchievementHierarchy} and adds all {@link appeng.core.stats.Achievements}
|
||||
* to a new {@link net.minecraft.advancements.Advancement}.
|
||||
*/
|
||||
public void registerAchievements()
|
||||
{
|
||||
if( this.isAchievementFeatureEnabled )
|
||||
{
|
||||
final AchievementHierarchy hierarchy = new AchievementHierarchy();
|
||||
hierarchy.registerAchievementHierarchy();
|
||||
|
||||
for( final Stats s : Stats.values() )
|
||||
{
|
||||
s.getStat();
|
||||
}
|
||||
|
||||
/**
|
||||
* register
|
||||
*/
|
||||
// final ArrayList<Achievement> list = new ArrayList<Achievement>();
|
||||
//
|
||||
// for( final Achievements a : Achievements.values() )
|
||||
// {
|
||||
// final Achievement ach = a.getAchievement();
|
||||
// if( ach != null )
|
||||
// {
|
||||
// list.add( ach );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// final AchievementPage ae2AchievementPage = new AchievementPage( "Applied Energistics 2", list.toArray(
|
||||
// new Achievement[list.size()] ) );
|
||||
// AchievementPage.registerAchievementPage( ae2AchievementPage );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,18 +44,18 @@ public enum Stats
|
||||
|
||||
public void addToPlayer( final EntityPlayer player, final int howMany )
|
||||
{
|
||||
player.addStat( this.getStat(), howMany );
|
||||
player.addStat( this.stat, howMany );
|
||||
}
|
||||
|
||||
StatBasic getStat()
|
||||
public static void register()
|
||||
{
|
||||
if( this.stat == null )
|
||||
for( final Stats s : Stats.values() )
|
||||
{
|
||||
this.stat = new StatBasic( "stat.ae2." + this.name(), new TextComponentTranslation( "stat.ae2." + this.name() ) );
|
||||
this.stat.registerStat();
|
||||
if( s.stat == null )
|
||||
{
|
||||
s.stat = new StatBasic( "stat.ae2." + s.name(), new TextComponentTranslation( "stat.ae2." + s.name() ) );
|
||||
s.stat.registerStat();
|
||||
}
|
||||
}
|
||||
|
||||
return this.stat;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@ import appeng.core.sync.packets.PacketMatterCannon;
|
||||
import appeng.core.sync.packets.PacketMockExplosion;
|
||||
import appeng.core.sync.packets.PacketPaintedEntity;
|
||||
import appeng.core.sync.packets.PacketPartPlacement;
|
||||
import appeng.core.sync.packets.PacketPartialItem;
|
||||
import appeng.core.sync.packets.PacketPatternSlot;
|
||||
import appeng.core.sync.packets.PacketProgressBar;
|
||||
import appeng.core.sync.packets.PacketSwapSlots;
|
||||
import appeng.core.sync.packets.PacketSwitchGuis;
|
||||
import appeng.core.sync.packets.PacketTargetItemStack;
|
||||
import appeng.core.sync.packets.PacketTransitionEffect;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
|
||||
@@ -90,7 +90,7 @@ public class AppEngPacketHandlerBase
|
||||
|
||||
PACKET_RECIPE_JEI( PacketJEIRecipe.class ),
|
||||
|
||||
PACKET_PARTIAL_ITEM( PacketPartialItem.class ),
|
||||
PACKET_TARGET_ITEM( PacketTargetItemStack.class ),
|
||||
|
||||
PACKET_CRAFTING_REQUEST( PacketCraftRequest.class ),
|
||||
|
||||
|
||||
@@ -20,13 +20,9 @@ package appeng.core.sync;
|
||||
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -36,8 +32,6 @@ import net.minecraftforge.fml.relauncher.ReflectionHelper;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.definitions.IComparableDefinition;
|
||||
import appeng.api.definitions.IMaterials;
|
||||
import appeng.api.exceptions.AppEngException;
|
||||
import appeng.api.features.IWirelessTermHandler;
|
||||
import appeng.api.implementations.IUpgradeableHost;
|
||||
@@ -92,7 +86,6 @@ import appeng.container.implementations.ContainerUpgradeable;
|
||||
import appeng.container.implementations.ContainerVibrationChamber;
|
||||
import appeng.container.implementations.ContainerWireless;
|
||||
import appeng.container.implementations.ContainerWirelessTerm;
|
||||
import appeng.core.stats.Achievements;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import appeng.helpers.WirelessTerminalGuiObject;
|
||||
@@ -356,27 +349,7 @@ public enum GuiBridge implements IGuiHandler
|
||||
.typeName( tE ) + " )" );
|
||||
}
|
||||
|
||||
final Object o = target.newInstance( inventory, tE );
|
||||
|
||||
/**
|
||||
* triggers achievement when the player sees presses.
|
||||
*/
|
||||
if( o instanceof AEBaseContainer )
|
||||
{
|
||||
final AEBaseContainer bc = (AEBaseContainer) o;
|
||||
for( final Object so : bc.inventorySlots )
|
||||
{
|
||||
if( so instanceof Slot )
|
||||
{
|
||||
final ItemStack is = ( (Slot) so ).getStack();
|
||||
|
||||
final IMaterials materials = AEApi.instance().definitions().materials();
|
||||
this.addPressAchievementToPlayer( is, materials, inventory.player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
return target.newInstance( inventory, tE );
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
@@ -410,26 +383,6 @@ public enum GuiBridge implements IGuiHandler
|
||||
return inventory.getClass().getName();
|
||||
}
|
||||
|
||||
private void addPressAchievementToPlayer( final ItemStack newItem, final IMaterials possibleMaterials, final EntityPlayer player )
|
||||
{
|
||||
final IComparableDefinition logic = possibleMaterials.logicProcessorPress();
|
||||
final IComparableDefinition eng = possibleMaterials.engProcessorPress();
|
||||
final IComparableDefinition calc = possibleMaterials.calcProcessorPress();
|
||||
final IComparableDefinition silicon = possibleMaterials.siliconPress();
|
||||
|
||||
final List<IComparableDefinition> presses = Lists.newArrayList( logic, eng, calc, silicon );
|
||||
|
||||
for( final IComparableDefinition press : presses )
|
||||
{
|
||||
if( press.isSameAs( newItem ) )
|
||||
{
|
||||
Achievements.Presses.addToPlayer( player );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getClientGuiElement( final int ordinal, final EntityPlayer player, final World w, final int x, final int y, final int z )
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@ import appeng.api.config.Actionable;
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.energy.IEnergyGrid;
|
||||
import appeng.api.networking.security.ISecurityGrid;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
@@ -132,6 +133,7 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
final IStorageGrid inv = grid.getCache( IStorageGrid.class );
|
||||
final IEnergyGrid energy = grid.getCache( IEnergyGrid.class );
|
||||
final ISecurityGrid security = grid.getCache( ISecurityGrid.class );
|
||||
final ICraftingGrid crafting = grid.getCache( ICraftingGrid.class );
|
||||
final IItemHandler craftMatrix = cct.getInventoryByName( "crafting" );
|
||||
final IItemHandler playerInventory = cct.getInventoryByName( "player" );
|
||||
|
||||
@@ -179,13 +181,23 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
{
|
||||
request.setStackSize( 1 );
|
||||
IAEItemStack out;
|
||||
|
||||
if( cct.useRealItems() )
|
||||
{
|
||||
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
||||
}
|
||||
else
|
||||
{
|
||||
out = storage.extractItems( request, Actionable.SIMULATE, cct.getActionSource() );
|
||||
// Query the crafting grid if there is a pattern providing the item
|
||||
if( !crafting.getCraftingFor( request, null, 0, null ).isEmpty() )
|
||||
{
|
||||
out = request;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back using an existing item
|
||||
out = storage.extractItems( request, Actionable.SIMULATE, cct.getActionSource() );
|
||||
}
|
||||
}
|
||||
|
||||
if( out != null )
|
||||
|
||||
+36
-30
@@ -25,35 +25,56 @@ import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.util.item.AEItemStack;
|
||||
|
||||
|
||||
public class PacketPartialItem extends AppEngPacket
|
||||
public class PacketTargetItemStack extends AppEngPacket
|
||||
{
|
||||
|
||||
private final short pageNum;
|
||||
private final byte[] data;
|
||||
private AEItemStack stack;
|
||||
|
||||
// automatic.
|
||||
public PacketPartialItem( final ByteBuf stream )
|
||||
public PacketTargetItemStack( final ByteBuf stream )
|
||||
{
|
||||
this.pageNum = stream.readShort();
|
||||
stream.readBytes( this.data = new byte[stream.readableBytes()] );
|
||||
try
|
||||
{
|
||||
if( stream.readableBytes() > 0 )
|
||||
{
|
||||
this.stack = AEItemStack.fromPacket( stream );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.stack = null;
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
AELog.debug( ex );
|
||||
this.stack = null;
|
||||
}
|
||||
}
|
||||
|
||||
// api
|
||||
public PacketPartialItem( final int page, final int maxPages, final byte[] buf )
|
||||
public PacketTargetItemStack( AEItemStack stack )
|
||||
{
|
||||
|
||||
this.stack = stack;
|
||||
|
||||
final ByteBuf data = Unpooled.buffer();
|
||||
|
||||
this.pageNum = (short) ( page | ( maxPages << 8 ) );
|
||||
this.data = buf;
|
||||
data.writeInt( this.getPacketID() );
|
||||
data.writeShort( this.pageNum );
|
||||
data.writeBytes( buf );
|
||||
|
||||
if( stack != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
stack.writeToPacket( data );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
AELog.debug( ex );
|
||||
}
|
||||
}
|
||||
this.configureWrite( data );
|
||||
}
|
||||
|
||||
@@ -62,23 +83,8 @@ public class PacketPartialItem extends AppEngPacket
|
||||
{
|
||||
if( player.openContainer instanceof AEBaseContainer )
|
||||
{
|
||||
( (AEBaseContainer) player.openContainer ).postPartial( this );
|
||||
( (AEBaseContainer) player.openContainer ).setTargetStack( this.stack );
|
||||
}
|
||||
}
|
||||
|
||||
public int getPageCount()
|
||||
{
|
||||
return this.pageNum >> 8;
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return this.data.length;
|
||||
}
|
||||
|
||||
public int write( final byte[] buffer, final int cursor )
|
||||
{
|
||||
System.arraycopy( this.data, 0, buffer, cursor, this.data.length );
|
||||
return cursor + this.data.length;
|
||||
}
|
||||
}
|
||||
@@ -363,7 +363,7 @@ public class CraftingTreeNode
|
||||
|
||||
if( this.howManyEmitted > 0 )
|
||||
{
|
||||
final IAEItemStack i = this.what.copy();
|
||||
final IAEItemStack i = this.what.copy().reset();
|
||||
i.setStackSize( this.howManyEmitted );
|
||||
craftingCPUCluster.addEmitable( i );
|
||||
}
|
||||
|
||||
+9
-26
@@ -16,37 +16,20 @@
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.stats;
|
||||
package appeng.debug;
|
||||
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraft.block.material.Material;
|
||||
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
|
||||
|
||||
/**
|
||||
* Can differentiate if a {@link net.minecraft.entity.player.EntityPlayer} is a real player or not
|
||||
*
|
||||
* @author thatsIch
|
||||
* @since rv2
|
||||
*/
|
||||
public class PlayerDifferentiator
|
||||
public class BlockEnergyGenerator extends AEBaseTileBlock
|
||||
{
|
||||
/**
|
||||
* Can determine if an {@link net.minecraft.entity.player.EntityPlayer} is not a real player.
|
||||
* This is based on if the
|
||||
*
|
||||
* @param player is:
|
||||
* - null
|
||||
* - dead
|
||||
* - fake
|
||||
*
|
||||
* @param player to be checked player
|
||||
*
|
||||
* @return true if
|
||||
* @param player is not a real player
|
||||
*/
|
||||
boolean isNoPlayer( final EntityPlayer player )
|
||||
|
||||
public BlockEnergyGenerator()
|
||||
{
|
||||
return player == null || player.isDead || player instanceof FakePlayer;
|
||||
super( Material.IRON );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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.debug;
|
||||
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.math.IntMath;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
|
||||
import appeng.tile.AEBaseTile;
|
||||
|
||||
|
||||
public class TileEnergyGenerator extends AEBaseTile implements ITickable, IEnergyStorage
|
||||
{
|
||||
/**
|
||||
* The base energy injected each tick.
|
||||
* Adjacent TileEnergyGenerators will increase it to pow(base, #generators).
|
||||
*/
|
||||
private static final int BASE_ENERGY = 8;
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
int tier = 1;
|
||||
final EnumSet<EnumFacing> validEnergyReceivers = EnumSet.noneOf( EnumFacing.class );
|
||||
|
||||
for( EnumFacing facing : EnumFacing.values() )
|
||||
{
|
||||
final TileEntity te = this.getWorld().getTileEntity( this.getPos().offset( facing ) );
|
||||
|
||||
if( te instanceof TileEnergyGenerator )
|
||||
{
|
||||
tier++;
|
||||
}
|
||||
|
||||
if( te != null && te.hasCapability( CapabilityEnergy.ENERGY, facing.getOpposite() ) )
|
||||
{
|
||||
validEnergyReceivers.add( facing );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final int energyToInsert = IntMath.pow( BASE_ENERGY, tier );
|
||||
|
||||
for( EnumFacing facing : validEnergyReceivers )
|
||||
{
|
||||
final TileEntity te = this.getWorld().getTileEntity( this.getPos().offset( facing ) );
|
||||
final IEnergyStorage cap = te.getCapability( CapabilityEnergy.ENERGY, facing.getOpposite() );
|
||||
|
||||
if( cap.canReceive() )
|
||||
{
|
||||
|
||||
cap.receiveEnergy( energyToInsert, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCapability( Capability<?> capability, @Nullable EnumFacing facing )
|
||||
{
|
||||
if( capability == CapabilityEnergy.ENERGY )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return super.hasCapability( capability, facing );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T getCapability( Capability<T> capability, @Nullable EnumFacing facing )
|
||||
{
|
||||
if( capability == CapabilityEnergy.ENERGY )
|
||||
{
|
||||
return (T) this;
|
||||
}
|
||||
return super.getCapability( capability, facing );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int receiveEnergy( int maxReceive, boolean simulate )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy( int maxExtract, boolean simulate )
|
||||
{
|
||||
return maxExtract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnergyStored()
|
||||
{
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxEnergyStored()
|
||||
{
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canReceive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,11 @@ import java.util.Random;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -36,15 +39,8 @@ import appeng.core.AEConfig;
|
||||
import appeng.core.AppEng;
|
||||
|
||||
|
||||
public final class BlockChargedQuartzOre extends BlockQuartzOre
|
||||
public class BlockChargedQuartzOre extends BlockQuartzOre
|
||||
{
|
||||
|
||||
public BlockChargedQuartzOre()
|
||||
{
|
||||
this.setBoostBrightnessLow( 2 );
|
||||
this.setBoostBrightnessHigh( 5 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemDropped( final IBlockState state, final Random rand, final int fortune )
|
||||
{
|
||||
@@ -68,6 +64,17 @@ public final class BlockChargedQuartzOre extends BlockQuartzOre
|
||||
.getItemDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickBlock( IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player )
|
||||
{
|
||||
return AEApi.instance()
|
||||
.definitions()
|
||||
.blocks()
|
||||
.quartzOreCharged()
|
||||
.maybeStack( 1 )
|
||||
.orElseThrow( () -> new MissingDefinitionException( "Tried to access charged certus quartz ore, even though they are disabled" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
public void randomDisplayTick( final IBlockState state, final World w, final BlockPos pos, final Random r )
|
||||
|
||||
@@ -27,7 +27,6 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -37,18 +36,11 @@ import appeng.block.AEBaseBlock;
|
||||
|
||||
public class BlockQuartzOre extends AEBaseBlock
|
||||
{
|
||||
private int boostBrightnessLow;
|
||||
private int boostBrightnessHigh;
|
||||
private boolean enhanceBrightness;
|
||||
|
||||
public BlockQuartzOre()
|
||||
{
|
||||
super( Material.ROCK );
|
||||
this.setHardness( 3.0F );
|
||||
this.setResistance( 5.0F );
|
||||
this.boostBrightnessLow = 0;
|
||||
this.boostBrightnessHigh = 1;
|
||||
this.enhanceBrightness = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,76 +50,7 @@ public class BlockQuartzOre extends AEBaseBlock
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightValue( final IBlockState state, final IBlockAccess worldIn, final BlockPos pos )
|
||||
{
|
||||
int j1 = super.getLightValue( state, worldIn, pos );
|
||||
if( this.enhanceBrightness )
|
||||
{
|
||||
j1 = Math.max( j1 >> 20, j1 >> 4 );
|
||||
|
||||
if( j1 > 4 )
|
||||
{
|
||||
j1 += this.boostBrightnessHigh;
|
||||
}
|
||||
else
|
||||
{
|
||||
j1 += this.boostBrightnessLow;
|
||||
}
|
||||
|
||||
if( j1 > 15 )
|
||||
{
|
||||
j1 = 15;
|
||||
}
|
||||
return j1 << 20 | j1 << 4;
|
||||
}
|
||||
return j1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int quantityDropped( final Random rand )
|
||||
{
|
||||
return 1 + rand.nextInt( 2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemDropped( final IBlockState state, /* is null */
|
||||
final Random rand, final int fortune )
|
||||
{
|
||||
return AEApi.instance()
|
||||
.definitions()
|
||||
.materials()
|
||||
.certusQuartzCrystal()
|
||||
.maybeItem()
|
||||
.orElseThrow( () -> new MissingDefinitionException( "Tried to access certus quartz crystal, even though they are disabled" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropBlockAsItemWithChance( final World w, final BlockPos pos, final IBlockState state, final float chance, final int fortune )
|
||||
{
|
||||
super.dropBlockAsItemWithChance( w, pos, state, chance, fortune );
|
||||
|
||||
if( this.getItemDropped( state, w.rand, fortune ) != Item.getItemFromBlock( this ) )
|
||||
{
|
||||
final int xp = MathHelper.getInt( w.rand, 2, 5 );
|
||||
|
||||
this.dropXpOnBlockBreak( w, pos, xp );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped( final IBlockState state )
|
||||
{
|
||||
return AEApi.instance()
|
||||
.definitions()
|
||||
.materials()
|
||||
.certusQuartzCrystal()
|
||||
.maybeStack( 1 )
|
||||
.orElseThrow( () -> new MissingDefinitionException( "Tried to access certus quartz crystal, even though they are disabled" ) )
|
||||
.getItemDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int quantityDroppedWithBonus( final int fortune, final Random rand )
|
||||
public int quantityDropped( IBlockState state, int fortune, Random rand )
|
||||
{
|
||||
if( fortune > 0 && Item.getItemFromBlock( this ) != this.getItemDropped( null, rand, fortune ) )
|
||||
{
|
||||
@@ -146,18 +69,45 @@ public class BlockQuartzOre extends AEBaseBlock
|
||||
}
|
||||
}
|
||||
|
||||
void setBoostBrightnessLow( final int boostBrightnessLow )
|
||||
@Override
|
||||
public int quantityDropped( final Random rand )
|
||||
{
|
||||
this.boostBrightnessLow = boostBrightnessLow;
|
||||
return 1 + rand.nextInt( 2 );
|
||||
}
|
||||
|
||||
void setBoostBrightnessHigh( final int boostBrightnessHigh )
|
||||
@Override
|
||||
public void dropBlockAsItemWithChance( final World w, final BlockPos pos, final IBlockState state, final float chance, final int fortune )
|
||||
{
|
||||
this.boostBrightnessHigh = boostBrightnessHigh;
|
||||
super.dropBlockAsItemWithChance( w, pos, state, chance, fortune );
|
||||
|
||||
if( this.getItemDropped( state, w.rand, fortune ) != Item.getItemFromBlock( this ) )
|
||||
{
|
||||
final int xp = MathHelper.getInt( w.rand, 2, 5 );
|
||||
|
||||
this.dropXpOnBlockBreak( w, pos, xp );
|
||||
}
|
||||
}
|
||||
|
||||
public void setEnhanceBrightness( final boolean enhanceBrightness )
|
||||
@Override
|
||||
public Item getItemDropped( final IBlockState state, final Random rand, final int fortune )
|
||||
{
|
||||
this.enhanceBrightness = enhanceBrightness;
|
||||
return AEApi.instance()
|
||||
.definitions()
|
||||
.materials()
|
||||
.certusQuartzCrystal()
|
||||
.maybeItem()
|
||||
.orElseThrow( () -> new MissingDefinitionException( "Tried to access certus quartz crystal, even though they are disabled" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped( final IBlockState state )
|
||||
{
|
||||
return AEApi.instance()
|
||||
.definitions()
|
||||
.materials()
|
||||
.certusQuartzCrystal()
|
||||
.maybeStack( 1 )
|
||||
.orElseThrow( () -> new MissingDefinitionException( "Tried to access certus quartz crystal, even though they are disabled" ) )
|
||||
.getItemDamage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
package appeng.entity;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
@@ -136,19 +138,20 @@ public final class EntityTinyTNTPrimed extends EntityTNTPrimed implements IEntit
|
||||
return;
|
||||
}
|
||||
|
||||
for( final Object e : this.world.getEntitiesWithinAABBExcludingEntity( this,
|
||||
new AxisAlignedBB( this.posX - 1.5, this.posY - 1.5f, this.posZ - 1.5, this.posX + 1.5, this.posY + 1.5, this.posZ + 1.5 ) ) )
|
||||
final Explosion ex = new Explosion( this.world, this, this.posX, this.posY, this.posZ, 0.2f, false, false );
|
||||
final AxisAlignedBB area = new AxisAlignedBB( this.posX - 1.5, this.posY - 1.5f, this.posZ - 1.5, this.posX + 1.5, this.posY + 1.5, this.posZ + 1.5 );
|
||||
final List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity( this, area );
|
||||
|
||||
net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate( this.world, ex, list, 0.2f * 2d );
|
||||
|
||||
for( final Entity e : list )
|
||||
{
|
||||
if( e instanceof Entity )
|
||||
{
|
||||
( (Entity) e ).attackEntityFrom( DamageSource.causeExplosionDamage( (Explosion) null ), 6 );
|
||||
}
|
||||
e.attackEntityFrom( DamageSource.causeExplosionDamage( ex ), 6 );
|
||||
}
|
||||
|
||||
if( AEConfig.instance().isFeatureEnabled( AEFeature.TINY_TNT_BLOCK_DAMAGE ) )
|
||||
{
|
||||
this.posY -= 0.25;
|
||||
final Explosion ex = new Explosion( this.world, this, this.posX, this.posY, this.posZ, 0.2f, false, false );
|
||||
|
||||
for( int x = (int) ( this.posX - 2 ); x <= this.posX + 2; x++ )
|
||||
{
|
||||
@@ -159,6 +162,7 @@ public final class EntityTinyTNTPrimed extends EntityTNTPrimed implements IEntit
|
||||
final BlockPos point = new BlockPos( x, y, z );
|
||||
final IBlockState state = this.world.getBlockState( point );
|
||||
final Block block = state.getBlock();
|
||||
|
||||
if( block != null && !block.isAir( state, this.world, point ) )
|
||||
{
|
||||
float strength = (float) ( 2.3f - ( ( ( x + 0.5f ) - this.posX ) * ( ( x + 0.5f ) - this.posX ) + ( ( y + 0.5f ) - this.posY ) * ( ( y + 0.5f ) - this.posY ) + ( ( z + 0.5f ) - this.posZ ) * ( ( z + 0.5f ) - this.posZ ) ) );
|
||||
|
||||
@@ -47,13 +47,16 @@ public enum IntegrationRegistry
|
||||
this.modules.add( new IntegrationNode( type.dspName, type.modID, type ) );
|
||||
}
|
||||
|
||||
public void init()
|
||||
public void preInit()
|
||||
{
|
||||
for( final IntegrationNode node : this.modules )
|
||||
{
|
||||
node.call( IntegrationStage.PRE_INIT );
|
||||
}
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
for( final IntegrationNode node : this.modules )
|
||||
{
|
||||
node.call( IntegrationStage.INIT );
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package appeng.integration;
|
||||
|
||||
|
||||
import appeng.integration.modules.crafttweaker.CTModule;
|
||||
import appeng.integration.modules.ic2.IC2Module;
|
||||
import appeng.integration.modules.jei.JEIModule;
|
||||
import appeng.integration.modules.theoneprobe.TheOneProbeModule;
|
||||
@@ -73,7 +74,16 @@ public enum IntegrationType
|
||||
}
|
||||
},
|
||||
|
||||
TESLA( IntegrationSide.BOTH, "Tesla", "tesla" );
|
||||
TESLA( IntegrationSide.BOTH, "Tesla", "tesla" ),
|
||||
|
||||
CRAFTTWEAKER( IntegrationSide.BOTH, "CraftTweaker", "crafttweaker" )
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return new CTModule();
|
||||
}
|
||||
};
|
||||
|
||||
public final IntegrationSide side;
|
||||
public final String dspName;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.abstraction;
|
||||
|
||||
|
||||
import appeng.integration.IIntegrationModule;
|
||||
|
||||
|
||||
public interface ICraftTweaker extends IIntegrationModule
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.crafttweaker;
|
||||
|
||||
|
||||
import crafttweaker.api.item.IIngredient;
|
||||
import stanhebben.zenscript.annotations.ZenClass;
|
||||
import stanhebben.zenscript.annotations.ZenMethod;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.TunnelType;
|
||||
import appeng.api.features.IP2PTunnelRegistry;
|
||||
|
||||
|
||||
@ZenClass( "mods.appliedenergistics2.Attunement" )
|
||||
public class AttunementRegistry
|
||||
{
|
||||
private AttunementRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneME( IIngredient itemStack )
|
||||
{
|
||||
attune( itemStack, TunnelType.ME );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneME( String modId )
|
||||
{
|
||||
attune( modId, TunnelType.ME );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneItem( IIngredient itemStack )
|
||||
{
|
||||
attune( itemStack, TunnelType.ITEM );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneItem( String modId )
|
||||
{
|
||||
attune( modId, TunnelType.ITEM );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneFluid( IIngredient itemStack )
|
||||
{
|
||||
attune( itemStack, TunnelType.FLUID );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneFluid( String modId )
|
||||
{
|
||||
attune( modId, TunnelType.FLUID );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneRedstone( IIngredient itemStack )
|
||||
{
|
||||
attune( itemStack, TunnelType.REDSTONE );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneRedstone( String modId )
|
||||
{
|
||||
attune( modId, TunnelType.REDSTONE );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneRF( IIngredient itemStack )
|
||||
{
|
||||
attune( itemStack, TunnelType.FE_POWER );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneRF( String modId )
|
||||
{
|
||||
attune( modId, TunnelType.FE_POWER );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneIC2( IIngredient itemStack )
|
||||
{
|
||||
attune( itemStack, TunnelType.IC2_POWER );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneIC2( String modId )
|
||||
{
|
||||
attune( modId, TunnelType.IC2_POWER );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneLight( IIngredient itemStack )
|
||||
{
|
||||
attune( itemStack, TunnelType.LIGHT );
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void attuneLight( String modId )
|
||||
{
|
||||
attune( modId, TunnelType.LIGHT );
|
||||
}
|
||||
|
||||
private static void attune( IIngredient itemStack, TunnelType type )
|
||||
{
|
||||
IP2PTunnelRegistry registry = AEApi.instance().registries().p2pTunnel();
|
||||
CTModule.toStacks( itemStack ).ifPresent( c -> c.forEach( i -> registry.addNewAttunement( i, type ) ) );
|
||||
}
|
||||
|
||||
private static void attune( String modid, TunnelType type )
|
||||
{
|
||||
AEApi.instance().registries().p2pTunnel().addNewAttunement( modid, type );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.crafttweaker;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import crafttweaker.CraftTweakerAPI;
|
||||
import crafttweaker.IAction;
|
||||
import crafttweaker.api.item.IIngredient;
|
||||
import crafttweaker.api.item.IItemStack;
|
||||
|
||||
import appeng.integration.abstraction.ICraftTweaker;
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
public class CTModule implements ICraftTweaker
|
||||
{
|
||||
static final List<IAction> MODIFICATIONS = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void preInit()
|
||||
{
|
||||
CraftTweakerAPI.registerClass( GrinderRecipes.class );
|
||||
CraftTweakerAPI.registerClass( InscriberRecipes.class );
|
||||
CraftTweakerAPI.registerClass( SpatialRegistry.class );
|
||||
CraftTweakerAPI.registerClass( AttunementRegistry.class );
|
||||
CraftTweakerAPI.registerClass( CannonRegistry.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit()
|
||||
{
|
||||
MODIFICATIONS.forEach( CraftTweakerAPI::apply );
|
||||
}
|
||||
|
||||
public static ItemStack toStack( IItemStack iStack )
|
||||
{
|
||||
if( iStack == null )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ItemStack) iStack.getInternal();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<ItemStack> toStackExpand( IItemStack iStack )
|
||||
{
|
||||
if( iStack == null )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemStack is = (ItemStack) iStack.getInternal();
|
||||
if( !is.isItemStackDamageable() && is.getItemDamage() == OreDictionary.WILDCARD_VALUE )
|
||||
{
|
||||
NonNullList<ItemStack> ret = NonNullList.create();
|
||||
is.getItem().getSubItems( CreativeTabs.SEARCH, ret );
|
||||
return ret.stream().map( i -> new ItemStack( i.getItem(), iStack.getAmount(), i.getItemDamage() ) ).collect( Collectors.toList() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return Collections.singletonList( is );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<Collection<ItemStack>> toStacks( IIngredient ingredient )
|
||||
{
|
||||
if( ingredient == null )
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
Set<ItemStack> ret = new TreeSet<>( CTModule::compareItemStacks );
|
||||
ingredient.getItems().stream().map( CTModule::toStackExpand ).forEach( ret::addAll );
|
||||
if( ret.isEmpty() )
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of( ret );
|
||||
}
|
||||
|
||||
private static int compareItemStacks( ItemStack a, ItemStack b )
|
||||
{
|
||||
if( Platform.itemComparisons().isSameItem( a, b ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if( a == null )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if( b == null )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return System.identityHashCode( a ) - System.identityHashCode( b );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.crafttweaker;
|
||||
|
||||
|
||||
import crafttweaker.api.item.IIngredient;
|
||||
import stanhebben.zenscript.annotations.ZenClass;
|
||||
import stanhebben.zenscript.annotations.ZenMethod;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.features.IMatterCannonAmmoRegistry;
|
||||
|
||||
|
||||
@ZenClass( "mods.appliedenergistics2.Cannon" )
|
||||
public class CannonRegistry
|
||||
{
|
||||
private CannonRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void registerAmmo( IIngredient itemStack, double weight )
|
||||
{
|
||||
IMatterCannonAmmoRegistry registry = AEApi.instance().registries().matterCannon();
|
||||
CTModule.toStacks( itemStack ).ifPresent( c -> c.forEach( i -> registry.registerAmmo( i, weight ) ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.crafttweaker;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import crafttweaker.IAction;
|
||||
import crafttweaker.api.item.IIngredient;
|
||||
import crafttweaker.api.item.IItemStack;
|
||||
import stanhebben.zenscript.annotations.ZenClass;
|
||||
import stanhebben.zenscript.annotations.ZenMethod;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.features.IGrinderRecipe;
|
||||
import appeng.api.features.IGrinderRecipeBuilder;
|
||||
|
||||
|
||||
@ZenClass( "mods.appliedenergistics2.Grinder" )
|
||||
public class GrinderRecipes
|
||||
{
|
||||
private GrinderRecipes()
|
||||
{
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void addRecipe( IItemStack output, IIngredient input, int turns, @stanhebben.zenscript.annotations.Optional IItemStack secondary1Output, @stanhebben.zenscript.annotations.Optional Float secondary1Chance, @stanhebben.zenscript.annotations.Optional IItemStack secondary2Output, @stanhebben.zenscript.annotations.Optional Float secondary2Chance )
|
||||
{
|
||||
Collection<ItemStack> inStacks = CTModule.toStacks( input ).orElse( Collections.emptySet() );
|
||||
|
||||
for( ItemStack inStack : inStacks )
|
||||
{
|
||||
IGrinderRecipeBuilder builder = AEApi.instance().registries().grinder().builder();
|
||||
builder.withInput( inStack )
|
||||
.withOutput( CTModule.toStack( output ) )
|
||||
.withTurns( turns );
|
||||
|
||||
final ItemStack s1 = CTModule.toStack( secondary1Output );
|
||||
if( !s1.isEmpty() )
|
||||
{
|
||||
builder.withFirstOptional( s1, secondary1Chance == null ? 1.0f : secondary1Chance );
|
||||
}
|
||||
final ItemStack s2 = CTModule.toStack( secondary2Output );
|
||||
if( !s2.isEmpty() )
|
||||
{
|
||||
builder.withFirstOptional( s2, secondary2Chance == null ? 1.0f : secondary2Chance );
|
||||
}
|
||||
CTModule.MODIFICATIONS.add( new Add( builder.build() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void removeRecipe( IIngredient input )
|
||||
{
|
||||
for( ItemStack inStack : CTModule.toStacks( input ).orElse( Collections.emptySet() ) )
|
||||
{
|
||||
CTModule.MODIFICATIONS.add( new Remove( inStack ) );
|
||||
}
|
||||
}
|
||||
|
||||
private static class Add implements IAction
|
||||
{
|
||||
private final IGrinderRecipe entry;
|
||||
|
||||
private Add( IGrinderRecipe entry )
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply()
|
||||
{
|
||||
AEApi.instance().registries().grinder().addRecipe( entry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describe()
|
||||
{
|
||||
return "Adding Grinder Entry for " + entry.getInput().getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Remove implements IAction
|
||||
{
|
||||
private final ItemStack stack;
|
||||
|
||||
private Remove( ItemStack stack )
|
||||
{
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply()
|
||||
{
|
||||
IGrinderRecipe recipe = AEApi.instance().registries().grinder().getRecipeForInput( stack );
|
||||
if( recipe != null )
|
||||
{
|
||||
AEApi.instance().registries().grinder().removeRecipe( recipe );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describe()
|
||||
{
|
||||
return "Removing Grinder Entry for " + stack.getDisplayName();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.crafttweaker;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import crafttweaker.IAction;
|
||||
import crafttweaker.api.item.IIngredient;
|
||||
import crafttweaker.api.item.IItemStack;
|
||||
import stanhebben.zenscript.annotations.ZenClass;
|
||||
import stanhebben.zenscript.annotations.ZenMethod;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.features.IInscriberRecipe;
|
||||
import appeng.api.features.IInscriberRecipeBuilder;
|
||||
import appeng.api.features.IInscriberRegistry;
|
||||
import appeng.api.features.InscriberProcessType;
|
||||
|
||||
|
||||
@ZenClass( "mods.appliedenergistics2.Inscriber" )
|
||||
public class InscriberRecipes
|
||||
{
|
||||
private InscriberRecipes()
|
||||
{
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void addRecipe( IItemStack output, IIngredient input, boolean inscribe, @stanhebben.zenscript.annotations.Optional IIngredient top, @stanhebben.zenscript.annotations.Optional IIngredient bottom )
|
||||
{
|
||||
Optional<Collection<ItemStack>> inStacks = CTModule.toStacks( input );
|
||||
if( !inStacks.isPresent() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<ItemStack> topList = CTModule.toStacks( top ).orElse( Collections.singleton( ItemStack.EMPTY ) );
|
||||
Collection<ItemStack> bottomList = CTModule.toStacks( bottom ).orElse( Collections.singleton( ItemStack.EMPTY ) );
|
||||
|
||||
for( ItemStack topStack : topList )
|
||||
{
|
||||
for( ItemStack bottomStack : bottomList )
|
||||
{
|
||||
final IInscriberRecipeBuilder builder = AEApi.instance().registries().inscriber().builder();
|
||||
builder.withProcessType( inscribe ? InscriberProcessType.INSCRIBE : InscriberProcessType.PRESS )
|
||||
.withOutput( CTModule.toStack( output ) )
|
||||
.withInputs( inStacks.get() );
|
||||
|
||||
if( !topStack.isEmpty() )
|
||||
{
|
||||
builder.withTopOptional( topStack );
|
||||
}
|
||||
if( !bottomStack.isEmpty() )
|
||||
{
|
||||
builder.withBottomOptional( bottomStack );
|
||||
}
|
||||
CTModule.MODIFICATIONS.add( new Add( builder.build() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void removeRecipe( IItemStack output )
|
||||
{
|
||||
CTModule.MODIFICATIONS.add( new Remove( (ItemStack) output.getInternal() ) );
|
||||
}
|
||||
|
||||
private static class Add implements IAction
|
||||
{
|
||||
private final IInscriberRecipe entry;
|
||||
|
||||
private Add( IInscriberRecipe entry )
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply()
|
||||
{
|
||||
AEApi.instance().registries().inscriber().addRecipe( entry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describe()
|
||||
{
|
||||
return "Adding Inscriber Entry for " + entry.getOutput().getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Remove implements IAction
|
||||
{
|
||||
private final ItemStack stack;
|
||||
|
||||
private Remove( ItemStack stack )
|
||||
{
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply()
|
||||
{
|
||||
final IInscriberRegistry inscriber = AEApi.instance().registries().inscriber();
|
||||
inscriber.getRecipes()
|
||||
.stream()
|
||||
.filter( r -> r.getOutput().isItemEqual( this.stack ) )
|
||||
.collect( Collectors.toList() )
|
||||
.forEach( inscriber::removeRecipe );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describe()
|
||||
{
|
||||
return "Removing Inscriber Entry for " + stack.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.crafttweaker;
|
||||
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
import stanhebben.zenscript.annotations.ZenClass;
|
||||
import stanhebben.zenscript.annotations.ZenMethod;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.core.AELog;
|
||||
|
||||
|
||||
@ZenClass( "mods.appliedenergistics2.Spatial" )
|
||||
public class SpatialRegistry
|
||||
{
|
||||
private SpatialRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
@ZenMethod
|
||||
public static void whitelistEntity( String entityClassName )
|
||||
{
|
||||
Class<? extends TileEntity> entityClass = loadClass( entityClassName );
|
||||
if( entityClass != null )
|
||||
{
|
||||
AEApi.instance().registries().movable().whiteListTileEntity( entityClass );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private static Class<? extends TileEntity> loadClass( String className )
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Class<? extends TileEntity>) Class.forName( className );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
AELog.warn( e, "Failed to load TileEntity class '" + className + "'" );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -54,13 +54,12 @@ public class NetworkToolViewer implements INetworkTool, IAEAppEngInventory
|
||||
@Override
|
||||
public void saveChanges()
|
||||
{
|
||||
this.inv.markDirty( -1 );
|
||||
this.inv.writeToNBT( Platform.openNbtData( this.is ), "inv" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeInventory( IItemHandler inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack )
|
||||
{
|
||||
this.inv.writeToNBT( Platform.openNbtData( this.is ), "inv" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -211,6 +211,7 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
|
||||
public ItemStack getOutput( final ItemStack item )
|
||||
{
|
||||
ItemStack out = SIMPLE_CACHE.get( item );
|
||||
|
||||
if( out != null )
|
||||
{
|
||||
return out;
|
||||
@@ -224,12 +225,9 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
|
||||
|
||||
final ICraftingPatternDetails details = this.getPatternForItem( item, w );
|
||||
|
||||
if( details == null )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
out = details != null ? details.getOutputs()[0].createItemStack() : ItemStack.EMPTY;
|
||||
|
||||
SIMPLE_CACHE.put( item, out = details.getCondensedOutputs()[0].createItemStack() );
|
||||
SIMPLE_CACHE.put( item, out );
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,13 +219,11 @@ public class ToolNetworkTool extends AEBaseItem implements IGuiItem, IAEWrench,
|
||||
@Override
|
||||
public void toolUsed( ItemStack item, EntityLivingBase user, BlockPos pos )
|
||||
{
|
||||
user.swingArm( user.getActiveHand() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toolUsed( ItemStack item, EntityLivingBase user, Entity entity )
|
||||
{
|
||||
user.swingArm( user.getActiveHand() );
|
||||
}
|
||||
// IToolHammer - end
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ public class ToolColorApplicator extends AEBasePoweredItem implements IStorageCe
|
||||
final IAEItemStack firstItem = itemList.getFirstItem();
|
||||
if( firstItem != null )
|
||||
{
|
||||
newColor = firstItem.createItemStack();
|
||||
newColor = firstItem.asItemStackRepresentation();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -324,7 +324,7 @@ public class ToolColorApplicator extends AEBasePoweredItem implements IStorageCe
|
||||
list.addFirst( list.removeLast() );
|
||||
}
|
||||
|
||||
return list.get( 0 ).createItemStack();
|
||||
return list.get( 0 ).asItemStackRepresentation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,21 +85,10 @@ class PoweredItemCapabilities implements ICapabilityProvider, IEnergyStorage
|
||||
@Override
|
||||
public int receiveEnergy( int maxReceive, boolean simulate )
|
||||
{
|
||||
if( simulate )
|
||||
{
|
||||
final int required = (int) PowerUnits.AE.convertTo( PowerUnits.RF, this.item.getAEMaxPower( this.is ) - this.item.getAECurrentPower( this.is ) );
|
||||
final double convertedOffer = PowerUnits.RF.convertTo( PowerUnits.AE, maxReceive );
|
||||
final double overflow = this.item.injectAEPower( this.is, convertedOffer, simulate ? Actionable.SIMULATE : Actionable.MODULATE );
|
||||
|
||||
if( maxReceive < required )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return maxReceive - required;
|
||||
}
|
||||
else
|
||||
{
|
||||
final double powerRemainder = this.item.injectAEPower( this.is, PowerUnits.RF.convertTo( PowerUnits.AE, maxReceive ), Actionable.MODULATE );
|
||||
return maxReceive - (int) PowerUnits.AE.convertTo( PowerUnits.RF, powerRemainder );
|
||||
}
|
||||
return maxReceive - (int) PowerUnits.AE.convertTo( PowerUnits.RF, overflow );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -103,14 +103,13 @@ public class ToolQuartzWrench extends AEBaseItem implements IAEWrench, IToolHamm
|
||||
@Override
|
||||
public void toolUsed( ItemStack item, EntityLivingBase user, BlockPos pos )
|
||||
{
|
||||
user.swingArm( user.getActiveHand() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toolUsed( ItemStack item, EntityLivingBase user, Entity entity )
|
||||
{
|
||||
user.swingArm( user.getActiveHand() );
|
||||
}
|
||||
|
||||
// IToolHammer - end
|
||||
|
||||
// TODO: BC Wrench Integration
|
||||
|
||||
@@ -54,80 +54,11 @@ public class GridConnection implements IGridConnection, IPathItem
|
||||
private AEPartLocation fromAtoB;
|
||||
private GridNode sideB;
|
||||
|
||||
public GridConnection( final IGridNode aNode, final IGridNode bNode, final AEPartLocation fromAtoB ) throws FailedConnectionException
|
||||
private GridConnection( final GridNode aNode, final GridNode bNode, final AEPartLocation fromAtoB )
|
||||
{
|
||||
|
||||
final GridNode a = (GridNode) aNode;
|
||||
final GridNode b = (GridNode) bNode;
|
||||
|
||||
if( Platform.securityCheck( a, b ) )
|
||||
{
|
||||
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
|
||||
{
|
||||
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
|
||||
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
|
||||
|
||||
AELog.info( "Security audit 1 failed at [%s] belonging to player [id=%d]", aCoordinates.toString(), a.getPlayerID() );
|
||||
AELog.info( "Security audit 2 failed at [%s] belonging to player [id=%d]", bCoordinates.toString(), b.getPlayerID() );
|
||||
}
|
||||
|
||||
throw new SecurityConnectionException();
|
||||
}
|
||||
|
||||
if( a == null || b == null )
|
||||
{
|
||||
throw new NullNodeConnectionException();
|
||||
}
|
||||
|
||||
if( a.hasConnection( b ) || b.hasConnection( a ) )
|
||||
{
|
||||
final String aMachineClass = a.getGridBlock().getMachine().getClass().getSimpleName();
|
||||
final String bMachineClass = b.getGridBlock().getMachine().getClass().getSimpleName();
|
||||
final String aCoordinates = a.getGridBlock().getLocation().toString();
|
||||
final String bCoordinates = b.getGridBlock().getLocation().toString();
|
||||
|
||||
throw new ExistingConnectionException( String.format( EXISTING_CONNECTION_MESSAGE, aMachineClass, aCoordinates, bMachineClass, bCoordinates,
|
||||
fromAtoB ) );
|
||||
}
|
||||
|
||||
this.sideA = a;
|
||||
this.sideA = aNode;
|
||||
this.fromAtoB = fromAtoB;
|
||||
this.sideB = b;
|
||||
|
||||
if( b.getMyGrid() == null )
|
||||
{
|
||||
b.setGrid( a.getInternalGrid() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( a.getMyGrid() == null )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
||||
a.beginVisit( gp );
|
||||
}
|
||||
else if( b.getMyGrid() == null )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
||||
b.beginVisit( gp );
|
||||
}
|
||||
else if( this.isNetworkABetter( a, b ) )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
||||
b.beginVisit( gp );
|
||||
}
|
||||
else
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
||||
a.beginVisit( gp );
|
||||
}
|
||||
}
|
||||
|
||||
// a connection was destroyed RE-PATH!!
|
||||
final IPathingGrid p = this.sideA.getInternalGrid().getCache( IPathingGrid.class );
|
||||
p.repath();
|
||||
|
||||
this.sideA.addConnection( this );
|
||||
this.sideB.addConnection( this );
|
||||
this.sideB = bNode;
|
||||
}
|
||||
|
||||
private boolean isNetworkABetter( final GridNode a, final GridNode b )
|
||||
@@ -291,4 +222,81 @@ public class GridConnection implements IGridConnection, IPathItem
|
||||
{
|
||||
this.visitorIterationNumber = visitorIterationNumber;
|
||||
}
|
||||
|
||||
public static GridConnection create( final IGridNode aNode, final IGridNode bNode, final AEPartLocation fromAtoB ) throws FailedConnectionException
|
||||
{
|
||||
if( aNode == null || bNode == null )
|
||||
{
|
||||
throw new NullNodeConnectionException();
|
||||
}
|
||||
|
||||
final GridNode a = (GridNode) aNode;
|
||||
final GridNode b = (GridNode) bNode;
|
||||
|
||||
if( a.hasConnection( b ) || b.hasConnection( a ) )
|
||||
{
|
||||
final String aMachineClass = a.getGridBlock().getMachine().getClass().getSimpleName();
|
||||
final String bMachineClass = b.getGridBlock().getMachine().getClass().getSimpleName();
|
||||
final String aCoordinates = a.getGridBlock().getLocation().toString();
|
||||
final String bCoordinates = b.getGridBlock().getLocation().toString();
|
||||
|
||||
throw new ExistingConnectionException( String.format( EXISTING_CONNECTION_MESSAGE, aMachineClass, aCoordinates, bMachineClass, bCoordinates,
|
||||
fromAtoB ) );
|
||||
}
|
||||
|
||||
if( !Platform.securityCheck( a, b ) )
|
||||
{
|
||||
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
|
||||
{
|
||||
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
|
||||
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
|
||||
|
||||
AELog.info( "Security audit 1 failed at [%s] belonging to player [id=%d]", aCoordinates.toString(), a.getPlayerID() );
|
||||
AELog.info( "Security audit 2 failed at [%s] belonging to player [id=%d]", bCoordinates.toString(), b.getPlayerID() );
|
||||
}
|
||||
|
||||
throw new SecurityConnectionException();
|
||||
}
|
||||
|
||||
// Create the actual connection
|
||||
final GridConnection connection = new GridConnection( a, b, fromAtoB );
|
||||
|
||||
// Update both nodes with the new connection.
|
||||
if( a.getMyGrid() == null )
|
||||
{
|
||||
b.setGrid( a.getInternalGrid() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( a.getMyGrid() == null )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
||||
aNode.beginVisit( gp );
|
||||
}
|
||||
else if( b.getMyGrid() == null )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
||||
bNode.beginVisit( gp );
|
||||
}
|
||||
else if( connection.isNetworkABetter( a, b ) )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
||||
b.beginVisit( gp );
|
||||
}
|
||||
else
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
||||
a.beginVisit( gp );
|
||||
}
|
||||
}
|
||||
|
||||
// a connection was destroyed RE-PATH!!
|
||||
final IPathingGrid p = connection.sideA.getInternalGrid().getCache( IPathingGrid.class );
|
||||
p.repath();
|
||||
|
||||
connection.sideA.addConnection( connection );
|
||||
connection.sideB.addConnection( connection );
|
||||
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.exceptions.FailedConnectionException;
|
||||
import appeng.api.exceptions.SecurityConnectionException;
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.networking.GridNotification;
|
||||
import appeng.api.networking.IGrid;
|
||||
@@ -50,6 +51,7 @@ import appeng.api.util.AEColor;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.api.util.IReadOnlyCollection;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.me.pathfinding.IPathItem;
|
||||
@@ -216,7 +218,7 @@ public class GridNode implements IGridNode, IPathItem
|
||||
this.compressedData |= ( 1 << ( dir.ordinal() + 8 ) );
|
||||
}
|
||||
|
||||
this.FindConnections();
|
||||
this.findConnections();
|
||||
this.getInternalGrid();
|
||||
}
|
||||
|
||||
@@ -393,7 +395,7 @@ public class GridNode implements IGridNode, IPathItem
|
||||
return this.usedChannels;
|
||||
}
|
||||
|
||||
private void FindConnections()
|
||||
private void findConnections()
|
||||
{
|
||||
if( !this.gridProxy.isWorldAccessible() )
|
||||
{
|
||||
@@ -455,11 +457,18 @@ public class GridNode implements IGridNode, IPathItem
|
||||
// construct a new connection between these two nodes.
|
||||
try
|
||||
{
|
||||
new GridConnection( node, this, f.getOpposite() );
|
||||
GridConnection.create( node, this, f.getOpposite() );
|
||||
}
|
||||
catch( SecurityConnectionException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
|
||||
|
||||
return;
|
||||
}
|
||||
catch( final FailedConnectionException e )
|
||||
{
|
||||
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
|
||||
AELog.debug( e );
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -482,11 +491,19 @@ public class GridNode implements IGridNode, IPathItem
|
||||
// construct a new connection between these two nodes.
|
||||
try
|
||||
{
|
||||
new GridConnection( node, this, f.getOpposite() );
|
||||
GridConnection.create( node, this, f.getOpposite() );
|
||||
}
|
||||
catch( SecurityConnectionException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
|
||||
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
|
||||
|
||||
return;
|
||||
}
|
||||
catch( final FailedConnectionException e )
|
||||
{
|
||||
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
|
||||
AELog.debug( e );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
+9
-5
@@ -336,10 +336,7 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
@Override
|
||||
public double injectProviderPower( double amt, final Actionable mode )
|
||||
{
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
this.tickInjectionPerTick += amt;
|
||||
}
|
||||
final double originalAmount = amt;
|
||||
|
||||
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
|
||||
|
||||
@@ -354,7 +351,14 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
}
|
||||
}
|
||||
|
||||
return Math.max( 0.0, amt );
|
||||
final double overflow = Math.max( 0.0, amt );
|
||||
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
this.tickInjectionPerTick += originalAmount - overflow;
|
||||
}
|
||||
|
||||
return overflow;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+17
-14
@@ -26,6 +26,10 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridBlock;
|
||||
@@ -43,8 +47,9 @@ import appeng.api.networking.pathing.IPathingGrid;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.features.AEFeature;
|
||||
import appeng.core.stats.Achievements;
|
||||
import appeng.core.stats.IAdvancementTrigger;
|
||||
import appeng.me.GridConnection;
|
||||
import appeng.me.GridNode;
|
||||
import appeng.me.pathfinding.AdHocChannelUpdater;
|
||||
@@ -340,26 +345,24 @@ public class PathGridCache implements IPathingGrid
|
||||
{
|
||||
if( this.lastChannels != this.getChannelsInUse() && AEConfig.instance().isFeatureEnabled( AEFeature.CHANNELS ) )
|
||||
{
|
||||
final Achievements currentBracket = this.getAchievementBracket( this.getChannelsInUse() );
|
||||
final Achievements lastBracket = this.getAchievementBracket( this.lastChannels );
|
||||
final IAdvancementTrigger currentBracket = this.getAchievementBracket( this.getChannelsInUse() );
|
||||
final IAdvancementTrigger lastBracket = this.getAchievementBracket( this.lastChannels );
|
||||
if( currentBracket != lastBracket && currentBracket != null )
|
||||
{
|
||||
final Set<Integer> players = new HashSet<>();
|
||||
for( final IGridNode n : this.requireChannels )
|
||||
{
|
||||
players.add( n.getPlayerID() );
|
||||
EntityPlayer player = AEApi.instance().registries().players().findPlayer( n.getPlayerID() );
|
||||
if( player instanceof EntityPlayerMP )
|
||||
{
|
||||
currentBracket.trigger( (EntityPlayerMP) player );
|
||||
}
|
||||
}
|
||||
|
||||
// for( final int id : players )
|
||||
// {
|
||||
// Platform.addStat( id, currentBracket.getAchievement() );
|
||||
// }
|
||||
}
|
||||
}
|
||||
this.lastChannels = this.getChannelsInUse();
|
||||
}
|
||||
|
||||
private Achievements getAchievementBracket( final int ch )
|
||||
private IAdvancementTrigger getAchievementBracket( final int ch )
|
||||
{
|
||||
if( ch < 8 )
|
||||
{
|
||||
@@ -368,15 +371,15 @@ public class PathGridCache implements IPathingGrid
|
||||
|
||||
if( ch < 128 )
|
||||
{
|
||||
return Achievements.Networking1;
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkApprentice();
|
||||
}
|
||||
|
||||
if( ch < 2048 )
|
||||
{
|
||||
return Achievements.Networking2;
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkEngineer();
|
||||
}
|
||||
|
||||
return Achievements.Networking3;
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkAdmin();
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
|
||||
@@ -440,7 +440,6 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
this.lastTime = 0;
|
||||
this.elapsedTime = 0;
|
||||
this.isComplete = true;
|
||||
|
||||
}
|
||||
|
||||
private void updateCPU()
|
||||
|
||||
@@ -38,6 +38,7 @@ import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.WorldCoord;
|
||||
import appeng.core.AELog;
|
||||
import appeng.me.cache.helpers.ConnectionWrapper;
|
||||
import appeng.me.cluster.IAECluster;
|
||||
import appeng.tile.qnb.TileQuantumBridge;
|
||||
@@ -161,6 +162,7 @@ public class QuantumCluster implements ILocatable, IAECluster
|
||||
catch( final FailedConnectionException e )
|
||||
{
|
||||
// :(
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -241,11 +241,11 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
{
|
||||
try
|
||||
{
|
||||
new GridConnection( cn, sn, AEPartLocation.INTERNAL );
|
||||
GridConnection.create( cn, sn, AEPartLocation.INTERNAL );
|
||||
}
|
||||
catch( final FailedConnectionException e )
|
||||
{
|
||||
// ekk!
|
||||
AELog.debug( e );
|
||||
|
||||
bp.removeFromWorld();
|
||||
this.setCenter( null );
|
||||
@@ -292,11 +292,11 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
{
|
||||
try
|
||||
{
|
||||
new GridConnection( cn, sn, AEPartLocation.INTERNAL );
|
||||
GridConnection.create( cn, sn, AEPartLocation.INTERNAL );
|
||||
}
|
||||
catch( final FailedConnectionException e )
|
||||
{
|
||||
// ekk!
|
||||
AELog.debug( e );
|
||||
|
||||
bp.removeFromWorld();
|
||||
this.setSide( side, null );
|
||||
@@ -637,6 +637,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
catch( final FailedConnectionException e )
|
||||
{
|
||||
// ekk
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1087,7 +1088,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
this.getFacadeContainer().readFromNBT( data );
|
||||
}
|
||||
|
||||
public List getDrops( final List drops )
|
||||
public List<ItemStack> getDrops( final List<ItemStack> drops )
|
||||
{
|
||||
for( final AEPartLocation s : AEPartLocation.values() )
|
||||
{
|
||||
@@ -1111,7 +1112,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
return drops;
|
||||
}
|
||||
|
||||
public List getNoDrops( final List drops )
|
||||
public List<ItemStack> getNoDrops( final List<ItemStack> drops )
|
||||
{
|
||||
for( final AEPartLocation s : AEPartLocation.values() )
|
||||
{
|
||||
@@ -1150,12 +1151,15 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
@Override
|
||||
public CableBusRenderState getRenderState()
|
||||
{
|
||||
PartCable cable = (PartCable) this.getCenter();
|
||||
final PartCable cable = (PartCable) this.getCenter();
|
||||
|
||||
CableBusRenderState renderState = new CableBusRenderState();
|
||||
final CableBusRenderState renderState = new CableBusRenderState();
|
||||
|
||||
if( cable != null )
|
||||
{
|
||||
final boolean isSmart = cable.getCableConnectionType() == AECableType.SMART || cable.getCableConnectionType() == AECableType.DENSE_SMART;
|
||||
final boolean isDense = cable.getCableConnectionType() == AECableType.DENSE_COVERED || cable.getCableConnectionType() == AECableType.DENSE_SMART;
|
||||
|
||||
renderState.setCableColor( cable.getCableColor() );
|
||||
renderState.setCableType( cable.getCableConnectionType() );
|
||||
renderState.setCoreType( CableCoreType.fromCableType( cable.getCableConnectionType() ) );
|
||||
@@ -1175,12 +1179,12 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
// Only use the incoming cable-type of the adjacent block, if it's not a cable bus itself
|
||||
// Dense cables however also respect the adjacent cable-type since their outgoing connection
|
||||
// point would look too big for other cable types
|
||||
BlockPos adjacentPos = this.getTile().getPos().offset( facing );
|
||||
TileEntity adjacentTe = this.getTile().getWorld().getTileEntity( adjacentPos );
|
||||
final BlockPos adjacentPos = this.getTile().getPos().offset( facing );
|
||||
final TileEntity adjacentTe = this.getTile().getWorld().getTileEntity( adjacentPos );
|
||||
|
||||
if( adjacentTe instanceof IGridHost )
|
||||
{
|
||||
if( !( adjacentTe instanceof IPartHost ) || cable.getCableConnectionType() == AECableType.DENSE_SMART || cable
|
||||
.getCableConnectionType() == AECableType.DENSE_COVERED )
|
||||
if( !( adjacentTe instanceof IPartHost ) || isDense )
|
||||
{
|
||||
IGridHost gridHost = (IGridHost) adjacentTe;
|
||||
connectionType = gridHost.getCableConnectionType( AEPartLocation.fromFacing( facing.getOpposite() ) );
|
||||
@@ -1201,7 +1205,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
// adjacent tile requires it
|
||||
for( EnumFacing facing : EnumFacing.values() )
|
||||
{
|
||||
int channels = cable.getChannelsOnSide( facing );
|
||||
int channels = isSmart ? cable.getChannelsOnSide( facing ) : 0;
|
||||
renderState.getChannelsOnSide().put( facing, channels );
|
||||
}
|
||||
}
|
||||
@@ -1209,14 +1213,14 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
// Determine attachments and facades
|
||||
for( EnumFacing facing : EnumFacing.values() )
|
||||
{
|
||||
final FacadeRenderState facadeState = this.getFacadeRenderState( facing );
|
||||
|
||||
FacadeRenderState facadeState = this.getFacadeRenderState( facing );
|
||||
if( facadeState != null )
|
||||
{
|
||||
renderState.getFacades().put( facing, facadeState );
|
||||
}
|
||||
|
||||
IPart part = this.getPart( facing );
|
||||
final IPart part = this.getPart( facing );
|
||||
|
||||
if( part == null )
|
||||
{
|
||||
@@ -1224,15 +1228,17 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
}
|
||||
|
||||
// This will add the part's bounding boxes to the render state, which is required for facades
|
||||
AEPartLocation loc = AEPartLocation.fromFacing( facing );
|
||||
IPartCollisionHelper bch = new BusCollisionHelper( renderState.getBoundingBoxes(), loc, null, true );
|
||||
final AEPartLocation loc = AEPartLocation.fromFacing( facing );
|
||||
final IPartCollisionHelper bch = new BusCollisionHelper( renderState.getBoundingBoxes(), loc, null, true );
|
||||
|
||||
part.getBoxes( bch );
|
||||
|
||||
if( part instanceof IGridHost )
|
||||
{
|
||||
// Some attachments want a thicker cable than glass, account for that
|
||||
IGridHost gridHost = (IGridHost) part;
|
||||
AECableType desiredType = gridHost.getCableConnectionType( AEPartLocation.INTERNAL );
|
||||
final IGridHost gridHost = (IGridHost) part;
|
||||
final AECableType desiredType = gridHost.getCableConnectionType( AEPartLocation.INTERNAL );
|
||||
|
||||
if( renderState.getCoreType() == CableCoreType.GLASS && ( desiredType == AECableType.SMART || desiredType == AECableType.COVERED ) )
|
||||
{
|
||||
renderState.setCoreType( CableCoreType.COVERED );
|
||||
@@ -1254,14 +1260,16 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
private FacadeRenderState getFacadeRenderState( EnumFacing side )
|
||||
{
|
||||
// Store the "masqueraded" itemstack for the given side, if there is a facade
|
||||
IFacadePart facade = this.getFacade( side.ordinal() );
|
||||
final IFacadePart facade = this.getFacade( side.ordinal() );
|
||||
|
||||
if( facade != null )
|
||||
{
|
||||
ItemStack textureItem = facade.getTextureItem();
|
||||
IBlockState blockState = facade.getBlockState();
|
||||
final ItemStack textureItem = facade.getTextureItem();
|
||||
final IBlockState blockState = facade.getBlockState();
|
||||
|
||||
if( blockState != null && textureItem != null )
|
||||
{
|
||||
EnumSet<EnumFacing> openFaces = this.calculateFaceOpenFaces( side );
|
||||
final EnumSet<EnumFacing> openFaces = this.calculateFaceOpenFaces( side );
|
||||
return new FacadeRenderState( blockState, openFaces, textureItem );
|
||||
}
|
||||
}
|
||||
@@ -1273,9 +1281,9 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
{
|
||||
final EnumSet<EnumFacing> out = EnumSet.of( side, side.getOpposite() );
|
||||
final IFacadePart facade = this.getFacade( side.ordinal() );
|
||||
final IBlockAccess blockAccess = this.getTile().getWorld();
|
||||
final BlockPos pos = this.getTile().getPos();
|
||||
|
||||
IBlockAccess blockAccess = this.getTile().getWorld();
|
||||
BlockPos pos = this.getTile().getPos();
|
||||
for( final EnumFacing it : EnumFacing.values() )
|
||||
{
|
||||
if( !out.contains( it ) && this.hasAlphaDiff( blockAccess.getTileEntity( pos.offset( it ) ), side, facade ) )
|
||||
|
||||
@@ -29,6 +29,7 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemBlockSpecial;
|
||||
import net.minecraft.item.ItemFirework;
|
||||
import net.minecraft.item.ItemSkull;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -452,32 +453,14 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine
|
||||
|
||||
if( w.getBlockState( tePos ).getBlock().isReplaceable( w, tePos ) )
|
||||
{
|
||||
if( placeBlock == YesNo.YES && ( i instanceof ItemBlock || i instanceof IPlantable || i instanceof ItemSkull || i instanceof ItemFirework || i instanceof IPartItem || i == Item
|
||||
.getItemFromBlock(
|
||||
Blocks.REEDS ) ) )
|
||||
if( placeBlock == YesNo.YES && ( i instanceof ItemBlock || i instanceof ItemBlockSpecial || i instanceof IPlantable || i instanceof ItemSkull || i instanceof ItemFirework || i instanceof IPartItem || i == Item
|
||||
.getItemFromBlock( Blocks.REEDS ) ) )
|
||||
{
|
||||
final EntityPlayer player = Platform.getPlayer( (WorldServer) w );
|
||||
Platform.configurePlayer( player, side, this.getTile() );
|
||||
EnumHand hand = player.getActiveHand();
|
||||
player.setHeldItem( hand, is );
|
||||
|
||||
// TODO: LIMIT FIREWORKS
|
||||
/*
|
||||
* if( i instanceof ItemFirework )
|
||||
* {
|
||||
* Chunk c = w.getChunkFromBlockCoords( tePos );
|
||||
* int sum = 0;
|
||||
* for( List Z : c.geten )
|
||||
* {
|
||||
* sum += Z.size();
|
||||
* }
|
||||
* if( sum > 32 )
|
||||
* {
|
||||
* return input;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
maxStorage = is.getCount();
|
||||
worked = true;
|
||||
if( type == Actionable.MODULATE )
|
||||
|
||||
@@ -29,7 +29,6 @@ import net.minecraft.util.math.Vec3d;
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.PowerMultiplier;
|
||||
import appeng.api.config.RedstoneMode;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.Upgrades;
|
||||
@@ -41,7 +40,6 @@ import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.networking.ticking.TickingRequest;
|
||||
import appeng.api.parts.IPartCollisionHelper;
|
||||
import appeng.api.parts.IPartModel;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
@@ -72,9 +70,7 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/import_bus_has_channel" ) );
|
||||
|
||||
private final IActionSource source;
|
||||
private IMEInventory<IAEItemStack> destination = null;
|
||||
private IAEItemStack lastItemChecked = null;
|
||||
private int itemToSend; // used in tickingRequest
|
||||
private int itemsToSend; // used in tickingRequest
|
||||
private boolean worked; // used in tickingRequest
|
||||
|
||||
@Reflected
|
||||
@@ -95,14 +91,24 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
return false;
|
||||
}
|
||||
|
||||
final IAEItemStack out = this.destination.injectItems(
|
||||
this.lastItemChecked = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ), Actionable.SIMULATE,
|
||||
this.source );
|
||||
if( out == null )
|
||||
try
|
||||
{
|
||||
return true;
|
||||
final IMEMonitor<IAEItemStack> inv = this.getProxy().getStorage().getInventory(
|
||||
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
|
||||
final IAEItemStack out = inv.injectItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ),
|
||||
Actionable.SIMULATE,
|
||||
this.source );
|
||||
if( out == null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return out.getStackSize() != stack.getCount();
|
||||
}
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return out.getStackSize() != stack.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,9 +171,7 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
{
|
||||
try
|
||||
{
|
||||
this.itemToSend = this.calculateItemsToSend();
|
||||
this.itemToSend = Math.min( this.itemToSend,
|
||||
(int) ( 0.01 + this.getProxy().getEnergy().extractAEPower( this.itemToSend, Actionable.SIMULATE, PowerMultiplier.CONFIG ) ) );
|
||||
this.itemsToSend = this.calculateItemsToSend();
|
||||
|
||||
final IMEMonitor<IAEItemStack> inv = this.getProxy().getStorage().getInventory(
|
||||
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
@@ -177,10 +181,10 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
for( int x = 0; x < this.availableSlots(); x++ )
|
||||
{
|
||||
final IAEItemStack ais = this.getConfig().getAEStackInSlot( x );
|
||||
if( ais != null && this.itemToSend > 0 )
|
||||
if( ais != null && itemsToSend > 0 )
|
||||
{
|
||||
Configured = true;
|
||||
while( this.itemToSend > 0 )
|
||||
while( itemsToSend > 0 )
|
||||
{
|
||||
if( this.importStuff( myAdaptor, ais, inv, energy, fzMode ) )
|
||||
{
|
||||
@@ -192,7 +196,7 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
|
||||
if( !Configured )
|
||||
{
|
||||
while( this.itemToSend > 0 )
|
||||
while( itemsToSend > 0 )
|
||||
{
|
||||
if( this.importStuff( myAdaptor, null, inv, energy, fzMode ) )
|
||||
{
|
||||
@@ -221,38 +225,32 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
|
||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||
{
|
||||
newItems = myAdaptor.removeSimilarItems( toSend, whatToImport == null ? ItemStack.EMPTY : whatToImport.getDefinition(), fzMode,
|
||||
this.configDestination( inv ) );
|
||||
newItems = myAdaptor.removeSimilarItems( toSend, whatToImport == null ? ItemStack.EMPTY : whatToImport.getDefinition(), fzMode, this );
|
||||
}
|
||||
else
|
||||
{
|
||||
newItems = myAdaptor.removeItems( toSend, whatToImport == null ? ItemStack.EMPTY : whatToImport.getDefinition(), this.configDestination( inv ) );
|
||||
newItems = myAdaptor.removeItems( toSend, whatToImport == null ? ItemStack.EMPTY : whatToImport.getDefinition(), this );
|
||||
}
|
||||
|
||||
if( !newItems.isEmpty() )
|
||||
{
|
||||
newItems.setCount( (int) ( Math.min( newItems.getCount(),
|
||||
energy.extractAEPower( newItems.getCount(), Actionable.SIMULATE, PowerMultiplier.CONFIG ) ) + 0.01 ) );
|
||||
this.itemToSend -= newItems.getCount();
|
||||
|
||||
if( this.lastItemChecked == null || !this.lastItemChecked.isSameType( newItems ) )
|
||||
{
|
||||
this.lastItemChecked = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( newItems );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.lastItemChecked.setStackSize( newItems.getCount() );
|
||||
}
|
||||
|
||||
final IAEItemStack failed = Platform.poweredInsert( energy, this.destination, this.lastItemChecked, this.source );
|
||||
final IAEItemStack aeStack = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( newItems );
|
||||
final IAEItemStack failed = Platform.poweredInsert( energy, inv, aeStack, this.source );
|
||||
|
||||
if( failed != null )
|
||||
{
|
||||
myAdaptor.addItems( failed.createItemStack() );
|
||||
// try unpowered insert, better be a bit lenient then void items
|
||||
final IAEItemStack spill = inv.injectItems( failed, Actionable.MODULATE, this.source );
|
||||
if( spill != null )
|
||||
{
|
||||
// last resort try to put it back .. lets hope it's a chest type of thing
|
||||
myAdaptor.addItems( spill.createItemStack() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.itemsToSend -= newItems.getCount();
|
||||
this.worked = true;
|
||||
}
|
||||
}
|
||||
@@ -266,7 +264,7 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
|
||||
private int calculateMaximumAmountToImport( final InventoryAdaptor myAdaptor, final IAEItemStack whatToImport, final IMEMonitor<IAEItemStack> inv, final FuzzyMode fzMode )
|
||||
{
|
||||
final int toSend = Math.min( this.itemToSend, 64 );
|
||||
final int toSend = Math.min( this.itemsToSend, 64 );
|
||||
final ItemStack itemStackToImport;
|
||||
|
||||
if( whatToImport == null )
|
||||
@@ -282,13 +280,13 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
final ItemStack simResult;
|
||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||
{
|
||||
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, this.configDestination( inv ) );
|
||||
itemAmountNotStorable = this.destination.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
||||
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, this );
|
||||
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
||||
}
|
||||
else
|
||||
{
|
||||
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, this.configDestination( inv ) );
|
||||
itemAmountNotStorable = this.destination.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
||||
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, this );
|
||||
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
||||
}
|
||||
|
||||
if( itemAmountNotStorable != null )
|
||||
@@ -299,12 +297,6 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
||||
return toSend;
|
||||
}
|
||||
|
||||
private IInventoryDestination configDestination( final IMEMonitor<IAEItemStack> itemInventory )
|
||||
{
|
||||
this.destination = itemInventory;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSleeping()
|
||||
{
|
||||
|
||||
@@ -144,7 +144,10 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
||||
@Override
|
||||
public void saveChanges()
|
||||
{
|
||||
this.parent.saveChanges();
|
||||
if( this.parent != null )
|
||||
{
|
||||
this.parent.saveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
package appeng.parts.misc;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -36,11 +36,12 @@ import appeng.api.networking.storage.IBaseMonitor;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.core.AELog;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.IGridProxyable;
|
||||
import appeng.me.storage.ITickingMonitor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
@@ -51,20 +52,17 @@ import appeng.util.item.AEItemStack;
|
||||
*/
|
||||
class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
|
||||
{
|
||||
|
||||
private final Map<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
|
||||
|
||||
private IActionSource mySource;
|
||||
|
||||
private final IItemHandler itemHandler;
|
||||
private final IGridProxyable proxyable;
|
||||
private final InventoryCache cache;
|
||||
|
||||
private ItemStack[] cachedStacks = new ItemStack[0];
|
||||
|
||||
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
|
||||
|
||||
ItemHandlerAdapter( IItemHandler itemHandler )
|
||||
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
|
||||
{
|
||||
this.itemHandler = itemHandler;
|
||||
this.proxyable = proxy;
|
||||
this.cache = new InventoryCache( this.itemHandler );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,7 +89,14 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
this.onTick();
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
|
||||
return AEItemStack.fromItemStack( remaining );
|
||||
@@ -167,7 +172,14 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
{
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
this.onTick();
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
|
||||
return AEItemStack.fromItemStack( gathered );
|
||||
@@ -176,72 +188,10 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
return null;
|
||||
}
|
||||
|
||||
private ItemStack getItemStackInCachedSlot( int pos )
|
||||
{
|
||||
if( pos > this.cachedStacks.length )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if( this.cachedStacks[pos] == null )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
return this.cachedStacks[pos];
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
LinkedList<IAEItemStack> changes = new LinkedList<>();
|
||||
|
||||
int slots = this.itemHandler.getSlots();
|
||||
|
||||
// Make room for new slots
|
||||
if( slots > this.cachedStacks.length )
|
||||
{
|
||||
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
|
||||
for( int slot = 0; slot < slots; slot++ )
|
||||
{
|
||||
// Save the old stuff
|
||||
ItemStack oldIS = this.getItemStackInCachedSlot( slot );
|
||||
IAEItemStack oldAeIS = this.cachedAeStacks[slot];
|
||||
|
||||
ItemStack newIS = this.itemHandler.getStackInSlot( slot );
|
||||
|
||||
if( this.isDifferent( newIS, oldIS ) )
|
||||
{
|
||||
this.addItemChange( slot, oldAeIS, newIS, changes );
|
||||
}
|
||||
else if( !newIS.isEmpty() && !oldIS.isEmpty() )
|
||||
{
|
||||
this.addPossibleStackSizeChange( slot, oldAeIS, newIS, changes );
|
||||
}
|
||||
}
|
||||
|
||||
// Handle cases where the number of slots actually is lower now than before
|
||||
if( slots < this.cachedStacks.length )
|
||||
{
|
||||
for( int slot = slots; slot < this.cachedStacks.length; slot++ )
|
||||
{
|
||||
IAEItemStack aeStack = this.cachedAeStacks[slot];
|
||||
if( aeStack != null )
|
||||
{
|
||||
IAEItemStack a = aeStack.copy();
|
||||
a.setStackSize( -a.getStackSize() );
|
||||
changes.add( a );
|
||||
}
|
||||
}
|
||||
|
||||
// Reduce the cache size
|
||||
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
|
||||
List<IAEItemStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
@@ -253,73 +203,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
}
|
||||
}
|
||||
|
||||
private void addItemChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
||||
{
|
||||
// Completely different item
|
||||
this.cachedStacks[slot] = newIS;
|
||||
this.cachedAeStacks[slot] = AEItemStack.fromItemStack( newIS );
|
||||
|
||||
// If we had a stack previously in this slot, notify the newtork about its disappearance
|
||||
if( oldAeIS != null )
|
||||
{
|
||||
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
|
||||
changes.add( oldAeIS );
|
||||
}
|
||||
|
||||
// Notify the network about the new stack. Note that this is null if newIS was null
|
||||
if( this.cachedAeStacks[slot] != null )
|
||||
{
|
||||
changes.add( this.cachedAeStacks[slot] );
|
||||
}
|
||||
}
|
||||
|
||||
private void addPossibleStackSizeChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
||||
{
|
||||
// Still the same item, but amount might have changed
|
||||
long diff = newIS.getCount() - oldAeIS.getStackSize();
|
||||
|
||||
if( diff != 0 )
|
||||
{
|
||||
IAEItemStack stack = oldAeIS.copy();
|
||||
stack.setStackSize( newIS.getCount() );
|
||||
|
||||
this.cachedStacks[slot] = newIS;
|
||||
this.cachedAeStacks[slot] = stack;
|
||||
|
||||
final IAEItemStack a = stack.copy();
|
||||
a.setStackSize( diff );
|
||||
changes.add( a );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDifferent( final ItemStack a, final ItemStack b )
|
||||
{
|
||||
if( a == b && b.isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return a.isEmpty() || b.isEmpty() || !Platform.itemComparisons().isSameItem( a, b );
|
||||
}
|
||||
|
||||
private void postDifference( Iterable<IAEItemStack> a )
|
||||
{
|
||||
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||
if( key.isValid( l.getValue() ) )
|
||||
{
|
||||
key.postChange( this, a, this.mySource );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionSource( final IActionSource mySource )
|
||||
{
|
||||
@@ -339,7 +222,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel getChannel()
|
||||
public IItemStorageChannel getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
@@ -355,4 +238,152 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
{
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
|
||||
private void postDifference( Iterable<IAEItemStack> a )
|
||||
{
|
||||
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||
if( key.isValid( l.getValue() ) )
|
||||
{
|
||||
key.postChange( this, a, this.mySource );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class InventoryCache
|
||||
{
|
||||
private ItemStack[] cachedStacks = new ItemStack[0];
|
||||
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
|
||||
private final IItemHandler itemHandler;
|
||||
|
||||
public InventoryCache( IItemHandler itemHandler )
|
||||
{
|
||||
this.itemHandler = itemHandler;
|
||||
}
|
||||
|
||||
public List<IAEItemStack> update()
|
||||
{
|
||||
List<IAEItemStack> changes = new ArrayList<>();
|
||||
|
||||
int slots = this.itemHandler.getSlots();
|
||||
|
||||
// Make room for new slots
|
||||
if( slots > this.cachedStacks.length )
|
||||
{
|
||||
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
|
||||
for( int slot = 0; slot < slots; slot++ )
|
||||
{
|
||||
// Save the old stuff
|
||||
ItemStack oldIS = this.getItemStackInCachedSlot( slot );
|
||||
IAEItemStack oldAeIS = this.cachedAeStacks[slot];
|
||||
|
||||
ItemStack newIS = this.itemHandler.getStackInSlot( slot );
|
||||
|
||||
if( isDifferent( newIS, oldIS ) )
|
||||
{
|
||||
this.addItemChange( slot, oldAeIS, newIS, changes );
|
||||
}
|
||||
else if( !newIS.isEmpty() && !oldIS.isEmpty() )
|
||||
{
|
||||
this.addPossibleStackSizeChange( slot, oldAeIS, newIS, changes );
|
||||
}
|
||||
}
|
||||
|
||||
// Handle cases where the number of slots actually is lower now than before
|
||||
if( slots < this.cachedStacks.length )
|
||||
{
|
||||
for( int slot = slots; slot < this.cachedStacks.length; slot++ )
|
||||
{
|
||||
IAEItemStack aeStack = this.cachedAeStacks[slot];
|
||||
if( aeStack != null )
|
||||
{
|
||||
IAEItemStack a = aeStack.copy();
|
||||
a.setStackSize( -a.getStackSize() );
|
||||
changes.add( a );
|
||||
}
|
||||
}
|
||||
|
||||
// Reduce the cache size
|
||||
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
private void addPossibleStackSizeChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
||||
{
|
||||
// Still the same item, but amount might have changed
|
||||
long diff = newIS.getCount() - oldAeIS.getStackSize();
|
||||
|
||||
if( diff != 0 )
|
||||
{
|
||||
IAEItemStack stack = oldAeIS.copy();
|
||||
stack.setStackSize( newIS.getCount() );
|
||||
|
||||
this.cachedStacks[slot] = newIS;
|
||||
this.cachedAeStacks[slot] = stack;
|
||||
|
||||
final IAEItemStack a = stack.copy();
|
||||
a.setStackSize( diff );
|
||||
changes.add( a );
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack getItemStackInCachedSlot( int pos )
|
||||
{
|
||||
if( pos > this.cachedStacks.length )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if( this.cachedStacks[pos] == null )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
return this.cachedStacks[pos];
|
||||
}
|
||||
|
||||
private void addItemChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
||||
{
|
||||
// Completely different item
|
||||
this.cachedStacks[slot] = newIS;
|
||||
this.cachedAeStacks[slot] = AEItemStack.fromItemStack( newIS );
|
||||
|
||||
// If we had a stack previously in this slot, notify the newtork about its disappearance
|
||||
if( oldAeIS != null )
|
||||
{
|
||||
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
|
||||
changes.add( oldAeIS );
|
||||
}
|
||||
|
||||
// Notify the network about the new stack. Note that this is null if newIS was null
|
||||
if( this.cachedAeStacks[slot] != null )
|
||||
{
|
||||
changes.add( this.cachedAeStacks[slot] );
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDifferent( final ItemStack a, final ItemStack b )
|
||||
{
|
||||
if( a == b && b.isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return a.isEmpty() || b.isEmpty() || !Platform.itemComparisons().isSameItem( a, b );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
package appeng.parts.misc;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -67,7 +66,6 @@ import appeng.api.storage.IStorageMonitorable;
|
||||
import appeng.api.storage.IStorageMonitorableAccessor;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.api.util.AECableType;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
@@ -113,7 +111,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
private int priority = 0;
|
||||
private boolean cached = false;
|
||||
private ITickingMonitor monitor = null;
|
||||
private MEInventoryHandler<? extends IAEStack> handler = null;
|
||||
private MEInventoryHandler<IAEItemStack> handler = null;
|
||||
private int handlerHash = 0;
|
||||
private boolean wasActive = false;
|
||||
private byte resetCacheLogic = 0;
|
||||
@@ -356,22 +354,18 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
|
||||
final IMEInventory<IAEItemStack> out = this.getInternalHandler();
|
||||
|
||||
if( this.monitor != null )
|
||||
if( in != out )
|
||||
{
|
||||
this.monitor.onTick();
|
||||
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
if( out != null )
|
||||
{
|
||||
after = out.getAvailableItems( after );
|
||||
}
|
||||
Platform.postListChanges( before, after, this, this.mySrc );
|
||||
}
|
||||
|
||||
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
if( out != null )
|
||||
{
|
||||
after = out.getAvailableItems( after );
|
||||
}
|
||||
|
||||
Platform.postListChanges( before, after, this, this.mySrc );
|
||||
}
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private IMEInventory<? extends IAEItemStack> getInventoryWrapper( TileEntity target )
|
||||
private IMEInventory<IAEItemStack> getInventoryWrapper( TileEntity target )
|
||||
{
|
||||
|
||||
EnumFacing targetSide = this.getSide().getFacing().getOpposite();
|
||||
@@ -398,7 +392,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
IItemHandler handlerExt = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide );
|
||||
if( handlerExt != null )
|
||||
{
|
||||
return new ItemHandlerAdapter( handlerExt );
|
||||
return new ItemHandlerAdapter( handlerExt, this );
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -429,7 +423,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
return 0;
|
||||
}
|
||||
|
||||
public MEInventoryHandler getInternalHandler()
|
||||
public MEInventoryHandler<IAEItemStack> getInternalHandler()
|
||||
{
|
||||
if( this.cached )
|
||||
{
|
||||
@@ -453,7 +447,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
this.monitor = null;
|
||||
if( target != null )
|
||||
{
|
||||
IMEInventory<? extends IAEStack> inv = this.getInventoryWrapper( target );
|
||||
IMEInventory<IAEItemStack> inv = this.getInventoryWrapper( target );
|
||||
|
||||
if( inv instanceof MEMonitorIInventory )
|
||||
{
|
||||
@@ -471,7 +465,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
{
|
||||
this.checkInterfaceVsStorageBus( target, this.getSide().getOpposite() );
|
||||
|
||||
this.handler = new MEInventoryHandler( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
this.handler = new MEInventoryHandler<IAEItemStack>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
|
||||
this.handler.setBaseAccess( (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
|
||||
@@ -492,16 +486,17 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||
{
|
||||
this.handler
|
||||
.setPartitionList( new FuzzyPriorityList( priorityList, (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ) ) );
|
||||
.setPartitionList( new FuzzyPriorityList<IAEItemStack>( priorityList, (FuzzyMode) this.getConfigManager()
|
||||
.getSetting( Settings.FUZZY_MODE ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.handler.setPartitionList( new PrecisePriorityList( priorityList ) );
|
||||
this.handler.setPartitionList( new PrecisePriorityList<IAEItemStack>( priorityList ) );
|
||||
}
|
||||
|
||||
if( inv instanceof IBaseMonitor )
|
||||
{
|
||||
( (IBaseMonitor) inv ).addListener( this, this.handler );
|
||||
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -571,7 +566,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
{
|
||||
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||
{
|
||||
final IMEInventoryHandler out = this.getProxy().isActive() ? this.getInternalHandler() : null;
|
||||
final IMEInventoryHandler<IAEItemStack> out = this.getProxy().isActive() ? this.getInternalHandler() : null;
|
||||
if( out != null )
|
||||
{
|
||||
return Collections.singletonList( out );
|
||||
|
||||
@@ -41,6 +41,7 @@ import appeng.api.parts.IPartHost;
|
||||
import appeng.api.parts.IPartModel;
|
||||
import appeng.api.util.AECableType;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.helpers.Reflected;
|
||||
import appeng.items.parts.PartModels;
|
||||
@@ -208,6 +209,7 @@ public class PartToggleBus extends PartBasicState
|
||||
catch( final FailedConnectionException e )
|
||||
{
|
||||
// :(
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -247,6 +247,8 @@ public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> implements I
|
||||
{
|
||||
final TileEntity start = this.getTile();
|
||||
final TileEntity end = me.getTile();
|
||||
|
||||
AELog.debug( e );
|
||||
|
||||
AELog.warn( "Failed to establish a ME P2P Tunnel between the tunnels at [x=%d, y=%d, z=%d] and [x=%d, y=%d, z=%d]",
|
||||
start.getPos().getX(), start.getPos().getY(), start.getPos().getZ(), end.getPos().getX(), end.getPos().getY(),
|
||||
|
||||
@@ -117,8 +117,11 @@ public abstract class AbstractPartReporting extends AEBasePart implements IPartM
|
||||
@Override
|
||||
public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor )
|
||||
{
|
||||
this.opacity = -1;
|
||||
this.getHost().markForUpdate();
|
||||
if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) )
|
||||
{
|
||||
this.opacity = -1;
|
||||
this.getHost().markForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,19 +19,34 @@
|
||||
package appeng.recipes.factories.recipes;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.JsonUtils;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.common.crafting.IRecipeFactory;
|
||||
import net.minecraftforge.common.crafting.JsonContext;
|
||||
import net.minecraftforge.oredict.ShapedOreRecipe;
|
||||
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.recipes.ResolverResult;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.recipes.helpers.PartShapedCraftingFactory;
|
||||
import appeng.recipes.helpers.PartShapelessCraftingFactory;
|
||||
|
||||
|
||||
/**
|
||||
@@ -45,25 +60,148 @@ public class PartRecipeFactory implements IRecipeFactory
|
||||
String type = JsonUtils.getString( json, "type" );
|
||||
if( type.contains( "shaped" ) )
|
||||
{
|
||||
PartShapedCraftingFactory recipe = PartShapedCraftingFactory.factory( context, json );
|
||||
CraftingHelper.ShapedPrimer primer = new CraftingHelper.ShapedPrimer();
|
||||
primer.width = recipe.getWidth();
|
||||
primer.height = recipe.getHeight();
|
||||
primer.mirrored = JsonUtils.getBoolean( json, "mirrored", true );
|
||||
primer.input = recipe.getIngredients();
|
||||
|
||||
return new PartShapedCraftingFactory( new ResourceLocation( AppEng.MOD_ID, "part_shaped_crafting" ), recipe.getRecipeOutput(), primer );
|
||||
return shapedFactory( context, json );
|
||||
}
|
||||
else if( type.contains( "shapeless" ) )
|
||||
{
|
||||
PartShapelessCraftingFactory recipe = PartShapelessCraftingFactory.factory( context, json );
|
||||
|
||||
return new PartShapelessCraftingFactory( new ResourceLocation( AppEng.MOD_ID, "part_shapeless_crafting" ), recipe.getIngredients(), recipe
|
||||
.getRecipeOutput() );
|
||||
return shapelessFactory( context, json );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonSyntaxException( "Applied Energistics 2 was given a custom recipe that it does not know how to handle!\n" + "Type should either be '" + AppEng.MOD_ID + ":shapeless' or '" + AppEng.MOD_ID + ":shaped', got '" + type + "'!" );
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemStack getResult( JsonObject json, JsonContext context )
|
||||
{
|
||||
JsonObject resultObject = JsonUtils.getJsonObject( json, "result" );
|
||||
|
||||
if( resultObject.has( "part" ) )
|
||||
{
|
||||
return getPart( resultObject );
|
||||
}
|
||||
else if( resultObject.has( "item" ) )
|
||||
{
|
||||
return CraftingHelper.getItemStack( resultObject, context );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonSyntaxException( "Result has no 'part' or 'item' property." );
|
||||
}
|
||||
}
|
||||
|
||||
private static ItemStack getPart( JsonObject resultObject )
|
||||
{
|
||||
String ingredient = JsonUtils.getString( resultObject, "part" );
|
||||
Object result = AEApi.instance().registries().recipes().resolveItem( AppEng.MOD_ID, ingredient );
|
||||
if( result instanceof ResolverResult )
|
||||
{
|
||||
ResolverResult resolverResult = (ResolverResult) result;
|
||||
|
||||
Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
|
||||
|
||||
if( item == null )
|
||||
{
|
||||
AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" );
|
||||
throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" );
|
||||
}
|
||||
|
||||
return new ItemStack( item, JsonUtils.getInt( resultObject, "count", 1 ), resolverResult.damageValue, resolverResult.compound );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\n" + "Was looking for : '" + ingredient + "'." );
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from ShapedOreRecipe.java, modified a bit.
|
||||
private static ShapedOreRecipe shapedFactory( JsonContext context, JsonObject json )
|
||||
{
|
||||
String group = JsonUtils.getString( json, "group", "" );
|
||||
|
||||
Map<Character, Ingredient> ingMap = Maps.newHashMap();
|
||||
for( Map.Entry<String, JsonElement> entry : JsonUtils.getJsonObject( json, "key" ).entrySet() )
|
||||
{
|
||||
if( entry.getKey().length() != 1 )
|
||||
{
|
||||
throw new JsonSyntaxException( "Invalid key entry: '" + entry.getKey() + "' is an invalid symbol (must be 1 character only)." );
|
||||
}
|
||||
if( " ".equals( entry.getKey() ) )
|
||||
{
|
||||
throw new JsonSyntaxException( "Invalid key entry: ' ' is a reserved symbol." );
|
||||
}
|
||||
|
||||
ingMap.put( entry.getKey().toCharArray()[0], CraftingHelper.getIngredient( entry.getValue(), context ) );
|
||||
}
|
||||
|
||||
ingMap.put( ' ', net.minecraft.item.crafting.Ingredient.EMPTY );
|
||||
|
||||
JsonArray patternJ = JsonUtils.getJsonArray( json, "pattern" );
|
||||
|
||||
if( patternJ.size() == 0 )
|
||||
{
|
||||
throw new JsonSyntaxException( "Invalid pattern: empty pattern not allowed" );
|
||||
}
|
||||
|
||||
String[] pattern = new String[patternJ.size()];
|
||||
for( int x = 0; x < pattern.length; ++x )
|
||||
{
|
||||
String line = JsonUtils.getString( patternJ.get( x ), "pattern[" + x + "]" );
|
||||
if( x > 0 && pattern[0].length() != line.length() )
|
||||
{
|
||||
throw new JsonSyntaxException( "Invalid pattern: each row must be the same width" );
|
||||
}
|
||||
pattern[x] = line;
|
||||
}
|
||||
|
||||
CraftingHelper.ShapedPrimer primer = new CraftingHelper.ShapedPrimer();
|
||||
primer.width = pattern[0].length();
|
||||
primer.height = pattern.length;
|
||||
primer.mirrored = JsonUtils.getBoolean( json, "mirrored", true );
|
||||
primer.input = NonNullList.withSize( primer.width * primer.height, net.minecraft.item.crafting.Ingredient.EMPTY );
|
||||
|
||||
Set<Character> keys = Sets.newHashSet( ingMap.keySet() );
|
||||
keys.remove( ' ' );
|
||||
|
||||
int x = 0;
|
||||
for( String line : pattern )
|
||||
{
|
||||
for( char chr : line.toCharArray() )
|
||||
{
|
||||
net.minecraft.item.crafting.Ingredient ing = ingMap.get( chr );
|
||||
if( ing == null )
|
||||
{
|
||||
throw new JsonSyntaxException( "Pattern references symbol '" + chr + "' but it's not defined in the key" );
|
||||
}
|
||||
primer.input.set( x++, ing );
|
||||
keys.remove( chr );
|
||||
}
|
||||
}
|
||||
|
||||
if( !keys.isEmpty() )
|
||||
{
|
||||
throw new JsonSyntaxException( "Key defines symbols that aren't used in pattern: " + keys );
|
||||
}
|
||||
|
||||
return new ShapedOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), getResult( json, context ), primer );
|
||||
}
|
||||
|
||||
// Copied from ShapelessOreRecipe.java, modified a bit.
|
||||
private static ShapelessOreRecipe shapelessFactory( JsonContext context, JsonObject json )
|
||||
{
|
||||
String group = JsonUtils.getString( json, "group", "" );
|
||||
|
||||
NonNullList<Ingredient> ings = NonNullList.create();
|
||||
for( JsonElement ele : JsonUtils.getJsonArray( json, "ingredients" ) )
|
||||
{
|
||||
ings.add( CraftingHelper.getIngredient( ele, context ) );
|
||||
}
|
||||
|
||||
if( ings.isEmpty() )
|
||||
{
|
||||
throw new JsonParseException( "No ingredients for shapeless recipe" );
|
||||
}
|
||||
|
||||
return new ShapelessOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), ings, getResult( json, context ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.recipes.helpers;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.JsonUtils;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.common.crafting.JsonContext;
|
||||
import net.minecraftforge.oredict.ShapedOreRecipe;
|
||||
|
||||
import appeng.api.recipes.ResolverResult;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.AppEng;
|
||||
|
||||
|
||||
/**
|
||||
* @author GuntherDW
|
||||
*/
|
||||
public class PartShapedCraftingFactory extends ShapedOreRecipe
|
||||
{
|
||||
|
||||
public PartShapedCraftingFactory( ResourceLocation group, @Nonnull ItemStack result, CraftingHelper.ShapedPrimer primer )
|
||||
{
|
||||
super( group, result, primer );
|
||||
}
|
||||
|
||||
// Copied from ShapedOreRecipe.java, modified a bit.
|
||||
public static PartShapedCraftingFactory factory( JsonContext context, JsonObject json )
|
||||
{
|
||||
String group = JsonUtils.getString( json, "group", "" );
|
||||
|
||||
Map<Character, Ingredient> ingMap = Maps.newHashMap();
|
||||
for( Map.Entry<String, JsonElement> entry : JsonUtils.getJsonObject( json, "key" ).entrySet() )
|
||||
{
|
||||
if( entry.getKey().length() != 1 )
|
||||
{
|
||||
throw new JsonSyntaxException( "Invalid key entry: '" + entry.getKey() + "' is an invalid symbol (must be 1 character only)." );
|
||||
}
|
||||
if( " ".equals( entry.getKey() ) )
|
||||
{
|
||||
throw new JsonSyntaxException( "Invalid key entry: ' ' is a reserved symbol." );
|
||||
}
|
||||
|
||||
ingMap.put( entry.getKey().toCharArray()[0], CraftingHelper.getIngredient( entry.getValue(), context ) );
|
||||
}
|
||||
|
||||
ingMap.put( ' ', net.minecraft.item.crafting.Ingredient.EMPTY );
|
||||
|
||||
JsonArray patternJ = JsonUtils.getJsonArray( json, "pattern" );
|
||||
|
||||
if( patternJ.size() == 0 )
|
||||
{
|
||||
throw new JsonSyntaxException( "Invalid pattern: empty pattern not allowed" );
|
||||
}
|
||||
|
||||
String[] pattern = new String[patternJ.size()];
|
||||
for( int x = 0; x < pattern.length; ++x )
|
||||
{
|
||||
String line = JsonUtils.getString( patternJ.get( x ), "pattern[" + x + "]" );
|
||||
if( x > 0 && pattern[0].length() != line.length() )
|
||||
{
|
||||
throw new JsonSyntaxException( "Invalid pattern: each row must be the same width" );
|
||||
}
|
||||
pattern[x] = line;
|
||||
}
|
||||
|
||||
CraftingHelper.ShapedPrimer primer = new CraftingHelper.ShapedPrimer();
|
||||
primer.width = pattern[0].length();
|
||||
primer.height = pattern.length;
|
||||
primer.mirrored = JsonUtils.getBoolean( json, "mirrored", true );
|
||||
primer.input = NonNullList.withSize( primer.width * primer.height, net.minecraft.item.crafting.Ingredient.EMPTY );
|
||||
|
||||
Set<Character> keys = Sets.newHashSet( ingMap.keySet() );
|
||||
keys.remove( ' ' );
|
||||
|
||||
int x = 0;
|
||||
for( String line : pattern )
|
||||
{
|
||||
for( char chr : line.toCharArray() )
|
||||
{
|
||||
net.minecraft.item.crafting.Ingredient ing = ingMap.get( chr );
|
||||
if( ing == null )
|
||||
{
|
||||
throw new JsonSyntaxException( "Pattern references symbol '" + chr + "' but it's not defined in the key" );
|
||||
}
|
||||
primer.input.set( x++, ing );
|
||||
keys.remove( chr );
|
||||
}
|
||||
}
|
||||
|
||||
if( !keys.isEmpty() )
|
||||
{
|
||||
throw new JsonSyntaxException( "Key defines symbols that aren't used in pattern: " + keys );
|
||||
}
|
||||
|
||||
JsonObject resultObject = (JsonObject) json.get( "result" );
|
||||
int count = JsonUtils.getInt( resultObject, "count", 1 );
|
||||
|
||||
String ingredient = resultObject.get( "part" ).getAsString();
|
||||
Object result = (Object) Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient );
|
||||
if( result instanceof ResolverResult )
|
||||
{
|
||||
ResolverResult resolverResult = (ResolverResult) result;
|
||||
|
||||
Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
|
||||
if( item == null )
|
||||
{
|
||||
AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" );
|
||||
throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" );
|
||||
}
|
||||
ItemStack itemStack = new ItemStack( item, count, resolverResult.damageValue, resolverResult.compound );
|
||||
|
||||
return new PartShapedCraftingFactory( group.isEmpty() ? null : new ResourceLocation( group ), itemStack, primer );
|
||||
}
|
||||
|
||||
// Should never reach this part unless mangled JSON or bug in AE.
|
||||
throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\nWas looking for : '" + ingredient + "'." );
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2017, 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.recipes.helpers;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.JsonUtils;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.common.crafting.JsonContext;
|
||||
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
|
||||
import appeng.api.recipes.ResolverResult;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.AppEng;
|
||||
|
||||
|
||||
/**
|
||||
* @author GuntherDW
|
||||
*/
|
||||
public class PartShapelessCraftingFactory extends ShapelessOreRecipe
|
||||
{
|
||||
|
||||
public PartShapelessCraftingFactory( ResourceLocation group, NonNullList<Ingredient> input, @Nonnull ItemStack result )
|
||||
{
|
||||
super( group, input, result );
|
||||
}
|
||||
|
||||
// Copied from ShapelessOreRecipe.java, modified a bit.
|
||||
public static PartShapelessCraftingFactory factory( JsonContext context, JsonObject json )
|
||||
{
|
||||
String group = JsonUtils.getString( json, "group", "" );
|
||||
|
||||
NonNullList<Ingredient> ings = NonNullList.create();
|
||||
for( JsonElement ele : JsonUtils.getJsonArray( json, "ingredients" ) )
|
||||
{
|
||||
ings.add( CraftingHelper.getIngredient( ele, context ) );
|
||||
}
|
||||
|
||||
if( ings.isEmpty() )
|
||||
{
|
||||
throw new JsonParseException( "No ingredients for shapeless recipe" );
|
||||
}
|
||||
|
||||
JsonObject resultObject = (JsonObject) json.get( "result" );
|
||||
int count = JsonUtils.getInt( resultObject, "count", 1 );
|
||||
|
||||
String ingredient = resultObject.get( "part" ).getAsString();
|
||||
Object result = (Object) Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient );
|
||||
if( result instanceof ResolverResult )
|
||||
{
|
||||
ResolverResult resolverResult = (ResolverResult) result;
|
||||
|
||||
Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
|
||||
|
||||
if( item == null )
|
||||
{
|
||||
AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" );
|
||||
throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" );
|
||||
}
|
||||
|
||||
ItemStack itemStack = new ItemStack( item, count, resolverResult.damageValue, resolverResult.compound );
|
||||
|
||||
return new PartShapelessCraftingFactory( group.isEmpty() ? null : new ResourceLocation( group ), ings, itemStack );
|
||||
}
|
||||
|
||||
throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\n" + "Was looking for : '" + ingredient + "'." );
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
@@ -58,7 +57,6 @@ public class RecipeResourceCopier
|
||||
private static final String FILE_PROTOCOL = "file";
|
||||
private static final String CLASS_EXTENSION = ".class";
|
||||
private static final String JAR_PROTOCOL = "jar";
|
||||
private static final String UTF_8_ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* copy source in the jar
|
||||
@@ -225,9 +223,9 @@ public class RecipeResourceCopier
|
||||
{
|
||||
/* A JAR path */
|
||||
final String dirPath = dirURL.getPath();
|
||||
final String jarPath = dirPath.substring( 5, dirPath.indexOf( '!' ) ); // strip out only
|
||||
final String jarPath = dirPath.substring( 0, dirPath.indexOf( '!' ) ); // strip out only
|
||||
// the JAR file
|
||||
final JarFile jar = new JarFile( URLDecoder.decode( jarPath, UTF_8_ENCODING ) );
|
||||
final JarFile jar = new JarFile( new File( new URI( jarPath ) ) );
|
||||
try
|
||||
{
|
||||
final Enumeration<JarEntry> entries = jar.entries(); // gives ALL entries in jar
|
||||
|
||||
@@ -27,7 +27,7 @@ public class BiomeGenStorage extends Biome
|
||||
|
||||
public BiomeGenStorage()
|
||||
{
|
||||
super( new BiomeProperties( "Storage Cell" ).setRainDisabled().setTemperature( -100 ) );
|
||||
super( new BiomeProperties( "Storage Cell" ).setBaseBiome( "void" ).setRainDisabled().setTemperature( -100 ) );
|
||||
|
||||
this.decorator.treesPerChunk = 0;
|
||||
this.decorator.flowersPerChunk = 0;
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.Map.Entry;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.NextTickListEntry;
|
||||
import net.minecraft.world.World;
|
||||
@@ -34,7 +35,6 @@ import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.definitions.IBlockDefinition;
|
||||
import appeng.api.movable.IMovableHandler;
|
||||
import appeng.api.movable.IMovableRegistry;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
@@ -61,7 +61,6 @@ public class CachedPlane
|
||||
private final World world;
|
||||
private final IMovableRegistry reg = AEApi.instance().registries().movable();
|
||||
private final LinkedList<WorldCoord> updates = new LinkedList<>();
|
||||
private final IBlockDefinition matrixFrame = AEApi.instance().definitions().blocks().matrixFrame();
|
||||
private int verticalBits;
|
||||
private final IBlockState matrixBlockState;
|
||||
|
||||
@@ -146,11 +145,11 @@ public class CachedPlane
|
||||
}
|
||||
else
|
||||
{
|
||||
final Object[] details = this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].getDetails( tePOS.getY() );
|
||||
final IBlockState blkState = (IBlockState) details[0];
|
||||
final BlockStorageData details = new BlockStorageData();
|
||||
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].fillData( tePOS.getY(), details );
|
||||
|
||||
// don't skip air, just let the code replace it...
|
||||
if( blkState != null && blkState.getBlock() == Platform.AIR_BLOCK && blkState.getMaterial().isReplaceable() )
|
||||
if( details.state != null && details.state.getBlock() == Platform.AIR_BLOCK && details.state.getMaterial().isReplaceable() )
|
||||
{
|
||||
w.setBlockToAir( tePOS );
|
||||
}
|
||||
@@ -168,12 +167,11 @@ public class CachedPlane
|
||||
}
|
||||
|
||||
final long k = this.getWorld().getTotalWorldTime();
|
||||
final List list = this.getWorld().getPendingBlockUpdates( c, false );
|
||||
final List<NextTickListEntry> list = this.getWorld().getPendingBlockUpdates( c, false );
|
||||
if( list != null )
|
||||
{
|
||||
for( final Object o : list )
|
||||
for( final NextTickListEntry entry : list )
|
||||
{
|
||||
final NextTickListEntry entry = (NextTickListEntry) o;
|
||||
final BlockPos tePOS = entry.position;
|
||||
if( tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS
|
||||
.getZ() <= maxZ )
|
||||
@@ -192,6 +190,10 @@ public class CachedPlane
|
||||
try
|
||||
{
|
||||
this.getWorld().loadedTileEntityList.remove( te );
|
||||
if( te instanceof ITickable )
|
||||
{
|
||||
this.getWorld().tickableTileEntities.remove( te );
|
||||
}
|
||||
}
|
||||
catch( final Exception e )
|
||||
{
|
||||
@@ -215,6 +217,8 @@ public class CachedPlane
|
||||
AELog.info( "Block Copy Scale: " + this.x_size + ", " + this.y_size + ", " + this.z_size );
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
final BlockStorageData aD = new BlockStorageData();
|
||||
final BlockStorageData bD = new BlockStorageData();
|
||||
|
||||
for( int x = 0; x < this.x_size; x++ )
|
||||
{
|
||||
@@ -230,8 +234,8 @@ public class CachedPlane
|
||||
|
||||
if( a.doNotSkip( src_y ) && b.doNotSkip( dst_y ) )
|
||||
{
|
||||
final Object[] aD = a.getDetails( src_y );
|
||||
final Object[] bD = b.getDetails( dst_y );
|
||||
a.fillData( src_y, aD );
|
||||
b.fillData( dst_y, bD );
|
||||
|
||||
a.setBlockIDWithMetadata( src_y, bD );
|
||||
b.setBlockIDWithMetadata( dst_y, aD );
|
||||
@@ -386,14 +390,17 @@ public class CachedPlane
|
||||
return this.world;
|
||||
}
|
||||
|
||||
private static class BlockStorageData
|
||||
{
|
||||
public IBlockState state;
|
||||
public int light;
|
||||
}
|
||||
|
||||
private class Column
|
||||
{
|
||||
|
||||
private final int x;
|
||||
private final int z;
|
||||
private final Chunk c;
|
||||
private final Object[] ch = { 0, 0 };
|
||||
private final ExtendedBlockStorage[] storage;
|
||||
private List<Integer> skipThese = null;
|
||||
|
||||
public Column( final Chunk chunk, final int x, final int z, final int chunkY, final int chunkHeight )
|
||||
@@ -401,44 +408,46 @@ public class CachedPlane
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.c = chunk;
|
||||
this.storage = this.c.getBlockStorageArray();
|
||||
|
||||
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
|
||||
|
||||
// make sure storage exists before hand...
|
||||
for( int ay = 0; ay < chunkHeight; ay++ )
|
||||
{
|
||||
final int by = ( ay + chunkY );
|
||||
ExtendedBlockStorage extendedblockstorage = this.storage[by];
|
||||
ExtendedBlockStorage extendedblockstorage = storage[by];
|
||||
if( extendedblockstorage == null )
|
||||
{
|
||||
extendedblockstorage = this.storage[by] = new ExtendedBlockStorage( by << 4, !this.c.getWorld().provider.hasSkyLight() );
|
||||
extendedblockstorage = storage[by] = new ExtendedBlockStorage( by << 4, this.c.getWorld().provider.hasSkyLight() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setBlockIDWithMetadata( final int y, final Object[] blk )
|
||||
private void setBlockIDWithMetadata( final int y, BlockStorageData data )
|
||||
{
|
||||
if( blk[0] == CachedPlane.this.matrixBlockState )
|
||||
if( data.state == CachedPlane.this.matrixBlockState )
|
||||
{
|
||||
blk[0] = Platform.AIR_BLOCK.getDefaultState();
|
||||
data.state = Platform.AIR_BLOCK.getDefaultState();
|
||||
}
|
||||
|
||||
final ExtendedBlockStorage extendedBlockStorage = this.storage[y >> 4];
|
||||
extendedBlockStorage.set( this.x, y & 15, this.z, (IBlockState) blk[0] );
|
||||
// extendedBlockStorage.setExtBlockID( x, y & 15, z, blk[0] );
|
||||
extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, (Integer) blk[1] );
|
||||
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
|
||||
final ExtendedBlockStorage extendedBlockStorage = storage[y >> 4];
|
||||
extendedBlockStorage.set( this.x, y & 15, this.z, data.state );
|
||||
extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light );
|
||||
}
|
||||
|
||||
private Object[] getDetails( final int y )
|
||||
private void fillData( final int y, BlockStorageData data )
|
||||
{
|
||||
final ExtendedBlockStorage extendedblockstorage = this.storage[y >> 4];
|
||||
this.ch[0] = extendedblockstorage.get( this.x, y & 15, this.z );
|
||||
this.ch[1] = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
|
||||
return this.ch;
|
||||
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
|
||||
final ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
|
||||
|
||||
data.state = extendedblockstorage.get( this.x, y & 15, this.z );
|
||||
data.light = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
|
||||
}
|
||||
|
||||
private boolean doNotSkip( final int y )
|
||||
{
|
||||
final ExtendedBlockStorage extendedblockstorage = this.storage[y >> 4];
|
||||
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
|
||||
final ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
|
||||
if( CachedPlane.this.reg.isBlacklisted( extendedblockstorage.get( this.x, y & 15, this.z ).getBlock() ) )
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package appeng.spatial;
|
||||
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
@@ -54,8 +55,9 @@ public class DefaultSpatialHandler implements IMovableHandler
|
||||
|
||||
if( c.isLoaded() )
|
||||
{
|
||||
final IBlockState state = w.getBlockState( newPosition );
|
||||
w.addTileEntity( te );
|
||||
w.notifyBlockUpdate( newPosition, w.getBlockState( newPosition ), w.getBlockState( newPosition ), 0 );
|
||||
w.notifyBlockUpdate( newPosition, state, state, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import net.minecraft.world.WorldServer;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.util.WorldCoord;
|
||||
import appeng.core.stats.Achievements;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
@@ -115,13 +115,18 @@ public class StorageHelper
|
||||
{
|
||||
if( link.dim.provider instanceof StorageWorldProvider )
|
||||
{
|
||||
Achievements.SpatialIOExplorer.addToPlayer( player );
|
||||
AppEng.instance().getAdvancementTriggers().getSpatialExplorer().trigger( player );
|
||||
}
|
||||
|
||||
player.mcServer.getPlayerList().transferPlayerToDimension( player, link.dim.provider.getDimension(), new METeleporter( newWorld, link ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// really remove from world, forge only marks it as removed
|
||||
final boolean wasDead = entity.isDead;
|
||||
oldWorld.removeEntityDangerously( entity );
|
||||
entity.isDead = wasDead;
|
||||
|
||||
entity.getServer().getPlayerList().transferEntityToWorld( entity, entity.dimension,
|
||||
entity.getServer().getWorld( entity.dimension ), (WorldServer) link.dim, new METeleporter( newWorld, link ) );
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class TileCraftingStorageTile extends TileCraftingTile
|
||||
@Override
|
||||
public int getStorageBytes()
|
||||
{
|
||||
if( this.world == null || this.notLoaded() )
|
||||
if( this.world == null || this.notLoaded() || this.isInvalid() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public class TileCraftingTile extends AENetworkTile implements IAEMultiBlock, IP
|
||||
|
||||
public void updateMeta( final boolean updateFormed )
|
||||
{
|
||||
if( this.world == null || this.notLoaded() )
|
||||
if( this.world == null || this.notLoaded() || this.isInvalid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ public class AppEngInternalAEInventory implements IInternalItemHandler, Iterable
|
||||
private final IAEItemStack[] inv;
|
||||
private final int size;
|
||||
private int maxStack;
|
||||
private boolean dirtyFlag = false;
|
||||
|
||||
public AppEngInternalAEInventory( final IAEAppEngInventory te, final int s )
|
||||
{
|
||||
@@ -252,8 +253,10 @@ public class AppEngInternalAEInventory implements IInternalItemHandler, Iterable
|
||||
{
|
||||
if( this.te != null && Platform.isServer() )
|
||||
{
|
||||
this.dirtyFlag = true;
|
||||
this.te.onChangeInventory( this, slot, op, removed, inserted );
|
||||
this.te.saveChanges();
|
||||
this.dirtyFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,6 +286,9 @@ public class AppEngInternalAEInventory implements IInternalItemHandler, Iterable
|
||||
@Override
|
||||
public void markDirty( int slot )
|
||||
{
|
||||
this.fireOnChangeInventory( slot, InvOperation.DIRTY, ItemStack.EMPTY, ItemStack.EMPTY );
|
||||
if( !this.dirtyFlag )
|
||||
{
|
||||
this.fireOnChangeInventory( slot, InvOperation.DIRTY, ItemStack.EMPTY, ItemStack.EMPTY );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ public class AppEngInternalInventory extends ItemStackHandler implements IIntern
|
||||
private final int[] maxStack;
|
||||
private ItemStack previousStack = ItemStack.EMPTY;
|
||||
private IAEItemFilter filter;
|
||||
private boolean dirtyFlag = false;
|
||||
|
||||
public AppEngInternalInventory( final IAEAppEngInventory inventory, final int size, final int maxStack, IAEItemFilter filter )
|
||||
{
|
||||
@@ -118,6 +119,7 @@ public class AppEngInternalInventory extends ItemStackHandler implements IIntern
|
||||
{
|
||||
if( this.getTileEntity() != null && this.eventsEnabled() )
|
||||
{
|
||||
this.dirtyFlag = true;
|
||||
ItemStack newStack = this.getStackInSlot( slot ).copy();
|
||||
ItemStack oldStack = this.previousStack;
|
||||
InvOperation op = InvOperation.SET;
|
||||
@@ -141,6 +143,7 @@ public class AppEngInternalInventory extends ItemStackHandler implements IIntern
|
||||
this.getTileEntity().onChangeInventory( this, slot, op, oldStack, newStack );
|
||||
this.getTileEntity().saveChanges();
|
||||
this.previousStack = ItemStack.EMPTY;
|
||||
this.dirtyFlag = false;
|
||||
}
|
||||
super.onContentsChanged( slot );
|
||||
}
|
||||
@@ -158,10 +161,12 @@ public class AppEngInternalInventory extends ItemStackHandler implements IIntern
|
||||
@Override
|
||||
public void markDirty( final int slot )
|
||||
{
|
||||
if( this.getTileEntity() != null && this.eventsEnabled() )
|
||||
if( this.getTileEntity() != null && this.eventsEnabled() && !this.dirtyFlag )
|
||||
{
|
||||
this.dirtyFlag = true;
|
||||
this.getTileEntity().onChangeInventory( this, slot, InvOperation.DIRTY, ItemStack.EMPTY, ItemStack.EMPTY );
|
||||
this.getTileEntity().saveChanges();
|
||||
this.dirtyFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,23 +19,37 @@
|
||||
package appeng.tile.misc;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.helpers.BaseActionSource;
|
||||
import appeng.me.storage.ITickingMonitor;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import appeng.util.item.ItemList;
|
||||
|
||||
|
||||
class CondenserItemInventory implements IMEMonitor<IAEItemStack>
|
||||
class CondenserItemInventory implements IMEMonitor<IAEItemStack>, ITickingMonitor
|
||||
{
|
||||
|
||||
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
|
||||
private final TileCondenser target;
|
||||
private boolean hasChanged = true;
|
||||
private final ItemList cachedList = new ItemList();
|
||||
private IActionSource actionSource = new BaseActionSource();
|
||||
private ItemList changeSet = new ItemList();
|
||||
|
||||
CondenserItemInventory( final TileCondenser te )
|
||||
{
|
||||
@@ -49,30 +63,46 @@ class CondenserItemInventory implements IMEMonitor<IAEItemStack>
|
||||
{
|
||||
this.target.addPower( input.getStackSize() );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack extractItems( final IAEItemStack request, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
return null;
|
||||
AEItemStack ret = null;
|
||||
ItemStack slotItem = target.getOutputSlot().getStackInSlot( 0 );
|
||||
if( !slotItem.isEmpty() && request.isSameType( slotItem ) )
|
||||
{
|
||||
int count = (int) Math.min( request.getStackSize(), Integer.MAX_VALUE );
|
||||
ret = AEItemStack.fromItemStack( target.getOutputSlot().extractItem( 0, count, mode == Actionable.SIMULATE ) );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
|
||||
public IItemList<IAEItemStack> getAvailableItems( final IItemList<IAEItemStack> out )
|
||||
{
|
||||
if( !target.getOutputSlot().getStackInSlot( 0 ).isEmpty() )
|
||||
{
|
||||
out.add( AEItemStack.fromItemStack( target.getOutputSlot().getStackInSlot( 0 ) ) );
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getStorageList()
|
||||
{
|
||||
return new ItemList();
|
||||
if( this.hasChanged )
|
||||
{
|
||||
this.hasChanged = false;
|
||||
this.cachedList.resetStatus();
|
||||
return this.getAvailableItems( this.cachedList );
|
||||
}
|
||||
return this.cachedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel getChannel()
|
||||
public IStorageChannel<IAEItemStack> getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
@@ -80,7 +110,7 @@ class CondenserItemInventory implements IMEMonitor<IAEItemStack>
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return AccessRestriction.WRITE;
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -114,14 +144,62 @@ class CondenserItemInventory implements IMEMonitor<IAEItemStack>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken )
|
||||
public void addListener( final IMEMonitorHandlerReceiver<IAEItemStack> l, final Object verificationToken )
|
||||
{
|
||||
// Not implemented since the Condenser automatically voids everything, and there are no updates
|
||||
this.listeners.put( l, verificationToken );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( IMEMonitorHandlerReceiver<IAEItemStack> l )
|
||||
public void removeListener( final IMEMonitorHandlerReceiver<IAEItemStack> l )
|
||||
{
|
||||
// Not implemented since we don't remember registered listeners anyway
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
|
||||
public void updateOutput( ItemStack added, ItemStack removed )
|
||||
{
|
||||
this.hasChanged = true;
|
||||
if( !added.isEmpty() )
|
||||
{
|
||||
this.changeSet.add( AEItemStack.fromItemStack( added ) );
|
||||
}
|
||||
if( !removed.isEmpty() )
|
||||
{
|
||||
this.changeSet.add( AEItemStack.fromItemStack( removed ).setStackSize( -removed.getCount() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
final ItemList currentChanges = this.changeSet;
|
||||
|
||||
if( currentChanges.isEmpty() )
|
||||
{
|
||||
return TickRateModulation.IDLE;
|
||||
}
|
||||
|
||||
this.changeSet = new ItemList();
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||
if( key.isValid( l.getValue() ) )
|
||||
{
|
||||
key.postChange( this, currentChanges, this.actionSource );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return TickRateModulation.URGENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionSource( IActionSource actionSource )
|
||||
{
|
||||
this.actionSource = actionSource;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user