diff --git a/src/main/java/cr0s/warpdrive/WarpDrive.java b/src/main/java/cr0s/warpdrive/WarpDrive.java index fb0acbf5..f4d6415c 100644 --- a/src/main/java/cr0s/warpdrive/WarpDrive.java +++ b/src/main/java/cr0s/warpdrive/WarpDrive.java @@ -117,6 +117,7 @@ import cr0s.warpdrive.data.EnumComponentType; import cr0s.warpdrive.data.EnumHullPlainType; import cr0s.warpdrive.data.EnumTier; import cr0s.warpdrive.data.StarMapRegistry; +import cr0s.warpdrive.entity.EntityLaserExploder; import cr0s.warpdrive.entity.EntityParticleBunch; import cr0s.warpdrive.event.ChunkHandler; import cr0s.warpdrive.event.ChunkLoadingHandler; @@ -1090,6 +1091,13 @@ public class WarpDrive { .build(); event.getRegistry().register(entityEntry); + entityEntry = EntityEntryBuilder.create() + .entity(EntityLaserExploder.class).factory(EntityLaserExploder::new) + .tracker(8, 1000, false) + .id("entityLaserExploder", WarpDriveConfig.G_ENTITY_LASER_EXPLODER_ID).name("entityLaserExploder") + .build(); + event.getRegistry().register(entityEntry); + LocalProfiler.stop(1000); } diff --git a/src/main/java/cr0s/warpdrive/block/TileEntityLaser.java b/src/main/java/cr0s/warpdrive/block/TileEntityLaser.java index 27a41a77..f35c0f9f 100644 --- a/src/main/java/cr0s/warpdrive/block/TileEntityLaser.java +++ b/src/main/java/cr0s/warpdrive/block/TileEntityLaser.java @@ -13,6 +13,7 @@ import cr0s.warpdrive.data.EnergyWrapper; import cr0s.warpdrive.data.ForceFieldSetup; import cr0s.warpdrive.data.SoundEvents; import cr0s.warpdrive.data.Vector3; +import cr0s.warpdrive.entity.EntityLaserExploder; import cr0s.warpdrive.network.PacketHandler; import li.cil.oc.api.machine.Arguments; @@ -345,6 +346,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre playSoundCorrespondsEnergy(energy); + final Entity entityExploder = new EntityLaserExploder(world, pos); + // This is a scanning beam, do not deal damage to block nor entity if (beamFrequency == IBeamFrequency.BEAM_FREQUENCY_SCANNING) { final RayTraceResult mopResult = rayTraceBlocks(world, vSource.toVec3d(), vReachPoint.toVec3d(), beamFrequency, @@ -359,8 +362,10 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre final IBlockState blockState = world.getBlockState(scanResult_position); scanResult_blockUnlocalizedName = blockState.getBlock().getTranslationKey(); scanResult_blockMetadata = blockState.getBlock().getMetaFromState(blockState); - final Explosion explosion = new Explosion(world, null, pos.getX(), pos.getY(), pos.getZ(), 1, true, true); - scanResult_blockResistance = blockState.getBlock().getExplosionResistance(world, scanResult_position, null, explosion); + final Explosion explosion = new Explosion(world, entityExploder, + scanResult_position.getX(), scanResult_position.getY(), scanResult_position.getZ(), + 1, true, true); + scanResult_blockResistance = blockState.getBlock().getExplosionResistance(world, scanResult_position, entityExploder, explosion); PacketHandler.sendBeamPacket(world, vSource, new Vector3(mopResult.hitVec), r, g, b, 50, energy, 200); } else { scanResult_type = ScanResultType.NONE; @@ -459,7 +464,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre if (energy > WarpDriveConfig.LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_THRESHOLD) { final float strength = (float) Commons.clamp(0.0D, WarpDriveConfig.LASER_CANNON_ENTITY_HIT_EXPLOSION_MAX_STRENGTH, WarpDriveConfig.LASER_CANNON_ENTITY_HIT_EXPLOSION_BASE_STRENGTH + energy / (double) WarpDriveConfig.LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_PER_STRENGTH); - world.newExplosion(null, mopEntity.entityHit.posX, mopEntity.entityHit.posY, mopEntity.entityHit.posZ, strength, true, true); + world.newExplosion(entityExploder, mopEntity.entityHit.posX, mopEntity.entityHit.posY, mopEntity.entityHit.posZ, + strength, true, true); } // remove entity from hit list @@ -530,7 +536,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre if (WarpDriveConfig.LOGGING_WEAPON) { WarpDrive.logger.info(String.format("Explosion triggered with strength %.1f", strength)); } - world.newExplosion(null, blockHit.getBlockPos().getX(), blockHit.getBlockPos().getY(), blockHit.getBlockPos().getZ(), strength, true, true); + world.newExplosion(entityExploder, blockHit.hitVec.x, blockHit.hitVec.y, blockHit.hitVec.z, + strength, true, true); vHitPoint = new Vector3(blockHit.hitVec); break; } @@ -602,8 +609,9 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre if (WarpDriveConfig.LOGGING_WEAPON) { WarpDrive.logger.info(String.format("Explosion triggered with strength %.1f", strength)); } - world.newExplosion(null, blockHit.getBlockPos().getX(), blockHit.getBlockPos().getY(), blockHit.getBlockPos().getZ(), strength, true, true); - world.setBlockState(blockHit.getBlockPos(), (world.rand.nextBoolean()) ? Blocks.FIRE.getDefaultState() : Blocks.AIR.getDefaultState()); + world.newExplosion(entityExploder, blockHit.hitVec.x, blockHit.hitVec.y, blockHit.hitVec.z, + strength, true, true); + world.setBlockState(blockHit.getBlockPos(), world.rand.nextBoolean() ? Blocks.FIRE.getDefaultState() : Blocks.AIR.getDefaultState()); } else { world.setBlockToAir(blockHit.getBlockPos()); } diff --git a/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java b/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java index 1ead2579..b308cdb7 100644 --- a/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java +++ b/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java @@ -165,6 +165,7 @@ public class WarpDriveConfig { public static int G_ENTITY_STAR_CORE_ID = 242; public static int G_ENTITY_CAMERA_ID = 243; public static int G_ENTITY_PARTICLE_BUNCH_ID = 244; + public static int G_ENTITY_LASER_EXPLODER_ID = 245; public static final int LUA_SCRIPTS_NONE = 0; public static final int LUA_SCRIPTS_TEMPLATES = 1; @@ -767,6 +768,8 @@ public class WarpDriveConfig { config.get("general", "entity_camera_id", G_ENTITY_CAMERA_ID, "Entity camera ID").getInt()); G_ENTITY_PARTICLE_BUNCH_ID = Commons.clamp(Integer.MIN_VALUE, Integer.MAX_VALUE, config.get("general", "entity_particle_bunch_id", G_ENTITY_PARTICLE_BUNCH_ID, "Entity particle bunch ID").getInt()); + G_ENTITY_LASER_EXPLODER_ID = Commons.clamp(Integer.MIN_VALUE, Integer.MAX_VALUE, + config.get("general", "entity_laser_exploder_id", G_ENTITY_LASER_EXPLODER_ID, "Entity laser exploder ID").getInt()); G_LUA_SCRIPTS = Commons.clamp(0, 2, config.get("general", "lua_scripts", G_LUA_SCRIPTS, diff --git a/src/main/java/cr0s/warpdrive/entity/EntityLaserExploder.java b/src/main/java/cr0s/warpdrive/entity/EntityLaserExploder.java new file mode 100644 index 00000000..2ea7bd43 --- /dev/null +++ b/src/main/java/cr0s/warpdrive/entity/EntityLaserExploder.java @@ -0,0 +1,127 @@ +package cr0s.warpdrive.entity; + +import cr0s.warpdrive.Commons; +import cr0s.warpdrive.WarpDrive; +import cr0s.warpdrive.config.WarpDriveConfig; +import cr0s.warpdrive.data.SoundEvents; +import cr0s.warpdrive.data.Vector3; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.DamageSource; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public class EntityLaserExploder extends Entity { + + // persistent properties + // (none) + + // computed properties + private int lastUpdateTicks = 0; + private static final int UPDATE_TICKS_TIMEOUT = 20; + + public EntityLaserExploder(final World world) { + super(world); + + if (WarpDriveConfig.LOGGING_WEAPON) { + WarpDrive.logger.info(String.format("%s created in dimension %s", + this, Commons.format(world))); + } + } + + public EntityLaserExploder(final World world, final BlockPos blockPos) { + this(world); + + setPosition(blockPos.getX() + 0.5D, blockPos.getY() + 0.5D, blockPos.getZ() + 0.5D); + } + + // override to skip the block bounding override on client side + @SideOnly(Side.CLIENT) + @Override + public void setPositionAndRotation(final double x, final double y, final double z, final float yaw, final float pitch) { + // super.setPositionAndRotation(x, y, z, yaw, pitch); + this.setPosition(x, y, z); + this.setRotation(yaw, pitch); + } + + @Override + public boolean isEntityInvulnerable(@Nonnull final DamageSource source) { + return true; + } + + @Override + public void onUpdate() { + if (world.isRemote) { + return; + } + + lastUpdateTicks++; + if (lastUpdateTicks > UPDATE_TICKS_TIMEOUT) { + setDead(); + } + } + + @Override + protected void entityInit() { + noClip = true; + } + + @Override + public float getEyeHeight() { + return 2.0F; + } + + @Override + public void setDead() { + super.setDead(); + if (WarpDriveConfig.LOGGING_WEAPON) { + WarpDrive.logger.info(this + " dead"); + } + } + + @Override + protected void readEntityFromNBT(@Nonnull final NBTTagCompound tagCompound) { + } + + @Override + protected void writeEntityToNBT(@Nonnull final NBTTagCompound tagCompound) { + } + + @Nonnull + @Override + public NBTTagCompound writeToNBT(@Nonnull final NBTTagCompound compound) { + return super.writeToNBT(compound); + } + + // prevent saving entity to chunk + @Override + public boolean writeToNBTAtomically(@Nonnull final NBTTagCompound tagCompound) { + return false; + } + + // prevent saving entity to chunk + @Override + public boolean writeToNBTOptional(@Nonnull final NBTTagCompound tagCompound) { + return false; + } + + @Nonnull + @Override + public String toString() { + return String.format("%s/%d %s", + getClass().getSimpleName(), + getEntityId(), + Commons.format(world, posX, posY, posZ)); + } +} \ No newline at end of file