Compare commits

...

30 Commits

Author SHA1 Message Date
yueh ac81418684 Changed some fluid recipes to match their item variant. (#3744) 2018-09-28 18:25:05 +02:00
yueh 7daad58607 Fixes #3742: Do not use storableInStorageCell() to identify generic c… (#3743)
Annotated IStorageCell with Nonnull where appropriate.
2018-09-28 17:38:08 +02:00
yueh 038ca23523 Fixes #3688: Invalidate Storage Bus cache immediately upon missing TE. (#3737) 2018-09-28 17:36:58 +02:00
yueh 37d8833b95 Fixes #3708: Move knifes/wrenches to oredict as constants are unreliable (#3729) 2018-09-22 20:14:28 +02:00
yueh fdcba13369 Power off a network in case it losses its local buffer. (#3703)
This better indicates power issue with dynamic consumption like
extracting/inserting items into a network. E.g. the terminals will
shutdown, no light/channel/etc indicators.

Due to the networks trying to extract from the largest possible energy
storage first, the network buffer will be used as last option after
energy cells or controllers.

Potentially needs evaluation in case of adhoc networks with a high
transfer rate locally. Increasing the local buffer might be an idea or
have it scale with the amount of local gridnodes. As long as it does not
invalidates energy cells.
2018-09-02 14:00:15 +02:00
yueh b1ac0adfd8 Added a new facade config. (#3706)
The whitelist is now based on manually add explicit entries instead of
automatically adding every existing block. This alone should save a few
MB of RAM depending on the modpack size.

Additionally the FacadeConfig is no longer extending the normal
Configuration provided by Forge. It will only parse the file once per
start and store the settings in an optimised collection to further
reduce memory consumption.

Any full block without a TileEntity and having a model is whitelisted
automatically and does not need an explicit entry anymore.

By default vanilla and AE2 glass is added as they are no fullblocks
technically.

The whitelist technically allows many more blocks now. E.g. stairs,
slabs or even items like saplings. But with various rendering quality.

Further there is an option to allow facades based on TileEntities, this
is completely unsupported and can work or corrupt the whole save.
2018-09-02 13:59:18 +02:00
covers1624 7ba2893635 New facade system (#3702)
Completely new system to render facades.

It will now support many more cases compared to the old system.
For example connected textures are now possible, as well as multilayer models and so on.
2018-09-02 13:26:20 +02:00
fscan ed8baf8c15 Fix tooltip for vibration chamber (#3675) 2018-08-30 23:13:38 +02:00
yueh 758377ed5d Various code fixes (#3704)
Correctly close streams.
Avoid ArithmeticException in case of /0.
2018-08-30 23:12:35 +02:00
yueh a2091d10fe Code cleanup
Added missing this, annotations, etc.
2018-08-30 20:33:08 +02:00
yueh fed12cb99f Organise Imports 2018-08-30 20:32:01 +02:00
yueh 66c365d11f Code Formatting 2018-08-30 20:31:27 +02:00
yueh 044f4c9ed3 Added jacoco for coverage reports (#3700) 2018-08-30 20:09:36 +02:00
yueh 91a74813d9 Updated Travis CI caches (#3699) 2018-08-30 20:09:25 +02:00
yueh a0b645a0a7 Added SonarCloud integration (#3698)
Updated gradle wrapper to 4.8
2018-08-29 23:24:55 +02:00
fscan d439fb2915 Fix fluid parts item models (#3676) 2018-08-29 19:09:04 +02:00
yueh 7efd4d872f Readded forge as required dependency. (#3678)
Version will automatically be computed based on the release used to
build as well as the next major release being marked as exclusive upper
bound.
2018-08-29 19:08:46 +02:00
yueh 1b09760631 Followup #3646: Assemblers actually have to render in both layers. (#3662) 2018-08-05 13:11:36 +02:00
fscan 04daadceed Increase Vibration Chamber AE/t (#3635) 2018-08-01 00:27:19 +02:00
yueh 4d3df96350 Fixes #3646: Render assemblers in the correct layer. (#3658) 2018-08-01 00:26:28 +02:00
fscan d7e2ae8fcb Fix ConcurrentModificatonException in NetworkEventBus (#3654)
Fixes #3653
2018-08-01 00:20:47 +02:00
fscan 73f471e685 Make search box toggle key configurable (#3650)
Fixes #3641
2018-08-01 00:20:17 +02:00
fscan 390ad875ee Fix Platform#postChanges to check all registered channels (#3644) 2018-08-01 00:19:49 +02:00
fscan e5f43bf315 Allow ME Chest to work with any cell (#3640) 2018-08-01 00:17:43 +02:00
fscan 8a72ebca89 check if actually added before removing (#3639)
Fixes #3634
2018-08-01 00:17:10 +02:00
fscan ad1eff2adb Condensor improvements (#3636) 2018-08-01 00:15:30 +02:00
fscan 9e252df8d9 Fix dupe bug with shulker box (#3633)
Fixes #3632
2018-08-01 00:13:58 +02:00
yueh 67584083c6 Fixes #3630: Formation planes not respecting the entity limit. (#3631) 2018-08-01 00:13:20 +02:00
fscan c1c7e94cf6 Generic ICellInventoryHandler (#3624)
Allows addons who register a custom IStorageChannel to use the IStorageCell interface without registering a cell handler. Also adds some helpers (poweredInsert/poweredExtract).
This breaks API!
2018-07-22 19:20:47 +02:00
fscan 85dec35366 Fix buckets in vibration chamber (#3626) 2018-07-20 21:51:05 +02:00
224 changed files with 4534 additions and 2429 deletions
+19 -6
View File
@@ -7,14 +7,27 @@ jdk:
- openjdk8
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
- rm -f $HOME/.gradle/caches/minecraft/deobfedDeps/providedDummy.jar
- rm -f $HOME/.gradle/caches/minecraft/deobfedDeps/compileDummy.jar
- rm -f $HOME/.gradle/caches/minecraft/ForgeVersion.json
- rm -f $HOME/.gradle/caches/minecraft/ForgeVersion.json.etag
- rm -fr $HOME/.gradle/caches/minecraft/deobfedDeps
- rm -f $HOME/.gradle/caches/*/fileHashes/fileHashes.bin
- rm -f $HOME/.gradle/caches/*/fileHashes/fileHashes.lock
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'
- '$HOME/.gradle/wrapper'
- '$HOME/.gradle/caches'
addons:
sonarcloud:
organization: "appliedenergistics"
install: "./gradlew setupCIWorkspace"
script: "./gradlew build test"
script:
- "./gradlew build"
- "./gradlew test"
- "./gradlew sonarqube"
+7 -1
View File
@@ -30,7 +30,13 @@ buildscript {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
}
}
plugins {
id "org.sonarqube" version "2.6"
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: 'jacoco'
repositories {
mavenLocal()
@@ -112,4 +118,4 @@ processResources
// move access transformer to META-INF
rename '(.+_at.cfg)', 'META-INF/$1'
}
}
+1
View File
@@ -26,6 +26,7 @@ top_version=1.12-1.4.23-16
cofhcore_version=1.12.2-4.5.2.19
crafttweaker_version=4.1.8.9
inventorytweaks_version=1.63
ctm_version=0.3.0.15
#########################################################
# Deployment #
+3 -2
View File
@@ -68,7 +68,7 @@ repositories {
name 'modmaven'
url "https://modmaven.k-4u.nl/"
}
maven {
name = "CurseForge"
url = "https://minecraft.curseforge.com/api/maven/"
@@ -94,7 +94,8 @@ dependencies {
compileOnly "cofh:CoFHCore:${cofhcore_version}:deobf"
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
compileOnly "team.chisel.ctm:CTM:MC1.12-${ctm_version}"
// at runtime, use the full JEI jar
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
Binary file not shown.
+1 -2
View File
@@ -1,6 +1,5 @@
#Tue Jul 04 22:38:49 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip
Vendored
+17 -9
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
##############################################################################
##
@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
warn () {
echo "$*"
}
die ( ) {
die () {
echo
echo "$*"
echo
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
Vendored
-6
View File
@@ -49,7 +49,6 @@ goto fail
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
+6
View File
@@ -30,6 +30,7 @@ import appeng.api.networking.IGridHelper;
import appeng.api.networking.IGridNode;
import appeng.api.parts.IPartHelper;
import appeng.api.storage.IStorageHelper;
import appeng.api.util.IClientHelper;
@AEInjectable
@@ -60,4 +61,9 @@ public interface IAppEngApi
*/
IDefinitions definitions();
/**
* @return Utility methods primarily useful for client side stuff
*/
IClientHelper client();
}
+6 -2
View File
@@ -37,12 +37,16 @@ public enum Upgrades
/**
* Gold Tier Upgrades.
*/
CAPACITY( 0 ), REDSTONE( 0 ), CRAFTING( 0 ),
CAPACITY( 0 ),
REDSTONE( 0 ),
CRAFTING( 0 ),
/**
* Diamond Tier Upgrades.
*/
FUZZY( 1 ), SPEED( 1 ), INVERTER( 1 );
FUZZY( 1 ),
SPEED( 1 ),
INVERTER( 1 );
private final int tier;
private final Map<ItemStack, Integer> supportedMax = new HashMap<>();
@@ -121,6 +121,6 @@ public interface IParts
IItemDefinition fluidLevelEmitter();
IItemDefinition fluidAnnihilationPlane();
IItemDefinition fluidFormationnPlane();
}
@@ -47,7 +47,9 @@ public interface IP2PTunnelRegistry
* @param type - the type of tunnel. Nullable, but then ignored
*/
void addNewAttunement( @Nonnull ItemStack trigger, @Nullable TunnelType type );
void addNewAttunement( @Nonnull String ModId, @Nullable TunnelType type );
void addNewAttunement( @Nonnull Capability<?> cap, @Nullable TunnelType type );
/**
@@ -35,6 +35,6 @@ import appeng.api.networking.IGridHost;
public interface INetworkTool extends IGuiItemObject
{
IGridHost getGridHost(); // null for most purposes.
IItemHandler getInventory();
}
@@ -24,6 +24,8 @@
package appeng.api.implementations.items;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import appeng.api.storage.ICellWorkbenchItem;
@@ -52,7 +54,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return number of bytes
*/
int getBytes( ItemStack cellItem );
int getBytes( @Nonnull ItemStack cellItem );
/**
* Determines the number of bytes used for any type included on the cell.
@@ -61,7 +63,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return number of bytes
*/
int getBytesPerType( ItemStack cellItem );
int getBytesPerType( @Nonnull ItemStack cellItem );
/**
* Must be between 1 and 63, indicates how many types you want to store on
@@ -71,7 +73,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return number of types
*/
int getTotalTypes( ItemStack cellItem );
int getTotalTypes( @Nonnull ItemStack cellItem );
/**
* Allows you to fine tune which items are allowed on a given cell, if you
@@ -83,7 +85,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return true to preventAdditionOfItem
*/
boolean isBlackListed( ItemStack cellItem, T requestedAddition );
boolean isBlackListed( @Nonnull ItemStack cellItem, @Nonnull T requestedAddition );
/**
* Allows you to specify if this storage cell can be stored inside other
@@ -104,7 +106,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return if the ItemStack should behavior as a storage cell.
*/
boolean isStorageCell( ItemStack i );
boolean isStorageCell( @Nonnull ItemStack i );
/**
* @return drain in ae/t this storage cell will use.
@@ -114,5 +116,6 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
/**
* @return the type of channel your cell should be part of
*/
@Nonnull
IStorageChannel<T> getChannel();
}
@@ -23,6 +23,7 @@
package appeng.api.implementations.tiles;
import net.minecraftforge.items.IItemHandler;
@@ -23,6 +23,7 @@
package appeng.api.implementations.tiles;
import net.minecraftforge.items.IItemHandler;
@@ -1,3 +1,4 @@
/*
* The MIT License (MIT)
*
+1 -1
View File
@@ -72,7 +72,7 @@ public interface IPartHost extends ICustomCableConnection
* @return null if the item failed to add, the side it was placed on other wise ( may different for cables,
* {@link AEPartLocation}.UNKNOWN )
*/
AEPartLocation addPart( ItemStack is, AEPartLocation side, EntityPlayer owner, EnumHand hand );
AEPartLocation addPart( ItemStack is, AEPartLocation side, EntityPlayer owner, EnumHand hand );
/**
* Get part by side ( center is {@link AEPartLocation}.UNKNOWN )
@@ -23,6 +23,7 @@
package appeng.api.parts;
/**
* TODO: Consider removing and replacing with capabilities.
*/
@@ -30,6 +30,7 @@ import appeng.api.exceptions.MissingIngredientException;
import appeng.api.exceptions.RecipeException;
import appeng.api.exceptions.RegistrationException;
@Deprecated
public interface ICraftHandler
{
@@ -29,6 +29,7 @@ import net.minecraft.item.ItemStack;
import appeng.api.exceptions.MissingIngredientException;
import appeng.api.exceptions.RegistrationException;
@Deprecated
public interface IIngredient
{
@@ -28,6 +28,7 @@ import java.io.BufferedReader;
import javax.annotation.Nonnull;
@Deprecated
public interface IRecipeLoader
{
@@ -0,0 +1,47 @@
package appeng.api.storage;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.storage.data.IAEStack;
public interface ICellGuiHandler
{
/**
* Return true if this handler can show GUI for this channel.
*
* @param channel Storage channel
* @return True if handled, else false.
*/
<T extends IAEStack<T>> boolean isHandlerFor( IStorageChannel<T> channel );
/**
* Return true to prioritize this handler for the provided {@link ItemStack}.
*
* @param is Cell ItemStack
* @return True, if specialized else false.
*/
default boolean isSpecializedFor( ItemStack is )
{
return false;
}
/**
* Called when the storage cell is placed in an ME Chest and the user tries to open the terminal side, if your item
* is not available via ME Chests simply tell the user they can't use it, or something, other wise you should open
* your gui and display the cell to the user.
*
* @param player player opening chest gui
* @param chest to be opened chest
* @param cellHandler cell handler
* @param inv inventory handler
* @param is item
* @param chan storage channel
*/
<T extends IAEStack<T>> void openChestGui( EntityPlayer player, IChestOrDrive chest, ICellHandler cellHandler, IMEInventoryHandler<T> inv, ItemStack is, IStorageChannel<T> chan );
}
@@ -24,10 +24,8 @@
package appeng.api.storage;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.storage.data.IAEStack;
@@ -59,20 +57,6 @@ public interface ICellHandler
*/
<T extends IAEStack<T>> ICellInventoryHandler<T> getCellInventory( ItemStack is, ISaveProvider host, IStorageChannel<T> channel );
/**
* Called when the storage cell is planed in an ME Chest and the user tries to open the terminal side, if your item
* is not available via ME Chests simply tell the user they can't use it, or something, other wise you should open
* your gui and display the cell to the user.
*
* @param player player opening chest gui
* @param chest to be opened chest
* @param cellHandler cell handler
* @param inv inventory handler
* @param is item
* @param chan storage channel
*/
<T extends IAEStack<T>> void openChestGui( EntityPlayer player, IChestOrDrive chest, ICellHandler cellHandler, IMEInventoryHandler<T> inv, ItemStack is, IStorageChannel<T> chan );
/**
* 0 - cell is missing.
*
@@ -87,10 +71,31 @@ public interface ICellHandler
*
* @return get the status of the cell based on its contents.
*/
<T extends IAEStack<T>> int getStatusForCell( ItemStack is, IMEInventory<T> handler );
default <T extends IAEStack<T>> int getStatusForCell( ItemStack is, ICellInventoryHandler<T> handler )
{
if( handler.getCellInv() != null )
{
int val = handler.getCellInv().getStatusForCell();
if( val == 1 && handler.isPreformatted() )
{
val = 2;
}
return val;
}
return 0;
}
/**
* @return the ae/t to drain for this storage cell inside a chest/drive.
*/
<T extends IAEStack<T>> double cellIdleDrain( ItemStack is, IMEInventory<T> handler );
default <T extends IAEStack<T>> double cellIdleDrain( ItemStack is, ICellInventoryHandler<T> handler )
{
if( handler.getCellInv() != null )
{
return handler.getCellInv().getIdleDrain();
}
return 1.0;
}
}
@@ -40,7 +40,7 @@ public interface ICellInventory<T extends IAEStack<T>> extends IMEInventory<T>
ItemStack getItemStack();
/**
* @return idle cost for this Storage Cell
* @return the ae/t to drain for this storage cell inside a chest/drive.
*/
double getIdleDrain();
@@ -115,7 +115,15 @@ public interface ICellInventory<T extends IAEStack<T>> extends IMEInventory<T>
int getUnusedItemCount();
/**
* @return the status number for this drive.
* 0 - cell is missing.
*
* 1 - green, ( usually means available room for types or items. )
*
* 2 - orange, ( usually means available room for items, but not types. )
*
* 3 - red, ( usually means the cell is 100% full )
*
* @return get the status of the cell based on its contents.
*/
int getStatusForCell();
@@ -24,6 +24,8 @@
package appeng.api.storage;
import javax.annotation.Nullable;
import appeng.api.config.IncludeExclude;
import appeng.api.storage.data.IAEStack;
@@ -32,8 +34,11 @@ public interface ICellInventoryHandler<T extends IAEStack<T>> extends IMEInvento
{
/**
* Get access to the ICellInventory. Can be null for custom cells.
*
* @return get access to the Cell Inventory.
*/
@Nullable
ICellInventory<T> getCellInv();
boolean isPreformatted();
@@ -53,6 +53,13 @@ public interface ICellRegistry
*/
void addCellHandler( @Nonnull ICellHandler handler );
/**
* Register a new handler
*
* @param handler cell gui handler
*/
void addCellGuiHandler( @Nonnull ICellGuiHandler handler );
/**
* return true, if you can get a InventoryHandler for the item passed.
*
@@ -64,7 +71,7 @@ public interface ICellRegistry
boolean isCellHandled( ItemStack is );
/**
* get the handler, for the requested type.
* get the handler, for the requested item.
*
* @param is to be checked item
*
@@ -74,13 +81,23 @@ public interface ICellRegistry
ICellHandler getHandler( ItemStack is );
/**
* returns an IMEInventoryHandler for the provided item.
* get the handler, for the requested channel.
*
* @param channel requested channel
* @param Cell ItemStack
* @return the handler registered for this channel.
*/
@Nullable
<T extends IAEStack<T>> ICellGuiHandler getGuiHandler( IStorageChannel<T> channel, ItemStack is );
/**
* returns an ICellInventoryHandler for the provided item by querying all registered handlers.
*
* @param is item with inventory handler
* @param host can be null. If provided, the host is responsible for persisting the cell content.
* @param chan the storage channel to request the handler for.
*
* @return new IMEInventoryHandler, or null if there isn't one.
* @return new ICellInventoryHandler, or null if there isn't one.
*/
@Nullable
<T extends IAEStack<T>> ICellInventoryHandler<T> getCellInventory( ItemStack is, ISaveProvider host, IStorageChannel<T> chan );
@@ -24,11 +24,19 @@
package appeng.api.storage;
import javax.annotation.Nullable;
/**
* Tells the cell provider that changes have been made an the cell must be persisted
*
*/
public interface ISaveProvider
{
void saveChanges( ICellInventory<?> cellInventory );
/**
* Cell has changed and needs to be changed.
*
* @param cellInventory can be null for custom cells.
*/
void saveChanges( @Nullable ICellInventory<?> cellInventory );
}
@@ -32,10 +32,9 @@ import javax.annotation.Nullable;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.IActionSource;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
@@ -56,6 +55,17 @@ public interface IStorageChannel<T extends IAEStack<T>>
return 1;
}
/**
* The number of units (eg item count, or millibuckets) that can be stored per byte in a storage cell.
* Standard value for items is 8, and for fluids it's 8000
*
* @return number of units
*/
default int getUnitsPerByte()
{
return 8;
}
/**
* Create a new {@link IItemList} of the specific type.
*
@@ -68,9 +78,12 @@ public interface IStorageChannel<T extends IAEStack<T>>
* Create a new {@link IAEStack} subtype of the specific object.
*
* The parameter is unbound to allow a slightly more flexible approach.
* But the general intention is about converting an {@link ItemStack} into the corresponding {@link IAEItemStack}.
* But the general intention is about converting an {@link ItemStack} or {@link FluidStack} into the corresponding
* {@link IAEStack}.
* Another valid case might be to use it instead of {@link IAEStack#copy()}, but this might not be supported by all
* types.
* IAEStacks that use custom items for {@link IAEStack#asItemStackRepresentation()} must also be able to convert
* these.
*
* @param input The object to turn into an {@link IAEStack}
* @return The converted stack or null
@@ -88,29 +101,11 @@ public interface IStorageChannel<T extends IAEStack<T>>
T readFromPacket( @Nonnull ByteBuf input ) throws IOException;
/**
* use energy from energy, to remove request items from cell, at the request of src.
*
* @param energy to be drained energy source
* @param cell cell of requested items
* @param request requested items
* @param src action source
*
* @return items that successfully extracted.
* create from nbt data
*
* @param nbt
* @return
*/
@Nullable
T poweredExtraction( @Nonnull IEnergySource energy, @Nonnull IMEInventory<T> cell, @Nonnull T request, @Nonnull IActionSource src );
/**
* use energy from energy, to inject input items into cell, at the request of src
*
* @param energy to be added energy source
* @param cell injected cell
* @param input to be injected items
* @param src action source
*
* @return items that failed to insert.
*/
@Nullable
T poweredInsert( @Nonnull IEnergySource energy, @Nonnull IMEInventory<T> cell, @Nonnull T input, @Nonnull IActionSource src );
T createFromNBT( @Nonnull NBTTagCompound nbt );
}
@@ -28,10 +28,15 @@ import java.util.Collection;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import appeng.api.config.Actionable;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingRequester;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
@@ -90,4 +95,38 @@ public interface IStorageHelper
*/
ICraftingLink loadCraftingLink( NBTTagCompound data, ICraftingRequester req );
/**
* Extracts items from a {@link IMEInventory} respecting power requirements.
*
* @param energy Energy source.
* @param inv Inventory to extract from.
* @param request Requested item and count.
* @param src Action source.
* @param mode Simulate or modulate
* @return extracted items or {@code null} of nothing was extracted.
*/
<T extends IAEStack<T>> T poweredExtraction( final IEnergySource energy, final IMEInventory<T> inv, final T request, final IActionSource src, final Actionable mode );
/**
* Inserts items into a {@link IMEInventory} respecting power requirements.
*
* @param energy Energy source.
* @param inv Inventory to insert into.
* @param request Items to insert.
* @param src Action source.
* @param mode Simulate or modulate
* @return items not inserted or {@code null} if everything was inserted.
*/
<T extends IAEStack<T>> T poweredInsert( final IEnergySource energy, final IMEInventory<T> inv, final T input, final IActionSource src, final Actionable mode );
/**
* Posts alteration of stored items to the provided {@link IStorageGrid}.
* This can be used by cell containers to notify the grid of storage cell changes.
*
* @param gs the storage grid.
* @param removedCell the removed cell itemstack
* @param addedCell the added cell itemstack
* @param src the action source
*/
void postChanges( @Nonnull final IStorageGrid gs, @Nonnull final ItemStack removedCell, @Nonnull final ItemStack addedCell, @Nonnull final IActionSource src );
}
@@ -75,12 +75,12 @@ public enum AECableType
public AECableSize size()
{
return size;
return this.size;
}
public AECableVariant variant()
{
return variant;
return this.variant;
}
public boolean isValid()
+12 -6
View File
@@ -74,25 +74,30 @@ public enum AEColor
TRANSPARENT( "gui.appliedenergistics2.Fluix", null, 0x1B2344, 0x895CA8, 0xD7BBEC );
public static final List<AEColor> VALID_COLORS = Arrays.asList( WHITE, ORANGE, MAGENTA, LIGHT_BLUE, YELLOW, LIME, PINK, GRAY, LIGHT_GRAY, CYAN, PURPLE, BLUE, BROWN, GREEN, RED, BLACK );
public static final List<AEColor> VALID_COLORS = Arrays.asList( WHITE, ORANGE, MAGENTA, LIGHT_BLUE, YELLOW, LIME, PINK, GRAY, LIGHT_GRAY, CYAN, PURPLE,
BLUE, BROWN, GREEN, RED, BLACK );
/**
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #blackVariant dark variant} of the apprioriate AE color.
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #blackVariant dark
* variant} of the apprioriate AE color.
*/
public static final int TINTINDEX_DARK = 1;
/**
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #mediumVariant medium variant} of the apprioriate AE color.
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #mediumVariant medium
* variant} of the apprioriate AE color.
*/
public static final int TINTINDEX_MEDIUM = 2;
/**
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #whiteVariant bright variant} of the apprioriate AE color.
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #whiteVariant bright
* variant} of the apprioriate AE color.
*/
public static final int TINTINDEX_BRIGHT = 3;
/**
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get a color between the {@link #mediumVariant medium}
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get a color between the
* {@link #mediumVariant medium}
* and {@link #whiteVariant bright variant} of the apprioriate AE color.
*/
public static final int TINTINDEX_MEDIUM_BRIGHT = 4;
@@ -141,7 +146,8 @@ public enum AEColor
{
switch( tintIndex )
{
// Please note that tintindex 0 is hardcoded for the block breaking particles. Returning anything other than -1 for tintindex=0 here
// Please note that tintindex 0 is hardcoded for the block breaking particles. Returning anything other than
// -1 for tintindex=0 here
// will cause issues with those particles
case 0:
return -1;
@@ -0,0 +1,21 @@
package appeng.api.util;
import java.util.List;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.data.IAEStack;
public interface IClientHelper
{
/**
* Add cell information to the provided list. Used for tooltip content.
*
* @param handler Cell handler.
* @param lines List of lines to add to.
*/
<T extends IAEStack<T>> void addCellInformation( ICellInventoryHandler<T> handler, List<String> lines );
}
@@ -23,8 +23,10 @@
package appeng.api.util;
import net.minecraft.util.math.RayTraceResult;
/**
* Implement on Tile or part to customize if the info gui opens, or an action is preformed.
*/
@@ -56,15 +56,18 @@ public class AEBaseItemBlockChargeable extends AEBaseItemBlock implements IAEIte
double internalCurrentPower = 0;
final double internalMaxPower = this.getMaxEnergyCapacity();
if( tag != null )
if( internalMaxPower > 0 )
{
internalCurrentPower = tag.getDouble( "internalCurrentPower" );
if( tag != null )
{
internalCurrentPower = tag.getDouble( "internalCurrentPower" );
}
final double percent = internalCurrentPower / internalMaxPower;
lines.add( GuiText.StoredEnergy.getLocal() + ':' + MessageFormat.format( " {0,number,#} ", internalCurrentPower ) + Platform
.gui_localize( PowerUnits.AE.unlocalizedName ) + " - " + MessageFormat.format( " {0,number,#.##%} ", percent ) );
}
final double percent = internalCurrentPower / internalMaxPower;
lines.add( GuiText.StoredEnergy.getLocal() + ':' + MessageFormat.format( " {0,number,#} ", internalCurrentPower ) + Platform
.gui_localize( PowerUnits.AE.unlocalizedName ) + " - " + MessageFormat.format( " {0,number,#.##%} ", percent ) );
}
@Override
@@ -87,7 +87,7 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
@Override
public boolean canRenderInLayer( IBlockState state, BlockRenderLayer layer )
{
return layer == BlockRenderLayer.TRANSLUCENT;
return layer == BlockRenderLayer.CUTOUT || layer == BlockRenderLayer.TRANSLUCENT;
}
@Override
@@ -150,9 +150,9 @@ public class BlockLightDetector extends AEBaseTileBlock implements IOrientableBl
public void neighborChanged( IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos )
{
final EnumFacing up = this.getOrientable( world, pos ).getUp();
if( !this.canPlaceAt( (World) world, pos, up.getOpposite() ) )
if( !this.canPlaceAt( world, pos, up.getOpposite() ) )
{
this.dropTorch( (World) world, pos );
this.dropTorch( world, pos );
}
}
@@ -61,10 +61,12 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import appeng.api.AEApi;
import appeng.api.parts.IFacadeContainer;
import appeng.api.parts.IFacadePart;
import appeng.api.parts.PartItemStack;
import appeng.api.parts.SelectedPart;
import appeng.api.util.AEColor;
import appeng.api.util.AEPartLocation;
import appeng.block.AEBaseTileBlock;
import appeng.client.UnlistedProperty;
import appeng.client.render.cablebus.CableBusBakedModel;
@@ -74,6 +76,7 @@ import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketClick;
import appeng.helpers.AEGlassMaterial;
import appeng.integration.abstraction.IAEFacade;
import appeng.parts.ICableBusContainer;
import appeng.parts.NullCableBusContainer;
import appeng.tile.AEBaseTile;
@@ -83,7 +86,7 @@ import appeng.tile.networking.TileCableBusTESR;
import appeng.util.Platform;
public class BlockCableBus extends AEBaseTileBlock
public class BlockCableBus extends AEBaseTileBlock implements IAEFacade
{
public static final UnlistedProperty<CableBusRenderState> RENDER_STATE_PROPERTY = new UnlistedProperty<>( "cable_bus_render_state", CableBusRenderState.class );
@@ -122,6 +125,8 @@ public class BlockCableBus extends AEBaseTileBlock
public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos )
{
CableBusRenderState renderState = this.cb( world, pos ).getRenderState();
renderState.setWorld( world );
renderState.setPos( pos );
return ( (IExtendedBlockState) state ).withProperty( RENDER_STATE_PROPERTY, renderState );
}
@@ -317,13 +322,14 @@ public class BlockCableBus extends AEBaseTileBlock
for( int l = 0; l < 4; ++l )
{
// Randomly select one of the textures if the cable bus has more than just one possibility here
TextureAtlasSprite texture = Platform.pickRandom( textures );
final TextureAtlasSprite texture = Platform.pickRandom( textures );
final double d0 = pos.getX() + ( j + 0.5D ) / 4.0D;
final double d1 = pos.getY() + ( k + 0.5D ) / 4.0D;
final double d2 = pos.getZ() + ( l + 0.5D ) / 4.0D;
final ParticleDigging particle = new DestroyFX( world, d0, d1, d2, d0 - pos.getX() - 0.5D, d1 - pos
.getY() - 0.5D, d2 - pos.getZ() - 0.5D, this.getDefaultState() ).setBlockPos( pos );
double d0 = (double) pos.getX() + ( (double) j + 0.5D ) / 4.0D;
double d1 = (double) pos.getY() + ( (double) k + 0.5D ) / 4.0D;
double d2 = (double) pos.getZ() + ( (double) l + 0.5D ) / 4.0D;
ParticleDigging particle = new DestroyFX( world, d0, d1, d2, d0 - (double) pos.getX() - 0.5D, d1 - (double) pos
.getY() - 0.5D, d2 - (double) pos.getZ() - 0.5D, this.getDefaultState() ).setBlockPos( pos );
particle.setParticleTexture( texture );
effectRenderer.addEffect( particle );
}
@@ -356,6 +362,20 @@ public class BlockCableBus extends AEBaseTileBlock
return out == null ? NULL_CABLE_BUS : out;
}
@Nullable
private IFacadeContainer fc( final IBlockAccess w, final BlockPos pos )
{
final TileEntity te = w.getTileEntity( pos );
IFacadeContainer out = null;
if( te instanceof TileCableBus )
{
out = ( (TileCableBus) te ).getCableBus().getFacadeContainer();
}
return out;
}
@Override
public void onBlockClicked( World worldIn, BlockPos pos, EntityPlayer playerIn )
{
@@ -436,14 +456,25 @@ public class BlockCableBus extends AEBaseTileBlock
@Override
public boolean canRenderInLayer( IBlockState state, BlockRenderLayer layer )
{
if( AEApi.instance().partHelper().getCableRenderMode().transparentFacades )
return true;
}
@Override
public IBlockState getFacadeState( IBlockAccess world, BlockPos pos, EnumFacing side )
{
if( side != null )
{
return layer == BlockRenderLayer.CUTOUT || layer == BlockRenderLayer.TRANSLUCENT;
}
else
{
return layer == BlockRenderLayer.CUTOUT;
IFacadeContainer container = this.fc( world, pos );
if( container != null )
{
IFacadePart facade = container.getFacade( AEPartLocation.fromFacing( side ) );
if( facade != null )
{
return facade.getBlockState();
}
}
}
return world.getBlockState( pos );
}
public static Class<? extends AEBaseTile> getNoTesrTile()
@@ -34,8 +34,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import appeng.api.AEApi;
import appeng.api.storage.ICellHandler;
import appeng.api.util.AEPartLocation;
import appeng.block.AEBaseTileBlock;
import appeng.core.localization.PlayerMessages;
@@ -108,14 +106,7 @@ public class BlockChest extends AEBaseTileBlock
}
else
{
final ItemStack cell = tg.getCell();
if( !cell.isEmpty() )
{
final ICellHandler ch = AEApi.instance().registries().cell().getHandler( cell );
tg.openGui( p, ch, cell, side );
}
else
if( !tg.openGui( p ) )
{
p.sendMessage( PlayerMessages.ChestCannotReadStorageCell.get() );
}
@@ -136,7 +136,7 @@ public class FeatureFactory
private <T extends IBootstrapComponent> void addBootstrapComponent( Class<? extends IBootstrapComponent> eventType, T component )
{
bootstrapComponents.computeIfAbsent( eventType, c -> new ArrayList<IBootstrapComponent>() ).add( component );
this.bootstrapComponents.computeIfAbsent( eventType, c -> new ArrayList<IBootstrapComponent>() ).add( component );
}
@SideOnly( Side.CLIENT )
@@ -1,10 +1,13 @@
package appeng.bootstrap.components;
import net.minecraftforge.fml.common.registry.EntityEntry;
import net.minecraftforge.registries.IForgeRegistry;
import appeng.bootstrap.IBootstrapComponent;
@FunctionalInterface
public interface IEntityRegistrationComponent extends IBootstrapComponent
{
@@ -0,0 +1,28 @@
package appeng.client;
import org.lwjgl.input.Keyboard;
public enum ActionKey
{
TOGGLE_FOCUS( Keyboard.KEY_TAB );
private final int defaultKey;
private ActionKey( int defaultKey )
{
this.defaultKey = defaultKey;
}
public String getTranslationKey()
{
return "key." + this.name().toLowerCase() + ".desc";
}
public int getDefaultKey()
{
return this.defaultKey;
}
}
@@ -21,11 +21,13 @@ package appeng.client;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Random;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.tileentity.TileEntity;
@@ -40,6 +42,7 @@ import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -74,6 +77,9 @@ import appeng.util.Platform;
public class ClientHelper extends ServerHelper
{
private final static String KEY_CATEGORY = "key.appliedenergistics2.category";
private final EnumMap<ActionKey, KeyBinding> bindings = new EnumMap<>( ActionKey.class );
@Override
public void preinit()
@@ -92,6 +98,12 @@ public class ClientHelper extends ServerHelper
@Override
public void init()
{
for( ActionKey key : ActionKey.values() )
{
final KeyBinding binding = new KeyBinding( key.getTranslationKey(), key.getDefaultKey(), KEY_CATEGORY );
ClientRegistry.registerKeyBinding( binding );
this.bindings.put( key, binding );
}
}
@Override
@@ -332,4 +344,16 @@ public class ClientHelper extends ServerHelper
ParticleTextures.registerSprite( event );
InscriberTESR.registerTexture( event );
}
@Override
public boolean isKeyPressed( ActionKey key )
{
return this.bindings.get( key ).isPressed();
}
@Override
public boolean isActionKey( ActionKey key, int pressedKeyCode )
{
return this.bindings.get( key ).isActiveAndMatches( pressedKeyCode );
}
}
@@ -161,16 +161,16 @@ public abstract class AEBaseGui extends GuiContainer
super.drawScreen( mouseX, mouseY, partialTicks );
GlStateManager.pushMatrix();
GlStateManager.translate( (float) this.guiLeft, (float) this.guiTop, 0.0F );
GlStateManager.translate( this.guiLeft, this.guiTop, 0.0F );
GlStateManager.enableDepth();
for( final GuiCustomSlot c : this.guiSlots )
{
drawGuiSlot( c, mouseX, mouseY, partialTicks );
this.drawGuiSlot( c, mouseX, mouseY, partialTicks );
}
GlStateManager.disableDepth();
for( final GuiCustomSlot c : this.guiSlots )
{
drawTooltip( c, mouseX - this.guiLeft, mouseY - this.guiTop );
this.drawTooltip( c, mouseX - this.guiLeft, mouseY - this.guiTop );
}
GlStateManager.popMatrix();
@@ -180,7 +180,7 @@ public abstract class AEBaseGui extends GuiContainer
{
if( c instanceof ITooltip )
{
drawTooltip( (ITooltip) c, mouseX, mouseY );
this.drawTooltip( (ITooltip) c, mouseX, mouseY );
}
}
}
@@ -40,6 +40,7 @@ import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseMEGui;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiScrollbar;
@@ -54,6 +55,7 @@ import appeng.container.slot.SlotCraftingMatrix;
import appeng.container.slot.SlotFakeCraftingMatrix;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import appeng.core.sync.GuiBridge;
import appeng.core.sync.network.NetworkHandler;
@@ -481,7 +483,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
if( !this.checkHotbarKeys( key ) )
{
if( key == Keyboard.KEY_TAB )
if( AppEng.proxy.isActionKey( ActionKey.TOGGLE_FOCUS, key ) )
{
this.searchField.setFocused( !this.searchField.isFocused() );
return;
@@ -78,8 +78,9 @@ public class GuiPatternTerm extends GuiMEMonitorable
if( this.tabCraftButton == btn || this.tabProcessButton == btn )
{
NetworkHandler.instance().sendToServer(
new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
NetworkHandler.instance()
.sendToServer(
new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
}
if( this.encodeBtn == btn )
@@ -94,8 +95,9 @@ public class GuiPatternTerm extends GuiMEMonitorable
if( this.substitutionsEnabledBtn == btn || this.substitutionsDisabledBtn == btn )
{
NetworkHandler.instance().sendToServer(
new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
NetworkHandler.instance()
.sendToServer(
new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
}
}
catch( final IOException e )
@@ -58,11 +58,11 @@ public class GuiVibrationChamber extends AEBaseGui
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.VibrationChamber.getLocal() ), 8, 6, 4210752 );
this.fontRenderer.drawString( GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752 );
this.pb.setFullMsg( this.cvc.getAePerTick() * this.cvc.getCurrentProgress() / 100 + " AE/t" );
this.pb.setFullMsg( TileVibrationChamber.POWER_PER_TICK * this.cvc.getCurrentProgress() / TileVibrationChamber.DILATION_SCALING + " AE/t" );
if( this.cvc.getCurrentProgress() > 0 )
if( this.cvc.getRemainingBurnTime() > 0 )
{
final int i1 = this.cvc.getCurrentProgress();
final int i1 = this.cvc.getRemainingBurnTime() * 12 / 100;
this.bindTexture( "guis/vibchamber.png" );
GlStateManager.color( 1, 1, 1 );
final int l = -15;
@@ -23,7 +23,7 @@ public abstract class GuiCustomSlot extends Gui implements ITooltip
public int getId()
{
return id;
return this.id;
}
public boolean canClick( final EntityPlayer player )
@@ -131,7 +131,9 @@ public class MEGuiTextField extends GuiTextField
public void drawSelectionBox( int startX, int startY, int endX, int endY )
{
if( !this.isFocused() )
{
return;
}
if( startX < endX )
{
@@ -165,20 +167,20 @@ public class MEGuiTextField extends GuiTextField
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer();
float red = (float) ( this.selectionColor >> 16 & 255 ) / 255.0F;
float blue = (float) ( this.selectionColor >> 8 & 255 ) / 255.0F;
float green = (float) ( this.selectionColor & 255 ) / 255.0F;
float alpha = (float) ( this.selectionColor >> 24 & 255 ) / 255.0F;
float red = ( this.selectionColor >> 16 & 255 ) / 255.0F;
float blue = ( this.selectionColor >> 8 & 255 ) / 255.0F;
float green = ( this.selectionColor & 255 ) / 255.0F;
float alpha = ( this.selectionColor >> 24 & 255 ) / 255.0F;
GlStateManager.color( red, green, blue, alpha );
GlStateManager.disableTexture2D();
GlStateManager.enableColorLogic();
GlStateManager.colorLogicOp( GlStateManager.LogicOp.OR_REVERSE );
bufferbuilder.begin( 7, DefaultVertexFormats.POSITION );
bufferbuilder.pos( (double) startX, (double) endY, 0.0D ).endVertex();
bufferbuilder.pos( (double) endX, (double) endY, 0.0D ).endVertex();
bufferbuilder.pos( (double) endX, (double) startY, 0.0D ).endVertex();
bufferbuilder.pos( (double) startX, (double) startY, 0.0D ).endVertex();
bufferbuilder.pos( startX, endY, 0.0D ).endVertex();
bufferbuilder.pos( endX, endY, 0.0D ).endVertex();
bufferbuilder.pos( endX, startY, 0.0D ).endVertex();
bufferbuilder.pos( startX, startY, 0.0D ).endVertex();
tessellator.draw();
GlStateManager.disableColorLogic();
GlStateManager.enableTexture2D();
@@ -41,6 +41,7 @@ import net.minecraft.util.EnumFacing;
public class DummyFluidBakedModel implements IBakedModel
{
private final ImmutableList<BakedQuad> quads;
public DummyFluidBakedModel( ImmutableList<BakedQuad> quads )
{
this.quads = quads;
@@ -49,7 +50,7 @@ public class DummyFluidBakedModel implements IBakedModel
@Override
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
return quads;
return this.quads;
}
@Override
@@ -104,13 +104,13 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel
fluidStack = new FluidStack( FluidRegistry.WATER, Fluid.BUCKET_VOLUME );
}
TextureAtlasSprite sprite = bakedTextureGetter.apply( fluidStack.getFluid().getStill( fluidStack ) );
TextureAtlasSprite sprite = DummyFluidDispatcherBakedModel.this.bakedTextureGetter.apply( fluidStack.getFluid().getStill( fluidStack ) );
if( sprite == null )
{
return new DummyFluidBakedModel( ImmutableList.of() );
}
return new DummyFluidBakedModel( ItemLayerModel.getQuadsForSprite( 0, sprite, format, Optional.empty() ) );
return new DummyFluidBakedModel( ItemLayerModel.getQuadsForSprite( 0, sprite, DummyFluidDispatcherBakedModel.this.format, Optional.empty() ) );
}
};
}
@@ -51,7 +51,7 @@ public class DummyFluidItemModel implements IModel
{
try
{
baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
this.baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
}
catch( Exception e )
{
@@ -78,12 +78,12 @@ public class DummyFluidItemModel implements IModel
{
IBakedModel bakedBaseModel = this.getBaseModel().bake( state, format, bakedTextureGetter );
return new DummyFluidDispatcherBakedModel( bakedBaseModel, format, bakedTextureGetter );
return new DummyFluidDispatcherBakedModel( bakedBaseModel, format, bakedTextureGetter );
}
@Override
public IModelState getDefaultState()
{
return getBaseModel().getDefaultState();
return this.getBaseModel().getDefaultState();
}
}
@@ -0,0 +1,86 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2018, 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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
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.ItemOverrideList;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import appeng.client.render.cablebus.FacadeBuilder;
/**
* This model used the provided FacadeBuilder to "slice" the item quads for the facade provided.
*
* @author covers1624
*/
public class FacadeBakedItemModel extends DelegateBakedModel
{
private final ItemStack textureStack;
private final FacadeBuilder facadeBuilder;
protected FacadeBakedItemModel( IBakedModel base, ItemStack textureStack, FacadeBuilder facadeBuilder )
{
super( base );
this.textureStack = textureStack;
this.facadeBuilder = facadeBuilder;
}
@Override
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
if( side != null )
{
return Collections.emptyList();
}
List<BakedQuad> quads = new ArrayList<>();
quads.addAll( this.facadeBuilder.buildFacadeItemQuads( this.textureStack, EnumFacing.NORTH ) );
quads.addAll( this.getBaseModel().getQuads( state, side, rand ) );
return quads;
}
@Override
public boolean isGui3d()
{
return false;
}
@Override
public boolean isBuiltInRenderer()
{
return false;
}
@Override
public ItemOverrideList getOverrides()
{
return ItemOverrideList.NONE;
}
}
@@ -34,6 +34,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import appeng.client.render.cablebus.FacadeBuilder;
import appeng.items.parts.ItemFacade;
@@ -45,11 +46,13 @@ import appeng.items.parts.ItemFacade;
public class FacadeDispatcherBakedModel extends DelegateBakedModel
{
private final VertexFormat format;
private final FacadeBuilder facadeBuilder;
public FacadeDispatcherBakedModel( IBakedModel baseModel, VertexFormat format )
public FacadeDispatcherBakedModel( IBakedModel baseModel, VertexFormat format, FacadeBuilder facadeBuilder )
{
super( baseModel );
this.format = format;
this.facadeBuilder = facadeBuilder;
}
// This is never used. See the item override list below.
@@ -86,11 +89,9 @@ public class FacadeDispatcherBakedModel extends DelegateBakedModel
ItemFacade itemFacade = (ItemFacade) stack.getItem();
IBlockState state = itemFacade.getTextureBlockState( stack );
ItemStack textureItem = itemFacade.getTextureItem( stack );
return new FacadeWithBlockBakedModel( FacadeDispatcherBakedModel.this
.getBaseModel(), state, textureItem, FacadeDispatcherBakedModel.this.format );
return new FacadeBakedItemModel( FacadeDispatcherBakedModel.this.getBaseModel(), textureItem, FacadeDispatcherBakedModel.this.facadeBuilder );
}
};
}
@@ -31,6 +31,7 @@ import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.model.IModelState;
import appeng.client.render.cablebus.FacadeBuilder;
import appeng.core.AppEng;
@@ -71,8 +72,9 @@ public class FacadeItemModel implements IModel
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
{
IBakedModel bakedBaseModel = this.getBaseModel().bake( state, format, bakedTextureGetter );
FacadeBuilder facadeBuilder = new FacadeBuilder();
return new FacadeDispatcherBakedModel( bakedBaseModel, format );
return new FacadeDispatcherBakedModel( bakedBaseModel, format, facadeBuilder );
}
@Override
@@ -1,106 +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.client.render;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.annotation.Nullable;
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.ItemOverrideList;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import appeng.client.render.cablebus.CubeBuilder;
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 extends DelegateBakedModel
{
private final IBlockState blockState;
private final IBakedModel textureModel;
private final VertexFormat format;
private final ItemStack textureItem;
public FacadeWithBlockBakedModel( IBakedModel baseModel, IBlockState blockState, ItemStack textureItem, VertexFormat format )
{
super( baseModel );
this.blockState = blockState;
this.textureItem = textureItem;
this.textureModel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState( blockState );
this.format = format;
}
@Override
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
// Only the north side is actually read from the base model for item models
if( side == EnumFacing.NORTH )
{
List<BakedQuad> quads = new ArrayList<>( 1 );
CubeBuilder builder = new CubeBuilder( this.format, quads );
FacadeBuilder.TextureAtlasAndTint sprite = FacadeBuilder.getSprite( this.textureModel, this.blockState, side, rand );
if( sprite != null && sprite.getSprite() != null )
{
if( sprite.getTint() != -1 )
{
builder.setColor( Minecraft.getMinecraft().getItemColors().colorMultiplier( this.textureItem, sprite.getTint() ) );
}
builder.setTexture( sprite.getSprite() );
builder.setDrawFaces( EnumSet.of( EnumFacing.NORTH ) );
builder.addCube( 0, 0, 0, 16, 16, 16 );
return quads;
}
}
return this.getBaseModel().getQuads( state, side, rand );
}
@Override
public boolean isGui3d()
{
return false;
}
@Override
public boolean isBuiltInRenderer()
{
return false;
}
@Override
public ItemOverrideList getOverrides()
{
return ItemOverrideList.NONE;
}
}
@@ -88,8 +88,9 @@ public class CableBusBakedModel implements IBakedModel
List<BakedQuad> quads = new ArrayList<>();
// The core parts of the cable will only be rendered in the CUTOUT layer. TRANSLUCENT is used only for
// translucent facades further down below.
// The core parts of the cable will only be rendered in the CUTOUT layer.
// Facades will add them selves to what ever the block would be rendered with,
// except when transparent facades are enabled, they are forced to TRANSPARENT.
if( layer == BlockRenderLayer.CUTOUT )
{
@@ -138,14 +139,7 @@ public class CableBusBakedModel implements IBakedModel
}
}
}
this.facadeBuilder.addFacades(
layer,
renderState.getFacades(),
renderState.getBoundingBoxes(),
renderState.getAttachments().keySet(),
rand,
quads );
this.facadeBuilder.buildFacadeQuads( layer, renderState, rand, quads, this.partModels::get );
return quads;
}
@@ -65,7 +65,6 @@ public class CableBusModel implements IModel
{
return ImmutableList.<ResourceLocation>builder()
.addAll( CableBuilder.getTextures() )
.addAll( FacadeBuilder.getTextures() )
.build();
}
@@ -75,7 +74,7 @@ public class CableBusModel implements IModel
Map<ResourceLocation, IBakedModel> partModels = this.loadPartModels( state, format, bakedTextureGetter );
CableBuilder cableBuilder = new CableBuilder( format, bakedTextureGetter );
FacadeBuilder facadeBuilder = new FacadeBuilder( format, bakedTextureGetter );
FacadeBuilder facadeBuilder = new FacadeBuilder();
// This should normally not be used, but we *have* to provide a particle texture or otherwise damage models will
// crash
@@ -19,6 +19,7 @@
package appeng.client.render.cablebus;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.EnumSet;
@@ -27,6 +28,8 @@ import java.util.Objects;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
@@ -69,6 +72,10 @@ public class CableBusRenderState
// Contains the facade to use for each side that has a facade attached
private EnumMap<EnumFacing, FacadeRenderState> facades = new EnumMap<>( EnumFacing.class );
// Used for Facades.
private WeakReference<IBlockAccess> world;
private BlockPos pos;
// Contains the bounding boxes of all parts on the cable bus to allow facades to cut out holes for the parts. This
// list is only populated if there are
// facades on this cable bus
@@ -151,6 +158,26 @@ public class CableBusRenderState
return this.facades;
}
public IBlockAccess getWorld()
{
return this.world.get();
}
public void setWorld( IBlockAccess world )
{
this.world = new WeakReference<>( world );
}
public BlockPos getPos()
{
return this.pos;
}
public void setPos( BlockPos pos )
{
this.pos = pos;
}
public List<AxisAlignedBB> getBoundingBoxes()
{
return this.boundingBoxes;
@@ -188,7 +215,7 @@ public class CableBusRenderState
{
return false;
}
if( getClass() != obj.getClass() )
if( this.getClass() != obj.getClass() )
{
return false;
}
@@ -196,9 +223,8 @@ public class CableBusRenderState
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 ) && Objects.equals( this.partFlags, other.partFlags );
.equals( this.attachmentConnections, other.attachmentConnections ) && Objects.equals( this.cableBusAdjacent, other.cableBusAdjacent ) && Objects
.equals( this.channelsOnSide, other.channelsOnSide ) && Objects.equals( this.connectionTypes, other.connectionTypes ) && Objects
.equals( this.partFlags, other.partFlags );
}
}
@@ -0,0 +1,115 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2018, 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.cablebus;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.WorldType;
import net.minecraft.world.biome.Biome;
/**
* This is used to retrieve the ExtendedState of a block for facade rendering.
* It fakes the block at BlockPos provided as the IBlockState provided.
*
* @author covers1624
*/
public class FacadeBlockAccess implements IBlockAccess
{
private final IBlockAccess world;
private final BlockPos pos;
private final EnumFacing side;
private final IBlockState state;
public FacadeBlockAccess( IBlockAccess world, BlockPos pos, EnumFacing side, IBlockState state )
{
this.world = world;
this.pos = pos;
this.side = side;
this.state = state;
}
@Nullable
@Override
public TileEntity getTileEntity( BlockPos pos )
{
return this.world.getTileEntity( pos );
}
@Override
public int getCombinedLight( BlockPos pos, int lightValue )
{
return this.world.getCombinedLight( pos, lightValue );
}
@Override
public IBlockState getBlockState( BlockPos pos )
{
if( this.pos == pos )
{
return this.state;
}
return this.world.getBlockState( pos );
}
@Override
public boolean isAirBlock( BlockPos pos )
{
IBlockState state = this.getBlockState( pos );
return state.getBlock().isAir( state, this.world, pos );
}
@Override
public Biome getBiome( BlockPos pos )
{
return this.world.getBiome( pos );
}
@Override
public int getStrongPower( BlockPos pos, EnumFacing direction )
{
return this.world.getStrongPower( pos, direction );
}
@Override
public WorldType getWorldType()
{
return this.world.getWorldType();
}
@Override
public boolean isSideSolid( BlockPos pos, EnumFacing side, boolean _default )
{
if( pos.getX() < -30000000 || pos.getZ() < -30000000 || pos.getX() >= 30000000 || pos.getZ() >= 30000000 )
{
return _default;
}
else
{
return this.getBlockState( pos ).isSideSolid( this, pos, side );
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
* Copyright (c) 2013 - 2018, 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,370 +19,372 @@
package appeng.client.render.cablebus;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;
import javax.vecmath.Vector3f;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumFacing.Axis;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.MinecraftForgeClient;
import appeng.api.AEApi;
import appeng.api.util.AEAxisAlignedBB;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.parts.misc.PartCableAnchor;
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
import appeng.thirdparty.codechicken.lib.model.Quad;
import appeng.thirdparty.codechicken.lib.model.pipeline.BakedPipeline;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadAlphaOverride;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadClamper;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadCornerKicker;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadFaceStripper;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadReInterpolator;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadTinter;
/**
* Handles creating the quads for facades attached to cable busses.
* The FacadeBuilder builds for facades..
*
* @author covers1624
*/
public class FacadeBuilder
{
private static final ResourceLocation TEXTURE_FACADE = new ResourceLocation( AppEng.MOD_ID, "parts/cable_anchor" );
public static double THICK_THICKNESS = 2D / 16D;
public static double THIN_THICKNESS = 1D / 16D;
private final VertexFormat format;
public static final AxisAlignedBB[] THICK_FACADE_BOXES = new AxisAlignedBB[] {
new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, THICK_THICKNESS, 1.0 ),
new AxisAlignedBB( 0.0, 1.0 - THICK_THICKNESS, 0.0, 1.0, 1.0, 1.0 ),
new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, THICK_THICKNESS ),
new AxisAlignedBB( 0.0, 0.0, 1.0 - THICK_THICKNESS, 1.0, 1.0, 1.0 ),
new AxisAlignedBB( 0.0, 0.0, 0.0, THICK_THICKNESS, 1.0, 1.0 ),
new AxisAlignedBB( 1.0 - THICK_THICKNESS, 0.0, 0.0, 1.0, 1.0, 1.0 )
};
private final TextureAtlasSprite facadeTexture;
public static final AxisAlignedBB[] THIN_FACADE_BOXES = new AxisAlignedBB[] {
new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, THIN_THICKNESS, 1.0 ),
new AxisAlignedBB( 0.0, 1.0 - THIN_THICKNESS, 0.0, 1.0, 1.0, 1.0 ),
new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, THIN_THICKNESS ),
new AxisAlignedBB( 0.0, 0.0, 1.0 - THIN_THICKNESS, 1.0, 1.0, 1.0 ),
new AxisAlignedBB( 0.0, 0.0, 0.0, THIN_THICKNESS, 1.0, 1.0 ),
new AxisAlignedBB( 1.0 - THIN_THICKNESS, 0.0, 0.0, 1.0, 1.0, 1.0 )
};
private static final Set<ResourceLocation> warnedFor = new HashSet<>();
private ThreadLocal<BakedPipeline> pipelines = ThreadLocal.withInitial( () -> BakedPipeline.builder()
// Clamper is responsible for clamping the vertex to the bounds specified.
.addElement( "clamper", QuadClamper.FACTORY )
// Strips faces if they match a mask.
.addElement( "face_stripper", QuadFaceStripper.FACTORY )
// Kicks the edge inner corners in, solves Z fighting
.addElement( "corner_kicker", QuadCornerKicker.FACTORY )
// Re-Interpolates the UV's for the quad.
.addElement( "interp", QuadReInterpolator.FACTORY )
// Tints the quad if we need it to. Disabled by default.
.addElement( "tinter", QuadTinter.FACTORY, false )
// Overrides the quad's alpha if we are forcing transparent facades.
.addElement( "transparent", QuadAlphaOverride.FACTORY, false, e -> e.setAlphaOverride( 0x4C / 255F ) )
.build()//
);
private ThreadLocal<Quad> collectors = ThreadLocal.withInitial( Quad::new );
FacadeBuilder( VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
{
this.format = format;
this.facadeTexture = bakedTextureGetter.apply( TEXTURE_FACADE );
}
static Collection<ResourceLocation> getTextures()
{
return Collections.singletonList( TEXTURE_FACADE );
}
void addFacades( BlockRenderLayer layer, Map<EnumFacing, FacadeRenderState> facadesState, List<AxisAlignedBB> partBoxes, Set<EnumFacing> sidesWithParts, long rand, List<BakedQuad> quads )
public void buildFacadeQuads( BlockRenderLayer layer, CableBusRenderState renderState, long rand, List<BakedQuad> quads, Function<ResourceLocation, IBakedModel> modelLookup )
{
BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get();
boolean transparent = AEApi.instance().partHelper().getCableRenderMode().transparentFacades;
Map<EnumFacing, FacadeRenderState> facadeStates = renderState.getFacades();
List<AxisAlignedBB> partBoxes = renderState.getBoundingBoxes();
Set<EnumFacing> sidesWithParts = renderState.getAttachments().keySet();
IBlockAccess parentWorld = renderState.getWorld();
BlockPos pos = renderState.getPos();
BlockColors blockColors = Minecraft.getMinecraft().getBlockColors();
boolean thinFacades = isUseThinFacades( partBoxes );
CubeBuilder builder = new CubeBuilder( this.format, quads );
facadesState.forEach( ( side, state ) ->
for( Entry<EnumFacing, FacadeRenderState> entry : facadeStates.entrySet() )
{
AxisAlignedBB facadeBox = getFacadeBox( side, thinFacades );
AEAxisAlignedBB cutOutBox = getCutOutBox( facadeBox, partBoxes );
EnumFacing side = entry.getKey();
int sideIndex = side.ordinal();
FacadeRenderState facadeRenderState = entry.getValue();
boolean renderStilt = !sidesWithParts.contains( side );
if( layer == BlockRenderLayer.CUTOUT && renderStilt )
{
for( ResourceLocation part : PartCableAnchor.FACADE_MODELS.getModels() )
{
IBakedModel partModel = modelLookup.apply( part );
QuadRotator rotator = new QuadRotator();
quads.addAll( rotator.rotateQuads( gatherQuads( partModel, null, rand ), side, EnumFacing.UP ) );
}
}
// If we are forcing transparency and this isn't the Translucent layer.
if( transparent && layer != BlockRenderLayer.TRANSLUCENT )
{
continue;
}
IBlockState blockState = facadeRenderState.getSourceBlock();
// If we aren't forcing transparency let the block decide if it should render.
if( !transparent )
{
if( !blockState.getBlock().canRenderInLayer( blockState, layer ) )
{
continue;
}
}
AxisAlignedBB fullBounds = thinFacades ? THIN_FACADE_BOXES[sideIndex] : THICK_FACADE_BOXES[sideIndex];
AxisAlignedBB facadeBox = fullBounds;
// If we are a transparent facade, we need to modify out BB.
if( facadeRenderState.isTransparent() )
{
double offset = thinFacades ? THIN_THICKNESS : THICK_THICKNESS;
AEAxisAlignedBB tmpBB = null;
for( EnumFacing face : EnumFacing.VALUES )
{
// Only faces that aren't on our axis
if( face.getAxis() != side.getAxis() )
{
FacadeRenderState otherState = facadeStates.get( face );
if( otherState != null && !otherState.isTransparent() )
{
if( tmpBB == null )
{
tmpBB = AEAxisAlignedBB.fromBounds( facadeBox );
}
switch( face )
{
case DOWN:
tmpBB.minY += offset;
break;
case UP:
tmpBB.maxY -= offset;
break;
case NORTH:
tmpBB.minZ += offset;
break;
case SOUTH:
tmpBB.maxZ -= offset;
break;
case WEST:
tmpBB.minX += offset;
break;
case EAST:
tmpBB.maxX -= offset;
break;
default:
throw new RuntimeException( "Switch falloff. " + String.valueOf( face ) );
}
}
}
}
if( tmpBB != null )
{
facadeBox = tmpBB.getBoundingBox();
}
}
AEAxisAlignedBB cutOutBox = getCutOutBox( facadeBox, partBoxes );
List<AxisAlignedBB> holeStrips = getBoxes( facadeBox, cutOutBox, side.getAxis() );
IBlockAccess facadeAccess = new FacadeBlockAccess( parentWorld, pos, side, blockState );
BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
try
{
this.addFacade( layer, facadesState, side, cutOutBox, thinFacades, renderStilt, rand, builder );
blockState = blockState.getActualState( facadeAccess, pos );
}
catch( Throwable t )
catch( Exception ignored )
{
AELog.debug( t );
}
} );
}
public static TextureAtlasAndTint getSprite( IBakedModel blockModel, IBlockState state, EnumFacing facing, long rand )
{
TextureAtlasAndTint firstFound = null;
BlockRenderLayer orgLayer = MinecraftForgeClient.getRenderLayer();
try
{
// Some other mods also distinguish between layers, so we're doing this in a loop from most likely to least
// likely
for( BlockRenderLayer layer : BlockRenderLayer.values() )
IBakedModel model = dispatcher.getModelForState( blockState );
try
{
blockState = blockState.getBlock().getExtendedState( blockState, facadeAccess, pos );
}
catch( Exception ignored )
{
}
List<BakedQuad> modelQuads = new ArrayList<>();
// If we are forcing transparent facades, fake the render layer, and grab all quads.
if( transparent )
{
for( BlockRenderLayer forcedLayer : BlockRenderLayer.values() )
{
// Check if the block renders on the layer we want to force.
if( blockState.getBlock().canRenderInLayer( blockState, forcedLayer ) )
{
// Force the layer and gather quads.
ForgeHooksClient.setRenderLayer( forcedLayer );
modelQuads.addAll( gatherQuads( model, blockState, rand ) );
}
}
// Reset.
ForgeHooksClient.setRenderLayer( layer );
}
else
{
modelQuads.addAll( gatherQuads( model, blockState, rand ) );
}
for( BakedQuad bakedQuad : blockModel.getQuads( state, facing, rand ) )
{
return new TextureAtlasAndTint( bakedQuad );
}
// No quads.. Cool, next!
if( modelQuads.isEmpty() )
{
continue;
}
for( BakedQuad bakedQuad : blockModel.getQuads( state, null, rand ) )
// Grab out pipeline elements.
QuadClamper clamper = pipeline.getElement( "clamper", QuadClamper.class );
QuadFaceStripper edgeStripper = pipeline.getElement( "face_stripper", QuadFaceStripper.class );
QuadTinter tinter = pipeline.getElement( "tinter", QuadTinter.class );
QuadCornerKicker kicker = pipeline.getElement( "corner_kicker", QuadCornerKicker.class );
// Set global element states.
// calculate the side mask.
int facadeMask = 0;
for( Entry<EnumFacing, FacadeRenderState> ent : facadeStates.entrySet() )
{
EnumFacing s = ent.getKey();
if( s.getAxis() != side.getAxis() )
{
if( firstFound == null )
FacadeRenderState otherState = ent.getValue();
if( !otherState.isTransparent() )
{
firstFound = new TextureAtlasAndTint( bakedQuad );
facadeMask |= 1 << s.ordinal();
}
if( bakedQuad.getFace() == facing )
}
}
// Setup the edge stripper.
edgeStripper.setBounds( fullBounds );
edgeStripper.setMask( facadeMask );
// Setup the kicker.
kicker.setSide( sideIndex );
kicker.setFacadeMask( facadeMask );
kicker.setBox( fullBounds );
kicker.setThickness( thinFacades ? THIN_THICKNESS : THICK_THICKNESS );
for( BakedQuad quad : modelQuads )
{
// lookup the format in CachedFormat.
CachedFormat format = CachedFormat.lookup( quad.getFormat() );
// If this quad has a tint index, setup the tinter.
if( quad.hasTintIndex() )
{
tinter.setTint( blockColors.colorMultiplier( blockState, facadeAccess, pos, quad.getTintIndex() ) );
}
for( AxisAlignedBB box : holeStrips )
{
// setup the clamper for this box
clamper.setClampBounds( box );
// Reset the pipeline, clears all enabled/disabled states.
pipeline.reset( format );
// Reset out collector.
collectorQuad.reset( format );
// Enable / disable the optional elements
pipeline.setElementState( "tinter", quad.hasTintIndex() );
pipeline.setElementState( "transparent", transparent );
// Prepare the pipeline for a quad.
pipeline.prepare( collectorQuad );
// Pipe our quad into the pipeline.
quad.pipe( pipeline );
// Check if the collector got any data.
if( collectorQuad.full )
{
return new TextureAtlasAndTint( bakedQuad );
// Add the result.
quads.add( collectorQuad.bake() );
}
}
}
}
catch( Exception e )
{
if( warnedFor.add( state.getBlock().getRegistryName() ) )
{
AELog.warn( "Unable to get facade sprite for blockstate %s. Supressing further warnings for this block.", state );
AELog.debug( e );
}
}
finally
{
ForgeHooksClient.setRenderLayer( orgLayer );
}
// Fall back to the particle texture, if we havent found anything else so far.
if( firstFound == null )
{
try
{
return new TextureAtlasAndTint( blockModel.getParticleTexture(), -1 );
}
catch( Exception e )
{
if( warnedFor.add( state.getBlock().getRegistryName() ) )
{
AELog.warn( "Unable to get facade sprite particle texture fallback for blockstate %s. Supressing further warnings for this block.", state );
AELog.debug( e );
}
}
}
return firstFound;
}
private void addFacade( BlockRenderLayer layer, Map<EnumFacing, FacadeRenderState> facades, EnumFacing side, AEAxisAlignedBB busBounds, boolean thinFacades, boolean renderStilt, long rand, CubeBuilder builder )
/**
* This is slow, so should be cached.
*
* @return The model.
*/
public List<BakedQuad> buildFacadeItemQuads( ItemStack textureItem, EnumFacing side )
{
List<BakedQuad> facadeQuads = new ArrayList<>();
IBakedModel model = Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides( textureItem, null, null );
List<BakedQuad> modelQuads = gatherQuads( model, null, 0 );
FacadeRenderState facadeState = facades.get( side );
IBlockState blockState = facadeState.getSourceBlock();
BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get();
builder.setDrawFaces( EnumSet.allOf( EnumFacing.class ) );
// Grab pipeline elements.
QuadClamper clamper = pipeline.getElement( "clamper", QuadClamper.class );
QuadTinter tinter = pipeline.getElement( "tinter", QuadTinter.class );
// 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 )
for( BakedQuad quad : modelQuads )
{
builder.setTexture( this.facadeTexture );
switch( side )
// Lookup the CachedFormat for this quads format.
CachedFormat format = CachedFormat.lookup( quad.getFormat() );
// Reset the pipeline.
pipeline.reset( format );
// Reset the collector.
collectorQuad.reset( format );
// If we have a tint index, setup the tinter and enable it.
if( quad.hasTintIndex() )
{
case DOWN:
builder.addCube( 7, 1, 7, 9, 6, 9 );
break;
case UP:
builder.addCube( 7, 10, 7, 9, 15, 9 );
break;
case NORTH:
builder.addCube( 7, 7, 1, 9, 9, 6 );
break;
case SOUTH:
builder.addCube( 7, 7, 10, 9, 9, 15 );
break;
case WEST:
builder.addCube( 1, 7, 7, 6, 9, 9 );
break;
case EAST:
builder.addCube( 10, 7, 7, 15, 9, 9 );
break;
}
}
// Do not add the translucent facade in any other layer than translucent
boolean translucent = AEApi.instance().partHelper().getCableRenderMode().transparentFacades;
if( translucent && layer != BlockRenderLayer.TRANSLUCENT )
{
return;
}
final float thickness = thinFacades ? 1 : 2;
BlockRendererDispatcher blockRendererDispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
IBakedModel blockModel = blockRendererDispatcher.getModelForState( blockState );
final int color;
if( translucent )
{
color = 0x4CFFFFFF;
}
else
{
color = 0xFFFFFFFF;
}
// TODO: Cache this
for( EnumFacing facing : facadeState.getOpenFaces() )
{
TextureAtlasAndTint spriteAndTint = getSprite( blockModel, blockState, facing, rand );
if( spriteAndTint != null && spriteAndTint.sprite != null )
{
// Use the tint color from the item stack here, which is based upon the assumption that the
// model used for the block will use the same meaning for tint indices as the item model does
if( spriteAndTint.tint != -1 )
{
int tintColor = facadeState.resolveTintColor( spriteAndTint.tint );
// Still apply the transparency color
tintColor &= 0xFFFFFF;
tintColor |= color & 0xFF000000;
builder.setColor( tintColor );
}
else
{
builder.setColor( color );
}
builder.setTexture( facing, spriteAndTint.sprite );
}
else
{
builder.setColor( color );
builder.setTexture( facing, this.facadeTexture );
}
}
builder.setDrawFaces( facadeState.getOpenFaces() );
AxisAlignedBB primaryBox = getFacadeBox( side, thinFacades );
Vector3f min = new Vector3f( (float) primaryBox.minX * 16, (float) primaryBox.minY * 16, (float) primaryBox.minZ * 16 );
Vector3f max = new Vector3f( (float) primaryBox.maxX * 16, (float) primaryBox.maxY * 16, (float) primaryBox.maxZ * 16 );
if( busBounds == null )
{
// Adjust the facade for neighboring facades so that facade cubes dont overlap with each other
if( side == EnumFacing.NORTH || side == EnumFacing.SOUTH )
{
if( facades.containsKey( EnumFacing.UP ) )
{
max.y -= thickness;
}
if( facades.containsKey( EnumFacing.DOWN ) )
{
min.y += thickness;
}
}
else if( side == EnumFacing.EAST || side == EnumFacing.WEST )
{
if( facades.containsKey( EnumFacing.UP ) )
{
max.y -= thickness;
}
if( facades.containsKey( EnumFacing.DOWN ) )
{
min.y += thickness;
}
if( facades.containsKey( EnumFacing.SOUTH ) )
{
max.z -= thickness;
}
if( facades.containsKey( EnumFacing.NORTH ) )
{
min.z += thickness;
}
}
builder.addCube( min.x, min.y, min.z, max.x, max.y, max.z );
}
else
{
Vector3f busMin = new Vector3f( (float) busBounds.minX * 16, (float) busBounds.minY * 16, (float) busBounds.minZ * 16 );
Vector3f busMax = new Vector3f( (float) busBounds.maxX * 16, (float) busBounds.maxY * 16, (float) busBounds.maxZ * 16 );
if( side == EnumFacing.UP || side == EnumFacing.DOWN )
{
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMax.z, 16.0f, 16.0f, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, 16.0f, 16.0f, busMin.z );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMin.z, busMin.x, 16.0f, busMax.z );
this.renderSegmentBlockCurrentBounds( builder, min, max, busMax.x, 0.0f, busMin.z, 16.0f, 16.0f, busMax.z );
}
else if( side == EnumFacing.NORTH || side == EnumFacing.SOUTH )
{
if( facades.get( EnumFacing.UP ) != null )
{
max.y -= thickness;
}
if( facades.get( EnumFacing.DOWN ) != null )
{
min.y += thickness;
}
this.renderSegmentBlockCurrentBounds( builder, min, max, busMax.x, 0.0f, 0.0f, 16.0f, 16.0f, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, busMin.x, 16.0f, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, busMin.x, 0.0f, 0.0f, busMax.x, busMin.y, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, busMin.x, busMax.y, 0.0f, busMax.x, 16.0f, 16.0f );
}
else
{
if( facades.get( EnumFacing.UP ) != null )
{
max.y -= thickness;
}
if( facades.get( EnumFacing.DOWN ) != null )
{
min.y += thickness;
}
if( facades.get( EnumFacing.SOUTH ) != null )
{
max.z -= thickness;
}
if( facades.get( EnumFacing.NORTH ) != null )
{
min.z += thickness;
}
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMax.z, 16.0f, 16.0f, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, 16.0f, 16.0f, busMin.z );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMin.z, 16.0f, busMin.y, busMax.z );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, busMax.y, busMin.z, 16.0f, 16.0f, busMax.z );
tinter.setTint( Minecraft.getMinecraft().getItemColors().colorMultiplier( textureItem, quad.getTintIndex() ) );
pipeline.enableElement( "tinter" );
}
// Disable elements we don't need for items.
pipeline.disableElement( "face_stripper" );
pipeline.disableElement( "corner_kicker" );
// Setup the clamper
clamper.setClampBounds( THICK_FACADE_BOXES[side.ordinal()] );
// Prepare the pipeline.
pipeline.prepare( collectorQuad );
// Pipe our quad into the pipeline.
quad.pipe( pipeline );
// Check the collector for data and add the quad if there was.
if( collectorQuad.full )
{
facadeQuads.add( collectorQuad.bakeUnpacked() );
}
}
return facadeQuads;
}
private void renderSegmentBlockCurrentBounds( CubeBuilder builder, Vector3f min, Vector3f max, float minX, float minY, float minZ, float maxX, float maxY, float maxZ )
// Helper to gather all quads from a model into a list.
private static List<BakedQuad> gatherQuads( IBakedModel model, IBlockState state, long rand )
{
minX = Math.max( min.x, minX );
minY = Math.max( min.y, minY );
minZ = Math.max( min.z, minZ );
maxX = Math.min( max.x, maxX );
maxY = Math.min( max.y, maxY );
maxZ = Math.min( max.z, maxZ );
// don't draw it if its not at least a pixel wide...
if( maxX - minX >= 1.0 && maxY - minY >= 1.0 && maxZ - minZ >= 1.0 )
List<BakedQuad> modelQuads = new ArrayList<>();
for( EnumFacing face : EnumFacing.VALUES )
{
builder.addCube( minX, minY, minZ, maxX, maxY, maxZ );
modelQuads.addAll( model.getQuads( state, face, rand ) );
}
modelQuads.addAll( model.getQuads( state, null, rand ) );
return modelQuads;
}
/**
* Given the actual facade bounding box, and the bounding boxes of all parts, determine the biggest union of AABB
* that intersect with the
* facade's bounding box. This AABB will need to be "cut out" when the facade is rendered.
* that intersect with the facade's bounding
* box. This AABB will need to be "cut out" when the facade is rendered.
*/
@Nullable
private static AEAxisAlignedBB getCutOutBox( AxisAlignedBB facadeBox, List<AxisAlignedBB> partBoxes )
@@ -411,8 +413,58 @@ public class FacadeBuilder
}
/**
* Determines if any of the part's bounding boxes intersects with the outside 2 voxel wide layer.
* If so, we should use thinner facades (1 voxel deep).
* Generates the box segments around the specified hole. If the specified hole is null, a Singleton of the Facade
* box is returned.
*
* @param fb The Facade's box.
* @param hole The hole to 'cut'.
* @param axis The axis the facade is on.
*
* @return The box segments.
*/
private static List<AxisAlignedBB> getBoxes( AxisAlignedBB fb, AEAxisAlignedBB hole, Axis axis )
{
if( hole == null )
{
return Collections.singletonList( fb );
}
List<AxisAlignedBB> boxes = new ArrayList<>();
switch( axis )
{
case Y:
boxes.add( new AxisAlignedBB( fb.minX, fb.minY, fb.minZ, hole.minX, fb.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( hole.maxX, fb.minY, fb.minZ, fb.maxX, fb.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( hole.minX, fb.minY, fb.minZ, hole.maxX, fb.maxY, hole.minZ ) );
boxes.add( new AxisAlignedBB( hole.minX, fb.minY, hole.maxZ, hole.maxX, fb.maxY, fb.maxZ ) );
break;
case Z:
boxes.add( new AxisAlignedBB( fb.minX, fb.minY, fb.minZ, fb.maxX, hole.minY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.maxY, fb.minZ, fb.maxX, fb.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.minY, fb.minZ, hole.minX, hole.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( hole.maxX, hole.minY, fb.minZ, fb.maxX, hole.maxY, fb.maxZ ) );
break;
case X:
boxes.add( new AxisAlignedBB( fb.minX, fb.minY, fb.minZ, fb.maxX, hole.minY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.maxY, fb.minZ, fb.maxX, fb.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.minY, fb.minZ, fb.maxX, hole.maxY, hole.minZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.minY, hole.maxZ, fb.maxX, hole.maxY, fb.maxZ ) );
break;
default:
// should never happen.
throw new RuntimeException( "switch falloff. " + String.valueOf( axis ) );
}
return boxes;
}
/**
* Determines if any of the part's bounding boxes intersects with the outside 2 voxel wide layer. If so, we should
* use thinner facades (1 voxel deep).
*/
private static boolean isUseThinFacades( List<AxisAlignedBB> partBoxes )
{
@@ -436,57 +488,4 @@ public class FacadeBuilder
}
return false;
}
private static AxisAlignedBB getFacadeBox( EnumFacing side, boolean thinFacades )
{
double thickness = ( thinFacades ? 1 : 2 ) / 16.0;
switch( side )
{
case DOWN:
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, thickness, 1.0 );
case EAST:
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 );
case SOUTH:
return new AxisAlignedBB( 0.0, 0.0, 1.0 - thickness, 1.0, 1.0, 1.0 );
case UP:
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, 1.0, 1.0 );
default:
throw new IllegalArgumentException( "Unsupported face: " + side );
}
}
public static class TextureAtlasAndTint
{
private final TextureAtlasSprite sprite;
private final int tint;
private TextureAtlasAndTint( BakedQuad quad )
{
this.sprite = quad.getSprite();
this.tint = quad.getTintIndex();
}
private TextureAtlasAndTint( TextureAtlasSprite sprite, int tint )
{
this.sprite = sprite;
this.tint = tint;
}
public TextureAtlasSprite getSprite()
{
return this.sprite;
}
public int getTint()
{
return this.tint;
}
}
}
@@ -2,12 +2,7 @@
package appeng.client.render.cablebus;
import java.util.EnumSet;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
/**
@@ -19,17 +14,12 @@ public class FacadeRenderState
// The block state to use for rendering this facade
private final IBlockState sourceBlock;
// Which faces of the cube should be rendered for this particular facade
private final EnumSet<EnumFacing> openFaces;
private final boolean transparent;
// For resolving the tint indices of a facade
private final ItemStack textureItem;
public FacadeRenderState( IBlockState sourceBlock, EnumSet<EnumFacing> openFaces, ItemStack textureItem )
public FacadeRenderState( IBlockState sourceBlock, boolean transparent )
{
this.sourceBlock = sourceBlock;
this.openFaces = openFaces;
this.textureItem = textureItem;
this.transparent = transparent;
}
public IBlockState getSourceBlock()
@@ -37,14 +27,8 @@ public class FacadeRenderState
return this.sourceBlock;
}
public EnumSet<EnumFacing> getOpenFaces()
public boolean isTransparent()
{
return this.openFaces;
return this.transparent;
}
public int resolveTintColor( int tintIndex )
{
return Minecraft.getMinecraft().getItemColors().colorMultiplier( this.textureItem, tintIndex );
}
}
@@ -56,7 +56,7 @@ public class P2PTunnelFrequencyBakedModel implements IBakedModel, IPartBakedMode
frequency = (short) ( partFlags.longValue() & 0xffffL );
active = ( partFlags.longValue() & 0x10000L ) != 0;
}
return getQuadsForFrequency( frequency, active );
return this.getQuadsForFrequency( frequency, active );
} );
}
catch( ExecutionException e )
@@ -72,7 +72,7 @@ public class P2PTunnelFrequencyBakedModel implements IBakedModel, IPartBakedMode
{
return Collections.emptyList();
}
return getPartQuads( null, rand );
return this.getPartQuads( null, rand );
}
private List<BakedQuad> getQuadsForFrequency( final short frequency, final boolean active )
@@ -100,7 +100,7 @@ class ItemEncodedPatternBakedModel implements IBakedModel
{
if( this.baseModel instanceof IBakedModel )
{
return ( (IBakedModel) this.baseModel ).handlePerspective( cameraTransformType );
return this.baseModel.handlePerspective( cameraTransformType );
}
return PerspectiveMapWrapper.handlePerspective( this, this.transforms, cameraTransformType );
@@ -150,7 +150,7 @@ class ItemEncodedPatternBakedModel implements IBakedModel
if( selectedModel instanceof IBakedModel )
{
return ( (IBakedModel) selectedModel ).handlePerspective( cameraTransformType );
return selectedModel.handlePerspective( cameraTransformType );
}
return PerspectiveMapWrapper.handlePerspective( this, ItemEncodedPatternBakedModel.this.transforms, cameraTransformType );
@@ -77,7 +77,7 @@ public class AssemblerFX extends Particle implements ICanDie
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -142,7 +142,7 @@ public class CraftingFx extends ParticleBreaking
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -132,7 +132,7 @@ public class EnergyFx extends ParticleBreaking
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -88,7 +88,7 @@ public class LightningFX extends Particle
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -67,7 +67,7 @@ public class MatterCannonFX extends ParticleBreaking
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -19,7 +19,6 @@
package appeng.client.render.model;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
@@ -247,8 +246,10 @@ public enum UVLModelLoader implements ICustomModelLoader
{
String s = modelLocation.getResourcePath();
iresource = Minecraft.getMinecraft().getResourceManager().getResource(
new ResourceLocation( modelLocation.getResourceDomain(), "models/" + modelPath + ".json" ) );
iresource = Minecraft.getMinecraft()
.getResourceManager()
.getResource(
new ResourceLocation( modelLocation.getResourceDomain(), "models/" + modelPath + ".json" ) );
reader = new InputStreamReader( iresource.getInputStream(), Charsets.UTF_8 );
lvt_5_1_ = JsonUtils.gsonDeserialize( this.UVLSERIALIZER, reader, ModelBlock.class, false );
@@ -261,7 +262,7 @@ public enum UVLModelLoader implements ICustomModelLoader
finally
{
IOUtils.closeQuietly( reader );
IOUtils.closeQuietly( (Closeable) iresource );
IOUtils.closeQuietly( iresource );
}
model = lvt_5_1_;
@@ -1033,7 +1033,7 @@ public abstract class AEBaseContainer extends Container
protected ItemStack transferStackToContainer( final ItemStack input )
{
return shiftStoreItem( input );
return this.shiftStoreItem( input );
}
private ItemStack shiftStoreItem( final ItemStack input )
@@ -468,8 +468,9 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
final ItemStack failed = real.getStackInSlot( x );
if( !failed.isEmpty() )
{
this.getCellInventory().injectItems( AEItemStack.fromItemStack( failed ), Actionable.MODULATE,
new MachineSource( this.getPatternTerminal() ) );
this.getCellInventory()
.injectItems( AEItemStack.fromItemStack( failed ), Actionable.MODULATE,
new MachineSource( this.getPatternTerminal() ) );
}
}
}
@@ -88,7 +88,7 @@ public class ContainerPriority extends AEBaseContainer
super.onUpdate( field, oldValue, newValue );
}
public IPriorityHost getPriorityHost()
{
return this.priHost;
@@ -31,14 +31,11 @@ import appeng.util.Platform;
public class ContainerVibrationChamber extends AEBaseContainer implements IProgressProvider
{
private static final int MAX_BURN_TIME = 200;
private final int aePerTick = 5;
private final TileVibrationChamber vibrationChamber;
@GuiSync( 0 )
public int burnProgress = 0;
public int burnSpeed = 0;
@GuiSync( 1 )
public int burnSpeed = 100;
public int remainingBurnTime = 0;
public ContainerVibrationChamber( final InventoryPlayer ip, final TileVibrationChamber vibrationChamber )
{
@@ -56,28 +53,28 @@ public class ContainerVibrationChamber extends AEBaseContainer implements IProgr
{
if( Platform.isServer() )
{
this.burnProgress = (int) ( this.vibrationChamber.getMaxBurnTime() <= 0 ? 0 : 12 * this.vibrationChamber.getBurnTime() / this.vibrationChamber
.getMaxBurnTime() );
this.burnSpeed = this.vibrationChamber.getBurnSpeed();
}
this.remainingBurnTime = this.vibrationChamber
.getMaxBurnTime() <= 0 ? 0 : (int) ( 100.0 * this.vibrationChamber.getBurnTime() / this.vibrationChamber.getMaxBurnTime() );
this.burnSpeed = this.remainingBurnTime <= 0 ? 0 : this.vibrationChamber.getBurnSpeed();
}
super.detectAndSendChanges();
}
@Override
public int getCurrentProgress()
{
return this.burnProgress > 0 ? this.burnSpeed : 0;
return this.burnSpeed;
}
public int getRemainingBurnTime()
{
return this.remainingBurnTime;
}
@Override
public int getMaxProgress()
{
return MAX_BURN_TIME;
}
public int getAePerTick()
{
return this.aePerTick;
return TileVibrationChamber.MAX_BURN_SPEED;
}
}
@@ -80,11 +80,13 @@ public class OptionalSlotFake extends SlotFake implements IOptionalSlot
this.renderDisabled = renderDisabled;
}
@Override
public int getSourceX()
{
return this.srcX;
}
@Override
public int getSourceY()
{
return this.srcY;
+10
View File
@@ -23,6 +23,8 @@ import appeng.api.IAppEngApi;
import appeng.api.features.IRegistryContainer;
import appeng.api.networking.IGridHelper;
import appeng.api.storage.IStorageHelper;
import appeng.api.util.IClientHelper;
import appeng.core.api.ApiClientHelper;
import appeng.core.api.ApiGrid;
import appeng.core.api.ApiPart;
import appeng.core.api.ApiStorage;
@@ -41,6 +43,7 @@ public final class Api implements IAppEngApi
private final IStorageHelper storageHelper;
private final IGridHelper networkHelper;
private final ApiDefinitions definitions;
private final IClientHelper client;
private Api()
{
@@ -49,6 +52,7 @@ public final class Api implements IAppEngApi
this.registryContainer = new RegistryContainer();
this.partHelper = new ApiPart();
this.definitions = new ApiDefinitions( (PartModels) this.registryContainer.partModels() );
this.client = new ApiClientHelper();
}
public PartModels getPartModels()
@@ -85,4 +89,10 @@ public final class Api implements IAppEngApi
{
return this.definitions;
}
@Override
public IClientHelper client()
{
return this.client;
}
}
+6 -1
View File
@@ -30,6 +30,7 @@ import com.google.common.collect.Lists;
import net.minecraft.world.DimensionType;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.FMLCommonHandler;
@@ -78,7 +79,9 @@ public final class AppEng
public static final String ASSETS = "appliedenergistics2:";
public static final String MOD_DEPENDENCIES = "";
private static final String FORGE_CURRENT_VERSION = ForgeVersion.majorVersion + "." + ForgeVersion.minorVersion + "." + ForgeVersion.revisionVersion + "." + ForgeVersion.buildVersion;
private static final String FORGE_MAX_VERSION = ( ForgeVersion.majorVersion + 1 ) + ".0.0.0";
public static final String MOD_DEPENDENCIES = "required-after:forge@[" + FORGE_CURRENT_VERSION + "," + FORGE_MAX_VERSION + ")";
@Nonnull
private static final AppEng INSTANCE = new AppEng();
@@ -198,6 +201,8 @@ public final class AppEng
final Stopwatch start = Stopwatch.createStarted();
AELog.info( "Initialization ( started )" );
AppEng.proxy.init();
if( this.exportConfig.isExportingItemNamesEnabled() )
{
if( FMLCommonHandler.instance().getSide().isClient() )
@@ -22,6 +22,8 @@ package appeng.core;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.RayTraceResult;
@@ -29,6 +31,7 @@ import net.minecraft.world.World;
import appeng.api.parts.CableRenderMode;
import appeng.block.AEBaseBlock;
import appeng.client.ActionKey;
import appeng.client.EffectType;
import appeng.core.sync.AppEngPacket;
@@ -62,4 +65,8 @@ public abstract class CommonHelper
public abstract void updateRenderMode( EntityPlayer player );
public abstract boolean isKeyPressed( @Nonnull final ActionKey key );
public abstract boolean isActionKey( @Nonnull final ActionKey key, int pressedKeyCode );
}
+111 -37
View File
@@ -20,32 +20,124 @@ package appeng.core;
import java.io.File;
import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.common.config.Property.Type;
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
public class FacadeConfig extends Configuration
public class FacadeConfig
{
private static final String CONFIG_VERSION = "1";
private static final String CONFIG_COMMON_KEY = "common";
private static final String CONFIG_COMMON_COMMENT = "Settings applied to all facades.\n\n" //
+ "By default full blocks with no tile entity and a model do not need whitelisting.\n"//
+ "This will only be read once during client startup.";
private static final String CONFIG_COMMON_ALLOW_TILEENTITIES_KEY = "allowTileEntityFacades";
private static final String CONFIG_COMMON_ALLOW_TILEENTITIES_COMMENT = "Unsupported: Allows whitelisting TileEntity as facades. Could work, have render issues, or corrupt your world. USE AT YOUR OWN RISK.";
private static final String CONFIG_FACADES_KEY = "facades";
private static final String CONFIG_FACADES_COMMENT = "A way to explicitly handle certain blocks as facades.\n\n" //
+ "Blocks can be added by their resource location under the following rules.\n" //
+ " - One category per domain like minecraft or appliedenergistics2\n" //
+ " - One key per id. E.g. glass in case of minecraft:glass\n" //
+ " - An integer value ranging from 0 to 16 representing the metadata 0-15 and 16 as wildcard for all" //
+ " - Multiple entries for the same id but different metadata are possible when needed";
private static FacadeConfig instance;
private final Pattern replacementPattern;
private final boolean allowTileEntityFacades;
private final Object2IntMap<ResourceLocation> whiteList;
public FacadeConfig( final File facadeFile )
private FacadeConfig( boolean allowTileEntityFacades, Object2IntMap<ResourceLocation> whiteList )
{
super( facadeFile );
this.replacementPattern = Pattern.compile( "[^a-zA-Z0-9]" );
this.allowTileEntityFacades = allowTileEntityFacades;
this.whiteList = whiteList;
}
/**
* Creates a custom confuration based on a {@link Configuration}, but ultimately throws it away after reading it
* once to save a couple MB of memory.
*
* @param configFile
*/
public static void init( final File configFile )
{
instance = new FacadeConfig( configFile );
final Configuration configurartion = migrate( new Configuration( configFile, CONFIG_VERSION ) );
final boolean allowTileEntityFacades = configurartion
.get( CONFIG_COMMON_KEY, CONFIG_COMMON_ALLOW_TILEENTITIES_KEY, false, CONFIG_COMMON_ALLOW_TILEENTITIES_COMMENT )
.setRequiresMcRestart( true )
.setShowInGui( false )
.getBoolean();
final Object2IntMap<ResourceLocation> configWhiteList = new Object2IntArrayMap<>();
final Set<ConfigCategory> whitelist = configurartion.getCategory( CONFIG_FACADES_KEY ).getChildren();
for( ConfigCategory configCategory : whitelist )
{
final String domain = configCategory.getName();
final Map<String, Property> values = configCategory.getValues();
for( Entry<String, Property> entry : values.entrySet() )
{
configWhiteList.put( new ResourceLocation( domain, entry.getKey() ), entry.getValue().getInt() );
}
}
if( configurartion.hasChanged() )
{
configurartion.save();
}
instance = new FacadeConfig( allowTileEntityFacades, configWhiteList );
}
private static Configuration migrate( Configuration configurartion )
{
// Clear pre rv6 configs.
if( configurartion.getLoadedConfigVersion() == null )
{
for( String category : configurartion.getCategoryNames() )
{
final ConfigCategory c = configurartion.getCategory( category );
configurartion.removeCategory( c );
}
}
// Create general category, if missing
if( !configurartion.hasCategory( CONFIG_COMMON_KEY ) )
{
configurartion.getCategory( CONFIG_COMMON_KEY ).setComment( CONFIG_COMMON_COMMENT );
}
// Create whitelist, if missing
if( !configurartion.hasCategory( CONFIG_FACADES_KEY ) )
{
final ConfigCategory category = configurartion.getCategory( CONFIG_FACADES_KEY );
category.setComment( CONFIG_FACADES_COMMENT );
// Whitelist some vanilla blocks like glass
final ConfigCategory minecraft = new ConfigCategory( "minecraft", category );
minecraft.put( "glass", new Property( "glass", "16", Type.INTEGER ) );
minecraft.put( "stained_glass", new Property( "stained_glass", "16", Type.INTEGER ) );
// Whitelist some AE2 blocks like quartz glass
final ConfigCategory appliedenergistics = new ConfigCategory( "appliedenergistics2", category );
appliedenergistics.put( "quartz_glass", new Property( "quartz_glass", "16", Type.INTEGER ) );
appliedenergistics.put( "quartz_vibrant_glass", new Property( "quartz_vibrant_glass", "16", Type.INTEGER ) );
}
return configurartion;
}
public static FacadeConfig instance()
@@ -53,36 +145,18 @@ public class FacadeConfig extends Configuration
return instance;
}
public boolean checkEnabled( final Block id, final int metadata, final boolean automatic )
public boolean allowTileEntityFacades()
{
if( id == null )
{
return false;
}
return this.allowTileEntityFacades;
}
final ResourceLocation blk = Item.REGISTRY.getNameForObject( Item.getItemFromBlock( id ) );
if( blk == null )
public boolean isWhiteListed( final Block block, final int metadata )
{
final Integer entry = this.whiteList.get( block.getRegistryName() );
if( entry != null )
{
for( final Field f : Block.class.getFields() )
{
try
{
if( f.get( Block.class ) == id )
{
return this.get( "minecraft", f.getName() + ( metadata == 0 ? "" : "/" + metadata ), automatic ).getBoolean( automatic );
}
}
catch( final Throwable e )
{
// :P
}
}
}
else
{
final Matcher mod = this.replacementPattern.matcher( blk.getResourceDomain() );
final Matcher name = this.replacementPattern.matcher( blk.getResourcePath() );
return this.get( mod.replaceAll( "" ), name.replaceAll( "" ) + ( metadata == 0 ? "" : "." + metadata ), automatic ).getBoolean( automatic );
return entry == metadata || entry == 16;
}
return false;
+13 -11
View File
@@ -91,7 +91,8 @@ import appeng.bootstrap.components.IRecipeRegistrationComponent;
import appeng.capabilities.Capabilities;
import appeng.core.features.AEFeature;
import appeng.core.features.registries.P2PTunnelRegistry;
import appeng.core.features.registries.cell.BasicItemCellHandler;
import appeng.core.features.registries.cell.BasicCellHandler;
import appeng.core.features.registries.cell.BasicItemCellGuiHandler;
import appeng.core.features.registries.cell.CreativeCellHandler;
import appeng.core.localization.GuiText;
import appeng.core.localization.PlayerMessages;
@@ -99,7 +100,7 @@ import appeng.core.stats.AdvancementTriggers;
import appeng.core.stats.PartItemPredicate;
import appeng.core.stats.Stats;
import appeng.core.worlddata.SpatialDimensionManager;
import appeng.fluids.registries.BasicFluidCellHandler;
import appeng.fluids.registries.BasicFluidCellGuiHandler;
import appeng.hooks.TickHandler;
import appeng.items.materials.ItemMaterial;
import appeng.items.parts.ItemFacade;
@@ -236,9 +237,10 @@ final class Registration
gcr.registerGridCache( ISecurityGrid.class, SecurityCache.class );
gcr.registerGridCache( ICraftingGrid.class, CraftingGridCache.class );
registries.cell().addCellHandler( new BasicItemCellHandler() );
registries.cell().addCellHandler( new BasicCellHandler() );
registries.cell().addCellHandler( new CreativeCellHandler() );
registries.cell().addCellHandler( new BasicFluidCellHandler() );
registries.cell().addCellGuiHandler( new BasicItemCellGuiHandler() );
registries.cell().addCellGuiHandler( new BasicFluidCellGuiHandler() );
api.definitions().materials().matterBall().maybeStack( 1 ).ifPresent( ammoStack ->
{
@@ -286,7 +288,7 @@ final class Registration
final Side side = FMLCommonHandler.instance().getEffectiveSide();
definitions.getRegistry().getBootstrapComponents( IItemRegistrationComponent.class ).forEachRemaining( b -> b.itemRegistration( side, registry ) );
// register oredicts
definitions.getRegistry().getBootstrapComponents( IOreDictComponent.class ).forEachRemaining( b -> b.oreRegistration( side ) );
definitions.getRegistry().getBootstrapComponents( IOreDictComponent.class ).forEachRemaining( b -> b.oreRegistration( side ) );
ItemMaterial.instance.registerOredicts();
ItemPart.instance.registerOreDicts();
}
@@ -320,15 +322,15 @@ final class Registration
final AERecipeLoader ldr = new AERecipeLoader();
ldr.loadProcessingRecipes();
}
@SubscribeEvent
public void registerEntities( RegistryEvent.Register<EntityEntry> event)
public void registerEntities( RegistryEvent.Register<EntityEntry> event )
{
final IForgeRegistry<EntityEntry> registry = event.getRegistry();
final ApiDefinitions definitions = Api.INSTANCE.definitions();
definitions.getRegistry().getBootstrapComponents( IEntityRegistrationComponent.class ).forEachRemaining( b -> b.entityRegistration( registry ) );
}
@SubscribeEvent
public void attachSpatialDimensionManager( AttachCapabilitiesEvent<World> event )
{
@@ -347,7 +349,7 @@ final class Registration
final IBlocks blocks = definitions.blocks();
final IItems items = definitions.items();
registerSpatialDimension();
this.registerSpatialDimension();
// default settings..
( (P2PTunnelRegistry) registries.p2pTunnel() ).configure();
@@ -560,7 +562,7 @@ final class Registration
CriterionTrigggerRegistry()
{
this.method = ReflectionHelper.findMethod( CriteriaTriggers.class, "register", "func_192118_a", ICriterionTrigger.class );
method.setAccessible( true );
this.method.setAccessible( true );
}
@Override
@@ -568,7 +570,7 @@ final class Registration
{
try
{
method.invoke( null, trigger );
this.method.invoke( null, trigger );
}
catch( IllegalAccessException | IllegalArgumentException | InvocationTargetException e )
{
@@ -0,0 +1,51 @@
package appeng.core.api;
import java.util.List;
import appeng.api.config.IncludeExclude;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.data.IAEStack;
import appeng.api.util.IClientHelper;
import appeng.core.localization.GuiText;
public class ApiClientHelper implements IClientHelper
{
@Override
public <T extends IAEStack<T>> void addCellInformation( ICellInventoryHandler<T> handler, List<String> lines )
{
if( handler == null )
{
return;
}
final ICellInventory<?> cellInventory = handler.getCellInv();
if( cellInventory != null )
{
lines.add( cellInventory.getUsedBytes() + " " + GuiText.Of.getLocal() + ' ' + cellInventory.getTotalBytes() + ' ' + GuiText.BytesUsed.getLocal() );
lines.add( cellInventory.getStoredItemTypes() + " " + GuiText.Of.getLocal() + ' ' + cellInventory.getTotalItemTypes() + ' ' + GuiText.Types
.getLocal() );
}
if( handler.isPreformatted() )
{
final String list = ( handler.getIncludeExcludeMode() == IncludeExclude.WHITELIST ? GuiText.Included : GuiText.Excluded ).getLocal();
if( handler.isFuzzy() )
{
lines.add( GuiText.Partitioned.getLocal() + " - " + list + ' ' + GuiText.Fuzzy.getLocal() );
}
else
{
lines.add( GuiText.Partitioned.getLocal() + " - " + list + ' ' + GuiText.Precise.getLocal() );
}
}
}
}
+55 -40
View File
@@ -32,11 +32,14 @@ import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import appeng.api.config.Actionable;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingRequester;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.IStorageHelper;
@@ -47,6 +50,7 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.crafting.CraftingLink;
import appeng.fluids.items.FluidDummyItem;
import appeng.fluids.util.AEFluidStack;
import appeng.fluids.util.FluidList;
import appeng.util.Platform;
@@ -104,6 +108,29 @@ public class ApiStorage implements IStorageHelper
return new CraftingLink( data, req );
}
@Override
public <T extends IAEStack<T>> T poweredInsert( IEnergySource energy, IMEInventory<T> inv, T input, IActionSource src, Actionable mode )
{
return Platform.poweredInsert( energy, inv, input, src, mode );
}
@Override
public <T extends IAEStack<T>> T poweredExtraction( IEnergySource energy, IMEInventory<T> inv, T request, IActionSource src, Actionable mode )
{
return Platform.poweredExtraction( energy, inv, request, src, mode );
}
@Override
public void postChanges( IStorageGrid gs, ItemStack removedCell, ItemStack addedCell, IActionSource src )
{
Preconditions.checkNotNull( gs );
Preconditions.checkNotNull( removedCell );
Preconditions.checkNotNull( addedCell );
Preconditions.checkNotNull( src );
Platform.postChanges( gs, removedCell, addedCell, src );
}
private static final class ItemStorageChannel implements IItemStorageChannel
{
@@ -126,6 +153,13 @@ public class ApiStorage implements IStorageHelper
return null;
}
@Override
public IAEItemStack createFromNBT( NBTTagCompound nbt )
{
Preconditions.checkNotNull( nbt );
return AEItemStack.fromNBT( nbt );
}
@Override
public IAEItemStack readFromPacket( ByteBuf input ) throws IOException
{
@@ -133,28 +167,6 @@ public class ApiStorage implements IStorageHelper
return AEItemStack.fromPacket( input );
}
@Override
public IAEItemStack poweredExtraction( IEnergySource energy, IMEInventory<IAEItemStack> cell, IAEItemStack request, IActionSource src )
{
Preconditions.checkNotNull( energy );
Preconditions.checkNotNull( cell );
Preconditions.checkNotNull( request );
Preconditions.checkNotNull( src );
return Platform.poweredExtraction( energy, cell, request, src );
}
@Override
public IAEItemStack poweredInsert( IEnergySource energy, IMEInventory<IAEItemStack> cell, IAEItemStack input, IActionSource src )
{
Preconditions.checkNotNull( energy );
Preconditions.checkNotNull( cell );
Preconditions.checkNotNull( input );
Preconditions.checkNotNull( src );
return Platform.poweredInsert( energy, cell, input, src );
}
}
private static final class FluidStorageChannel implements IFluidStorageChannel
@@ -166,6 +178,12 @@ public class ApiStorage implements IStorageHelper
return 125;
}
@Override
public int getUnitsPerByte()
{
return 8000;
}
@Override
public IItemList<IAEFluidStack> createList()
{
@@ -181,6 +199,18 @@ public class ApiStorage implements IStorageHelper
{
return AEFluidStack.fromFluidStack( (FluidStack) input );
}
if( input instanceof ItemStack )
{
final ItemStack is = (ItemStack) input;
if( is.getItem() instanceof FluidDummyItem )
{
return AEFluidStack.fromFluidStack( ( (FluidDummyItem) is.getItem() ).getFluidStack( is ) );
}
else
{
return AEFluidStack.fromFluidStack( FluidUtil.getFluidContained( is ) );
}
}
return null;
}
@@ -194,25 +224,10 @@ public class ApiStorage implements IStorageHelper
}
@Override
public IAEFluidStack poweredExtraction( IEnergySource energy, IMEInventory<IAEFluidStack> cell, IAEFluidStack request, IActionSource src )
public IAEFluidStack createFromNBT( NBTTagCompound nbt )
{
Preconditions.checkNotNull( energy );
Preconditions.checkNotNull( cell );
Preconditions.checkNotNull( request );
Preconditions.checkNotNull( src );
return Platform.poweredExtraction( energy, cell, request, src );
}
@Override
public IAEFluidStack poweredInsert( IEnergySource energy, IMEInventory<IAEFluidStack> cell, IAEFluidStack input, IActionSource src )
{
Preconditions.checkNotNull( energy );
Preconditions.checkNotNull( cell );
Preconditions.checkNotNull( input );
Preconditions.checkNotNull( src );
return Platform.poweredInsert( energy, cell, input, src );
Preconditions.checkNotNull( nbt );
return AEFluidStack.fromNBT( nbt );
}
}
@@ -1067,6 +1067,6 @@ public final class ApiBlocks implements IBlocks
public IBlockDefinition energyGenerator()
{
return energyGenerator;
return this.energyGenerator;
}
}
@@ -19,14 +19,17 @@
package appeng.core.api.definitions;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.registry.EntityEntryBuilder;
import net.minecraftforge.oredict.OreDictionary;
import appeng.api.definitions.IItemDefinition;
import appeng.api.definitions.IItems;
import appeng.api.util.AEColoredItemDefinition;
import appeng.bootstrap.FeatureFactory;
import appeng.bootstrap.components.IEntityRegistrationComponent;
import appeng.bootstrap.components.IOreDictComponent;
import appeng.client.render.crafting.ItemEncodedPatternRendering;
import appeng.core.CreativeTabFacade;
import appeng.core.features.AEFeature;
@@ -158,9 +161,13 @@ public final class ApiItems implements IItems
this.certusQuartzSword = certusTools.item( "certus_quartz_sword", () -> new ToolQuartzSword( AEFeature.CERTUS_QUARTZ_TOOLS ) )
.addFeatures( AEFeature.QUARTZ_SWORD )
.build();
this.certusQuartzWrench = certusTools.item( "certus_quartz_wrench", ToolQuartzWrench::new ).addFeatures( AEFeature.QUARTZ_WRENCH ).build();
this.certusQuartzWrench = certusTools.item( "certus_quartz_wrench", ToolQuartzWrench::new )
.addFeatures( AEFeature.QUARTZ_WRENCH )
.bootstrap( item -> (IOreDictComponent) side -> OreDictionary.registerOre( "itemQuartzWrench", new ItemStack( item ) ) )
.build();
this.certusQuartzKnife = certusTools.item( "certus_quartz_cutting_knife", () -> new ToolQuartzCuttingKnife( AEFeature.CERTUS_QUARTZ_TOOLS ) )
.addFeatures( AEFeature.QUARTZ_KNIFE )
.bootstrap( item -> (IOreDictComponent) side -> OreDictionary.registerOre( "itemQuartzKnife", new ItemStack( item ) ) )
.build();
FeatureFactory netherTools = registry.features( AEFeature.NETHER_QUARTZ_TOOLS );
@@ -179,9 +186,13 @@ public final class ApiItems implements IItems
this.netherQuartzSword = netherTools.item( "nether_quartz_sword", () -> new ToolQuartzSword( AEFeature.NETHER_QUARTZ_TOOLS ) )
.addFeatures( AEFeature.QUARTZ_SWORD )
.build();
this.netherQuartzWrench = netherTools.item( "nether_quartz_wrench", ToolQuartzWrench::new ).addFeatures( AEFeature.QUARTZ_WRENCH ).build();
this.netherQuartzWrench = netherTools.item( "nether_quartz_wrench", ToolQuartzWrench::new )
.addFeatures( AEFeature.QUARTZ_WRENCH )
.bootstrap( item -> (IOreDictComponent) side -> OreDictionary.registerOre( "itemQuartzWrench", new ItemStack( item ) ) )
.build();
this.netherQuartzKnife = netherTools.item( "nether_quartz_cutting_knife", () -> new ToolQuartzCuttingKnife( AEFeature.NETHER_QUARTZ_TOOLS ) )
.addFeatures( AEFeature.QUARTZ_KNIFE )
.bootstrap( item -> (IOreDictComponent) side -> OreDictionary.registerOre( "itemQuartzKnife", new ItemStack( item ) ) )
.build();
FeatureFactory powerTools = registry.features( AEFeature.POWERED_TOOLS );
@@ -151,7 +151,7 @@ public final class ApiMaterials implements IMaterials
.entity( EntityChargedQuartz.class )
.id( new ResourceLocation( "appliedenergistics2", EntityChargedQuartz.class.getName() ),
EntityIds.get( EntityChargedQuartz.class ) )
.name( EntityChargedQuartz.class.getSimpleName() )
.name( EntityChargedQuartz.class.getSimpleName() )
.tracker( 16, 4, true )
.build() );
} )
@@ -438,7 +438,7 @@ public final class ApiParts implements IParts
{
return this.fluidAnnihilationPlane;
}
@Override
public IItemDefinition fluidFormationnPlane()
{
@@ -0,0 +1,54 @@
/*
* 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.core.features.registries.cell;
import net.minecraft.item.ItemStack;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.ISaveProvider;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.me.storage.BasicCellInventory;
import appeng.me.storage.BasicCellInventoryHandler;
public class BasicCellHandler implements ICellHandler
{
@Override
public boolean isCell( final ItemStack is )
{
return BasicCellInventory.isCell( is );
}
@Override
public <T extends IAEStack<T>> ICellInventoryHandler<T> getCellInventory( final ItemStack is, final ISaveProvider container, final IStorageChannel<T> channel )
{
final ICellInventory<T> inv = BasicCellInventory.createInventory( is, container );
if( inv == null || inv.getChannel() != channel )
{
return null;
}
return new BasicCellInventoryHandler<>( inv, channel );
}
}
@@ -0,0 +1,35 @@
package appeng.core.features.registries.cell;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import appeng.api.AEApi;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.storage.ICellGuiHandler;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.util.AEPartLocation;
import appeng.core.sync.GuiBridge;
import appeng.util.Platform;
public class BasicItemCellGuiHandler implements ICellGuiHandler
{
@Override
public <T extends IAEStack<T>> boolean isHandlerFor( final IStorageChannel<T> channel )
{
return channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
}
@Override
public void openChestGui( final EntityPlayer player, final IChestOrDrive chest, final ICellHandler cellHandler, final IMEInventoryHandler inv, final ItemStack is, final IStorageChannel chan )
{
Platform.openGUI( player, (TileEntity) chest, AEPartLocation.fromFacing( chest.getUp() ), GuiBridge.GUI_ME );
}
}
@@ -1,90 +0,0 @@
/*
* 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.core.features.registries.cell;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import appeng.api.AEApi;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.ISaveProvider;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.util.AEPartLocation;
import appeng.core.sync.GuiBridge;
import appeng.me.storage.ItemCellInventory;
import appeng.me.storage.ItemCellInventoryHandler;
import appeng.util.Platform;
public class BasicItemCellHandler implements ICellHandler
{
@Override
public boolean isCell( final ItemStack is )
{
return ItemCellInventory.isCell( is );
}
@Override
public <T extends IAEStack<T>> ICellInventoryHandler<T> getCellInventory( final ItemStack is, final ISaveProvider container, final IStorageChannel<T> channel )
{
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
return (ICellInventoryHandler<T>) ItemCellInventory.getCell( is, container );
}
return null;
}
@Override
public void openChestGui( final EntityPlayer player, final IChestOrDrive chest, final ICellHandler cellHandler, final IMEInventoryHandler inv, final ItemStack is, final IStorageChannel chan )
{
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
Platform.openGUI( player, (TileEntity) chest, AEPartLocation.fromFacing( chest.getUp() ), GuiBridge.GUI_ME );
}
}
@Override
public int getStatusForCell( final ItemStack is, final IMEInventory handler )
{
if( handler instanceof ItemCellInventoryHandler )
{
final ItemCellInventoryHandler ci = (ItemCellInventoryHandler) handler;
return ci.getStatusForCell();
}
return 0;
}
@Override
public double cellIdleDrain( final ItemStack is, final IMEInventory handler )
{
final ICellInventory inv = ( (ICellInventoryHandler) handler ).getCellInv();
return inv.getIdleDrain();
}
}
@@ -27,6 +27,7 @@ import com.google.common.base.Verify;
import net.minecraft.item.ItemStack;
import appeng.api.storage.ICellGuiHandler;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.ICellRegistry;
@@ -39,10 +40,12 @@ public class CellRegistry implements ICellRegistry
{
private final List<ICellHandler> handlers;
private final List<ICellGuiHandler> guiHandlers;
public CellRegistry()
{
this.handlers = new ArrayList<>();
this.guiHandlers = new ArrayList<>();
}
@Override
@@ -54,7 +57,7 @@ public class CellRegistry implements ICellRegistry
this.handlers.add( handler );
// Verify that the first entry is always our own handler.
Verify.verify( this.handlers.get( 0 ) instanceof BasicItemCellHandler );
Verify.verify( this.handlers.get( 0 ) instanceof BasicCellHandler );
}
@Override
@@ -107,4 +110,33 @@ public class CellRegistry implements ICellRegistry
}
return null;
}
@Override
public void addCellGuiHandler( ICellGuiHandler handler )
{
this.guiHandlers.add( handler );
}
@Override
public <T extends IAEStack<T>> ICellGuiHandler getGuiHandler( final IStorageChannel<T> channel, final ItemStack is )
{
ICellGuiHandler fallBack = null;
for( final ICellGuiHandler ch : this.guiHandlers )
{
if( ch.isHandlerFor( channel ) )
{
if( ch.isSpecializedFor( is ) )
{
return ch;
}
if( fallBack == null )
{
fallBack = ch;
}
}
}
return fallBack;
}
}
@@ -19,24 +19,16 @@
package appeng.core.features.registries.cell;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import appeng.api.AEApi;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.ISaveProvider;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.util.AEPartLocation;
import appeng.core.sync.GuiBridge;
import appeng.items.storage.ItemCreativeStorageCell;
import appeng.me.storage.CreativeCellInventory;
import appeng.util.Platform;
public final class CreativeCellHandler implements ICellHandler
@@ -60,19 +52,13 @@ public final class CreativeCellHandler implements ICellHandler
}
@Override
public void openChestGui( final EntityPlayer player, final IChestOrDrive chest, final ICellHandler cellHandler, final IMEInventoryHandler inv, final ItemStack is, final IStorageChannel chan )
{
Platform.openGUI( player, (TileEntity) chest, AEPartLocation.fromFacing( chest.getUp() ), GuiBridge.GUI_ME );
}
@Override
public int getStatusForCell( final ItemStack is, final IMEInventory handler )
public int getStatusForCell( final ItemStack is, final ICellInventoryHandler handler )
{
return 2;
}
@Override
public double cellIdleDrain( final ItemStack is, final IMEInventory handler )
public double cellIdleDrain( final ItemStack is, final ICellInventoryHandler handler )
{
return 0;
}
@@ -372,7 +372,7 @@ public final class GrinderRecipeManager implements IGrinderRegistry, IOreListene
{
return true;
}
if( obj == null || getClass() != obj.getClass() )
if( obj == null || this.getClass() != obj.getClass() )
{
return false;
}
@@ -31,10 +31,10 @@ public class AdvancementTriggers
public AdvancementTriggers( ICriterionTriggerRegistry registry )
{
registry.register( networkApprentice );
registry.register( networkEngineer );
registry.register( networkAdmin );
registry.register( spatialExplorer );
registry.register( this.networkApprentice );
registry.register( this.networkEngineer );
registry.register( this.networkAdmin );
registry.register( this.spatialExplorer );
}
public IAdvancementTrigger getNetworkApprentice()
@@ -46,13 +46,13 @@ public class AppEngAdvancementTrigger implements ICriterionTrigger<AppEngAdvance
public AppEngAdvancementTrigger( String parString )
{
super();
ID = new ResourceLocation( AppEng.MOD_ID, parString );
this.ID = new ResourceLocation( AppEng.MOD_ID, parString );
}
@Override
public ResourceLocation getId()
{
return ID;
return this.ID;
}
@Override
@@ -97,6 +97,7 @@ public class AppEngAdvancementTrigger implements ICriterionTrigger<AppEngAdvance
return new AppEngAdvancementTrigger.Instance( this.getId() );
}
@Override
public void trigger( EntityPlayerMP parPlayer )
{
AppEngAdvancementTrigger.Listeners l = this.listeners.get( parPlayer.getAdvancements() );
@@ -150,7 +150,7 @@ public class PacketJEIRecipe extends AppEngPacket
if( !currentItem.isEmpty() )
{
// already the correct item?
ItemStack newItem = canUseInSlot( x, currentItem );
ItemStack newItem = this.canUseInSlot( x, currentItem );
// put away old item
if( newItem != currentItem && security.hasPermission( player, SecurityPermissions.INJECT ) )
@@ -27,6 +27,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.annotation.Nullable;
import io.netty.buffer.ByteBuf;
@@ -83,7 +84,7 @@ public class PacketMEFluidInventoryUpdate extends AppEngPacket
// int originalBytes = stream.readableBytes();
final GZIPInputStream gzReader = new GZIPInputStream( new InputStream()
try( final GZIPInputStream gzReader = new GZIPInputStream( new InputStream()
{
@Override
public int read() throws IOException
@@ -95,26 +96,26 @@ public class PacketMEFluidInventoryUpdate extends AppEngPacket
return stream.readByte() & STREAM_MASK;
}
} );
final ByteBuf uncompressed = Unpooled.buffer( stream.readableBytes() );
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
while( gzReader.available() != 0 )
} ) )
{
final int bytes = gzReader.read( tmp );
if( bytes > 0 )
final ByteBuf uncompressed = Unpooled.buffer( stream.readableBytes() );
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
while( gzReader.available() != 0 )
{
uncompressed.writeBytes( tmp, 0, bytes );
final int bytes = gzReader.read( tmp );
if( bytes > 0 )
{
uncompressed.writeBytes( tmp, 0, bytes );
}
}
}
gzReader.close();
// int uncompressedBytes = uncompressed.readableBytes();
// AELog.info( "Receiver: " + originalBytes + " -> " + uncompressedBytes );
while( uncompressed.readableBytes() > 0 )
{
this.list.add( AEFluidStack.fromPacket( uncompressed ) );
while( uncompressed.readableBytes() > 0 )
{
this.list.add( AEFluidStack.fromPacket( uncompressed ) );
}
}
this.empty = this.list.isEmpty();
@@ -82,7 +82,7 @@ public class PacketMEInventoryUpdate extends AppEngPacket
// int originalBytes = stream.readableBytes();
final GZIPInputStream gzReader = new GZIPInputStream( new InputStream()
try( GZIPInputStream gzReader = new GZIPInputStream( new InputStream()
{
@Override
public int read() throws IOException
@@ -94,29 +94,29 @@ public class PacketMEInventoryUpdate extends AppEngPacket
return stream.readByte() & STREAM_MASK;
}
} );
final ByteBuf uncompressed = Unpooled.buffer( stream.readableBytes() );
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
while( gzReader.available() != 0 )
} ) )
{
final int bytes = gzReader.read( tmp );
if( bytes > 0 )
final ByteBuf uncompressed = Unpooled.buffer( stream.readableBytes() );
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
while( gzReader.available() != 0 )
{
uncompressed.writeBytes( tmp, 0, bytes );
final int bytes = gzReader.read( tmp );
if( bytes > 0 )
{
uncompressed.writeBytes( tmp, 0, bytes );
}
}
}
gzReader.close();
// int uncompressedBytes = uncompressed.readableBytes();
// AELog.info( "Receiver: " + originalBytes + " -> " + uncompressedBytes );
while( uncompressed.readableBytes() > 0 )
{
this.list.add( AEItemStack.fromPacket( uncompressed ) );
while( uncompressed.readableBytes() > 0 )
{
this.list.add( AEItemStack.fromPacket( uncompressed ) );
}
}
this.empty = this.list.isEmpty();
}
// api
@@ -73,7 +73,7 @@ public class SpatialDimensionManager implements ISpatialDimension, ICapabilitySe
@Override
public void deleteCellDimension( int cellStorageId )
{
StorageCellData removed = spatialData.remove( cellStorageId );
StorageCellData removed = this.spatialData.remove( cellStorageId );
if( removed != null )
{
this.clearCellArea( cellStorageId, removed );
@@ -102,7 +102,7 @@ public class SpatialDimensionManager implements ISpatialDimension, ICapabilitySe
{
if( this.isCellDimension( cellStorageId ) )
{
return getBlockPosFromId( cellStorageId );
return this.getBlockPosFromId( cellStorageId );
}
return null;
}
@@ -228,18 +228,18 @@ public class SpatialDimensionManager implements ISpatialDimension, ICapabilitySe
public NBTTagCompound serializeNBT()
{
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger( NBT_DIM_X_KEY, contentDimension.getX() );
nbt.setInteger( NBT_DIM_Y_KEY, contentDimension.getY() );
nbt.setInteger( NBT_DIM_Z_KEY, contentDimension.getZ() );
nbt.setInteger( NBT_OWNER_KEY, owner );
nbt.setInteger( NBT_DIM_X_KEY, this.contentDimension.getX() );
nbt.setInteger( NBT_DIM_Y_KEY, this.contentDimension.getY() );
nbt.setInteger( NBT_DIM_Z_KEY, this.contentDimension.getZ() );
nbt.setInteger( NBT_OWNER_KEY, this.owner );
return nbt;
}
@Override
public void deserializeNBT( NBTTagCompound nbt )
{
contentDimension = new BlockPos( nbt.getInteger( NBT_DIM_X_KEY ), nbt.getInteger( NBT_DIM_Y_KEY ), nbt.getInteger( NBT_DIM_Z_KEY ) );
owner = nbt.getInteger( NBT_OWNER_KEY );
this.contentDimension = new BlockPos( nbt.getInteger( NBT_DIM_X_KEY ), nbt.getInteger( NBT_DIM_Y_KEY ), nbt.getInteger( NBT_DIM_Z_KEY ) );
this.owner = nbt.getInteger( NBT_OWNER_KEY );
}
}
}
@@ -64,7 +64,7 @@ public class CraftingWatcher implements ICraftingWatcher
@Override
public boolean remove( final IAEStack o )
{
return this.myInterests.remove( o ) && this.gsc.getInterestManager().remove( (IAEStack) o, this );
return this.myInterests.remove( o ) && this.gsc.getInterestManager().remove( o, this );
}
@Override
@@ -139,7 +139,7 @@ public class ToolReplicatorCard extends AEBaseItem
final TileEntity nte = blk.createTileEntity( world, state );
final NBTTagCompound data = new NBTTagCompound();
ote.writeToNBT( data );
nte.readFromNBT( (NBTTagCompound) data.copy() );
nte.readFromNBT( data.copy() );
world.setTileEntity( d, nte );
}
world.notifyBlockUpdate( d, prev, state, 3 );

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