Search in sources :

Example 6 with EntityFlyingBlock

use of icbm.classic.content.entity.EntityFlyingBlock in project ICBM-Classic by BuiltBrokenModding.

the class BlastSonic method doExplode.

@Override
public // TODO Rewrite this entire method
boolean doExplode(// TODO Rewrite this entire method
int callCount) {
    if (callCount <= 0) {
        firstTick();
    }
    // TODO scale off of size & callcout
    final int radius = Math.max(1, this.callCount);
    if (callCount % 4 == 0) {
        if (isThreadCompleted()) {
            if (!getThreadResults().isEmpty()) {
                final Iterator<BlockPos> it = getThreadResults().iterator();
                while (it.hasNext()) {
                    final BlockPos targetPosition = it.next();
                    final double distance = location.distance(targetPosition);
                    // Only act on blocks inside the current radius TODO scale radius separate from ticks so we can control block creation
                    if (distance <= radius) {
                        // Remove
                        it.remove();
                        // Get data
                        final IBlockState blockState = world.getBlockState(targetPosition);
                        final Block block = blockState.getBlock();
                        // Only act on movable blocks
                        if (!block.isAir(blockState, world, targetPosition) && blockState.getBlockHardness(world, targetPosition) >= 0) {
                            // Trigger explosions
                            if (block == BlockReg.blockExplosive) {
                                ((TileEntityExplosive) this.world().getTileEntity(targetPosition)).trigger(false);
                            }
                            // Destroy block
                            this.world().setBlockToAir(targetPosition);
                            // Create floating block
                            if (!(block instanceof BlockFluidBase || block instanceof IFluidBlock) && this.world().rand.nextFloat() < 0.1) {
                                this.world().spawnEntity(new EntityFlyingBlock(this.world(), targetPosition, blockState));
                            }
                        }
                    }
                }
            } else {
                isAlive = false;
                if (ConfigDebug.DEBUG_THREADS) {
                    String msg = String.format("BlastSonic#doPostExplode() -> Thread failed to find blocks to edit. Either thread failed or no valid blocks were found in range." + "\nWorld = %s " + "\nThread = %s" + "\nSize = %s" + "\nPos = %s", world, getThread(), size, location);
                    ICBMClassic.logger().error(msg);
                }
            }
        }
    }
    // TODO scale to radius
    final int entityEffectRadius = 2 * this.callCount;
    final AxisAlignedBB bounds = new AxisAlignedBB(location.x() - entityEffectRadius, location.y() - entityEffectRadius, location.z() - entityEffectRadius, location.x() + entityEffectRadius, location.y() + entityEffectRadius, location.z() + entityEffectRadius);
    final List<Entity> allEntities = this.world().getEntitiesWithinAABB(Entity.class, bounds);
    for (Entity entity : allEntities) {
        if (entity instanceof IMissile) {
            // TODO change from guided to dummy fire
            ((IMissile) entity).destroyMissile(true);
        } else if (!(entity instanceof EntityPlayer) || !((EntityPlayer) entity).isCreative()) {
            // Get difference
            double xDelta = entity.posX - location.x();
            double yDelta = entity.posY - location.y();
            double zDelta = entity.posZ - location.z();
            // Normalize
            float distance = MathHelper.sqrt(xDelta * xDelta + yDelta * yDelta + zDelta * zDelta);
            xDelta = xDelta / (double) distance;
            yDelta = yDelta / (double) distance;
            zDelta = zDelta / (double) distance;
            // Scale
            final double scale = Math.max(0, (1 - (distance / getBlastRadius()))) * 3;
            xDelta *= scale;
            yDelta *= scale;
            zDelta *= scale;
            entity.motionX += xDelta * this.world().rand.nextFloat() * 0.2;
            entity.motionY += Math.abs(yDelta * this.world().rand.nextFloat()) * 1;
            entity.motionZ += zDelta * this.world().rand.nextFloat() * 0.2;
        }
    }
    return this.callCount > this.getBlastRadius();
}
Also used : AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) Entity(net.minecraft.entity.Entity) IBlockState(net.minecraft.block.state.IBlockState) IMissile(icbm.classic.api.caps.IMissile) BlockFluidBase(net.minecraftforge.fluids.BlockFluidBase) EntityFlyingBlock(icbm.classic.content.entity.EntityFlyingBlock) IFluidBlock(net.minecraftforge.fluids.IFluidBlock) EntityFlyingBlock(icbm.classic.content.entity.EntityFlyingBlock) IFluidBlock(net.minecraftforge.fluids.IFluidBlock) Block(net.minecraft.block.Block) TileEntityExplosive(icbm.classic.content.blocks.explosive.TileEntityExplosive) EntityPlayer(net.minecraft.entity.player.EntityPlayer) BlockPos(net.minecraft.util.math.BlockPos)

