pick 97420a31d The big reformat of 2020
This commit is contained in:
@@ -18,8 +18,8 @@
|
||||
|
||||
package appeng.items.tools.powered;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
@@ -44,6 +44,7 @@ import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.Upgrades;
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.api.implementations.items.IStorageCell;
|
||||
import appeng.api.storage.ICellInventoryHandler;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
@@ -55,7 +56,6 @@ import appeng.api.util.DimensionalCoord;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.core.localization.PlayerMessages;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketMatterCannon;
|
||||
@@ -70,455 +70,389 @@ import appeng.tile.misc.TilePaint;
|
||||
import appeng.util.LookDirection;
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
public class ToolMatterCannon extends AEBasePoweredItem implements IStorageCell<IAEItemStack>
|
||||
{
|
||||
|
||||
public ToolMatterCannon(Item.Properties props)
|
||||
{
|
||||
super( AEConfig.instance().getMatterCannonBattery(), props );
|
||||
}
|
||||
|
||||
@OnlyIn( Dist.CLIENT )
|
||||
@Override
|
||||
public void addInformation( final ItemStack stack, final World world, final List<ITextComponent> lines, final ITooltipFlag advancedTooltips )
|
||||
{
|
||||
super.addInformation( stack, world, lines, advancedTooltips );
|
||||
|
||||
final ICellInventoryHandler<IAEItemStack> cdi = AEApi.instance().registries().cell().getCellInventory( stack, null, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
|
||||
AEApi.instance().client().addCellInformation( cdi, lines );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick( final World w, final PlayerEntity p, final @Nullable Hand hand )
|
||||
{
|
||||
if( this.getAECurrentPower( p.getHeldItem( hand ) ) > 1600 )
|
||||
{
|
||||
int shots = 1;
|
||||
|
||||
final CellUpgrades cu = (CellUpgrades) this.getUpgradesInventory( p.getHeldItem( hand ) );
|
||||
if( cu != null )
|
||||
{
|
||||
shots += cu.getInstalledUpgrades( Upgrades.SPEED );
|
||||
}
|
||||
|
||||
final ICellInventoryHandler<IAEItemStack> inv = AEApi.instance().registries().cell().getCellInventory( p.getHeldItem( hand ), null, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
if( inv != null )
|
||||
{
|
||||
final IItemList<IAEItemStack> itemList = inv.getAvailableItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() );
|
||||
IAEItemStack req = itemList.getFirstItem();
|
||||
if( req instanceof IAEItemStack )
|
||||
{
|
||||
shots = Math.min( shots, (int) req.getStackSize() );
|
||||
for( int sh = 0; sh < shots; sh++ )
|
||||
{
|
||||
IAEItemStack aeAmmo = req.copy();
|
||||
this.extractAEPower( p.getHeldItem( hand ), 1600, Actionable.MODULATE );
|
||||
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
return new ActionResult<>( ActionResultType.SUCCESS, p.getHeldItem( hand ) );
|
||||
}
|
||||
|
||||
aeAmmo.setStackSize( 1 );
|
||||
final ItemStack ammo = aeAmmo.createItemStack();
|
||||
if( ammo == null )
|
||||
{
|
||||
return new ActionResult<>( ActionResultType.SUCCESS, p.getHeldItem( hand ) );
|
||||
}
|
||||
|
||||
aeAmmo = inv.extractItems( aeAmmo, Actionable.MODULATE, new PlayerSource( p, null ) );
|
||||
if( aeAmmo == null )
|
||||
{
|
||||
return new ActionResult<>( ActionResultType.SUCCESS, p.getHeldItem( hand ) );
|
||||
}
|
||||
|
||||
final LookDirection dir = Platform.getPlayerRay( p );
|
||||
|
||||
final Vec3d Vec3d = dir.getA();
|
||||
final Vec3d Vec3d1 = dir.getB();
|
||||
final Vec3d direction = Vec3d1.subtract( Vec3d );
|
||||
direction.normalize();
|
||||
|
||||
final double d0 = Vec3d.x;
|
||||
final double d1 = Vec3d.y;
|
||||
final double d2 = Vec3d.z;
|
||||
|
||||
final float penetration = AEApi.instance().registries().matterCannon().getPenetration( ammo ); // 196.96655f;
|
||||
if( penetration <= 0 )
|
||||
{
|
||||
final ItemStack type = aeAmmo.asItemStackRepresentation();
|
||||
if( type.getItem() instanceof ItemPaintBall )
|
||||
{
|
||||
this.shootPaintBalls( type, w, p, Vec3d, Vec3d1, direction, d0, d1, d2 );
|
||||
}
|
||||
return new ActionResult<>( ActionResultType.SUCCESS, p.getHeldItem( hand ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.standardAmmo( penetration, w, p, Vec3d, Vec3d1, direction, d0, d1, d2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( Platform.isServer() )
|
||||
{
|
||||
p.sendMessage( PlayerMessages.AmmoDepleted.get() );
|
||||
}
|
||||
return new ActionResult<>( ActionResultType.SUCCESS, p.getHeldItem( hand ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ActionResult<>( ActionResultType.FAIL, p.getHeldItem( hand ) );
|
||||
}
|
||||
|
||||
private void shootPaintBalls( final ItemStack type, final World w, final PlayerEntity p, final Vec3d Vec3d, final Vec3d Vec3d1, final Vec3d direction, final double d0, final double d1, final double d2 )
|
||||
{
|
||||
final AxisAlignedBB bb = new AxisAlignedBB( Math.min( Vec3d.x, Vec3d1.x ), Math.min( Vec3d.y, Vec3d1.y ), Math.min( Vec3d.z, Vec3d1.z ), Math.max( Vec3d.x, Vec3d1.x ), Math.max( Vec3d.y, Vec3d1.y ), Math.max( Vec3d.z, Vec3d1.z ) ).grow( 16, 16, 16 );
|
||||
|
||||
Entity entity = null;
|
||||
Vec3d entityIntersection = null;
|
||||
final List list = w.getEntitiesWithinAABBExcludingEntity( p, bb );
|
||||
double closest = 9999999.0D;
|
||||
|
||||
for( int l = 0; l < list.size(); ++l )
|
||||
{
|
||||
final Entity entity1 = (Entity) list.get( l );
|
||||
|
||||
if( !entity1.isAlive() && entity1 != p && !( entity1 instanceof ItemEntity ) )
|
||||
{
|
||||
if( entity1.isAlive() )
|
||||
{
|
||||
// prevent killing / flying of mounts.
|
||||
if( entity1.isRidingOrBeingRiddenBy( p ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final float f1 = 0.3F;
|
||||
|
||||
final AxisAlignedBB boundingBox = entity1.getBoundingBox().grow( f1, f1, f1 );
|
||||
final Vec3d intersection = boundingBox.rayTrace( Vec3d, Vec3d1 ).orElse(null);
|
||||
|
||||
if( intersection != null )
|
||||
{
|
||||
final double nd = Vec3d.squareDistanceTo( intersection );
|
||||
|
||||
if( nd < closest )
|
||||
{
|
||||
entity = entity1;
|
||||
entityIntersection = intersection;
|
||||
closest = nd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RayTraceContext rayTraceContext = new RayTraceContext(Vec3d, Vec3d1, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, p);
|
||||
RayTraceResult pos = w.rayTraceBlocks( rayTraceContext );
|
||||
|
||||
final Vec3d vec = new Vec3d( d0, d1, d2 );
|
||||
if( entity != null && pos.getType() != RayTraceResult.Type.MISS && pos.getHitVec().squareDistanceTo( vec ) > closest )
|
||||
{
|
||||
pos = new EntityRayTraceResult( entity, entityIntersection );
|
||||
}
|
||||
else if( entity != null && pos.getType() == RayTraceResult.Type.MISS )
|
||||
{
|
||||
pos = new EntityRayTraceResult( entity, entityIntersection );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
AppEng.proxy.sendToAllNearExcept( null, d0, d1, d2, 128, w, new PacketMatterCannon( d0, d1, d2, (float) direction.x, (float) direction.y, (float) direction.z, (byte) ( pos.getType() == RayTraceResult.Type.MISS ? 32 : pos.getHitVec().squareDistanceTo( vec ) + 1 ) ) );
|
||||
}
|
||||
catch( final Exception err )
|
||||
{
|
||||
AELog.debug( err );
|
||||
}
|
||||
|
||||
if( pos.getType() != RayTraceResult.Type.MISS && type != null && type.getItem() instanceof ItemPaintBall )
|
||||
{
|
||||
final ItemPaintBall ipb = (ItemPaintBall) type.getItem();
|
||||
|
||||
final AEColor col = ipb.getColor();
|
||||
// boolean lit = ipb.isLumen( type );
|
||||
|
||||
if( pos instanceof EntityRayTraceResult )
|
||||
{
|
||||
EntityRayTraceResult entityResult = (EntityRayTraceResult) pos;
|
||||
Entity entityHit = entityResult.getEntity();
|
||||
|
||||
final int id = entityHit.getEntityId();
|
||||
final PlayerColor marker = new PlayerColor( id, col, 20 * 30 );
|
||||
TickHandler.INSTANCE.getPlayerColors().put( id, marker );
|
||||
|
||||
if( entityHit instanceof SheepEntity)
|
||||
{
|
||||
final SheepEntity sh = (SheepEntity) entityHit;
|
||||
sh.setFleeceColor( col.dye );
|
||||
}
|
||||
|
||||
entityHit.attackEntityFrom( DamageSource.causePlayerDamage( p ), 0 );
|
||||
NetworkHandler.instance().sendToAll( marker.getPacket() );
|
||||
}
|
||||
else if( pos instanceof BlockRayTraceResult )
|
||||
{
|
||||
BlockRayTraceResult blockResult = (BlockRayTraceResult) pos;
|
||||
final Direction side = blockResult.getFace();
|
||||
final BlockPos hitPos = blockResult.getPos().offset( side );
|
||||
|
||||
if( !Platform.hasPermissions( new DimensionalCoord( w, hitPos ), p ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final BlockState whatsThere = w.getBlockState( hitPos );
|
||||
if( whatsThere.getMaterial().isReplaceable() && w.isAirBlock( hitPos ) )
|
||||
{
|
||||
AEApi.instance().definitions().blocks().paint().maybeBlock().ifPresent( paintBlock -> {
|
||||
w.setBlockState( hitPos, paintBlock.getDefaultState(), 3 );
|
||||
} );
|
||||
}
|
||||
|
||||
final TileEntity te = w.getTileEntity( hitPos );
|
||||
if( te instanceof TilePaint )
|
||||
{
|
||||
final Vec3d hp = pos.getHitVec().subtract( hitPos.getX(), hitPos.getY(), hitPos.getZ() );
|
||||
( (TilePaint) te ).addBlot( type, side.getOpposite(), hp );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void standardAmmo( float penetration, final World w, final PlayerEntity p, final Vec3d Vec3d, final Vec3d Vec3d1, final Vec3d direction, final double d0, final double d1, final double d2 )
|
||||
{
|
||||
boolean hasDestroyed = true;
|
||||
while( penetration > 0 && hasDestroyed )
|
||||
{
|
||||
hasDestroyed = false;
|
||||
|
||||
final AxisAlignedBB bb = new AxisAlignedBB( Math.min( Vec3d.x, Vec3d1.x ), Math.min( Vec3d.y, Vec3d1.y ), Math.min( Vec3d.z, Vec3d1.z ), Math.max( Vec3d.x, Vec3d1.x ), Math.max( Vec3d.y, Vec3d1.y ), Math.max( Vec3d.z, Vec3d1.z ) ).grow( 16, 16, 16 );
|
||||
|
||||
Entity entity = null;
|
||||
Vec3d entityIntersection = null;
|
||||
final List list = w.getEntitiesWithinAABBExcludingEntity( p, bb );
|
||||
double closest = 9999999.0D;
|
||||
|
||||
for( int l = 0; l < list.size(); ++l )
|
||||
{
|
||||
final Entity entity1 = (Entity) list.get( l );
|
||||
|
||||
if( entity1.isAlive() && entity1 != p && !( entity1 instanceof ItemEntity ) )
|
||||
{
|
||||
if( entity1.isAlive() )
|
||||
{
|
||||
// prevent killing / flying of mounts.
|
||||
if( entity1.isRidingOrBeingRiddenBy( p ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final float f1 = 0.3F;
|
||||
|
||||
final AxisAlignedBB boundingBox = entity1.getBoundingBox().grow( f1, f1, f1 );
|
||||
final Vec3d intersection = boundingBox.rayTrace( Vec3d, Vec3d1 ).orElse(null);
|
||||
|
||||
if( intersection != null )
|
||||
{
|
||||
final double nd = Vec3d.squareDistanceTo( intersection );
|
||||
|
||||
if( nd < closest )
|
||||
{
|
||||
entity = entity1;
|
||||
entityIntersection = intersection;
|
||||
closest = nd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RayTraceContext rayTraceContext = new RayTraceContext(Vec3d, Vec3d1, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, p);
|
||||
final Vec3d vec = new Vec3d( d0, d1, d2 );
|
||||
RayTraceResult pos = w.rayTraceBlocks( rayTraceContext );
|
||||
if( entity != null && pos.getType() != RayTraceResult.Type.MISS && pos.getHitVec().squareDistanceTo( vec ) > closest )
|
||||
{
|
||||
pos = new EntityRayTraceResult( entity, entityIntersection );
|
||||
}
|
||||
else if( entity != null && pos.getType() == RayTraceResult.Type.MISS )
|
||||
{
|
||||
pos = new EntityRayTraceResult( entity, entityIntersection );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
AppEng.proxy.sendToAllNearExcept( null, d0, d1, d2, 128, w, new PacketMatterCannon( d0, d1, d2, (float) direction.x, (float) direction.y, (float) direction.z, (byte) ( pos.getType() == RayTraceResult.Type.MISS ? 32 : pos.getHitVec().squareDistanceTo( vec ) + 1 ) ) );
|
||||
}
|
||||
catch( final Exception err )
|
||||
{
|
||||
AELog.debug( err );
|
||||
}
|
||||
|
||||
if( pos.getType() != RayTraceResult.Type.MISS )
|
||||
{
|
||||
final DamageSource dmgSrc = new EntityDamageSource( "matter_cannon", p );
|
||||
|
||||
if( pos instanceof EntityRayTraceResult )
|
||||
{
|
||||
EntityRayTraceResult entityResult = (EntityRayTraceResult) pos;
|
||||
Entity entityHit = entityResult.getEntity();
|
||||
|
||||
final int dmg = (int) Math.ceil( penetration / 20.0f );
|
||||
if( entityHit instanceof LivingEntity )
|
||||
{
|
||||
final LivingEntity el = (LivingEntity) entityHit;
|
||||
penetration -= dmg;
|
||||
el.knockBack( p, 0, -direction.x, -direction.z );
|
||||
// el.knockBack( p, 0, Vec3d.x,
|
||||
// Vec3d.z );
|
||||
el.attackEntityFrom( dmgSrc, dmg );
|
||||
if( !el.isAlive() )
|
||||
{
|
||||
hasDestroyed = true;
|
||||
}
|
||||
}
|
||||
else if( entityHit instanceof ItemEntity )
|
||||
{
|
||||
hasDestroyed = true;
|
||||
entityHit.remove();
|
||||
}
|
||||
else if( entityHit.attackEntityFrom( dmgSrc, dmg ) )
|
||||
{
|
||||
hasDestroyed = true;
|
||||
}
|
||||
}
|
||||
else if( pos instanceof BlockRayTraceResult )
|
||||
{
|
||||
BlockRayTraceResult blockResult = (BlockRayTraceResult) pos;
|
||||
|
||||
if( !AEConfig.instance().isFeatureEnabled( AEFeature.MASS_CANNON_BLOCK_DAMAGE ) )
|
||||
{
|
||||
penetration = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockPos = blockResult.getPos();
|
||||
final BlockState bs = w.getBlockState(blockPos);
|
||||
|
||||
final float hardness = bs.getBlockHardness( w, blockPos) * 9.0f;
|
||||
if( hardness >= 0.0 )
|
||||
{
|
||||
if( penetration > hardness && Platform.hasPermissions( new DimensionalCoord( w, blockPos), p ) )
|
||||
{
|
||||
hasDestroyed = true;
|
||||
penetration -= hardness;
|
||||
penetration *= 0.60;
|
||||
w.destroyBlock(blockPos, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable( final ItemStack is )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getUpgradesInventory( final ItemStack is )
|
||||
{
|
||||
return new CellUpgrades( is, 4 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getConfigInventory( final ItemStack is )
|
||||
{
|
||||
return new CellConfig( is );
|
||||
}
|
||||
|
||||
@Override
|
||||
public FuzzyMode getFuzzyMode( final ItemStack is )
|
||||
{
|
||||
final String fz = is.getOrCreateTag().getString( "FuzzyMode" );
|
||||
try
|
||||
{
|
||||
return FuzzyMode.valueOf( fz );
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
return FuzzyMode.IGNORE_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFuzzyMode( final ItemStack is, final FuzzyMode fzMode )
|
||||
{
|
||||
is.getOrCreateTag().putString( "FuzzyMode", fzMode.name() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes( final ItemStack cellItem )
|
||||
{
|
||||
return 512;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytesPerType( final ItemStack cellItem )
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalTypes( final ItemStack cellItem )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlackListed( final ItemStack cellItem, final IAEItemStack requestedAddition )
|
||||
{
|
||||
final float pen = AEApi.instance().registries().matterCannon().getPenetration( requestedAddition.createItemStack() );
|
||||
if( pen > 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( requestedAddition.getItem() instanceof ItemPaintBall )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean storableInStorageCell()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStorageCell( final ItemStack i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getIdleDrain()
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<IAEItemStack> getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
public class ToolMatterCannon extends AEBasePoweredItem implements IStorageCell<IAEItemStack> {
|
||||
|
||||
public ToolMatterCannon(Item.Properties props) {
|
||||
super(AEConfig.instance().getMatterCannonBattery(), props);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Override
|
||||
public void addInformation(final ItemStack stack, final World world, final List<ITextComponent> lines,
|
||||
final ITooltipFlag advancedTooltips) {
|
||||
super.addInformation(stack, world, lines, advancedTooltips);
|
||||
|
||||
final ICellInventoryHandler<IAEItemStack> cdi = AEApi.instance().registries().cell().getCellInventory(stack,
|
||||
null, AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||
|
||||
AEApi.instance().client().addCellInformation(cdi, lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(final World w, final PlayerEntity p, final @Nullable Hand hand) {
|
||||
if (this.getAECurrentPower(p.getHeldItem(hand)) > 1600) {
|
||||
int shots = 1;
|
||||
|
||||
final CellUpgrades cu = (CellUpgrades) this.getUpgradesInventory(p.getHeldItem(hand));
|
||||
if (cu != null) {
|
||||
shots += cu.getInstalledUpgrades(Upgrades.SPEED);
|
||||
}
|
||||
|
||||
final ICellInventoryHandler<IAEItemStack> inv = AEApi.instance().registries().cell().getCellInventory(
|
||||
p.getHeldItem(hand), null, AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||
if (inv != null) {
|
||||
final IItemList<IAEItemStack> itemList = inv.getAvailableItems(
|
||||
AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList());
|
||||
IAEItemStack req = itemList.getFirstItem();
|
||||
if (req instanceof IAEItemStack) {
|
||||
shots = Math.min(shots, (int) req.getStackSize());
|
||||
for (int sh = 0; sh < shots; sh++) {
|
||||
IAEItemStack aeAmmo = req.copy();
|
||||
this.extractAEPower(p.getHeldItem(hand), 1600, Actionable.MODULATE);
|
||||
|
||||
if (Platform.isClient()) {
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, p.getHeldItem(hand));
|
||||
}
|
||||
|
||||
aeAmmo.setStackSize(1);
|
||||
final ItemStack ammo = aeAmmo.createItemStack();
|
||||
if (ammo == null) {
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, p.getHeldItem(hand));
|
||||
}
|
||||
|
||||
aeAmmo = inv.extractItems(aeAmmo, Actionable.MODULATE, new PlayerSource(p, null));
|
||||
if (aeAmmo == null) {
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, p.getHeldItem(hand));
|
||||
}
|
||||
|
||||
final LookDirection dir = Platform.getPlayerRay(p);
|
||||
|
||||
final Vec3d Vec3d = dir.getA();
|
||||
final Vec3d Vec3d1 = dir.getB();
|
||||
final Vec3d direction = Vec3d1.subtract(Vec3d);
|
||||
direction.normalize();
|
||||
|
||||
final double d0 = Vec3d.x;
|
||||
final double d1 = Vec3d.y;
|
||||
final double d2 = Vec3d.z;
|
||||
|
||||
final float penetration = AEApi.instance().registries().matterCannon().getPenetration(ammo); // 196.96655f;
|
||||
if (penetration <= 0) {
|
||||
final ItemStack type = aeAmmo.asItemStackRepresentation();
|
||||
if (type.getItem() instanceof ItemPaintBall) {
|
||||
this.shootPaintBalls(type, w, p, Vec3d, Vec3d1, direction, d0, d1, d2);
|
||||
}
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, p.getHeldItem(hand));
|
||||
} else {
|
||||
this.standardAmmo(penetration, w, p, Vec3d, Vec3d1, direction, d0, d1, d2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Platform.isServer()) {
|
||||
p.sendMessage(PlayerMessages.AmmoDepleted.get());
|
||||
}
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, p.getHeldItem(hand));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ActionResult<>(ActionResultType.FAIL, p.getHeldItem(hand));
|
||||
}
|
||||
|
||||
private void shootPaintBalls(final ItemStack type, final World w, final PlayerEntity p, final Vec3d Vec3d,
|
||||
final Vec3d Vec3d1, final Vec3d direction, final double d0, final double d1, final double d2) {
|
||||
final AxisAlignedBB bb = new AxisAlignedBB(Math.min(Vec3d.x, Vec3d1.x), Math.min(Vec3d.y, Vec3d1.y),
|
||||
Math.min(Vec3d.z, Vec3d1.z), Math.max(Vec3d.x, Vec3d1.x), Math.max(Vec3d.y, Vec3d1.y),
|
||||
Math.max(Vec3d.z, Vec3d1.z)).grow(16, 16, 16);
|
||||
|
||||
Entity entity = null;
|
||||
Vec3d entityIntersection = null;
|
||||
final List list = w.getEntitiesWithinAABBExcludingEntity(p, bb);
|
||||
double closest = 9999999.0D;
|
||||
|
||||
for (int l = 0; l < list.size(); ++l) {
|
||||
final Entity entity1 = (Entity) list.get(l);
|
||||
|
||||
if (!entity1.isAlive() && entity1 != p && !(entity1 instanceof ItemEntity)) {
|
||||
if (entity1.isAlive()) {
|
||||
// prevent killing / flying of mounts.
|
||||
if (entity1.isRidingOrBeingRiddenBy(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final float f1 = 0.3F;
|
||||
|
||||
final AxisAlignedBB boundingBox = entity1.getBoundingBox().grow(f1, f1, f1);
|
||||
final Vec3d intersection = boundingBox.rayTrace(Vec3d, Vec3d1).orElse(null);
|
||||
|
||||
if (intersection != null) {
|
||||
final double nd = Vec3d.squareDistanceTo(intersection);
|
||||
|
||||
if (nd < closest) {
|
||||
entity = entity1;
|
||||
entityIntersection = intersection;
|
||||
closest = nd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RayTraceContext rayTraceContext = new RayTraceContext(Vec3d, Vec3d1, RayTraceContext.BlockMode.COLLIDER,
|
||||
RayTraceContext.FluidMode.NONE, p);
|
||||
RayTraceResult pos = w.rayTraceBlocks(rayTraceContext);
|
||||
|
||||
final Vec3d vec = new Vec3d(d0, d1, d2);
|
||||
if (entity != null && pos.getType() != RayTraceResult.Type.MISS
|
||||
&& pos.getHitVec().squareDistanceTo(vec) > closest) {
|
||||
pos = new EntityRayTraceResult(entity, entityIntersection);
|
||||
} else if (entity != null && pos.getType() == RayTraceResult.Type.MISS) {
|
||||
pos = new EntityRayTraceResult(entity, entityIntersection);
|
||||
}
|
||||
|
||||
try {
|
||||
AppEng.proxy.sendToAllNearExcept(null, d0, d1, d2, 128, w,
|
||||
new PacketMatterCannon(d0, d1, d2, (float) direction.x, (float) direction.y, (float) direction.z,
|
||||
(byte) (pos.getType() == RayTraceResult.Type.MISS ? 32
|
||||
: pos.getHitVec().squareDistanceTo(vec) + 1)));
|
||||
} catch (final Exception err) {
|
||||
AELog.debug(err);
|
||||
}
|
||||
|
||||
if (pos.getType() != RayTraceResult.Type.MISS && type != null && type.getItem() instanceof ItemPaintBall) {
|
||||
final ItemPaintBall ipb = (ItemPaintBall) type.getItem();
|
||||
|
||||
final AEColor col = ipb.getColor();
|
||||
// boolean lit = ipb.isLumen( type );
|
||||
|
||||
if (pos instanceof EntityRayTraceResult) {
|
||||
EntityRayTraceResult entityResult = (EntityRayTraceResult) pos;
|
||||
Entity entityHit = entityResult.getEntity();
|
||||
|
||||
final int id = entityHit.getEntityId();
|
||||
final PlayerColor marker = new PlayerColor(id, col, 20 * 30);
|
||||
TickHandler.INSTANCE.getPlayerColors().put(id, marker);
|
||||
|
||||
if (entityHit instanceof SheepEntity) {
|
||||
final SheepEntity sh = (SheepEntity) entityHit;
|
||||
sh.setFleeceColor(col.dye);
|
||||
}
|
||||
|
||||
entityHit.attackEntityFrom(DamageSource.causePlayerDamage(p), 0);
|
||||
NetworkHandler.instance().sendToAll(marker.getPacket());
|
||||
} else if (pos instanceof BlockRayTraceResult) {
|
||||
BlockRayTraceResult blockResult = (BlockRayTraceResult) pos;
|
||||
final Direction side = blockResult.getFace();
|
||||
final BlockPos hitPos = blockResult.getPos().offset(side);
|
||||
|
||||
if (!Platform.hasPermissions(new DimensionalCoord(w, hitPos), p)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final BlockState whatsThere = w.getBlockState(hitPos);
|
||||
if (whatsThere.getMaterial().isReplaceable() && w.isAirBlock(hitPos)) {
|
||||
AEApi.instance().definitions().blocks().paint().maybeBlock().ifPresent(paintBlock -> {
|
||||
w.setBlockState(hitPos, paintBlock.getDefaultState(), 3);
|
||||
});
|
||||
}
|
||||
|
||||
final TileEntity te = w.getTileEntity(hitPos);
|
||||
if (te instanceof TilePaint) {
|
||||
final Vec3d hp = pos.getHitVec().subtract(hitPos.getX(), hitPos.getY(), hitPos.getZ());
|
||||
((TilePaint) te).addBlot(type, side.getOpposite(), hp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void standardAmmo(float penetration, final World w, final PlayerEntity p, final Vec3d Vec3d,
|
||||
final Vec3d Vec3d1, final Vec3d direction, final double d0, final double d1, final double d2) {
|
||||
boolean hasDestroyed = true;
|
||||
while (penetration > 0 && hasDestroyed) {
|
||||
hasDestroyed = false;
|
||||
|
||||
final AxisAlignedBB bb = new AxisAlignedBB(Math.min(Vec3d.x, Vec3d1.x), Math.min(Vec3d.y, Vec3d1.y),
|
||||
Math.min(Vec3d.z, Vec3d1.z), Math.max(Vec3d.x, Vec3d1.x), Math.max(Vec3d.y, Vec3d1.y),
|
||||
Math.max(Vec3d.z, Vec3d1.z)).grow(16, 16, 16);
|
||||
|
||||
Entity entity = null;
|
||||
Vec3d entityIntersection = null;
|
||||
final List list = w.getEntitiesWithinAABBExcludingEntity(p, bb);
|
||||
double closest = 9999999.0D;
|
||||
|
||||
for (int l = 0; l < list.size(); ++l) {
|
||||
final Entity entity1 = (Entity) list.get(l);
|
||||
|
||||
if (entity1.isAlive() && entity1 != p && !(entity1 instanceof ItemEntity)) {
|
||||
if (entity1.isAlive()) {
|
||||
// prevent killing / flying of mounts.
|
||||
if (entity1.isRidingOrBeingRiddenBy(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final float f1 = 0.3F;
|
||||
|
||||
final AxisAlignedBB boundingBox = entity1.getBoundingBox().grow(f1, f1, f1);
|
||||
final Vec3d intersection = boundingBox.rayTrace(Vec3d, Vec3d1).orElse(null);
|
||||
|
||||
if (intersection != null) {
|
||||
final double nd = Vec3d.squareDistanceTo(intersection);
|
||||
|
||||
if (nd < closest) {
|
||||
entity = entity1;
|
||||
entityIntersection = intersection;
|
||||
closest = nd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RayTraceContext rayTraceContext = new RayTraceContext(Vec3d, Vec3d1, RayTraceContext.BlockMode.COLLIDER,
|
||||
RayTraceContext.FluidMode.NONE, p);
|
||||
final Vec3d vec = new Vec3d(d0, d1, d2);
|
||||
RayTraceResult pos = w.rayTraceBlocks(rayTraceContext);
|
||||
if (entity != null && pos.getType() != RayTraceResult.Type.MISS
|
||||
&& pos.getHitVec().squareDistanceTo(vec) > closest) {
|
||||
pos = new EntityRayTraceResult(entity, entityIntersection);
|
||||
} else if (entity != null && pos.getType() == RayTraceResult.Type.MISS) {
|
||||
pos = new EntityRayTraceResult(entity, entityIntersection);
|
||||
}
|
||||
|
||||
try {
|
||||
AppEng.proxy.sendToAllNearExcept(null, d0, d1, d2, 128, w,
|
||||
new PacketMatterCannon(d0, d1, d2, (float) direction.x, (float) direction.y,
|
||||
(float) direction.z, (byte) (pos.getType() == RayTraceResult.Type.MISS ? 32
|
||||
: pos.getHitVec().squareDistanceTo(vec) + 1)));
|
||||
} catch (final Exception err) {
|
||||
AELog.debug(err);
|
||||
}
|
||||
|
||||
if (pos.getType() != RayTraceResult.Type.MISS) {
|
||||
final DamageSource dmgSrc = new EntityDamageSource("matter_cannon", p);
|
||||
|
||||
if (pos instanceof EntityRayTraceResult) {
|
||||
EntityRayTraceResult entityResult = (EntityRayTraceResult) pos;
|
||||
Entity entityHit = entityResult.getEntity();
|
||||
|
||||
final int dmg = (int) Math.ceil(penetration / 20.0f);
|
||||
if (entityHit instanceof LivingEntity) {
|
||||
final LivingEntity el = (LivingEntity) entityHit;
|
||||
penetration -= dmg;
|
||||
el.knockBack(p, 0, -direction.x, -direction.z);
|
||||
// el.knockBack( p, 0, Vec3d.x,
|
||||
// Vec3d.z );
|
||||
el.attackEntityFrom(dmgSrc, dmg);
|
||||
if (!el.isAlive()) {
|
||||
hasDestroyed = true;
|
||||
}
|
||||
} else if (entityHit instanceof ItemEntity) {
|
||||
hasDestroyed = true;
|
||||
entityHit.remove();
|
||||
} else if (entityHit.attackEntityFrom(dmgSrc, dmg)) {
|
||||
hasDestroyed = true;
|
||||
}
|
||||
} else if (pos instanceof BlockRayTraceResult) {
|
||||
BlockRayTraceResult blockResult = (BlockRayTraceResult) pos;
|
||||
|
||||
if (!AEConfig.instance().isFeatureEnabled(AEFeature.MASS_CANNON_BLOCK_DAMAGE)) {
|
||||
penetration = 0;
|
||||
} else {
|
||||
BlockPos blockPos = blockResult.getPos();
|
||||
final BlockState bs = w.getBlockState(blockPos);
|
||||
|
||||
final float hardness = bs.getBlockHardness(w, blockPos) * 9.0f;
|
||||
if (hardness >= 0.0) {
|
||||
if (penetration > hardness
|
||||
&& Platform.hasPermissions(new DimensionalCoord(w, blockPos), p)) {
|
||||
hasDestroyed = true;
|
||||
penetration -= hardness;
|
||||
penetration *= 0.60;
|
||||
w.destroyBlock(blockPos, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable(final ItemStack is) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getUpgradesInventory(final ItemStack is) {
|
||||
return new CellUpgrades(is, 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getConfigInventory(final ItemStack is) {
|
||||
return new CellConfig(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FuzzyMode getFuzzyMode(final ItemStack is) {
|
||||
final String fz = is.getOrCreateTag().getString("FuzzyMode");
|
||||
try {
|
||||
return FuzzyMode.valueOf(fz);
|
||||
} catch (final Throwable t) {
|
||||
return FuzzyMode.IGNORE_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFuzzyMode(final ItemStack is, final FuzzyMode fzMode) {
|
||||
is.getOrCreateTag().putString("FuzzyMode", fzMode.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes(final ItemStack cellItem) {
|
||||
return 512;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytesPerType(final ItemStack cellItem) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalTypes(final ItemStack cellItem) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlackListed(final ItemStack cellItem, final IAEItemStack requestedAddition) {
|
||||
final float pen = AEApi.instance().registries().matterCannon()
|
||||
.getPenetration(requestedAddition.createItemStack());
|
||||
if (pen > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (requestedAddition.getItem() instanceof ItemPaintBall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean storableInStorageCell() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStorageCell(final ItemStack i) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getIdleDrain() {
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<IAEItemStack> getChannel() {
|
||||
return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user