Integrated particle accelerator (wip)
This commit is contained in:
parent
0e79638d74
commit
29155a1b99
16 changed files with 1624 additions and 39 deletions
|
@ -10,7 +10,7 @@ import cr0s.warpdrive.block.TileEntityLaser;
|
|||
import cr0s.warpdrive.block.TileEntityLaserMedium;
|
||||
import cr0s.warpdrive.block.TileEntitySecurityStation;
|
||||
import cr0s.warpdrive.block.atomic.BlockAcceleratorControlPoint;
|
||||
import cr0s.warpdrive.block.atomic.BlockAcceleratorController;
|
||||
import cr0s.warpdrive.block.atomic.BlockAcceleratorCore;
|
||||
import cr0s.warpdrive.block.atomic.BlockChiller;
|
||||
import cr0s.warpdrive.block.atomic.BlockElectromagnetGlass;
|
||||
import cr0s.warpdrive.block.atomic.BlockElectromagnetPlain;
|
||||
|
@ -226,7 +226,7 @@ public class WarpDrive {
|
|||
public static ItemComponent itemComponent;
|
||||
|
||||
// atomic blocks and items
|
||||
public static Block blockAcceleratorController;
|
||||
public static Block blockAcceleratorCore;
|
||||
public static Block blockAcceleratorControlPoint;
|
||||
public static Block blockParticlesCollider;
|
||||
public static Block blockParticlesInjector;
|
||||
|
@ -395,7 +395,7 @@ public class WarpDrive {
|
|||
|
||||
// atomic blocks and items
|
||||
if (WarpDriveConfig.ACCELERATOR_ENABLE) {
|
||||
blockAcceleratorController = new BlockAcceleratorController("accelerator_core", EnumTier.BASIC);
|
||||
blockAcceleratorCore = new BlockAcceleratorCore("accelerator_core", EnumTier.BASIC);
|
||||
blockAcceleratorControlPoint = new BlockAcceleratorControlPoint("accelerator_control_point", EnumTier.BASIC, false);
|
||||
blockParticlesCollider = new BlockParticlesCollider("particles_collider", EnumTier.BASIC);
|
||||
blockParticlesInjector = new BlockParticlesInjector("particles_injector", EnumTier.BASIC);
|
||||
|
@ -1006,7 +1006,7 @@ public class WarpDrive {
|
|||
event.getRegistry().register(block);
|
||||
}
|
||||
|
||||
GameRegistry.registerTileEntity(TileEntityAcceleratorController.class, new ResourceLocation(WarpDrive.MODID, "accelerator_controller"));
|
||||
GameRegistry.registerTileEntity(TileEntityAcceleratorController.class, new ResourceLocation(WarpDrive.MODID, "accelerator_core"));
|
||||
GameRegistry.registerTileEntity(TileEntityAcceleratorControlPoint.class, new ResourceLocation(WarpDrive.MODID, "accelerator_control_point"));
|
||||
GameRegistry.registerTileEntity(TileEntityAirGeneratorTiered.class, new ResourceLocation(WarpDrive.MODID, "air_generator"));
|
||||
GameRegistry.registerTileEntity(TileEntityCamera.class, new ResourceLocation(WarpDrive.MODID, "camera"));
|
||||
|
|
|
@ -12,12 +12,12 @@ import net.minecraft.world.World;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class BlockAcceleratorController extends BlockAbstractContainer {
|
||||
public class BlockAcceleratorCore extends BlockAbstractContainer {
|
||||
|
||||
public BlockAcceleratorController(final String registryName, final EnumTier enumTier) {
|
||||
public BlockAcceleratorCore(final String registryName, final EnumTier enumTier) {
|
||||
super(registryName, enumTier, Material.IRON);
|
||||
|
||||
setTranslationKey("warpdrive.atomic.accelerator_controller");
|
||||
setTranslationKey("warpdrive.atomic.accelerator_core");
|
||||
|
||||
setDefaultState(getDefaultState()
|
||||
.withProperty(BlockProperties.ACTIVE, false)
|
File diff suppressed because it is too large
Load diff
|
@ -5,6 +5,7 @@ import cr0s.warpdrive.WarpDrive;
|
|||
import cr0s.warpdrive.api.IBlockBase;
|
||||
import cr0s.warpdrive.api.IItemBase;
|
||||
import cr0s.warpdrive.block.breathing.BlockColorAirShield;
|
||||
import cr0s.warpdrive.entity.EntityParticleBunch;
|
||||
import cr0s.warpdrive.event.ClientHandler;
|
||||
import cr0s.warpdrive.event.ModelBakeEventHandler;
|
||||
import cr0s.warpdrive.event.TooltipHandler;
|
||||
|
@ -19,6 +20,9 @@ import net.minecraft.block.properties.IProperty;
|
|||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -28,6 +32,8 @@ import net.minecraftforge.client.model.ModelLoader;
|
|||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.client.model.obj.OBJLoader;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.client.registry.IRenderFactory;
|
||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||
|
||||
public class ClientProxy extends CommonProxy {
|
||||
|
||||
|
@ -40,6 +46,15 @@ public class ClientProxy extends CommonProxy {
|
|||
ModelLoaderRegistry.registerLoader(CustomModelLoaderProjector.INSTANCE);
|
||||
MinecraftForge.EVENT_BUS.register(ModelBakeEventHandler.INSTANCE);
|
||||
MinecraftForge.EVENT_BUS.register(SpriteManager.INSTANCE);
|
||||
|
||||
// entity rendering
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityParticleBunch.class, new IRenderFactory<EntityParticleBunch>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Render<Entity> createRenderFor(final RenderManager manager) {
|
||||
return new RenderEntityParticleBunch(manager);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,10 +77,6 @@ public class ClientProxy extends CommonProxy {
|
|||
MinecraftForge.EVENT_BUS.register(new RenderOverlayLocation());
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new ClientCameraHandler());
|
||||
|
||||
// entity rendering
|
||||
// RenderingRegistry.registerEntityRenderingHandler(EntityParticleBunch.class, new RenderEntityParticleBunch());
|
||||
// @TODO MC1.10 force field rendering
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -901,7 +901,7 @@ public class Recipes {
|
|||
|
||||
// Accelerator controller
|
||||
WarpDrive.register(new ShapedOreRecipe(groupMachines,
|
||||
new ItemStack(WarpDrive.blockAcceleratorController), "MmM", "mcm", "MmM",
|
||||
new ItemStack(WarpDrive.blockAcceleratorCore), "MmM", "mcm", "MmM",
|
||||
'M', ItemComponent.getItemStack(EnumComponentType.MEMORY_CRYSTAL),
|
||||
'm', "blockElectromagnet1",
|
||||
'c', WarpDrive.blockAcceleratorControlPoint));
|
||||
|
|
|
@ -17,6 +17,7 @@ import cr0s.warpdrive.block.energy.BlockCapacitor;
|
|||
import cr0s.warpdrive.block.energy.TileEntityCapacitor;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -77,10 +78,11 @@ public class AcceleratorSetup extends GlobalPosition {
|
|||
public double[] temperatures_sustainEnergyCost_perTick = new double[3];
|
||||
public double particleEnergy_energyCost_perTick;
|
||||
|
||||
public AcceleratorSetup(final int dimensionId, final int x, final int y, final int z) {
|
||||
super(dimensionId, x, y, z);
|
||||
public AcceleratorSetup(final int dimensionId, @Nonnull final BlockPos blockPos) {
|
||||
super(dimensionId, blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
|
||||
LocalProfiler.start(String.format("[AcceleratorSetup] Scanning @ DIM%d (%d %d %d)", dimensionId, x, y, z));
|
||||
LocalProfiler.start(String.format("[AcceleratorSetup] Scanning @ DIM%d (%d %d %d)",
|
||||
dimensionId, x, y, z));
|
||||
|
||||
refresh();
|
||||
|
||||
|
@ -172,12 +174,12 @@ public class AcceleratorSetup extends GlobalPosition {
|
|||
private void fillTrajectoryPoints(final WorldServer world) {
|
||||
// find closest connected VoidShell
|
||||
Set<Block> whitelist = ImmutableSet.of(
|
||||
WarpDrive.blockElectromagnets_plain[0],
|
||||
WarpDrive.blockElectromagnets_glass[0],
|
||||
WarpDrive.blockElectromagnets_plain[1],
|
||||
WarpDrive.blockElectromagnets_glass[1],
|
||||
WarpDrive.blockElectromagnets_plain[2],
|
||||
WarpDrive.blockElectromagnets_glass[2],
|
||||
WarpDrive.blockElectromagnets_plain[3],
|
||||
WarpDrive.blockElectromagnets_glass[3],
|
||||
WarpDrive.blockVoidShellPlain,
|
||||
WarpDrive.blockVoidShellGlass);
|
||||
final Set<BlockPos> connections = Commons.getConnectedBlocks(world, new BlockPos(x, y, z), Commons.DIRECTIONS_ANY, whitelist, 3);
|
||||
|
@ -321,7 +323,9 @@ public class AcceleratorSetup extends GlobalPosition {
|
|||
for (final TrajectoryPoint trajectoryPoint : trajectoryAccelerator.values()) {
|
||||
// check for invalid setup
|
||||
if (trajectoryPoint.isJammed()) {
|
||||
setJammed.add(trajectoryPoint);
|
||||
setJammed.add(trajectoryPoint);
|
||||
WarpDrive.logger.info(String.format("Jammed point %s",
|
||||
trajectoryPoint ));
|
||||
}
|
||||
|
||||
// check for injectors
|
||||
|
|
428
src/main/java/cr0s/warpdrive/data/ParticleBunch.java
Normal file
428
src/main/java/cr0s/warpdrive/data/ParticleBunch.java
Normal file
|
@ -0,0 +1,428 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import cr0s.warpdrive.CommonProxy;
|
||||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.block.atomic.BlockVoidShellPlain;
|
||||
import cr0s.warpdrive.block.atomic.TileEntityAcceleratorController;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.entity.EntityParticleBunch;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
|
||||
public class ParticleBunch extends Vector3 {
|
||||
|
||||
private static final double RADIATION_RADIUS_VOID_PIPE = 2.1D;
|
||||
private static final double RADIATION_RADIUS_FREE_FLIGHT = 3.1D;
|
||||
private static final int FREE_FLIGHT_MAXIMUM_RANGE = 64;
|
||||
private static final double FREE_FLIGHT_ENERGY_FACTOR_PER_TICK = 0.997;
|
||||
private static final double SPEED_STEPS = 0.999D;
|
||||
|
||||
// persistent properties
|
||||
public int id;
|
||||
public double energy = TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_MINIMUM[0];
|
||||
public EnumFacing directionCurrentMotion = null;
|
||||
public Vector3 vectorCurrentMotion = new Vector3(0.0D, 0.0D, 0.0D);
|
||||
public Vector3 vectorTurningPoint = null;
|
||||
private int tickFreeFlight = 0;
|
||||
private Vector3 vectorFreeFlightStart = null;
|
||||
private VectorI vLastBlock = null;
|
||||
|
||||
// calculated properties
|
||||
private int entityId = -1;
|
||||
private TrajectoryPoint trajectoryPointCurrent = null;
|
||||
private boolean isDead = false;
|
||||
|
||||
public ParticleBunch(final int x, final int y, final int z, final EnumFacing directionCurrentMotion, final Vector3 vectorCurrentMotion) {
|
||||
super(x + 0.5D, y + 0.5D, z + 0.5D);
|
||||
this.id = (int) System.nanoTime();
|
||||
this.directionCurrentMotion = directionCurrentMotion;
|
||||
this.vectorCurrentMotion = vectorCurrentMotion;
|
||||
}
|
||||
|
||||
public ParticleBunch(final NBTTagCompound tagCompound) {
|
||||
super(0.0D, 0.0D, 0.0D);
|
||||
readFromNBT(tagCompound);
|
||||
}
|
||||
|
||||
public boolean onUpdate(final World world, final Map<Integer, AcceleratorControlParameter> mapParameters, final AcceleratorSetup acceleratorSetup) {
|
||||
// clear dead entities
|
||||
if (entityId >= 0) {
|
||||
final Entity entity = world.getEntityByID(entityId);
|
||||
if (entity == null || entity.isDead) {
|
||||
entityId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// compute speed
|
||||
double speed = getSpeedFromEnergy(energy);
|
||||
|
||||
// update position, 1 block at a time
|
||||
boolean isChunkLoaded = (speed > 0.0D);
|
||||
while (!isDead && speed > 0.0D) {
|
||||
isChunkLoaded = isChunkLoaded && moveForward(world, mapParameters, acceleratorSetup, Math.min(SPEED_STEPS, speed));
|
||||
speed -= SPEED_STEPS;
|
||||
}
|
||||
|
||||
// create and remove entity as needed
|
||||
Entity entity = null;
|
||||
if (entityId < 0 && isChunkLoaded && !isDead) {
|
||||
entity = new EntityParticleBunch(world, x, y, z);
|
||||
entityId = entity.getEntityId();
|
||||
world.spawnEntity(entity);
|
||||
} else if (entityId > 0) {
|
||||
entity = world.getEntityByID(entityId);
|
||||
if (entity == null) {
|
||||
entityId = -1;
|
||||
} else if (!isChunkLoaded || isDead) {
|
||||
entity.setDead();
|
||||
entity = null;
|
||||
entityId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// update entity
|
||||
if (entity instanceof EntityParticleBunch) {
|
||||
final EntityParticleBunch entityParticleBunch = (EntityParticleBunch) entity;
|
||||
entityParticleBunch.onRefreshFromSimulation(energy, this, vectorTurningPoint);
|
||||
|
||||
// apply radiation
|
||||
doIrradiation(world,
|
||||
tickFreeFlight > 0 ? RADIATION_RADIUS_FREE_FLIGHT : RADIATION_RADIUS_VOID_PIPE,
|
||||
tickFreeFlight > 0 ? 3.0F : 1.0F);
|
||||
}
|
||||
|
||||
return !isDead;
|
||||
}
|
||||
|
||||
public void onCollided(final World world, final TrajectoryPoint trajectoryPointCollider) {
|
||||
// ignore if there's no entity
|
||||
if (entityId < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get entity
|
||||
final Entity entity = world.getEntityByID(entityId);
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// update entity position to collider center
|
||||
if (entity instanceof EntityParticleBunch) {
|
||||
final EntityParticleBunch entityParticleBunch = (EntityParticleBunch) entity;
|
||||
x = trajectoryPointCollider.x + 0.5D;
|
||||
y = trajectoryPointCollider.y + 0.5D;
|
||||
z = trajectoryPointCollider.z + 0.5D;
|
||||
entityParticleBunch.onRefreshFromSimulation(energy, this, vectorTurningPoint);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean moveForward(final World world, final Map<Integer, AcceleratorControlParameter> mapParameters, final AcceleratorSetup acceleratorSetup, final double speed) {
|
||||
// get current position
|
||||
final VectorI vCurrentBlock = new VectorI((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z));
|
||||
final boolean isNewBlock = (vLastBlock == null || vLastBlock.x != vCurrentBlock.x || vLastBlock.z != vCurrentBlock.z);
|
||||
if (trajectoryPointCurrent == null) {
|
||||
trajectoryPointCurrent = (acceleratorSetup == null) ? null : acceleratorSetup.getTrajectoryPoint(vCurrentBlock);
|
||||
}
|
||||
|
||||
// get current tier
|
||||
final int tier = trajectoryPointCurrent == null ? 0 : trajectoryPointCurrent.getTier();
|
||||
|
||||
// apply magnets only once per passage
|
||||
if ( tier > 0
|
||||
&& trajectoryPointCurrent.hasNoMissingVoidShells()
|
||||
&& isNewBlock ) {
|
||||
// validate energy level
|
||||
if ( energy >= TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_MINIMUM[tier - 1]
|
||||
&& energy <= TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_MAXIMUM[tier - 1]) {
|
||||
// linear accelerate
|
||||
final int countMagnets = trajectoryPointCurrent.getMagnetsCount();
|
||||
final double energy_before = energy;
|
||||
energy *= 1.0D + countMagnets * TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_FACTOR_PER_MAGNET[tier - 1];
|
||||
energy = Math.min(energy, TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_MAXIMUM[tier - 1]);
|
||||
if (WarpDriveConfig.LOGGING_ACCELERATOR && WarpDrive.isDev) {
|
||||
WarpDrive.logger.info(String.format(this + " accelerating by %d magnets energy %.5f -> %.5f at [%d %d %d]",
|
||||
countMagnets, energy_before, energy, vCurrentBlock.x, vCurrentBlock.y, vCurrentBlock.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check control point
|
||||
final int controlChannel = trajectoryPointCurrent == null ? -1 : trajectoryPointCurrent.controlChannel;
|
||||
final boolean enableControlPoint;
|
||||
if (tier > 0 && controlChannel >= 0) {
|
||||
final AcceleratorControlParameter acceleratorControlParameter = mapParameters.get(controlChannel);
|
||||
final double threshold = (acceleratorControlParameter == null ? WarpDriveConfig.ACCELERATOR_THRESHOLD_DEFAULT : acceleratorControlParameter.threshold);
|
||||
enableControlPoint = energy > threshold
|
||||
* TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_MAXIMUM[tier - 1];
|
||||
if (enableControlPoint && WarpDriveConfig.LOGGING_ACCELERATOR) {
|
||||
WarpDrive.logger.info(String.format(this + " control point enabled at [%d %d %d]",
|
||||
vCurrentBlock.x, vCurrentBlock.y, vCurrentBlock.z));
|
||||
}
|
||||
} else {
|
||||
enableControlPoint = false;
|
||||
}
|
||||
|
||||
// get new orientation and turning point, as applicable
|
||||
EnumFacing directionNewMotion = null;
|
||||
Vector3 vectorNewMotion = null;
|
||||
Vector3 vectorNewTurningPoint = null;
|
||||
boolean isTurning = false;
|
||||
if (trajectoryPointCurrent != null) {
|
||||
// recover from free flight => boom
|
||||
if (tickFreeFlight != 0 || vectorFreeFlightStart != null) {
|
||||
doExplosion(world, "Re-entry");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!trajectoryPointCurrent.isTransferPipe()) {
|
||||
if (enableControlPoint) {
|
||||
vectorNewMotion = trajectoryPointCurrent.getJunctionOut(directionCurrentMotion);
|
||||
if (vectorNewMotion != null) {
|
||||
directionNewMotion = directionCurrentMotion;
|
||||
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
|
||||
WarpDrive.logger.info(String.format(this + " approaching tier %d transfer towards %s %s",
|
||||
tier, directionNewMotion, vectorNewMotion));
|
||||
}
|
||||
} else if (WarpDriveConfig.LOGGING_ACCELERATOR) {
|
||||
WarpDrive.logger.info(String.format(this + " ignoring output junction in other direction",
|
||||
tier, directionNewMotion, vectorNewMotion));
|
||||
}
|
||||
}
|
||||
|
||||
if (!enableControlPoint || vectorNewMotion == null) {
|
||||
directionNewMotion = trajectoryPointCurrent.getTurnedDirection(directionCurrentMotion);
|
||||
if (directionNewMotion != null) {
|
||||
vectorNewMotion = new Vector3(directionNewMotion);
|
||||
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
|
||||
WarpDrive.logger.info(String.format(this + " approaching tier %d turn towards %s %s",
|
||||
tier, directionNewMotion, vectorNewMotion));
|
||||
}
|
||||
isTurning = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
} else {// in a transfer trajectory
|
||||
if (enableControlPoint) {
|
||||
directionNewMotion = trajectoryPointCurrent.getJunctionIn(vectorCurrentMotion);
|
||||
if (directionNewMotion != null) {
|
||||
vectorNewMotion = new Vector3(directionNewMotion);
|
||||
}
|
||||
}
|
||||
/**/
|
||||
}
|
||||
|
||||
// when changing direction, compute the turning point
|
||||
if (vectorNewMotion != null) {
|
||||
// default to center of block
|
||||
vectorNewTurningPoint = new Vector3(vCurrentBlock.x + 0.5D, vCurrentBlock.y + 0.5D, vCurrentBlock.z + 0.5D);
|
||||
// adjust if it's not a straight 90 deg turn (i.e. it's a 45 deg turn)
|
||||
if (Math.abs(vectorNewMotion.x) != 1.0D && Math.abs(vectorNewMotion.z) != 1.0D) {
|
||||
vectorNewTurningPoint.translateFactor(vectorCurrentMotion, -0.5D);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
final IBlockState blockStateCurrent = vCurrentBlock.getBlockState(world);
|
||||
final Block blockCurrent = blockStateCurrent.getBlock();
|
||||
if (!(blockCurrent instanceof BlockVoidShellPlain)) {
|
||||
if (vectorFreeFlightStart == null) {
|
||||
vectorFreeFlightStart = new Vector3(x, y, z);
|
||||
} else if (distanceTo_square(vectorFreeFlightStart) > FREE_FLIGHT_MAXIMUM_RANGE * FREE_FLIGHT_MAXIMUM_RANGE) {
|
||||
doExplosion(world, "Out of range");
|
||||
return false;
|
||||
}
|
||||
tickFreeFlight++;
|
||||
if (!blockCurrent.isAir(blockStateCurrent, world, vCurrentBlock.getBlockPos())) {
|
||||
if (blockStateCurrent.isOpaqueCube()) {
|
||||
doExplosion(world, "Opaque cube");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
energy *= FREE_FLIGHT_ENERGY_FACTOR_PER_TICK;
|
||||
}
|
||||
}
|
||||
|
||||
// move forward
|
||||
double speedAdjusted = speed;
|
||||
Vector3 vectorOldPosition = new Vector3(x, y, z);
|
||||
Vector3 vectorNewPosition = new Vector3(x + speedAdjusted * vectorCurrentMotion.x,
|
||||
y + speedAdjusted * vectorCurrentMotion.y,
|
||||
z + speedAdjusted * vectorCurrentMotion.z);
|
||||
if (vectorNewTurningPoint != null) {
|
||||
// rollback if it's a new block so we recover the turning point in case we overshoot last time
|
||||
if (isNewBlock) {
|
||||
vectorOldPosition = new Vector3(x - vectorCurrentMotion.x, y - vectorCurrentMotion.y, z - vectorCurrentMotion.z);
|
||||
speedAdjusted += 1.0D;
|
||||
}
|
||||
|
||||
// is the turning point ahead of us?
|
||||
final Vector3 vectorOffset = vectorNewTurningPoint.clone().subtract(vectorOldPosition);
|
||||
if (vectorOffset.x * vectorCurrentMotion.x >= 0.0D && vectorOffset.z * vectorCurrentMotion.z >= 0.0D) {
|
||||
// did we just pass the turning point?
|
||||
final Vector3 vectorAfter = vectorNewTurningPoint.clone().subtract(vectorNewPosition);
|
||||
if (vectorAfter.x * vectorCurrentMotion.x <= 0.0D && vectorAfter.z * vectorCurrentMotion.z <= 0.0D) {
|
||||
// adjust position after the turn
|
||||
final double distanceLeft = speedAdjusted - vectorOffset.getMagnitude();
|
||||
vectorNewPosition = vectorNewTurningPoint.clone().translateFactor(vectorNewMotion, distanceLeft);
|
||||
|
||||
// adjust speed
|
||||
if (isTurning) {
|
||||
// @TODO
|
||||
final double energy_before = energy;
|
||||
// final double energyMin = TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_MINIMUM[tier - 1];
|
||||
// energy = energyMin + (energy - energyMin) * TileEntityAcceleratorController.ACCELERATOR_PARTICLE_ENERGY_TURN_COEFFICIENTS[tier - 1];
|
||||
final double energyMin = TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_MINIMUM[tier - 1];
|
||||
final double energyMax = TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_MAXIMUM[tier - 1];
|
||||
energy = Commons.clamp(energyMin, energyMax, energy * Commons.interpolate(
|
||||
new double[] { energyMin, energyMax },
|
||||
new double[] { TileEntityAcceleratorController.PARTICLE_BUNCH_TURN_COEFFICIENTS_AT_MIN_ENERGY[tier - 1], TileEntityAcceleratorController.PARTICLE_BUNCH_TURN_COEFFICIENTS_AT_MAX_ENERGY[tier - 1] },
|
||||
energy));
|
||||
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
|
||||
WarpDrive.logger.info(String.format(this + " turning energy %.5f -> %.5f at [%d %d %d]",
|
||||
energy_before, energy, vCurrentBlock.x, vCurrentBlock.y, vCurrentBlock.z));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// cancel turning
|
||||
directionNewMotion = null;
|
||||
vectorNewMotion = null;
|
||||
vectorNewTurningPoint = null;
|
||||
}
|
||||
|
||||
} else {
|
||||
// cancel turning
|
||||
directionNewMotion = null;
|
||||
vectorNewMotion = null;
|
||||
vectorNewTurningPoint = null;
|
||||
}
|
||||
}
|
||||
|
||||
// update properties
|
||||
vLastBlock = vCurrentBlock.clone();
|
||||
final VectorI vNewBlock = new VectorI((int) vectorNewPosition.x, (int) vectorNewPosition.y, (int) vectorNewPosition.z);
|
||||
if (vNewBlock != vCurrentBlock) {
|
||||
trajectoryPointCurrent = null;
|
||||
}
|
||||
if (directionNewMotion != null) {
|
||||
directionCurrentMotion = directionNewMotion;
|
||||
vectorCurrentMotion = vectorNewMotion;
|
||||
vectorTurningPoint = vectorNewTurningPoint;
|
||||
} else {
|
||||
vectorTurningPoint = null;
|
||||
}
|
||||
x = vectorNewPosition.x;
|
||||
y = vectorNewPosition.y;
|
||||
z = vectorNewPosition.z;
|
||||
|
||||
return Commons.isChunkLoaded(world, vCurrentBlock.x, vCurrentBlock.z)
|
||||
&& ( vCurrentBlock == vNewBlock
|
||||
|| Commons.isChunkLoaded(world, vNewBlock.x, vNewBlock.z) );
|
||||
}
|
||||
|
||||
private static double getSpeedFromEnergy(final double energy) {
|
||||
return Commons.interpolate(
|
||||
TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_TO_SPEEDS_X,
|
||||
TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_TO_SPEEDS_Y,
|
||||
energy);
|
||||
}
|
||||
|
||||
private void doIrradiation(final World world, final double radius, final float strength) {
|
||||
final AxisAlignedBB axisAlignedBB = new AxisAlignedBB(
|
||||
x + 0.5D - radius, y + 0.5D - radius, z + 0.5D - radius,
|
||||
x + 0.5D + radius, y + 0.5D + radius, z + 0.5D + radius);
|
||||
final List<EntityLivingBase> listEntityLivingBase = world.getEntitiesWithinAABB(EntityLivingBase.class, axisAlignedBB);
|
||||
for (final EntityLivingBase entityLivingBase : listEntityLivingBase) {
|
||||
WarpDrive.damageIrradiation.onEntityEffect(strength, world, this, entityLivingBase);
|
||||
}
|
||||
}
|
||||
|
||||
private void doExplosion(final World world, final String reason) {
|
||||
WarpDrive.logger.info(String.format("Particle bunch explosion due to %s %s",
|
||||
reason, Commons.format(world, x, y, z) ));
|
||||
if (world instanceof WorldServer) {
|
||||
final double explosionStrength = Commons.interpolate(
|
||||
TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_TO_EXPLOSION_STRENGTH_X,
|
||||
TileEntityAcceleratorController.PARTICLE_BUNCH_ENERGY_TO_EXPLOSION_STRENGTH_Y,
|
||||
energy);
|
||||
final EntityPlayer entityPlayer = CommonProxy.getFakePlayer(null, (WorldServer) world, getBlockPos());
|
||||
world.newExplosion(entityPlayer, x, y, z, (float) explosionStrength, true, true);
|
||||
doIrradiation(world, explosionStrength, (float) explosionStrength);
|
||||
isDead = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(final NBTTagCompound tagCompound) {
|
||||
super.readFromNBT(tagCompound);
|
||||
id = tagCompound.getInteger("id");
|
||||
try {
|
||||
directionCurrentMotion = EnumFacing.valueOf(tagCompound.getString("direction"));
|
||||
} catch (final Exception exception) {
|
||||
WarpDrive.logger.error(String.format("Invalid direction %s in ParticleBunch NBT %s", tagCompound.getString("direction"), tagCompound));
|
||||
}
|
||||
vectorCurrentMotion = Vector3.createFromNBT(tagCompound.getCompoundTag("vector"));
|
||||
energy = tagCompound.getDouble("energy");
|
||||
|
||||
tickFreeFlight = tagCompound.getInteger("freeFlight_ticks");
|
||||
if (tagCompound.hasKey("freeFlightStart")) {
|
||||
vectorFreeFlightStart = Vector3.createFromNBT(tagCompound.getCompoundTag("freeFlightStart"));
|
||||
} else {
|
||||
vectorFreeFlightStart = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(final NBTTagCompound tagCompound) {
|
||||
super.writeToNBT(tagCompound);
|
||||
tagCompound.setInteger("id", id);
|
||||
tagCompound.setString("direction", directionCurrentMotion.name());
|
||||
tagCompound.setTag("vector", vectorCurrentMotion.writeToNBT(new NBTTagCompound()));
|
||||
tagCompound.setDouble("energy", energy);
|
||||
|
||||
tagCompound.setInteger("freeFlight_ticks", tickFreeFlight);
|
||||
if (vectorFreeFlightStart != null) {
|
||||
tagCompound.setTag("freeFlightStart", vectorFreeFlightStart.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
return tagCompound;
|
||||
}
|
||||
|
||||
// Hash based collections need a stable hashcode, so we use a unique id instead
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
if (object instanceof ParticleBunch) {
|
||||
final ParticleBunch particleBunch = (ParticleBunch) object;
|
||||
return id == particleBunch.id && x == particleBunch.x && y == particleBunch.y && z == particleBunch.z;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s/%d @ (%.2f %.2f %.2f) energy %.5f",
|
||||
getClass().getSimpleName(),
|
||||
entityId,
|
||||
x, y, z,
|
||||
energy);
|
||||
}
|
||||
}
|
|
@ -572,7 +572,7 @@ public class StarMapRegistry {
|
|||
case WARP_ECHO:
|
||||
break;
|
||||
case ACCELERATOR:
|
||||
isValid = block == WarpDrive.blockAcceleratorController && tileEntity != null && !tileEntity.isInvalid();
|
||||
isValid = block == WarpDrive.blockAcceleratorCore && tileEntity != null && !tileEntity.isInvalid();
|
||||
break;
|
||||
case TRANSPORTER:
|
||||
isValid = block == WarpDrive.blockTransporterCore && tileEntity != null && !tileEntity.isInvalid();
|
||||
|
|
|
@ -110,7 +110,7 @@ public class TrajectoryPoint extends VectorI {
|
|||
|
||||
// get main blocks
|
||||
final EnumFacing directionLeft = directionMain.rotateY();
|
||||
final EnumFacing directionRight = directionLeft.rotateYCCW();
|
||||
final EnumFacing directionRight = directionMain.rotateYCCW();
|
||||
final Block blockForward = world.getBlockState(blockPos.offset(directionMain)).getBlock();
|
||||
final Block blockUp = world.getBlockState(blockPos.up()).getBlock();
|
||||
final Block blockDown = world.getBlockState(blockPos.down()).getBlock();
|
||||
|
|
|
@ -255,8 +255,8 @@ tile.warpdrive.machines.laser_medium.superior.name=Superior Lasermedium
|
|||
|
||||
tile.warpdrive.machines.security_station.name=Security Station
|
||||
|
||||
tile.warpdrive.atomic.accelerator_controller.name=Beschleunigungsregler
|
||||
tile.warpdrive.atomic.accelerator_controller.tooltip=Regelt einen oder mehrere Teilchenbeschleuniger.\nSollte neben einem Elektromagnet platziert werden.
|
||||
tile.warpdrive.atomic.accelerator_core.name=Beschleunigungsregler
|
||||
tile.warpdrive.atomic.accelerator_core.tooltip=Regelt einen oder mehrere Teilchenbeschleuniger.\nSollte neben einem Elektromagnet platziert werden.
|
||||
tile.warpdrive.atomic.accelerator_control_point.name=Beschleuniger Kontrollpunkt
|
||||
tile.warpdrive.atomic.accelerator_control_point.tooltip=Regele Beschleuniger Knotenpunkte wie Collider, Input und Output.\nSollte genau einen Block neben einer Void Shell platziert werden.\nSpeichere Erzeugnisse in jedem direkt verbundenen Speicher.
|
||||
tile.warpdrive.atomic.chiller.basic.name=Standard Kühler
|
||||
|
|
|
@ -255,8 +255,8 @@ tile.warpdrive.machines.laser_medium.superior.name=Superior Laser Medium
|
|||
|
||||
tile.warpdrive.machines.security_station.name=Security Station
|
||||
|
||||
tile.warpdrive.atomic.accelerator_controller.name=Accelerator Controller
|
||||
tile.warpdrive.atomic.accelerator_controller.tooltip=Controls one or more particle accelerators.\nShall be placed next to an electromagnet.
|
||||
tile.warpdrive.atomic.accelerator_core.name=Accelerator Core
|
||||
tile.warpdrive.atomic.accelerator_core.tooltip=Controls one or more particle accelerators.\nShall be placed next to an electromagnet.
|
||||
tile.warpdrive.atomic.accelerator_control_point.name=Accelerator control point
|
||||
tile.warpdrive.atomic.accelerator_control_point.tooltip=Control accelerator nodes like collider, input and output.\nShall be placed exactly 1 block away from a void shell.\nStore results in any directly connected storage.
|
||||
tile.warpdrive.atomic.chiller.basic.name=Basic Chiller
|
||||
|
|
|
@ -255,8 +255,8 @@ tile.warpdrive.machines.laser_medium.superior.name=Milieu amplificateur supérie
|
|||
|
||||
tile.warpdrive.machines.security_station.name=Station de sécurité
|
||||
|
||||
tile.warpdrive.atomic.accelerator_controller.name=Controlleur d'accélérateurs
|
||||
tile.warpdrive.atomic.accelerator_controller.tooltip=Contrôle un ou plusieurs accélérateurs de particules.\nDoit être placé à coté d'un électroaimant.
|
||||
tile.warpdrive.atomic.accelerator_core.name=Noyau d'accélérateurs
|
||||
tile.warpdrive.atomic.accelerator_core.tooltip=Contrôle un ou plusieurs accélérateurs de particules.\nDoit être placé à coté d'un électroaimant.
|
||||
tile.warpdrive.atomic.accelerator_control_point.name=Point de contrôle d'accélérateur
|
||||
tile.warpdrive.atomic.accelerator_control_point.tooltip=Contrôle un noeud de l'accélérateur tel que collisionneur, entrée et sortie.\nDoit être placé à exactement 1 block de distance d'une coquille sous vide.\nStocke les résultats dans tout conteneur directement connecté.
|
||||
tile.warpdrive.atomic.chiller.basic.name=Refroidisseur élémentaire
|
||||
|
|
|
@ -255,8 +255,8 @@ tile.warpdrive.machines.laser_medium.superior.name=Superieure Deeltjesversneller
|
|||
|
||||
tile.warpdrive.machines.security_station.name=Security Station
|
||||
|
||||
tile.warpdrive.atomic.accelerator_controller.name=Versnellers-regelaar
|
||||
tile.warpdrive.atomic.accelerator_controller.tooltip=Regelt één of meer deeltjesversnellers.\nMoet naast een elektromagneet worden geplaats.
|
||||
tile.warpdrive.atomic.accelerator_core.name=Versnellers-regelaar
|
||||
tile.warpdrive.atomic.accelerator_core.tooltip=Regelt één of meer deeltjesversnellers.\nMoet naast een elektromagneet worden geplaats.
|
||||
tile.warpdrive.atomic.accelerator_control_point.name=Versnellings-regelaars punt
|
||||
tile.warpdrive.atomic.accelerator_control_point.tooltip=Reguleer versnellingsknooppunten zoals de deeltjesbotser, input en output.\nSMoet exact op een afstand van 1 blok van een void shell staan.\nSlaat de resultaten op naar een direct aangesloten opslag.
|
||||
tile.warpdrive.atomic.chiller.basic.name=Normale Koeler
|
||||
|
|
|
@ -255,8 +255,8 @@ tile.warpdrive.machines.laser_medium.superior.name=Superior Лазерный и
|
|||
|
||||
tile.warpdrive.machines.security_station.name=Security Station
|
||||
|
||||
tile.warpdrive.atomic.accelerator_controller.name=Accelerator Controller
|
||||
tile.warpdrive.atomic.accelerator_controller.tooltip=Controls one or more particle accelerators.\nShall be placed next to an electromagnet.
|
||||
tile.warpdrive.atomic.accelerator_core.name=Accelerator Core
|
||||
tile.warpdrive.atomic.accelerator_core.tooltip=Controls one or more particle accelerators.\nShall be placed next to an electromagnet.
|
||||
tile.warpdrive.atomic.accelerator_control_point.name=Accelerator control point
|
||||
tile.warpdrive.atomic.accelerator_control_point.tooltip=Control accelerator nodes like collider, input and output.\nShall be placed exactly 1 block away from a void shell.\nStore results in any directly connected storage.
|
||||
tile.warpdrive.atomic.chiller.basic.name=Basic Chiller
|
||||
|
|
|
@ -260,8 +260,8 @@ tile.warpdrive.machines.laser_medium.superior.name=Superior 激光介质
|
|||
|
||||
tile.warpdrive.machines.security_station.name=Security Station
|
||||
|
||||
tile.warpdrive.atomic.accelerator_controller.name=加速器操纵仪
|
||||
tile.warpdrive.atomic.accelerator_controller.tooltip=操纵一或多个粒子加速器.\n需要连接电磁体.
|
||||
tile.warpdrive.atomic.accelerator_core.name=加速器操纵仪
|
||||
tile.warpdrive.atomic.accelerator_core.tooltip=操纵一或多个粒子加速器.\n需要连接电磁体.
|
||||
tile.warpdrive.atomic.accelerator_control_point.name=加速器控制点
|
||||
tile.warpdrive.atomic.accelerator_control_point.tooltip=控制加速器上的对撞机、输入、输出等节点.\n需要贴真空腔放置.\n会将产物存入任何相连存储设施.
|
||||
tile.warpdrive.atomic.chiller.basic.name=基础冷却器
|
||||
|
|
|
@ -255,8 +255,8 @@ tile.warpdrive.machines.laser_medium.superior.name=Superior 鐳射單元
|
|||
|
||||
tile.warpdrive.machines.security_station.name=Security Station
|
||||
|
||||
tile.warpdrive.atomic.accelerator_controller.name=Accelerator Controller
|
||||
tile.warpdrive.atomic.accelerator_controller.tooltip=Controls one or more particle accelerators.\nShall be placed next to an electromagnet.
|
||||
tile.warpdrive.atomic.accelerator_core.name=Accelerator Core
|
||||
tile.warpdrive.atomic.accelerator_core.tooltip=Controls one or more particle accelerators.\nShall be placed next to an electromagnet.
|
||||
tile.warpdrive.atomic.accelerator_control_point.name=Accelerator control point
|
||||
tile.warpdrive.atomic.accelerator_control_point.tooltip=Control accelerator nodes like collider, input and output.\nShall be placed exactly 1 block away from a void shell.\nStore results in any directly connected storage.
|
||||
tile.warpdrive.atomic.chiller.basic.name=Basic Chiller
|
||||
|
|
Loading…
Reference in a new issue