Example 7 with EntityFlyingBlock

use of icbm.classic.content.entity.EntityFlyingBlock in project ICBM-Classic by BuiltBrokenModding.

the class BlastBeam method doExplode.

@Override
protected boolean doExplode(int callCount) {
    if (!hasDoneSetup) {
        hasDoneSetup = true;
        // Play audio
        ICBMSounds.BEAM_CHARGING.play(world, location.x(), location.y(), location.z(), 4.0F, 0.8F, true);
        // Basic explosion
        // TODO remove basic in favor of thread
        this.world().createExplosion(this.exploder, location.x(), location.y(), location.z(), 4F, true);
        // Create beam
        this.lightBeam = new EntityLightBeam(this.world()).setPosition(location).setColor(this.red, this.green, this.blue);
        this.lightBeam.beamSize = 1;
        this.lightBeam.beamGlowSize = 2;
        this.lightBeam.setTargetBeamProgress(0.1f);
        this.world().spawnEntity(this.lightBeam);
    }
    // Start first thread if not already started
    if (!hasStartedFirstThread) {
        hasStartedFirstThread = true;
        this.lightBeam.setTargetBeamProgress(0.2f);
        WorkerThreadManager.INSTANCE.addWork(getFirstThread());
    }
    // When first thread is completed start floating blocks and ticking down to start second thread
    if (hasCompletedFirstThread && !hasStartedSecondThread) {
        // Spawn flying blocks
        if (!hasGeneratedFlyingBlocks) {
            hasGeneratedFlyingBlocks = true;
            this.lightBeam.setTargetBeamProgress(0.5f);
            // Edit blocks and queue spawning
            for (BlockPos blockPos : blocksToRemove) {
                // TODO filter what can turn into a flying block
                final IBlockState state = world.getBlockState(blockPos);
                // Remove block
                if (world.setBlockToAir(blockPos)) {
                    // Create an spawn
                    final EntityFlyingBlock entity = new EntityFlyingBlock(this.world(), blockPos, state);
                    entity.gravity = -0.01f;
                    if (world.spawnEntity(entity)) {
                        flyingBlocks.add(entity);
                    }
                }
            }
            blocksToRemove.clear();
        }
        // Delay second thread start
        if (secondThreadTimer-- <= 0) {
            this.lightBeam.setTargetBeamProgress(0.8f);
            hasStartedSecondThread = true;
            WorkerThreadManager.INSTANCE.addWork(getSecondThread());
        }
    }
    if (hasCompetedSecondThread) {
        this.lightBeam.setTargetBeamProgress(1f);
        if (!hasEnabledGravityForFlyingBlocks) {
            hasEnabledGravityForFlyingBlocks = true;
            flyingBlocks.forEach(entity -> entity.gravity = 0.5f);
        }
        if (!hasPlacedBlocks) {
            hasPlacedBlocks = true;
            mutateBlocks(blocksToRemove);
            blocksToRemove.clear();
        }
    }
    return hasPlacedBlocks;
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) EntityFlyingBlock(icbm.classic.content.entity.EntityFlyingBlock) EntityLightBeam(icbm.classic.content.entity.EntityLightBeam) BlockPos(net.minecraft.util.math.BlockPos)

