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();
}
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;
}
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();
}
}
}
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();
}
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;
}
Aggregations