385 lines
11 KiB
Java
385 lines
11 KiB
Java
package appeng.items.tools.powered;
|
|
|
|
import java.util.EnumSet;
|
|
import java.util.List;
|
|
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.BlockDispenser;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.entity.item.EntityItem;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.inventory.IInventory;
|
|
import net.minecraft.item.ItemBlock;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.util.AxisAlignedBB;
|
|
import net.minecraft.util.DamageSource;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.util.MovingObjectPosition;
|
|
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
|
|
import net.minecraft.util.Vec3;
|
|
import net.minecraft.world.World;
|
|
import appeng.api.AEApi;
|
|
import appeng.api.config.Actionable;
|
|
import appeng.api.config.FuzzyMode;
|
|
import appeng.api.config.Upgrades;
|
|
import appeng.api.implementations.items.IStorageCell;
|
|
import appeng.api.networking.security.PlayerSource;
|
|
import appeng.api.storage.ICellInventory;
|
|
import appeng.api.storage.ICellInventoryHandler;
|
|
import appeng.api.storage.IMEInventory;
|
|
import appeng.api.storage.StorageChannel;
|
|
import appeng.api.storage.data.IAEItemStack;
|
|
import appeng.api.storage.data.IAEStack;
|
|
import appeng.api.storage.data.IItemList;
|
|
import appeng.core.AEConfig;
|
|
import appeng.core.AELog;
|
|
import appeng.core.CommonHelper;
|
|
import appeng.core.features.AEFeature;
|
|
import appeng.core.localization.GuiText;
|
|
import appeng.core.localization.PlayerMessages;
|
|
import appeng.core.sync.packets.PacketMatterCannon;
|
|
import appeng.hooks.DispenserMatterCannon;
|
|
import appeng.items.contents.CellConfig;
|
|
import appeng.items.contents.CellUpgrades;
|
|
import appeng.items.misc.ItemPaintBall;
|
|
import appeng.items.tools.powered.powersink.AEBasePoweredItem;
|
|
import appeng.me.storage.CellInventoryHandler;
|
|
import appeng.util.Platform;
|
|
|
|
public class ToolMassCannon extends AEBasePoweredItem implements IStorageCell
|
|
{
|
|
|
|
public ToolMassCannon() {
|
|
super( ToolMassCannon.class, null );
|
|
setfeature( EnumSet.of( AEFeature.MatterCannon, AEFeature.PoweredTools ) );
|
|
maxStoredPower = AEConfig.instance.mattercannon_battery;
|
|
}
|
|
|
|
@Override
|
|
public void postInit()
|
|
{
|
|
super.postInit();
|
|
BlockDispenser.dispenseBehaviorRegistry.putObject( this, new DispenserMatterCannon() );
|
|
}
|
|
|
|
@Override
|
|
public void addInformation(ItemStack is, EntityPlayer player, List lines, boolean advancedItemTooltips)
|
|
{
|
|
super.addInformation( is, player, lines, advancedItemTooltips );
|
|
|
|
IMEInventory<IAEItemStack> cdi = AEApi.instance().registries().cell().getCellInventory( is, StorageChannel.ITEMS );
|
|
|
|
if ( cdi instanceof CellInventoryHandler )
|
|
{
|
|
ICellInventory cd = ((ICellInventoryHandler) cdi).getCellInv();
|
|
if ( cd != null )
|
|
{
|
|
lines.add( cd.getUsedBytes() + " " + GuiText.Of.getLocal() + " " + cd.getTotalBytes() + " " + GuiText.BytesUsed.getLocal() );
|
|
lines.add( cd.getStoredItemTypes() + " " + GuiText.Of.getLocal() + " " + cd.getTotalItemTypes() + " " + GuiText.Types.getLocal() );
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public ItemStack onItemRightClick(ItemStack item, World w, EntityPlayer p)
|
|
{
|
|
if ( this.getAECurrentPower( item ) > 1600 )
|
|
{
|
|
int shots = 1;
|
|
|
|
CellUpgrades cu = (CellUpgrades) getUpgradesInventory( item );
|
|
if ( cu != null )
|
|
shots += cu.getInstalledUpgrades( Upgrades.SPEED );
|
|
|
|
IMEInventory inv = AEApi.instance().registries().cell().getCellInventory( item, StorageChannel.ITEMS );
|
|
if ( inv != null )
|
|
{
|
|
IItemList itemList = inv.getAvailableItems( AEApi.instance().storage().createItemList() );
|
|
IAEStack aeammo = itemList.getFirstItem();
|
|
if ( aeammo instanceof IAEItemStack )
|
|
{
|
|
shots = Math.min( shots, (int) aeammo.getStackSize() );
|
|
for (int sh = 0; sh < shots; sh++)
|
|
{
|
|
extractAEPower( item, 1600 );
|
|
|
|
if ( Platform.isClient() )
|
|
return item;
|
|
|
|
aeammo.setStackSize( 1 );
|
|
ItemStack ammo = ((IAEItemStack) aeammo).getItemStack();
|
|
if ( ammo == null )
|
|
return item;
|
|
|
|
ammo.stackSize = 1;
|
|
aeammo = inv.extractItems( aeammo, Actionable.MODULATE, new PlayerSource( p, null ) );
|
|
if ( aeammo == null )
|
|
return item;
|
|
|
|
float f = 1.0F;
|
|
float f1 = p.prevRotationPitch + (p.rotationPitch - p.prevRotationPitch) * f;
|
|
float f2 = p.prevRotationYaw + (p.rotationYaw - p.prevRotationYaw) * f;
|
|
double d0 = p.prevPosX + (p.posX - p.prevPosX) * (double) f;
|
|
double d1 = p.prevPosY + (p.posY - p.prevPosY) * (double) f + 1.62D - (double) p.yOffset;
|
|
double d2 = p.prevPosZ + (p.posZ - p.prevPosZ) * (double) f;
|
|
Vec3 vec3 = Vec3.createVectorHelper( d0, d1, d2 );
|
|
float f3 = MathHelper.cos( -f2 * 0.017453292F - (float) Math.PI );
|
|
float f4 = MathHelper.sin( -f2 * 0.017453292F - (float) Math.PI );
|
|
float f5 = -MathHelper.cos( -f1 * 0.017453292F );
|
|
float f6 = MathHelper.sin( -f1 * 0.017453292F );
|
|
float f7 = f4 * f5;
|
|
float f8 = f3 * f5;
|
|
double d3 = 32.0D;
|
|
|
|
Vec3 vec31 = vec3.addVector( (double) f7 * d3, (double) f6 * d3, (double) f8 * d3 );
|
|
Vec3 direction = Vec3.createVectorHelper( (double) f7 * d3, (double) f6 * d3, (double) f8 * d3 );
|
|
|
|
float penitration = AEApi.instance().registries().matterCannon().getPenetration( ammo ); // 196.96655f;
|
|
if ( penitration <= 0 )
|
|
{
|
|
ItemStack type = ((IAEItemStack) aeammo).getItemStack();
|
|
if ( type.getItem() instanceof ItemBlock )
|
|
{
|
|
|
|
}
|
|
else if ( type.getItem() instanceof ItemPaintBall )
|
|
{
|
|
|
|
}
|
|
return item;
|
|
}
|
|
else
|
|
{
|
|
standardAmmo( penitration, w, p, vec3, vec31, direction, d0, d1, d2 );
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( Platform.isServer() )
|
|
p.addChatMessage( PlayerMessages.AmmoDepleted.get() );
|
|
return item;
|
|
}
|
|
}
|
|
}
|
|
return item;
|
|
}
|
|
|
|
private void standardAmmo(float penitration, World w, EntityPlayer p, Vec3 vec3, Vec3 vec31, Vec3 direction, double d0, double d1, double d2)
|
|
{
|
|
boolean hasDestroyedSomething = true;
|
|
while (penitration > 0 && hasDestroyedSomething)
|
|
{
|
|
hasDestroyedSomething = false;
|
|
|
|
AxisAlignedBB bb = AxisAlignedBB.getBoundingBox( Math.min( vec3.xCoord, vec31.xCoord ), Math.min( vec3.yCoord, vec31.yCoord ),
|
|
Math.min( vec3.zCoord, vec31.zCoord ), Math.max( vec3.xCoord, vec31.xCoord ), Math.max( vec3.yCoord, vec31.yCoord ),
|
|
Math.max( vec3.zCoord, vec31.zCoord ) ).expand( 16, 16, 16 );
|
|
|
|
Entity entity = null;
|
|
List list = w.getEntitiesWithinAABBExcludingEntity( p, bb );
|
|
double Closeest = 9999999.0D;
|
|
int l;
|
|
|
|
for (l = 0; l < list.size(); ++l)
|
|
{
|
|
Entity entity1 = (Entity) list.get( l );
|
|
|
|
if ( entity1.isDead == false && entity1 != p && !(entity1 instanceof EntityItem) )
|
|
{
|
|
if ( entity1.isEntityAlive() )
|
|
{
|
|
// prevent killing / flying of mounts.
|
|
if ( entity1.riddenByEntity == p )
|
|
continue;
|
|
|
|
float f1 = 0.3F;
|
|
AxisAlignedBB axisalignedbb1 = entity1.boundingBox.expand( (double) f1, (double) f1, (double) f1 );
|
|
MovingObjectPosition movingobjectposition1 = axisalignedbb1.calculateIntercept( vec3, vec31 );
|
|
|
|
if ( movingobjectposition1 != null )
|
|
{
|
|
double nd = vec3.squareDistanceTo( movingobjectposition1.hitVec );
|
|
|
|
if ( nd < Closeest )
|
|
{
|
|
entity = entity1;
|
|
Closeest = nd;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Vec3 Srec = Vec3.createVectorHelper( d0, d1, d2 );
|
|
MovingObjectPosition pos = w.rayTraceBlocks( vec3, vec31, true );
|
|
if ( entity != null && pos != null && pos.hitVec.squareDistanceTo( Srec ) > Closeest )
|
|
{
|
|
pos = new MovingObjectPosition( entity );
|
|
}
|
|
else if ( entity != null && pos == null )
|
|
{
|
|
pos = new MovingObjectPosition( entity );
|
|
}
|
|
|
|
try
|
|
{
|
|
CommonHelper.proxy.sendToAllNearExcept( null, d0, d1, d2, 128, w, new PacketMatterCannon( d0, d1, d2, (float) direction.xCoord,
|
|
(float) direction.yCoord, (float) direction.zCoord, (byte) (pos == null ? 32 : pos.hitVec.squareDistanceTo( Srec ) + 1) ) );
|
|
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
AELog.error( err );
|
|
}
|
|
|
|
if ( pos != null )
|
|
{
|
|
DamageSource dmgSrc = DamageSource.causePlayerDamage( p );
|
|
dmgSrc.damageType = "masscannon";
|
|
|
|
if ( pos.typeOfHit == MovingObjectType.ENTITY )
|
|
{
|
|
int dmg = (int) Math.ceil( penitration / 20.0f );
|
|
if ( pos.entityHit instanceof EntityLivingBase )
|
|
{
|
|
EntityLivingBase el = (EntityLivingBase) pos.entityHit;
|
|
penitration -= dmg;
|
|
el.knockBack( p, 0, (double) -direction.xCoord, (double) -direction.zCoord );
|
|
// el.knockBack( p, 0, vec3.xCoord,
|
|
// vec3.zCoord );
|
|
el.attackEntityFrom( dmgSrc, dmg );
|
|
if ( !el.isEntityAlive() )
|
|
hasDestroyedSomething = true;
|
|
}
|
|
else if ( pos.entityHit instanceof EntityItem )
|
|
{
|
|
hasDestroyedSomething = true;
|
|
pos.entityHit.setDead();
|
|
}
|
|
else if ( pos.entityHit.attackEntityFrom( dmgSrc, dmg ) )
|
|
{
|
|
hasDestroyedSomething = true;
|
|
}
|
|
}
|
|
else if ( pos.typeOfHit == MovingObjectType.BLOCK )
|
|
{
|
|
if ( !AEConfig.instance.isFeatureEnabled( AEFeature.MassCannonBlockDamage ) )
|
|
penitration = 0;
|
|
else
|
|
{
|
|
Block b = w.getBlock( pos.blockX, pos.blockY, pos.blockZ );
|
|
// int meta = w.getBlockMetadata(
|
|
// pos.blockX, pos.blockY, pos.blockZ );
|
|
|
|
float hardness = b.getBlockHardness( w, pos.blockX, pos.blockY, pos.blockZ ) * 9.0f;
|
|
if ( hardness >= 0.0 )
|
|
{
|
|
if ( penitration > hardness )
|
|
{
|
|
hasDestroyedSomething = true;
|
|
penitration -= hardness;
|
|
penitration *= 0.60;
|
|
w.func_147480_a( pos.blockX, pos.blockY, pos.blockZ, true );
|
|
// w.destroyBlock( pos.blockX, pos.blockY, pos.blockZ, true );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean storableInStorageCell()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isStorageCell(ItemStack i)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public double getIdleDrain()
|
|
{
|
|
return 0.5;
|
|
}
|
|
|
|
@Override
|
|
public IInventory getUpgradesInventory(ItemStack is)
|
|
{
|
|
return new CellUpgrades( is, 4 );
|
|
}
|
|
|
|
@Override
|
|
public IInventory getConfigInventory(ItemStack is)
|
|
{
|
|
return new CellConfig( is );
|
|
}
|
|
|
|
@Override
|
|
public FuzzyMode getFuzzyMode(ItemStack is)
|
|
{
|
|
String fz = Platform.openNbtData( is ).getString( "FuzzyMode" );
|
|
try
|
|
{
|
|
return FuzzyMode.valueOf( fz );
|
|
}
|
|
catch (Throwable t)
|
|
{
|
|
return FuzzyMode.IGNORE_ALL;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void setFuzzyMode(ItemStack is, FuzzyMode fzMode)
|
|
{
|
|
Platform.openNbtData( is ).setString( "FuzzyMode", fzMode.name() );
|
|
}
|
|
|
|
@Override
|
|
public boolean isEditable(ItemStack is)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public int getBytes(ItemStack cellItem)
|
|
{
|
|
return 512;
|
|
}
|
|
|
|
@Override
|
|
public int BytePerType(ItemStack iscellItem)
|
|
{
|
|
return 8;
|
|
}
|
|
|
|
@Override
|
|
public int getTotalTypes(ItemStack cellItem)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
@Override
|
|
public boolean isBlackListed(ItemStack cellItem, IAEItemStack requsetedAddition)
|
|
{
|
|
float pen = AEApi.instance().registries().matterCannon().getPenetration( requsetedAddition.getItemStack() );
|
|
if ( pen > 0 )
|
|
return false;
|
|
|
|
/*
|
|
* if ( requsetedAddition.getItem() instanceof ItemPaintBall ) return false;
|
|
*
|
|
* if ( requsetedAddition.getItem() instanceof ItemBlock ) { Block blk = Block.getBlockFromItem(
|
|
* requsetedAddition.getItem() ); return blk == null; }
|
|
*/
|
|
|
|
return true;
|
|
}
|
|
}
|