Example 8 with EntityFlyingBlock

use of icbm.classic.content.entity.EntityFlyingBlock in project ICBM-Classic by BuiltBrokenModding.

the class BlastBeam method doExplode.

@Override
public void doExplode() {
    if (!this.world().isRemote) {
        if (this.callCount > 100 / this.proceduralInterval() && this.thread.isComplete) {
            this.controller.endExplosion();
        }
        if (this.canFocusBeam(this.world(), position)) {
            Pos currentPos;
            int blockID;
            int metadata;
            double dist;
            int r = radius;
            for (int x = -r; x < r; x++) {
                for (int y = -r; y < r; y++) {
                    for (int z = -r; z < r; z++) {
                        dist = MathHelper.sqrt_double((x * x + y * y + z * z));
                        if (dist > r || dist < r - 3) {
                            continue;
                        }
                        currentPos = new Pos(position.x() + x, position.y() + y, position.z() + z);
                        Block block = currentPos.getBlock(world());
                        if (block == null || block.isAir(this.world(), x, y, z) || block.getBlockHardness(this.world(), x, y, x) < 0) {
                            continue;
                        }
                        metadata = this.world().getBlockMetadata(currentPos.xi(), currentPos.yi(), currentPos.zi());
                        if (this.world().rand.nextInt(2) > 0) {
                            this.world().setBlockToAir(currentPos.xi(), currentPos.yi(), currentPos.zi());
                            currentPos = currentPos.add(0.5D);
                            EntityFlyingBlock entity = new EntityFlyingBlock(this.world(), currentPos, block, metadata);
                            this.world().spawnEntityInWorld(entity);
                            this.feiBlocks.add(entity);
                            entity.pitchChange = 50 * this.world().rand.nextFloat();
                        }
                    }
                }
            }
        } else {
            this.controller.endExplosion();
        }
        for (EntityFlyingBlock entity : this.feiBlocks) {
            Pos entityPosition = new Pos(entity);
            Pos centeredPosition = entityPosition.add(this.position.multiply(-1));
            centeredPosition.rotate(2);
            Location newPosition = this.position.add(centeredPosition);
            entity.motionX /= 3;
            entity.motionY /= 3;
            entity.motionZ /= 3;
            entity.addVelocity((newPosition.x() - entityPosition.x()) * 0.5 * this.proceduralInterval(), 0.09 * this.proceduralInterval(), (newPosition.z() - entityPosition.z()) * 0.5 * this.proceduralInterval());
            entity.yawChange += 3 * this.world().rand.nextFloat();
        }
    }
}
Also used : Pos(com.builtbroken.mc.imp.transform.vector.Pos) EntityFlyingBlock(icbm.classic.content.entity.EntityFlyingBlock) Block(net.minecraft.block.Block) EntityFlyingBlock(icbm.classic.content.entity.EntityFlyingBlock) Location(com.builtbroken.mc.imp.transform.vector.Location)

Example 9 with EntityFlyingBlock

use of icbm.classic.content.entity.EntityFlyingBlock in project ICBM-Classic by BuiltBrokenModding.

the class RenderEntityBlock method doRenderGravityBlock.

