use of icbm.classic.api.caps.IMissile in project ICBM-Classic by BuiltBrokenModding.
the class TileRadarStation method doScan.
private // TODO document and thread
void doScan() {
this.incomingMissiles.clear();
this.detectedEntities.clear();
List<Entity> entities = RadarRegistry.getAllLivingObjectsWithin(world, xi() + 1.5, yi() + 0.5, zi() + 0.5, Math.min(alarmRange, MAX_DETECTION_RANGE));
for (Entity entity : entities) {
if (// TODO && ((EntityMissile) entity).getExplosiveType() != Explosives.MISSILE_ANTI.handler)
ICBMClassicHelpers.isMissile(entity)) {
final IMissile newMissile = ICBMClassicHelpers.getMissile(entity);
if (newMissile != null && newMissile.getTicksInAir() > 1) {
if (!this.detectedEntities.contains(entity)) {
this.detectedEntities.add(entity);
}
if (this.isMissileGoingToHit((EntityMissile) entity)) {
if (this.incomingMissiles.size() > 0) {
/**
* Sort in order of distance
*/
double dist = new Pos((TileEntity) this).distance(newMissile);
for (int i = 0; i < this.incomingMissiles.size(); i++) {
IMissile missile = this.incomingMissiles.get(i);
if (dist < new Pos((TileEntity) this).distance(missile)) {
this.incomingMissiles.add(i, missile);
break;
} else if (i == this.incomingMissiles.size() - 1) {
this.incomingMissiles.add(missile);
break;
}
}
} else {
this.incomingMissiles.add(newMissile);
}
}
}
}
}
}
use of icbm.classic.api.caps.IMissile in project ICBM-Classic by BuiltBrokenModding.
the class TileRadarStation method getStrongRedstonePower.
public int getStrongRedstonePower(EnumFacing side) {
if (incomingMissiles.size() > 0) {
if (this.emitAll) {
return Math.min(15, 5 + incomingMissiles.size());
}
for (IMissile incomingMissile : this.incomingMissiles) {
Point position = new Point(incomingMissile.x(), incomingMissile.y());
EnumFacing missileTravelDirection = EnumFacing.DOWN;
double closest = -1;
for (EnumFacing rotation : EnumFacing.HORIZONTALS) {
double dist = position.distance(new Point(this.getPos().getX() + rotation.getXOffset(), this.getPos().getZ() + rotation.getZOffset()));
if (dist < closest || closest < 0) {
missileTravelDirection = rotation;
closest = dist;
}
}
if (missileTravelDirection.getOpposite().ordinal() == side.ordinal()) {
return Math.min(15, 5 + incomingMissiles.size());
}
}
}
return 0;
}
use of icbm.classic.api.caps.IMissile 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.api.caps.IMissile in project ICBM-Classic by BuiltBrokenModding.
the class Blast method doDamageEntities.
/**
* @return true if the method ran successfully, false if it was interrupted
*/
protected boolean doDamageEntities(float radius, float power, boolean destroyItem) {
// Step 2: Damage all entities
radius *= 2.0F;
Location minCoord = location.add(-radius - 1);
Location maxCoord = location.add(radius + 1);
List<Entity> allEntities = world().getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(minCoord.xi(), minCoord.yi(), minCoord.zi(), maxCoord.xi(), maxCoord.yi(), maxCoord.zi()));
Vec3d var31 = new Vec3d(location.x(), location.y(), location.z());
if (!ConfigBlast.ANTIMATTER_BLOCK_AND_ENT_DAMAGE_ON_REDMATTER && this instanceof BlastAntimatter) {
allEntities.sort((e1, e2) -> {
if (e2 instanceof EntityExplosion && ((EntityExplosion) e2).getBlast() instanceof BlastRedmatter) {
// put red matter at the front
return 1;
} else {
return -1;
}
});
if (// remove red matter blast and stop doing anything else
onDamageEntity(allEntities.get(0))) {
return false;
}
}
for (int i = 0; i < allEntities.size(); ++i) {
Entity entity = allEntities.get(i);
if (this.onDamageEntity(entity)) {
continue;
}
if (entity instanceof IMissile) {
((IMissile) entity).destroyMissile(true);
continue;
}
if (entity instanceof EntityItem && !destroyItem) {
continue;
}
double distance = entity.getDistance(location.x(), location.y(), location.z()) / radius;
if (distance <= 1.0D) {
double xDifference = entity.posX - location.x();
double yDifference = entity.posY - location.y();
double zDifference = entity.posZ - location.z();
double var35 = MathHelper.sqrt(xDifference * xDifference + yDifference * yDifference + zDifference * zDifference);
xDifference /= var35;
yDifference /= var35;
zDifference /= var35;
double var34 = world().getBlockDensity(var31, entity.getEntityBoundingBox());
double var36 = (1.0D - distance) * var34;
int damage = 0;
damage = (int) ((var36 * var36 + var36) / 2.0D * 8.0D * power + 1.0D);
entity.attackEntityFrom(DamageSource.causeExplosionDamage(this), damage);
entity.motionX += xDifference * var36;
entity.motionY += yDifference * var36;
entity.motionZ += zDifference * var36;
}
}
return true;
}
Aggregations