4a77b401d9
Increased default formation plane "Max Entities" to 128 from 32 Formation plane now updates properly to reflect power state.
514 lines
15 KiB
Java
514 lines
15 KiB
Java
package appeng.parts.automation;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import net.minecraft.client.renderer.RenderBlocks;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.item.EntityItem;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.inventory.IInventory;
|
|
import net.minecraft.item.Item;
|
|
import net.minecraft.item.ItemBlock;
|
|
import net.minecraft.item.ItemFirework;
|
|
import net.minecraft.item.ItemReed;
|
|
import net.minecraft.item.ItemSkull;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.util.Vec3;
|
|
import net.minecraft.world.World;
|
|
import net.minecraft.world.WorldServer;
|
|
import net.minecraft.world.chunk.Chunk;
|
|
import net.minecraftforge.common.IPlantable;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
import appeng.api.AEApi;
|
|
import appeng.api.config.AccessRestriction;
|
|
import appeng.api.config.Actionable;
|
|
import appeng.api.config.FuzzyMode;
|
|
import appeng.api.config.IncludeExclude;
|
|
import appeng.api.config.Settings;
|
|
import appeng.api.config.Upgrades;
|
|
import appeng.api.networking.events.MENetworkCellArrayUpdate;
|
|
import appeng.api.networking.events.MENetworkChannelsChanged;
|
|
import appeng.api.networking.events.MENetworkEventSubscribe;
|
|
import appeng.api.networking.events.MENetworkPowerStatusChange;
|
|
import appeng.api.networking.security.BaseActionSource;
|
|
import appeng.api.parts.IPart;
|
|
import appeng.api.parts.IPartCollsionHelper;
|
|
import appeng.api.parts.IPartHost;
|
|
import appeng.api.parts.IPartItem;
|
|
import appeng.api.parts.IPartRenderHelper;
|
|
import appeng.api.storage.ICellContainer;
|
|
import appeng.api.storage.IMEInventory;
|
|
import appeng.api.storage.IMEInventoryHandler;
|
|
import appeng.api.storage.StorageChannel;
|
|
import appeng.api.storage.data.IAEItemStack;
|
|
import appeng.api.storage.data.IItemList;
|
|
import appeng.api.util.IConfigManager;
|
|
import appeng.client.texture.CableBusTextures;
|
|
import appeng.core.AEConfig;
|
|
import appeng.core.sync.GuiBridge;
|
|
import appeng.helpers.IPriorityHost;
|
|
import appeng.me.GridAccessException;
|
|
import appeng.me.storage.MEInventoryHandler;
|
|
import appeng.tile.inventory.AppEngInternalAEInventory;
|
|
import appeng.tile.inventory.InvOperation;
|
|
import appeng.util.Platform;
|
|
import appeng.util.prioitylist.FuzzyPriorityList;
|
|
import appeng.util.prioitylist.PrecisePriorityList;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
|
|
public class PartFormationPlane extends PartUpgradeable implements ICellContainer, IPriorityHost, IMEInventory<IAEItemStack>
|
|
{
|
|
|
|
int priority = 0;
|
|
boolean wasActive = false;
|
|
boolean blocked = false;
|
|
MEInventoryHandler myHandler = new MEInventoryHandler( this, StorageChannel.ITEMS );
|
|
AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 );
|
|
|
|
public PartFormationPlane(ItemStack is) {
|
|
super( PartFormationPlane.class, is );
|
|
settings.registerSetting( Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL );
|
|
updateHandler();
|
|
}
|
|
|
|
@Override
|
|
public boolean onPartActivate(EntityPlayer player, Vec3 pos)
|
|
{
|
|
if ( !player.isSneaking() )
|
|
{
|
|
if ( Platform.isClient() )
|
|
return true;
|
|
|
|
Platform.openGUI( player, getHost().getTile(), side, GuiBridge.GUI_FPLANE );
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected int getUpgradeSlots()
|
|
{
|
|
return 5;
|
|
}
|
|
|
|
@Override
|
|
public IInventory getInventoryByName(String name)
|
|
{
|
|
if ( name.equals( "config" ) )
|
|
return Config;
|
|
|
|
return super.getInventoryByName( name );
|
|
}
|
|
|
|
@MENetworkEventSubscribe
|
|
public void powerRender(MENetworkPowerStatusChange c)
|
|
{
|
|
boolean currentActive = proxy.isActive();
|
|
if ( wasActive != currentActive )
|
|
{
|
|
wasActive = currentActive;
|
|
updateHandler();// proxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
|
|
getHost().markForUpdate();
|
|
}
|
|
}
|
|
|
|
@MENetworkEventSubscribe
|
|
public void updateChannels(MENetworkChannelsChanged chann)
|
|
{
|
|
boolean currentActive = proxy.isActive();
|
|
if ( wasActive != currentActive )
|
|
{
|
|
wasActive = currentActive;
|
|
updateHandler();// proxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
|
|
getHost().markForUpdate();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public void renderInventory(IPartRenderHelper rh, RenderBlocks renderer)
|
|
{
|
|
rh.setTexture( CableBusTextures.PartPlaneSides.getIcon(), CableBusTextures.PartPlaneSides.getIcon(),
|
|
CableBusTextures.PartTransitionPlaneBack.getIcon(), is.getIconIndex(), CableBusTextures.PartPlaneSides.getIcon(),
|
|
CableBusTextures.PartPlaneSides.getIcon() );
|
|
|
|
rh.setBounds( 1, 1, 15, 15, 15, 16 );
|
|
rh.renderInventoryBox( renderer );
|
|
|
|
rh.setBounds( 5, 5, 14, 11, 11, 15 );
|
|
rh.renderInventoryBox( renderer );
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public void renderStatic(int x, int y, int z, IPartRenderHelper rh, RenderBlocks renderer)
|
|
{
|
|
int minX = 1;
|
|
int minY = 1;
|
|
int maxX = 15;
|
|
int maxY = 15;
|
|
|
|
ForgeDirection e = rh.getWorldX();
|
|
ForgeDirection u = rh.getWorldY();
|
|
|
|
TileEntity te = getHost().getTile();
|
|
|
|
if ( isTransitionPlane( te.getWorldObj().getTileEntity( x - e.offsetX, y - e.offsetY, z - e.offsetZ ), side ) )
|
|
minX = 0;
|
|
|
|
if ( isTransitionPlane( te.getWorldObj().getTileEntity( x + e.offsetX, y + e.offsetY, z + e.offsetZ ), side ) )
|
|
maxX = 16;
|
|
|
|
if ( isTransitionPlane( te.getWorldObj().getTileEntity( x - u.offsetX, y - u.offsetY, z - u.offsetZ ), side ) )
|
|
minY = 0;
|
|
|
|
if ( isTransitionPlane( te.getWorldObj().getTileEntity( x + u.offsetX, y + u.offsetY, z + u.offsetZ ), side ) )
|
|
maxY = 16;
|
|
|
|
boolean isActive = (clientFlags & (POWERED_FLAG | CHANNEL_FLAG)) == (POWERED_FLAG | CHANNEL_FLAG);
|
|
|
|
renderCache = rh.useSimpliedRendering( x, y, z, this, renderCache );
|
|
rh.setTexture( CableBusTextures.PartPlaneSides.getIcon(), CableBusTextures.PartPlaneSides.getIcon(),
|
|
CableBusTextures.PartTransitionPlaneBack.getIcon(), isActive ? CableBusTextures.BlockFormPlaneOn.getIcon() : is.getIconIndex(),
|
|
CableBusTextures.PartPlaneSides.getIcon(), CableBusTextures.PartPlaneSides.getIcon() );
|
|
|
|
rh.setBounds( minX, minY, 15, maxX, maxY, 16 );
|
|
rh.renderBlock( x, y, z, renderer );
|
|
|
|
rh.setTexture( CableBusTextures.PartMonitorSidesStatus.getIcon(), CableBusTextures.PartMonitorSidesStatus.getIcon(),
|
|
CableBusTextures.PartTransitionPlaneBack.getIcon(), isActive ? CableBusTextures.BlockFormPlaneOn.getIcon() : is.getIconIndex(),
|
|
CableBusTextures.PartMonitorSidesStatus.getIcon(), CableBusTextures.PartMonitorSidesStatus.getIcon() );
|
|
|
|
rh.setBounds( 5, 5, 14, 11, 11, 15 );
|
|
rh.renderBlock( x, y, z, renderer );
|
|
|
|
renderLights( x, y, z, rh, renderer );
|
|
}
|
|
|
|
private boolean isTransitionPlane(TileEntity blockTileEntity, ForgeDirection side)
|
|
{
|
|
if ( blockTileEntity instanceof IPartHost )
|
|
{
|
|
IPart p = ((IPartHost) blockTileEntity).getPart( side );
|
|
return p instanceof PartFormationPlane;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void getBoxes(IPartCollsionHelper bch)
|
|
{
|
|
int minX = 1;
|
|
int minY = 1;
|
|
int maxX = 15;
|
|
int maxY = 15;
|
|
|
|
IPartHost host = getHost();
|
|
if ( host != null )
|
|
{
|
|
TileEntity te = host.getTile();
|
|
|
|
int x = te.xCoord;
|
|
int y = te.yCoord;
|
|
int z = te.zCoord;
|
|
|
|
ForgeDirection e = bch.getWorldX();
|
|
ForgeDirection u = bch.getWorldY();
|
|
|
|
if ( isTransitionPlane( te.getWorldObj().getTileEntity( x - e.offsetX, y - e.offsetY, z - e.offsetZ ), side ) )
|
|
minX = 0;
|
|
|
|
if ( isTransitionPlane( te.getWorldObj().getTileEntity( x + e.offsetX, y + e.offsetY, z + e.offsetZ ), side ) )
|
|
maxX = 16;
|
|
|
|
if ( isTransitionPlane( te.getWorldObj().getTileEntity( x - u.offsetX, y - u.offsetY, z - u.offsetZ ), side ) )
|
|
minY = 0;
|
|
|
|
if ( isTransitionPlane( te.getWorldObj().getTileEntity( x + u.offsetX, y + u.offsetY, z + u.offsetZ ), side ) )
|
|
maxY = 16;
|
|
}
|
|
|
|
bch.addBox( 5, 5, 14, 11, 11, 15 );
|
|
bch.addBox( minX, minY, 15, maxX, maxY, 16 );
|
|
}
|
|
|
|
@Override
|
|
public int cableConnectionRenderTo()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
@Override
|
|
public List<IMEInventoryHandler> getCellArray(StorageChannel channel)
|
|
{
|
|
if ( proxy.isActive() )
|
|
{
|
|
List<IMEInventoryHandler> Handler = new ArrayList( 1 );
|
|
Handler.add( myHandler );
|
|
return Handler;
|
|
}
|
|
return new ArrayList();
|
|
}
|
|
|
|
@Override
|
|
public void updateSetting(IConfigManager manager, Enum settingName, Enum newValue)
|
|
{
|
|
updateHandler();
|
|
host.markForSave();
|
|
}
|
|
|
|
@Override
|
|
public void setPriority(int newValue)
|
|
{
|
|
priority = newValue;
|
|
host.markForSave();
|
|
updateHandler();
|
|
}
|
|
|
|
@Override
|
|
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack)
|
|
{
|
|
super.onChangeInventory( inv, slot, mc, removedStack, newStack );
|
|
|
|
if ( inv == Config )
|
|
updateHandler();
|
|
}
|
|
|
|
public void upgradesChanged()
|
|
{
|
|
updateHandler();
|
|
}
|
|
|
|
private void updateHandler()
|
|
{
|
|
myHandler.myAccess = AccessRestriction.WRITE;
|
|
myHandler.myWhitelist = getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST;
|
|
myHandler.myPriority = priority;
|
|
|
|
IItemList<IAEItemStack> priorityList = AEApi.instance().storage().createItemList();
|
|
|
|
int slotsToUse = 18 + getInstalledUpgrades( Upgrades.CAPACITY ) * 9;
|
|
for (int x = 0; x < Config.getSizeInventory() && x < slotsToUse; x++)
|
|
{
|
|
IAEItemStack is = Config.getAEStackInSlot( x );
|
|
if ( is != null )
|
|
priorityList.add( is );
|
|
}
|
|
|
|
if ( getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
|
myHandler.myPartitionList = new FuzzyPriorityList( priorityList, (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ) );
|
|
else
|
|
myHandler.myPartitionList = new PrecisePriorityList( priorityList );
|
|
|
|
try
|
|
{
|
|
proxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
|
|
}
|
|
catch (GridAccessException e)
|
|
{
|
|
// :P
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound data)
|
|
{
|
|
super.writeToNBT( data );
|
|
Config.writeToNBT( data, "config" );
|
|
data.setInteger( "priority", priority );
|
|
}
|
|
|
|
public void readFromNBT(NBTTagCompound data)
|
|
{
|
|
super.readFromNBT( data );
|
|
Config.readFromNBT( data, "config" );
|
|
priority = data.getInteger( "priority" );
|
|
updateHandler();
|
|
}
|
|
|
|
@Override
|
|
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public IItemList<IAEItemStack> getAvailableItems(IItemList<IAEItemStack> out)
|
|
{
|
|
return out;
|
|
}
|
|
|
|
@Override
|
|
public StorageChannel getChannel()
|
|
{
|
|
return StorageChannel.ITEMS;
|
|
}
|
|
|
|
@Override
|
|
public int getPriority()
|
|
{
|
|
return priority;
|
|
}
|
|
|
|
@Override
|
|
public void blinkCell(int slot)
|
|
{
|
|
// :P
|
|
}
|
|
|
|
@Override
|
|
public void onNeighborChanged()
|
|
{
|
|
TileEntity te = host.getTile();
|
|
World w = te.getWorldObj();
|
|
ForgeDirection side = this.side;
|
|
|
|
int x = te.xCoord + side.offsetX;
|
|
int y = te.yCoord + side.offsetY;
|
|
int z = te.zCoord + side.offsetZ;
|
|
|
|
blocked = !w.getBlock( x, y, z ).isReplaceable( w, x, y, z );
|
|
}
|
|
|
|
@Override
|
|
public IAEItemStack injectItems(IAEItemStack input, Actionable type, BaseActionSource src)
|
|
{
|
|
if ( blocked || input == null || input.getStackSize() <= 0 )
|
|
return input;
|
|
|
|
ItemStack is = input.getItemStack();
|
|
Item i = is.getItem();
|
|
|
|
long maxStorage = Math.min( input.getStackSize(), is.getMaxStackSize() );
|
|
boolean worked = false;
|
|
|
|
TileEntity te = host.getTile();
|
|
World w = te.getWorldObj();
|
|
ForgeDirection side = this.side;
|
|
|
|
int x = te.xCoord + side.offsetX;
|
|
int y = te.yCoord + side.offsetY;
|
|
int z = te.zCoord + side.offsetZ;
|
|
|
|
if ( w.getBlock( x, y, z ).isReplaceable( w, x, y, z ) )
|
|
{
|
|
if ( i instanceof ItemBlock || i instanceof IPlantable || i instanceof ItemSkull || i instanceof ItemFirework || i instanceof IPartItem
|
|
|| i instanceof ItemReed )
|
|
{
|
|
EntityPlayer player = Platform.getPlayer( (WorldServer) w );
|
|
Platform.configurePlayer( player, side, tile );
|
|
|
|
if ( i instanceof ItemFirework )
|
|
{
|
|
Chunk c = w.getChunkFromBlockCoords( x, z );
|
|
int sum = 0;
|
|
for (List Z : c.entityLists)
|
|
sum += Z.size();
|
|
if ( sum > 32 )
|
|
return input;
|
|
}
|
|
maxStorage = is.stackSize;
|
|
worked = true;
|
|
if ( type == Actionable.MODULATE )
|
|
{
|
|
if ( i instanceof IPlantable || i instanceof ItemSkull || i instanceof ItemReed )
|
|
{
|
|
boolean Worked = false;
|
|
|
|
if ( Worked == false && side.offsetX == 0 && side.offsetZ == 0 )
|
|
Worked = i.onItemUse( is, player, w, x + side.offsetX, y + side.offsetY, z + side.offsetZ, side.getOpposite().ordinal(),
|
|
side.offsetX, side.offsetY, side.offsetZ );
|
|
|
|
if ( Worked == false && side.offsetX == 0 && side.offsetZ == 0 )
|
|
Worked = i.onItemUse( is, player, w, x - side.offsetX, y - side.offsetY, z - side.offsetZ, side.ordinal(), side.offsetX,
|
|
side.offsetY, side.offsetZ );
|
|
|
|
if ( Worked == false && side.offsetY == 0 )
|
|
Worked = i.onItemUse( is, player, w, x, y - 1, z, ForgeDirection.UP.ordinal(), side.offsetX, side.offsetY, side.offsetZ );
|
|
|
|
if ( Worked == false )
|
|
Worked = i.onItemUse( is, player, w, x, y, z, side.getOpposite().ordinal(), side.offsetX, side.offsetY, side.offsetZ );
|
|
|
|
maxStorage = maxStorage - is.stackSize;
|
|
}
|
|
else
|
|
{
|
|
i.onItemUse( is, player, w, x, y, z, side.getOpposite().ordinal(), side.offsetX, side.offsetY, side.offsetZ );
|
|
maxStorage = maxStorage - is.stackSize;
|
|
}
|
|
}
|
|
else
|
|
maxStorage = 1;
|
|
}
|
|
else
|
|
{
|
|
worked = true;
|
|
Chunk c = w.getChunkFromBlockCoords( x, z );
|
|
int sum = 0;
|
|
for (List Z : c.entityLists)
|
|
sum += Z.size();
|
|
|
|
if ( sum < AEConfig.instance.formationPlaneEntityLimit )
|
|
{
|
|
if ( type == Actionable.MODULATE )
|
|
{
|
|
|
|
is.stackSize = (int) maxStorage;
|
|
EntityItem ei = new EntityItem( w, // w
|
|
((side.offsetX != 0 ? 0.0 : 0.7) * (Platform.getRandomFloat() - 0.5f)) + 0.5 + side.offsetX * -0.3 + (double) x, // spawn
|
|
((side.offsetY != 0 ? 0.0 : 0.7) * (Platform.getRandomFloat() - 0.5f)) + 0.5 + side.offsetY * -0.3 + (double) y, // spawn
|
|
((side.offsetZ != 0 ? 0.0 : 0.7) * (Platform.getRandomFloat() - 0.5f)) + 0.5 + side.offsetZ * -0.3 + (double) z, // spawn
|
|
is.copy() );
|
|
|
|
Entity result = ei;
|
|
|
|
ei.motionX = side.offsetX * 0.2;
|
|
ei.motionY = side.offsetY * 0.2;
|
|
ei.motionZ = side.offsetZ * 0.2;
|
|
|
|
if ( is.getItem().hasCustomEntity( is ) )
|
|
{
|
|
result = is.getItem().createEntity( w, ei, is );
|
|
if ( result != null )
|
|
ei.setDead();
|
|
else
|
|
result = ei;
|
|
}
|
|
|
|
if ( !w.spawnEntityInWorld( result ) )
|
|
{
|
|
result.setDead();
|
|
worked = false;
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
worked = false;
|
|
}
|
|
}
|
|
|
|
blocked = !w.getBlock( x, y, z ).isReplaceable( w, x, y, z );
|
|
|
|
if ( worked )
|
|
{
|
|
IAEItemStack out = input.copy();
|
|
out.decStackSize( maxStorage );
|
|
if ( out.getStackSize() == 0 )
|
|
return null;
|
|
return out;
|
|
}
|
|
|
|
return input;
|
|
}
|
|
|
|
@Override
|
|
public void saveChanges(IMEInventory cellInventory)
|
|
{
|
|
// nope!
|
|
}
|
|
}
|