/** The actual render method that is used in doRender */
public void doRenderGravityBlock(EntityFlyingBlock entity, double x, double y, double z, float par8, float par9) {
    Block block = entity.block;
    if (block == null || block.getMaterial() == Material.air) {
        block = Blocks.stone;
    }
    GL11.glPushMatrix();
    try {
        GL11.glTranslatef((float) x + 0.5f, (float) y + 0.5f, (float) z + 0.5f);
        RenderUtility.setTerrainTexture();
        EulerAngle rotation = new EulerAngle(entity.rotationYaw, entity.rotationPitch);
        Pos translation = rotation.toPos();
        GL11.glTranslated(translation.x(), translation.y(), translation.z());
        //GL11.glDisable(GL11.GL_LIGHTING);
        GL11.glRotatef(entity.rotationPitch, 0.0F, 0.0F, 1.0F);
        GL11.glRotatef(entity.rotationYaw, 0.0F, 1.0F, 0.0F);
        if (block.getRenderType() != 0) {
            Tessellator tessellator = Tessellator.instance;
            tessellator.startDrawingQuads();
            try {
                tessellator.setTranslation((-MathHelper.floor_double(entity.posX)) - 0.5F, (-MathHelper.floor_double(entity.posY)) - 0.5F, (-MathHelper.floor_double(entity.posZ)) - 0.5F);
                RenderUtility.getBlockRenderer().renderBlockByRenderType(block, MathHelper.floor_double(entity.posX), MathHelper.floor_double(entity.posY), MathHelper.floor_double(entity.posZ));
                tessellator.setTranslation(0.0D, 0.0D, 0.0D);
                tessellator.draw();
            } catch (Exception e) {
                ICBMClassic.INSTANCE.logger().error("Unexpected error while rendering EntityBlock[" + entity + "] with data [" + block + ":" + entity.metadata + "] forcing to render as stone to prevent additional errors.", e);
                entity.block = Blocks.stone;
                //Hacky way of clearing current draw state
                tessellator.isDrawing = false;
                tessellator.startDrawingQuads();
                tessellator.isDrawing = false;
            }
        } else {
            RenderUtility.renderCube(0, 0, 0, 1, 1, 1, block, null, entity.metadata);
        }
    //GL11.glEnable(GL11.GL_LIGHTING);
    } catch (Exception e) {
        ICBMClassic.INSTANCE.logger().error("Unexpected error while rendering EntityBlock[" + entity + "] with data [" + block + ":" + entity.metadata + "]", e);
    }
    GL11.glPopMatrix();
}
Also used : Tessellator(net.minecraft.client.renderer.Tessellator) Pos(com.builtbroken.mc.imp.transform.vector.Pos) EntityFlyingBlock(icbm.classic.content.entity.EntityFlyingBlock) Block(net.minecraft.block.Block) EulerAngle(com.builtbroken.mc.imp.transform.rotation.EulerAngle)

Example 10 with EntityFlyingBlock

use of icbm.classic.content.entity.EntityFlyingBlock in project ICBM-Classic by BuiltBrokenModding.

the class BlastAntiGravitational method doExplode.

@Override
public // TODO rewrite entire method
boolean doExplode(// TODO rewrite entire method
int callCount) {
    int r = this.callCount;
    if (world() != null && !this.world().isRemote) {
        try {
            if (// TODO replace thread check with callback triggered by thread and delayed into main thread
            this.thread != null) {
                if (this.thread.isComplete) {
                    // Copy as concurrent list is not fast to sort
                    List<BlockPos> results = new ArrayList();
                    results.addAll(getThreadResults());
                    if (r == 0) {
                        Collections.sort(results, new PosDistanceSorter(location, true));
                    }
                    int blocksToTake = 20;
                    for (BlockPos targetPosition : results) {
                        final IBlockState blockState = world.getBlockState(targetPosition);
                        if (// don't pick up air
                        !blockState.getBlock().isAir(blockState, world, targetPosition) && // don't pick up replacable blocks like fire, grass, or snow (this does not include crops)
                        !blockState.getBlock().isReplaceable(world, targetPosition) && !(blockState.getBlock() instanceof IFluidBlock) && // don't pick up liquids
                        !(blockState.getBlock() instanceof BlockLiquid)) {
                            float hardness = blockState.getBlockHardness(world, targetPosition);
                            if (hardness >= 0 && hardness < 1000) {
                                if (world().rand.nextInt(3) > 0) {
                                    // Remove block
                                    world.setBlockToAir(targetPosition);
                                    // Mark blocks taken
                                    blocksToTake--;
                                    if (blocksToTake <= 0) {
                                        break;
                                    }
                                    // Create flying block
                                    EntityFlyingBlock entity = new EntityFlyingBlock(world(), targetPosition, blockState, 0);
                                    entity.yawChange = 50 * world().rand.nextFloat();
                                    entity.pitchChange = 100 * world().rand.nextFloat();
                                    entity.motionY += Math.max(0.15 * world().rand.nextFloat(), 0.1);
                                    entity.noClip = true;
                                    world().spawnEntity(entity);
                                    // Track flying block
                                    flyingBlocks.add(entity);
                                }
                            }
                        }
                    }
                }
            } else {
                String msg = String.format("BlastAntiGravitational#doPostExplode() -> Failed to run due to null thread" + "\nWorld = %s " + "\nThread = %s" + "\nSize = %s" + "\nPos = ", world, thread, size, location);
                ICBMClassic.logger().error(msg);
            }
        } catch (Exception e) {
            String msg = String.format("BlastAntiGravitational#doPostExplode() ->  Unexpected error while running post detonation code " + "\nWorld = %s " + "\nThread = %s" + "\nSize = %s" + "\nPos = ", world, thread, size, location);
            ICBMClassic.logger().error(msg, e);
        }
    }
    int radius = (int) this.getBlastRadius();
    AxisAlignedBB bounds = new AxisAlignedBB(location.x() - radius, location.y() - radius, location.z() - radius, location.y() + radius, 100, location.z() + radius);
    List<Entity> allEntities = world().getEntitiesWithinAABB(Entity.class, bounds);
    for (Entity entity : allEntities) {
        if (!(entity instanceof EntityFlyingBlock) && entity.posY < 100 + location.y()) {
            if (entity.motionY < 0.4) {
                entity.motionY += 0.15;
            }
        }
    }
    return this.callCount > 20 * 120;
}
Also used : PosDistanceSorter(icbm.classic.lib.transform.PosDistanceSorter) AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) Entity(net.minecraft.entity.Entity) IBlockState(net.minecraft.block.state.IBlockState) ArrayList(java.util.ArrayList) BlockLiquid(net.minecraft.block.BlockLiquid) EntityFlyingBlock(icbm.classic.content.entity.EntityFlyingBlock) IFluidBlock(net.minecraftforge.fluids.IFluidBlock) BlockPos(net.minecraft.util.math.BlockPos)

Aggregations

EntityFlyingBlock (icbm.classic.content.entity.EntityFlyingBlock)11 Block (net.minecraft.block.Block)6 Entity (net.minecraft.entity.Entity)5 Pos (com.builtbroken.mc.imp.transform.vector.Pos)4 IFluidBlock (net.minecraftforge.fluids.IFluidBlock)4 IBlockState (net.minecraft.block.state.IBlockState)3 EntityPlayer (net.minecraft.entity.player.EntityPlayer)3 AxisAlignedBB (net.minecraft.util.AxisAlignedBB)3 BlockPos (net.minecraft.util.math.BlockPos)3 Location (com.builtbroken.mc.imp.transform.vector.Location)2 EntityExplosion (icbm.classic.content.entity.EntityExplosion)2 EntityMissile (icbm.classic.content.entity.EntityMissile)2 BlockLiquid (net.minecraft.block.BlockLiquid)2 AxisAlignedBB (net.minecraft.util.math.AxisAlignedBB)2 EulerAngle (com.builtbroken.mc.imp.transform.rotation.EulerAngle)1 IMissile (icbm.classic.api.caps.IMissile)1 IBlast (icbm.classic.api.explosion.IBlast)1 BlastAntimatter (icbm.classic.content.blast.threaded.BlastAntimatter)1 TileEntityExplosive (icbm.classic.content.blocks.explosive.TileEntityExplosive)1 EntityExplosive (icbm.classic.content.entity.EntityExplosive)1