Refactored assembly validation & starmap registration

Added anti-highjacking an assembled enantiomorphic reactor
Added jammed particles on injector with no connected inventory
Fixed bad multi-threading in accelerator core
Improved LUA API consistency, renaming isAssemblyValid to getAssemblyStatus
Improved response time when removing a stabilization laser obstacle
This commit is contained in:
Unknown 2019-06-10 22:27:58 +02:00 committed by unknown
parent 56c98ab9b9
commit 95dd55a9c8
39 changed files with 1291 additions and 912 deletions

View file

@ -6,5 +6,7 @@ public interface IMachine extends IInterfaced {
Object[] enable(final Object[] arguments);
Object[] isAssemblyValid();
Object[] getAssemblyStatus();
boolean isAssemblyValid();
}

View file

@ -1,14 +1,21 @@
package cr0s.warpdrive.block;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IStarMapRegistryTileEntity;
import cr0s.warpdrive.api.computer.ICoreSignature;
import cr0s.warpdrive.api.computer.IEnergyConsumer;
import cr0s.warpdrive.api.computer.IMultiBlockCoreOrController;
import cr0s.warpdrive.api.computer.IMultiBlockCore;
import cr0s.warpdrive.config.WarpDriveConfig;
import javax.annotation.Nonnull;
import java.util.UUID;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public abstract class TileEntityAbstractEnergyCoreOrController extends TileEntityAbstractEnergyConsumer implements IMultiBlockCoreOrController, IEnergyConsumer {
@ -16,7 +23,10 @@ public abstract class TileEntityAbstractEnergyCoreOrController extends TileEntit
public UUID uuid = null;
// computed properties
// (none)
private boolean isDirtyParameters = true;
private int tickUpdateParameters = 0;
private boolean isDirtyStarMapEntry = true;
private int tickUpdateStarMapEntry = 0;
public TileEntityAbstractEnergyCoreOrController() {
super();
@ -26,6 +36,80 @@ public abstract class TileEntityAbstractEnergyCoreOrController extends TileEntit
// });
}
@Override
public void update() {
super.update();
if (world.isRemote) {
return;
}
// update operational parameters when dirty or periodically to recover whatever may have desynchronized them
if (isDirtyParameters) {
tickUpdateParameters = 0;
}
tickUpdateParameters--;
if (tickUpdateParameters <= 0) {
tickUpdateParameters = WarpDriveConfig.G_PARAMETERS_UPDATE_INTERVAL_TICKS;
final boolean isDirty = isDirtyParameters;
isDirtyParameters = false;
doUpdateParameters(isDirty);
}
// update starmap registry upon request or periodically to recover whatever may have desynchronized it
if (this instanceof IStarMapRegistryTileEntity) {
if (isDirtyStarMapEntry) {
tickUpdateStarMapEntry = 0;
}
tickUpdateStarMapEntry--;
if (tickUpdateStarMapEntry <= 0) {
tickUpdateStarMapEntry = WarpDriveConfig.STARMAP_REGISTRY_UPDATE_INTERVAL_TICKS;
final boolean isDirty = isDirtyStarMapEntry;
isDirtyStarMapEntry = false;
doRegisterStarMapEntry(isDirty);
}
}
}
public boolean isDirtyParameters() {
return isDirtyParameters;
}
protected void markDirtyParameters() {
isDirtyParameters = true;
}
protected abstract void doUpdateParameters(final boolean isDirty);
public boolean isDirtyStarMapEntry() {
return isDirtyStarMapEntry;
}
protected void markDirtyStarMapEntry() {
assert this instanceof IStarMapRegistryTileEntity;
isDirtyStarMapEntry = true;
}
protected void doRegisterStarMapEntry(final boolean isDirty) {
if (uuid == null || (uuid.getMostSignificantBits() == 0 && uuid.getLeastSignificantBits() == 0)) {
uuid = UUID.randomUUID();
}
WarpDrive.starMap.updateInRegistry((IStarMapRegistryTileEntity) this);
}
@Override
public void onBlockBroken(@Nonnull final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
if ( !world.isRemote
&& this instanceof IStarMapRegistryTileEntity ) {
WarpDrive.starMap.removeFromRegistry((IStarMapRegistryTileEntity) this);
}
super.onBlockBroken(world, blockPos, blockState);
}
@Override
public void onCoreUpdated(@Nonnull final IMultiBlockCore multiblockCore) {
assert multiblockCore instanceof TileEntityAbstractEnergyCoreOrController;

View file

@ -1,5 +1,6 @@
package cr0s.warpdrive.block;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.api.computer.IAbstractLaser;
@ -35,11 +36,6 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractEnergyBa
protected long cache_laserMedium_energyStored = 0L;
protected long cache_laserMedium_maxStorage = 0L;
private final int updateInterval_slow_ticks = 20 * WarpDriveConfig.SHIP_CONTROLLER_UPDATE_INTERVAL_SECONDS;
protected int updateInterval_ticks = updateInterval_slow_ticks;
private int updateTicks = updateInterval_ticks;
private int bootTicks = 20;
public TileEntityAbstractLaser() {
super();
@ -52,35 +48,9 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractEnergyBa
}
@Override
protected void onFirstUpdateTick() {
super.onFirstUpdateTick();
updateLaserMediumDirection();
}
@Override
public void update() {
super.update();
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
final boolean isValid = super.doScanAssembly(isDirty, textReason);
if (world.isRemote) {
return;
}
// accelerate update ticks during boot
if (bootTicks > 0) {
bootTicks--;
if (laserMedium_direction == null) {
updateTicks = 1;
}
}
updateTicks--;
if (updateTicks <= 0) {
updateTicks = updateInterval_ticks;
updateLaserMediumDirection();
}
}
private void updateLaserMediumDirection() {
assert laserMedium_maxCount != 0;
for (final EnumFacing facing : laserMedium_directionsValid) {
@ -120,7 +90,7 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractEnergyBa
cache_laserMedium_factor = Math.max(1.0D, count * WarpDriveConfig.LASER_MEDIUM_FACTOR_BY_TIER[enumTier.getIndex()]);
cache_laserMedium_energyStored = energyStored;
cache_laserMedium_maxStorage = maxStorage;
return;
return isValid;
}
}
}
@ -131,6 +101,9 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractEnergyBa
cache_laserMedium_factor = 0.0D;
cache_laserMedium_energyStored = 0;
cache_laserMedium_maxStorage = 0;
textReason.append(Commons.styleWarning, "warpdrive.laser.status_line.missing_laser_medium",
Commons.format(laserMedium_directionsValid) );
return false;
}
public int laserMedium_getEnergyStored(final boolean isCached) {
@ -243,14 +216,6 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractEnergyBa
return new Object[] { cache_laserMedium_count };
}
@Override
public Object[] isAssemblyValid() {
if (laserMedium_direction == null) {
return new Object[] { false, "No laser medium detected" };
}
return super.isAssemblyValid();
}
@Override
protected WarpDriveText getEnergyStatusText() {
final WarpDriveText text = new WarpDriveText();

View file

@ -2,6 +2,7 @@ package cr0s.warpdrive.block;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.api.computer.ICoreSignature;
import cr0s.warpdrive.api.computer.IMachine;
import cr0s.warpdrive.config.WarpDriveConfig;
@ -27,6 +28,12 @@ public abstract class TileEntityAbstractMachine extends TileEntityAbstractInterf
public String name = "";
protected boolean isEnabled = true;
// computed properties
private boolean isDirtyAssembly = true;
private int tickScanAssembly = 0;
protected boolean isAssemblyValid = true;
protected WarpDriveText textValidityIssues = new WarpDriveText(Commons.styleWarning, "unknown");
// allow only one computation at a time
protected static final AtomicBoolean isGlobalThreadRunning = new AtomicBoolean(false);
// computation is ongoing for this specific tile
@ -41,16 +48,83 @@ public abstract class TileEntityAbstractMachine extends TileEntityAbstractInterf
addMethods(new String[] {
"name",
"enable",
"isAssemblyValid"
"getAssemblyStatus"
});
}
@Override
protected void onFirstUpdateTick() {
super.onFirstUpdateTick();
doScanAssembly(true);
}
@Override
public void update() {
super.update();
if (world.isRemote) {
return;
}
// scan the assembly after a block update was detected or periodically to recover whatever may have desynchronized it
if (isDirtyAssembly) {
tickScanAssembly = Math.min(10, tickScanAssembly);
}
tickScanAssembly--;
if (tickScanAssembly <= 0) {
tickScanAssembly = WarpDriveConfig.G_ASSEMBLY_SCAN_INTERVAL_TICKS;
final boolean isDirty = isDirtyAssembly;
isDirtyAssembly = false;
doScanAssembly(isDirty);
}
}
public boolean isDirtyAssembly() {
return isDirtyAssembly;
}
public void markDirtyAssembly() {
isDirtyAssembly = true;
}
private void doScanAssembly(final boolean isDirty) {
if (world.isRemote) {
return;
}
final WarpDriveText textReason = new WarpDriveText();
final boolean isValid = doScanAssembly(isDirty, textReason);
if (!isValid && textReason.isEmpty()) {
textReason.append(Commons.styleWarning, "unknown");
WarpDrive.logger.warn(String.format("Unknown assembly status %s %s, please report to mod author",
this, Commons.format(world, pos) ));
}
isAssemblyValid = isValid;
textValidityIssues = textReason;
}
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
return true;
}
@Override
public WarpDriveText getStatus() {
final WarpDriveText textStatus = super.getStatus();
if ( world != null
&& !textValidityIssues.isEmpty() ) {
textStatus.append(textValidityIssues);
}
return textStatus;
}
public boolean isCalculated() {
return !isDirty.get() && !isThreadRunning.get();
}
protected boolean calculation_start() {
if ((!world.isRemote) && (boolean) isAssemblyValid()[0]) {
assert !world.isRemote;
if (isAssemblyValid) {
if (!isGlobalThreadRunning.getAndSet(true)) {
isThreadRunning.set(true);
isDirty.set(false);
@ -169,8 +243,16 @@ public abstract class TileEntityAbstractMachine extends TileEntityAbstractInterf
}
@Override
public Object[] isAssemblyValid() {
return new Object[] { true, "ok" };
public Object[] getAssemblyStatus() {
if (isAssemblyValid && textValidityIssues.isEmpty()) {
return new Object[] { isAssemblyValid, "ok" };
}
return new Object[] { isAssemblyValid, Commons.removeFormatting( textValidityIssues.getUnformattedText() ) };
}
@Override
public boolean isAssemblyValid() {
return isAssemblyValid;
}
// OpenComputers callback methods
@ -188,9 +270,9 @@ public abstract class TileEntityAbstractMachine extends TileEntityAbstractInterf
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] isAssemblyValid(final Context context, final Arguments arguments) {
public Object[] getAssemblyStatus(final Context context, final Arguments arguments) {
OC_convertArgumentsAndLogCall(context, arguments);
return isAssemblyValid();
return getAssemblyStatus();
}
// ComputerCraft IPeripheral methods
@ -204,8 +286,8 @@ public abstract class TileEntityAbstractMachine extends TileEntityAbstractInterf
case "enable":
return enable(arguments);
case "isAssemblyValid":
return isAssemblyValid();
case "getAssemblyStatus":
return getAssemblyStatus();
}
return super.CC_callMethod(methodName, arguments);

View file

@ -55,6 +55,7 @@ import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.FakePlayer;
@ -115,14 +116,10 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
public UUID uuid = null;
// computed properties
private final int registryUpdateInterval_ticks = 20 * WarpDriveConfig.STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS;
private int registryUpdateTicks = 0;
private int cooldownTicks;
private int guideTicks;
protected boolean isPowered = true;
private AcceleratorSetup cache_acceleratorSetup;
private boolean isBlockUpdated = false;
private AcceleratorSetup acceleratorSetup;
public TileEntityAcceleratorCore() {
@ -158,6 +155,8 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
return;
}
assert acceleratorSetup != null;
// update counters
if (cooldownTicks > 0) {
cooldownTicks--;
@ -166,17 +165,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
guideTicks--;
}
// Update starmap registry
registryUpdateTicks--;
if (registryUpdateTicks <= 0) {
registryUpdateTicks = registryUpdateInterval_ticks;
if (uuid == null || (uuid.getMostSignificantBits() == 0 && uuid.getLeastSignificantBits() == 0)) {
uuid = UUID.randomUUID();
}
// recover registration, shouldn't be needed, in theory...
WarpDrive.starMap.updateInRegistry(this);
}
// Evaluate current state
final int tierCurrentTemperature;
if (temperatureCurrent_K <= WarpDriveConfig.ACCELERATOR_TEMPERATURES_K[1]) {
@ -188,7 +176,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
}
// Powered ?
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
reportJammed(acceleratorSetup);
int energyRequired;
@ -204,7 +191,7 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
final int energyPotential = acceleratorSetup.energy_getPotentialOutput();
isPowered = energyRequired > 0 && energyPotential >= energyRequired;
final boolean isEnabledAndValid = isEnabled && isValid();
final boolean isEnabledAndValid = isEnabled && isAssemblyValid;
final boolean isOn = isEnabledAndValid && cooldownTicks <= 0 && isPowered;
updateBlockState(null, BlockProperties.ACTIVE, isOn);
if (isOn) {
@ -249,7 +236,7 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
injectionTicks = injectionPeriodTicks;
final int countInjectors = acceleratorSetup.keyInjectors.length;
if (indexNextInjector < countInjectors) {
onInject(acceleratorSetup.keyInjectors[indexNextInjector]);
onInject(acceleratorSetup.mapInjectors.get(acceleratorSetup.keyInjectors[indexNextInjector]));
} else {
// invalid setup => force a reset
rebootAccelerator(acceleratorSetup,false, true);
@ -333,10 +320,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
}
}
public boolean isValid() {
return true;
}
boolean isOn() {
return legacy_isOn;
}
@ -398,26 +381,32 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
}
// inject a particle bunch
private boolean onInject(final int controlChannel) {
final VectorI vInjector = getAcceleratorSetup().mapInjectors.get(controlChannel);
if (vInjector == null) {
return false;
}
if (setParticleBunches.size() >= WarpDriveConfig.ACCELERATOR_MAX_PARTICLE_BUNCHES) {
return false;
}
private void onInject(@Nonnull final VectorI vInjector) {
assert setParticleBunches.size() < WarpDriveConfig.ACCELERATOR_MAX_PARTICLE_BUNCHES;
final TileEntity tileEntity = vInjector.getTileEntity(world);
if ( !(tileEntity instanceof TileEntityParticlesInjector)
|| !((TileEntityParticlesInjector) tileEntity).getIsEnabled() ) {
return false;
if (!(tileEntity instanceof TileEntityParticlesInjector)) {
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
WarpDrive.logger.info(String.format("%s Unable to inject with missing injector %s %s",
this, tileEntity, Commons.format(world, pos) ));
}
markDirtyAssembly();
return;
}
if (!((TileEntityParticlesInjector) tileEntity).getIsEnabled()) {
return;
}
// find consumable
final Collection<Object> inventories = InventoryWrapper.getConnectedInventories(tileEntity.getWorld(), tileEntity.getPos());
if (inventories.isEmpty()) {
return false;
PacketHandler.sendSpawnParticlePacket(world, "jammed", (byte) 5,
new Vector3(pos),
new Vector3(0.0D, 0.0D, 0.0D),
1.0F, 1.0F, 1.0F,
1.0F, 1.0F, 1.0F,
32);
return;
}
int slotIndex = 0;
@ -451,7 +440,7 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
WarpDrive.logger.debug(this + " No valid item found to inject");
}
return false;
return;
}
//noinspection ConstantConditions
assert(found);
@ -489,7 +478,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
// 0.20F + 0.10F * world.rand.nextFloat(), 0.90F + 0.10F * world.rand.nextFloat(), 0.40F + 0.15F * world.rand.nextFloat(),
0.0F, 0.0F, 0.0F, 32);
sendEvent("particleBunchInjected");
return true;
}
// simulate a particle bunch
@ -687,7 +675,7 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
// WarpDrive.logger.info(this + " rebootAccelerator");
registryUpdateTicks = 1;
markDirtyStarMapEntry();
updateChillers(acceleratorSetup, false, false, isChunkLoading);
legacy_isOn = false;
if (isLeaking) {
@ -805,48 +793,59 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
}
@Override
public void validate() {
super.validate();
if (world.isRemote) {
return;
public void onBlockBroken(@Nonnull final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
if (!world.isRemote) {
if (acceleratorSetup == null) {
final WarpDriveText textAssemblyValid = new WarpDriveText();
doScanAssembly(true, textAssemblyValid);
}
rebootAccelerator(acceleratorSetup, true, true);
}
WarpDrive.starMap.updateInRegistry(this);
super.onBlockBroken(world, blockPos, blockState);
}
@Override
public void invalidate() {
if (!world.isRemote) {
rebootAccelerator(cache_acceleratorSetup != null ? cache_acceleratorSetup : getAcceleratorSetup(), true, true);
WarpDrive.starMap.removeFromRegistry(this);
}
super.invalidate();
}
public AcceleratorSetup getAcceleratorSetup() {
final AcceleratorSetup legacy_acceleratorSetup = cache_acceleratorSetup;
if ( isBlockUpdated
|| cache_acceleratorSetup == null
|| (!cache_acceleratorSetup.isValid() && cooldownTicks <= 0) ) {
cache_acceleratorSetup = new AcceleratorSetup(world.provider.getDimension(), pos);
if (!cache_acceleratorSetup.isValid()) {
cooldownTicks = ACCELERATOR_COOLDOWN_TICKS;
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
final boolean isValid = super.doScanAssembly(isDirty, textReason);
final AcceleratorSetup legacy_acceleratorSetup = acceleratorSetup;
if ( isDirty
|| acceleratorSetup == null
|| acceleratorSetup.isDirty() ) {
acceleratorSetup = new AcceleratorSetup(world.provider.getDimension(), pos);
if (!acceleratorSetup.getAssemblyStatus(textReason)) {
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
WarpDrive.logger.info(String.format("%s invalid accelerator setup: %s",
this, textReason.getUnformattedText() ));
}
// don't return false, so the player can still enable the accelerator "at their own risk"
} else {
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
WarpDrive.logger.info(String.format("%s valid accelerator setup",
this ));
}
}
} else {
acceleratorSetup.getAssemblyStatus(textReason);
}
// reset accelerator in case of major changes
if (isBlockUpdated) {
isBlockUpdated = false;
if (cache_acceleratorSetup.isMajorChange(legacy_acceleratorSetup)) {
if (isDirty) {
if (acceleratorSetup.isMajorChange(legacy_acceleratorSetup)) {
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
WarpDrive.logger.info(this + " rebooting due to major change...");
}
rebootAccelerator(legacy_acceleratorSetup != null ? legacy_acceleratorSetup : cache_acceleratorSetup, true, true);
rebootAccelerator(legacy_acceleratorSetup != null ? legacy_acceleratorSetup : acceleratorSetup, true, true);
}
sendEvent("acceleratorUpdated");
}
return cache_acceleratorSetup;
return isValid;
}
@Override
protected void doUpdateParameters(final boolean isDirty) {
// no operation
}
@Override
@ -854,7 +853,9 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
if (!hasWorld()) {
return 0;
}
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
if (acceleratorSetup == null) {
return 0;
}
return acceleratorSetup.energy_getEnergyStored();
}
@ -863,7 +864,9 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
if (!hasWorld()) {
return 0;
}
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
if (acceleratorSetup == null) {
return 0;
}
return acceleratorSetup.energy_getMaxStorage();
}
@ -924,8 +927,11 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
// Common OC/CC methods
@Override
public Object[] getEnergyRequired() {
if (acceleratorSetup == null) {
return new Object[] { 0, 0, 0, 0 };
}
final String units = energy_getDisplayUnits();
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
final long energyCoolingCost_perTick = EnergyWrapper.convert(Math.round( acceleratorSetup.temperature_coolingEnergyCost_perTick
+ acceleratorSetup.particleEnergy_energyCost_perTick * 0.1D ), units);
@ -954,7 +960,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
}
private Object[] getControlPoints() {
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
if (acceleratorSetup != null) {
return acceleratorSetup.getControlPoints(world);
}
@ -962,7 +967,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
}
private Object[] getControlPointsCount() {
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
if (acceleratorSetup != null) {
final Object[] controlPoints = acceleratorSetup.getControlPoints(world);
return new Integer[] { controlPoints.length };
@ -972,7 +976,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
@Nonnull
private Object[] getControlPoint(@Nonnull final Object[] arguments) {
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
if (acceleratorSetup == null) {
return new Object[] { false, "No accelerator setup" };
}
@ -1084,7 +1087,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
}
private Object[] state() {
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
final String units = energy_getDisplayUnits();
final long energy = EnergyWrapper.convert(acceleratorSetup.energy_getEnergyStored(), units);
final String status = getStatusHeaderInPureText();
@ -1140,7 +1142,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
@Override
public AxisAlignedBB getStarMapArea() {
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
if (acceleratorSetup == null) {
return null;
}
@ -1149,7 +1150,6 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
@Override
public int getMass() {
final AcceleratorSetup acceleratorSetup = getAcceleratorSetup();
if (acceleratorSetup != null) {
return acceleratorSetup.getMass();
}
@ -1169,7 +1169,7 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
@Override
public void onBlockUpdatedInArea(final VectorI vector, final IBlockState blockState) {
// skip in case of explosion, etc.
if (isBlockUpdated) {
if (isDirtyAssembly()) {
return;
}
@ -1177,7 +1177,7 @@ public class TileEntityAcceleratorCore extends TileEntityAbstractEnergyCoreOrCon
// (we don't check the controller itself: it'll be triggered in invalidate() and we don't want to reevaluate the setup at that point)
if ( blockState.getBlock() instanceof BlockAbstractAccelerator
|| blockState.getBlock() instanceof BlockCapacitor ) {
isBlockUpdated = true;
markDirtyAssembly();
return;
}
if (WarpDriveConfig.LOGGING_ACCELERATOR) {

View file

@ -274,7 +274,7 @@ public class TileEntityShipScanner extends TileEntityAbstractMachine implements
tileEntityShipCore = (TileEntityShipCore) world.getTileEntity(mutableBlockPos);
if (tileEntityShipCore != null) {
if (!tileEntityShipCore.isValid()) { // If we can't refresh ship's spatial parameters
if (!tileEntityShipCore.isAssemblyValid()) { // If we can't refresh ship's spatial parameters
tileEntityShipCore = null;
} else {
break;
@ -287,7 +287,7 @@ public class TileEntityShipScanner extends TileEntityAbstractMachine implements
}
private boolean saveShipToSchematic(final String fileName, final WarpDriveText reason) {
if (!shipCore.isValid()) {
if (!shipCore.isAssemblyValid()) {
return false;
}
final short width = (short) (shipCore.maxX - shipCore.minX + 1);

View file

@ -33,6 +33,7 @@ public class BlockCloakingCoil extends BlockAbstractBase {
setTranslationKey("warpdrive.detection.cloaking_coil");
setDefaultState(getDefaultState()
.withProperty(BlockProperties.CONNECTED, false)
.withProperty(BlockProperties.ACTIVE, false)
.withProperty(OUTER, false)
.withProperty(BlockProperties.FACING, EnumFacing.DOWN)
@ -42,37 +43,48 @@ public class BlockCloakingCoil extends BlockAbstractBase {
@Nonnull
@Override
protected BlockStateContainer createBlockState() {
return new BlockStateContainer(this, BlockProperties.ACTIVE, OUTER, BlockProperties.FACING);
return new BlockStateContainer(this, BlockProperties.CONNECTED, BlockProperties.ACTIVE, OUTER, BlockProperties.FACING);
}
@SuppressWarnings("deprecation")
@Nonnull
@Override
public IBlockState getStateFromMeta(final int metadata) {
// 15 = not used
// 9-14 = active, outer facing
// 8 = active, inner
// 7 = not used
// 1-6 = outer facing
// 0 = inner
// 10-15 = connected, active, outer (facing)
// 9 = connected, active, inner, down
// 8 = not used (disconnected, active, down)
// 2-7 = connected, outer, (facing)
// 1 = connected, inner, down
// 0 = idle (disconnected, inactive, down)
final boolean isActive = (metadata & 0x8) != 0;
final boolean isOuter = (metadata & 0x7) > 0;
final boolean isConnected = (metadata & 0x7) > 0;
final boolean isOuter = (metadata & 0x7) > 1;
return getDefaultState()
.withProperty(BlockProperties.ACTIVE, isActive)
.withProperty(OUTER, isOuter)
.withProperty(BlockProperties.FACING, isOuter ? EnumFacing.byIndex((metadata & 0x7) - 1) : EnumFacing.DOWN);
.withProperty(BlockProperties.CONNECTED, isConnected)
.withProperty(BlockProperties.ACTIVE, isActive)
.withProperty(OUTER, isOuter)
.withProperty(BlockProperties.FACING, isOuter ? EnumFacing.byIndex((metadata & 0x7) - 2) : EnumFacing.DOWN);
}
@SuppressWarnings("deprecation")
@Override
public int getMetaFromState(@Nonnull final IBlockState blockState) {
return (blockState.getValue(BlockProperties.ACTIVE) ? 8 : 0)
+ (blockState.getValue(OUTER) ? 1 + blockState.getValue(BlockProperties.FACING).ordinal() : 0);
if (blockState.getValue(BlockProperties.CONNECTED)) {
return (blockState.getValue(BlockProperties.ACTIVE) ? 8 : 0)
+ (blockState.getValue(OUTER) ? 2 + blockState.getValue(BlockProperties.FACING).ordinal() : 1);
} else if ( !blockState.getValue(OUTER)
&& blockState.getValue(BlockProperties.FACING) == EnumFacing.DOWN ) {
return 0;
} else {
return 8;
}
}
public static void setBlockState(@Nonnull final World world, @Nonnull final BlockPos blockPos, final boolean isActive, final boolean isOuter, final EnumFacing enumFacing) {
public static void setBlockState(@Nonnull final World world, @Nonnull final BlockPos blockPos,
final boolean isConnected, final boolean isActive, final boolean isOuter, final EnumFacing enumFacing) {
final IBlockState blockStateActual = world.getBlockState(blockPos);
IBlockState blockStateNew = blockStateActual.withProperty(BlockProperties.ACTIVE, isActive).withProperty(OUTER, isOuter);
IBlockState blockStateNew = blockStateActual.withProperty(BlockProperties.CONNECTED, isConnected)
.withProperty(BlockProperties.ACTIVE, isActive)
.withProperty(OUTER, isOuter);
if (enumFacing != null) {
blockStateNew = blockStateNew.withProperty(BlockProperties.FACING, enumFacing);
}

View file

@ -11,7 +11,6 @@ import net.minecraft.block.material.Material;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockCloakingCore extends BlockAbstractContainer {
@ -50,16 +49,4 @@ public class BlockCloakingCore extends BlockAbstractContainer {
public TileEntity createNewTileEntity(@Nonnull final World world, final int metadata) {
return new TileEntityCloakingCore();
}
@Override
public void breakBlock(@Nonnull final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
final TileEntity tileEntity = world.getTileEntity(blockPos);
if (tileEntity instanceof TileEntityCloakingCore) {
((TileEntityCloakingCore) tileEntity).setIsEnabled(false);
((TileEntityCloakingCore) tileEntity).disableCloakingField();
}
super.breakBlock(world, blockPos, blockState);
}
}

View file

@ -3,7 +3,7 @@ package cr0s.warpdrive.block.detection;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.block.TileEntityAbstractEnergyConsumer;
import cr0s.warpdrive.block.TileEntityAbstractEnergyCoreOrController;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.BlockProperties;
import cr0s.warpdrive.data.CloakedArea;
@ -13,6 +13,7 @@ import cr0s.warpdrive.data.SoundEvents;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.network.PacketHandler;
import javax.annotation.Nonnull;
import java.util.Arrays;
import net.minecraft.block.state.IBlockState;
@ -22,8 +23,9 @@ import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.MutableBlockPos;
import net.minecraft.world.World;
public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
public class TileEntityCloakingCore extends TileEntityAbstractEnergyCoreOrController {
private static final int CLOAKING_CORE_SOUND_UPDATE_TICKS = 40;
private static final int DISTANCE_INNER_COILS_BLOCKS = 2;
@ -35,7 +37,8 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
private static final float[] innerCoilColor_g = { 0.00f, 0.25f, 0.75f, 1.00f, 1.00f, 1.00f, 1.00f, 1.00f, 0.50f, 0.25f, 0.00f, 0.00f };
private static final float[] innerCoilColor_b = { 0.25f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.50f, 1.00f, 1.00f, 1.00f, 1.00f, 0.75f };
// Spatial cloaking field parameters
// computed properties
// spatial cloaking field parameters
private final boolean[] isValidInnerCoils = { false, false, false, false, false, false };
private final int[] distanceOuterCoils_blocks = { 0, 0, 0, 0, 0, 0 }; // 0 means invalid
private int minX = 0;
@ -45,8 +48,6 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
private int maxY = 0;
private int maxZ = 0;
private boolean isValid = false;
private WarpDriveText textValidityIssues = new WarpDriveText();
private boolean isFullyTransparent = false;
private boolean isCloaking = false;
private int volume = 0;
@ -61,9 +62,7 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
super();
peripheralName = "warpdriveCloakingCore";
addMethods(new String[] {
"isAssemblyValid"
});
// addMethods(new String[] {});
CC_scripts = Arrays.asList("enable", "disable");
setUpgradeMaxCount(EnumComponentType.DIAMOND_CRYSTAL, 1);
@ -100,117 +99,265 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
isFullyTransparent = hasUpgrade(EnumComponentType.DIAMOND_CRYSTAL);
updateTicks = ((!isFullyTransparent) ? 20 : 10) * WarpDriveConfig.CLOAKING_FIELD_REFRESH_INTERVAL_SECONDS; // resetting timer
isRefreshNeeded = validateAssembly();
isCloaking = WarpDrive.cloaks.isAreaExists(world, pos);
if (!isEnabled) {// disabled
if (isCloaking) {// disabled, cloaking => stop cloaking
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info(this + " Disabled, cloak field going down...");
}
disableCloakingField();
final boolean hasEnoughPower = energy_consume(energyRequired, (!isAssemblyValid && isEnabled));
final boolean shouldBeCloaking = isAssemblyValid && isEnabled && hasEnoughPower;
if (!isCloaking) {
if (shouldBeCloaking) {// start cloaking
updateCoils(true, true);
isRefreshNeeded = true;
} else {// disabled, not cloaking
// IDLE
if (isRefreshNeeded) {
setCoilsState(false);
}
}
} else {// isEnabled
updateVolumeAndEnergyRequired();
final boolean hasEnoughPower = energy_consume(energyRequired, false);
if (!isCloaking) {// enabled, not cloaking
if (hasEnoughPower && isValid) {// enabled, can cloak and able to
setCoilsState(true);
isRefreshNeeded = true;
// register cloak
final CloakedArea area = WarpDrive.cloaks.updateCloakedArea(world, pos, isFullyTransparent,
minX, minY, minZ, maxX, maxY, maxZ);
if (!soundPlayed) {
soundPlayed = true;
world.playSound(null, pos, SoundEvents.CLOAK, SoundCategory.BLOCKS, 4F, 1F);
}
// start cloaking
area.sendCloakPacketToPlayersEx(false);
} else {// enabled, not cloaking and not able to
// IDLE
setCoilsState(false);
// register cloak
final CloakedArea area = WarpDrive.cloaks.updateCloakedArea(world, pos, isFullyTransparent,
minX, minY, minZ, maxX, maxY, maxZ);
if (!soundPlayed) {
soundPlayed = true;
world.playSound(null, pos, SoundEvents.CLOAK, SoundCategory.BLOCKS, 4F, 1F);
}
} else {// enabled & cloaking
if (!isValid) {// enabled, cloaking but invalid
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info(String.format("%s Coil(s) lost, cloak field is collapsing...", this));
}
energy_consume(energy_getEnergyStored());
disableCloakingField();
isRefreshNeeded = true;
} else {// enabled, cloaking and valid
if (hasEnoughPower) {// enabled, cloaking and able to
if (isRefreshNeeded) {
WarpDrive.cloaks.updateCloakedArea(world, pos, isFullyTransparent,
minX, minY, minZ, maxX, maxY, maxZ);
}
// IDLE
// Refresh the field (workaround to re-synchronize players since client may 'eat up' the packets)
final CloakedArea area = WarpDrive.cloaks.getCloakedArea(world, pos);
if (area != null) {
area.sendCloakPacketToPlayersEx(false); // re-cloak field
} else {
WarpDrive.logger.error(String.format("getCloakedArea2 returned null %s",
Commons.format(world, pos)));
}
setCoilsState(true);
} else {// loosing power
// start cloaking
area.sendCloakPacketToPlayersEx(false);
}
} else {// is cloaking
if (shouldBeCloaking) {// maintain cloaking
// Refresh the field (workaround to re-synchronize players since client may 'eat up' the packets)
final CloakedArea area = WarpDrive.cloaks.getCloakedArea(world, pos);
if (area == null) {
WarpDrive.logger.error(String.format("Cloaked area lost %s",
Commons.format(world, pos) ));
} else {
area.sendCloakPacketToPlayersEx(false); // re-cloak field
}
} else {// stop cloaking
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info(String.format("%s Disabled, cloak field going down...",
this ));
}
if (isEnabled) {// collapsing
if (!isAssemblyValid) {
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info(String.format("%s Low power, cloak field is collapsing...", this));
WarpDrive.logger.info(String.format("%s Coil(s) lost, cloak field is collapsing...",
this ));
}
energy_consume(energy_getEnergyStored());
} else if (!hasEnoughPower) {
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info(String.format("%s Low power, cloak field is collapsing...",
this ));
}
disableCloakingField();
isRefreshNeeded = true;
}
}
updateCoils(true, false);
disableCloakingField();
}
}
}
}
laserDrawingTicks--;
if (isRefreshNeeded || laserDrawingTicks < 0) {
if (isRefreshNeeded || laserDrawingTicks <= 0) {
laserDrawingTicks = LASER_REFRESH_TICKS;
if (isEnabled && isValid) {
if (isEnabled && isAssemblyValid) {
drawLasers();
}
}
}
private void setCoilsState(final boolean enabled) {
updateBlockState(null, BlockProperties.ACTIVE, enabled);
@Override
public void onBlockBroken(@Nonnull final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
setIsEnabled(false);
updateCoils(false, false);
disableCloakingField();
super.onBlockBroken(world, blockPos, blockState);
}
@Override
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
boolean isValid = super.doScanAssembly(isDirty, textReason);
final int maxOuterCoilDistance = WarpDriveConfig.CLOAKING_MAX_FIELD_RADIUS - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
boolean isRefreshNeeded = false;
int countIntegrity = 1; // 1 for the core + 1 per coil
final StringBuilder messageInnerCoils = new StringBuilder();
final StringBuilder messageOuterCoils = new StringBuilder();
// Directions to check (all six directions: left, right, up, down, front, back)
for (final EnumFacing direction : EnumFacing.values()) {
// check validity of inner coil
BlockPos blockPos = new BlockPos(pos.offset(direction, DISTANCE_INNER_COILS_BLOCKS));
final boolean isInnerValid = world.getBlockState(blockPos).getBlock() instanceof BlockCloakingCoil;
if (isInnerValid) {
BlockCloakingCoil.setBlockState(world, blockPos, true, isCloaking, false, direction);
}
// whenever a change is detected, force a laser redraw
if (isInnerValid != isValidInnerCoils[direction.ordinal()]) {
isRefreshNeeded = true;
isValidInnerCoils[direction.ordinal()] = isInnerValid;
}
// update validity results
if (isValidInnerCoils[direction.ordinal()]) {
countIntegrity++;
} else {
if (messageInnerCoils.length() != 0) {
messageInnerCoils.append(", ");
}
messageInnerCoils.append(direction.name());
}
// find closest outer coil
int newCoilDistance = 0;
for (int distance = DISTANCE_INNER_COILS_BLOCKS + 1; distance < maxOuterCoilDistance; distance++) {
blockPos = blockPos.offset(direction);
if (world.getBlockState(blockPos).getBlock() instanceof BlockCloakingCoil) {
BlockCloakingCoil.setBlockState(world, blockPos, true, isCloaking, true, direction);
newCoilDistance = distance;
break;
}
}
// whenever a change is detected, disable previous outer coil if it was valid and force a laser redraw
final int oldCoilDistance = distanceOuterCoils_blocks[direction.ordinal()];
if (newCoilDistance != oldCoilDistance) {
if (oldCoilDistance > 0) {
final BlockPos blockPosOld = pos.offset(direction, oldCoilDistance);
if (world.getBlockState(blockPosOld).getBlock() instanceof BlockCloakingCoil) {
BlockCloakingCoil.setBlockState(world, blockPos, false, false, false, EnumFacing.DOWN);
}
}
isRefreshNeeded = true;
distanceOuterCoils_blocks[direction.ordinal()] = Math.max(0, newCoilDistance);
}
// update validity results
if (newCoilDistance > 0) {
countIntegrity++;
} else {
if (messageOuterCoils.length() != 0) {
messageOuterCoils.append(", ");
}
messageOuterCoils.append(direction.name());
}
}
// build status message
final float integrity = countIntegrity / 13.0F;
if (messageInnerCoils.length() > 0 && messageOuterCoils.length() > 0) {
textReason.append(Commons.styleWarning, "warpdrive.cloaking_core.missing_channeling_and_projecting_coils",
Math.round(100.0F * integrity), messageInnerCoils, messageOuterCoils);
} else if (messageInnerCoils.length() > 0) {
textReason.append(Commons.styleWarning, "warpdrive.cloaking_core.missing_channeling_coils",
Math.round(100.0F * integrity), messageInnerCoils);
} else if (messageOuterCoils.length() > 0) {
textReason.append(Commons.styleWarning, "warpdrive.cloaking_core.missing_projecting_coils",
Math.round(100.0F * integrity), messageOuterCoils);
} else {
textReason.append(Commons.styleCorrect, "warpdrive.cloaking_core.valid");
}
// Update cloaking field parameters defined by coils
isValid = isValid && countIntegrity >= 13;
minX = pos.getX() - distanceOuterCoils_blocks[4] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
maxX = pos.getX() + distanceOuterCoils_blocks[5] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
minY = Math.max( 0, pos.getY() - distanceOuterCoils_blocks[0] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS);
maxY = Math.min(255, pos.getY() + distanceOuterCoils_blocks[1] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS);
minZ = pos.getZ() - distanceOuterCoils_blocks[2] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
maxZ = pos.getZ() + distanceOuterCoils_blocks[3] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
// refresh cloaking area only when needed
if (isCloaking && isValid && isRefreshNeeded) {
WarpDrive.cloaks.updateCloakedArea(world, pos, isFullyTransparent,
minX, minY, minZ, maxX, maxY, maxZ);
}
// scan volume @TODO reuse ShipCore scanner for cloaking volume computation
if (isEnabled && isValid) {
updateVolumeAndEnergyRequired();
}
return isValid;
}
private void updateVolumeAndEnergyRequired() {
int x, y, z;
final int energyRequired_new;
int volume_new = 0;
final MutableBlockPos mutableBlockPos = new MutableBlockPos(pos);
if (!isFullyTransparent) {// partial transparency = gas and air blocks don't count
for (y = minY; y <= maxY; y++) {
for (x = minX; x <= maxX; x++) {
for (z = minZ; z <= maxZ; z++) {
mutableBlockPos.setPos(x, y, z);
if (!world.isAirBlock(mutableBlockPos)) {
volume_new++;
}
}
}
}
energyRequired_new = volume_new * WarpDriveConfig.CLOAKING_TIER1_ENERGY_PER_BLOCK;
} else {// full transparency = everything counts
for (y = minY; y <= maxY; y++) {
for (x = minX; x <= maxX; x++) {
for (z = minZ; z <= maxZ; z++) {
mutableBlockPos.setPos(x, y, z);
if (world.getBlockState(mutableBlockPos).getBlock() != Blocks.AIR) {
volume_new++;
}
}
}
}
energyRequired_new = volume_new * WarpDriveConfig.CLOAKING_TIER2_ENERGY_PER_BLOCK;
}
volume = volume_new;
energyRequired = energyRequired_new;
if (WarpDriveConfig.LOGGING_ENERGY) {
WarpDrive.logger.info(String.format("%s Requiring %d EU for %d blocks",
this, energyRequired, volume));
}
}
@Override
protected void doUpdateParameters(final boolean isDirty) {
}
private void updateCoils(final boolean isConnected, final boolean isActive) {
updateBlockState(null, BlockProperties.ACTIVE, isActive);
for (final EnumFacing direction : EnumFacing.VALUES) {
if (isValidInnerCoils[direction.ordinal()]) {
setCoilState(DISTANCE_INNER_COILS_BLOCKS, direction, enabled);
updateCoil(isConnected, isActive, direction, DISTANCE_INNER_COILS_BLOCKS);
}
if (distanceOuterCoils_blocks[direction.ordinal()] > 0) {
setCoilState(distanceOuterCoils_blocks[direction.ordinal()], direction, enabled);
updateCoil(isConnected, isActive, direction, distanceOuterCoils_blocks[direction.ordinal()]);
}
}
}
private void setCoilState(final int distance, final EnumFacing direction, final boolean enabled) {
final BlockPos blockPos = pos.offset(direction);
private void updateCoil(final boolean isConnected, final boolean isActive, final EnumFacing direction, final int distance) {
final BlockPos blockPos = pos.offset(direction, distance);
final IBlockState blockState = world.getBlockState(blockPos);
if (blockState.getBlock().isAssociatedBlock(WarpDrive.blockCloakingCoil)) {
if (distance == DISTANCE_INNER_COILS_BLOCKS) {
BlockCloakingCoil.setBlockState(world, blockPos, enabled, false, EnumFacing.UP);
if (blockState.getBlock() instanceof BlockCloakingCoil) {
if (isConnected) {
if (distance == DISTANCE_INNER_COILS_BLOCKS) {
BlockCloakingCoil.setBlockState(world, blockPos, true, isActive, false, EnumFacing.DOWN);
} else {
BlockCloakingCoil.setBlockState(world, blockPos, true, isActive, true, direction);
}
} else {
BlockCloakingCoil.setBlockState(world, blockPos, enabled, true, direction);
BlockCloakingCoil.setBlockState(world, blockPos, false, false, true, EnumFacing.DOWN);
}
}
}
@ -285,7 +432,6 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
}
public void disableCloakingField() {
setCoilsState(false);
if (WarpDrive.cloaks.isAreaExists(world, pos)) {
WarpDrive.cloaks.removeCloakedArea(world.provider.getDimension(), pos);
@ -296,142 +442,6 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
}
}
public void updateVolumeAndEnergyRequired() {
int x, y, z;
final int energyRequired_new;
int volume_new = 0;
final MutableBlockPos mutableBlockPos = new MutableBlockPos(pos);
if (!isFullyTransparent) {// partial transparency = gas and air blocks don't count
for (y = minY; y <= maxY; y++) {
for (x = minX; x <= maxX; x++) {
for (z = minZ; z <= maxZ; z++) {
mutableBlockPos.setPos(x, y, z);
if (!world.isAirBlock(mutableBlockPos)) {
volume_new++;
}
}
}
}
energyRequired_new = volume_new * WarpDriveConfig.CLOAKING_TIER1_ENERGY_PER_BLOCK;
} else {// full transparency = everything counts
for (y = minY; y <= maxY; y++) {
for (x = minX; x <= maxX; x++) {
for (z = minZ; z <= maxZ; z++) {
mutableBlockPos.setPos(x, y, z);
if (world.getBlockState(mutableBlockPos).getBlock() != Blocks.AIR) {
volume_new++;
}
}
}
}
energyRequired_new = volume_new * WarpDriveConfig.CLOAKING_TIER2_ENERGY_PER_BLOCK;
}
volume = volume_new;
energyRequired = energyRequired_new;
if (WarpDriveConfig.LOGGING_ENERGY) {
WarpDrive.logger.info(String.format("%s Requiring %d EU for %d blocks",
this, energyRequired, volume));
}
}
public boolean validateAssembly() {
final int maxOuterCoilDistance = WarpDriveConfig.CLOAKING_MAX_FIELD_RADIUS - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
boolean isRefreshNeeded = false;
int countIntegrity = 1; // 1 for the core + 1 per coil
final StringBuilder messageInnerCoils = new StringBuilder();
final StringBuilder messageOuterCoils = new StringBuilder();
// Directions to check (all six directions: left, right, up, down, front, back)
for (final EnumFacing direction : EnumFacing.values()) {
// check validity of inner coil
BlockPos blockPos = new BlockPos(pos.offset(direction, DISTANCE_INNER_COILS_BLOCKS));
final boolean isInnerValid = (world.getBlockState(blockPos).getBlock() == WarpDrive.blockCloakingCoil);
if (isInnerValid) {
BlockCloakingCoil.setBlockState(world, blockPos, true, false, direction);
}
// whenever a change is detected, force a laser redraw
if (isInnerValid != isValidInnerCoils[direction.ordinal()]) {
isRefreshNeeded = true;
isValidInnerCoils[direction.ordinal()] = isInnerValid;
}
// update validity results
if (isValidInnerCoils[direction.ordinal()]) {
countIntegrity++;
} else {
if (messageInnerCoils.length() != 0) {
messageInnerCoils.append(", ");
}
messageInnerCoils.append(direction.name());
}
// find closest outer coil
int newCoilDistance = 0;
for (int distance = DISTANCE_INNER_COILS_BLOCKS + 1; distance < maxOuterCoilDistance; distance++) {
blockPos = blockPos.offset(direction);
if (world.getBlockState(blockPos).getBlock() == WarpDrive.blockCloakingCoil) {
BlockCloakingCoil.setBlockState(world, blockPos, true, true, direction);
newCoilDistance = distance;
break;
}
}
// whenever a change is detected, disable previous outer coil if it was valid and force a laser redraw
final int oldCoilDistance = distanceOuterCoils_blocks[direction.ordinal()];
if (newCoilDistance != oldCoilDistance) {
if (oldCoilDistance > 0) {
final BlockPos blockPosOld = pos.offset(direction, oldCoilDistance);
if (world.getBlockState(blockPosOld).getBlock() == WarpDrive.blockCloakingCoil) {
BlockCloakingCoil.setBlockState(world, blockPos, false, false, EnumFacing.UP);
}
}
isRefreshNeeded = true;
distanceOuterCoils_blocks[direction.ordinal()] = Math.max(0, newCoilDistance);
}
// update validity results
if (newCoilDistance > 0) {
countIntegrity++;
} else {
if (messageOuterCoils.length() != 0) {
messageOuterCoils.append(", ");
}
messageOuterCoils.append(direction.name());
}
}
// build status message
final float integrity = countIntegrity / 13.0F;
if (messageInnerCoils.length() > 0 && messageOuterCoils.length() > 0) {
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.cloaking_core.missing_channeling_and_projecting_coils",
Math.round(100.0F * integrity), messageInnerCoils, messageOuterCoils);
} else if (messageInnerCoils.length() > 0) {
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.cloaking_core.missing_channeling_coils",
Math.round(100.0F * integrity), messageInnerCoils);
} else if (messageOuterCoils.length() > 0) {
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.cloaking_core.missing_projecting_coils",
Math.round(100.0F * integrity), messageOuterCoils);
} else {
textValidityIssues = new WarpDriveText(Commons.styleCorrect, "warpdrive.cloaking_core.valid");
}
// Update cloaking field parameters defined by coils
isValid = countIntegrity >= 13;
minX = pos.getX() - distanceOuterCoils_blocks[4] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
maxX = pos.getX() + distanceOuterCoils_blocks[5] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
minY = Math.max( 0, pos.getY() - distanceOuterCoils_blocks[0] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS);
maxY = Math.min(255, pos.getY() + distanceOuterCoils_blocks[1] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS);
minZ = pos.getZ() - distanceOuterCoils_blocks[2] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
maxZ = pos.getZ() + distanceOuterCoils_blocks[3] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
return isRefreshNeeded;
}
@Override
public WarpDriveText getStatusHeader() {
if (world == null) {
@ -439,7 +449,7 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
}
final WarpDriveText textStatus;
if (!isValid) {
if (!isAssemblyValid) {
textStatus = textValidityIssues;
} else if (!isEnabled) {
textStatus = new WarpDriveText(Commons.styleNormal, "warpdrive.cloaking_core.disabled",
@ -468,14 +478,6 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergyConsumer {
EnergyWrapper.convert((long) Math.ceil(energyRate), units) };
}
@Override
public Object[] isAssemblyValid() {
if (!isValid) {
return new Object[] { false, Commons.removeFormatting( textValidityIssues.getUnformattedText() ) };
}
return super.isAssemblyValid();
}
// OpenComputers callback methods
// (none)

View file

@ -1,7 +1,6 @@
package cr0s.warpdrive.block.energy;
import cr0s.warpdrive.block.BlockAbstractContainer;
import cr0s.warpdrive.data.ReactorFace;
import cr0s.warpdrive.data.EnumTier;
import cr0s.warpdrive.render.TileEntityEnanReactorCoreRenderer;
@ -10,7 +9,6 @@ import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
@ -71,22 +69,4 @@ public class BlockEnanReactorCore extends BlockAbstractContainer {
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityEnanReactorCore.class, new TileEntityEnanReactorCoreRenderer());
}
}
@Override
public void breakBlock(final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
super.breakBlock(world, blockPos, blockState);
for (final ReactorFace reactorFace : ReactorFace.getLasers(enumTier)) {
if (reactorFace.indexStability < 0) {
continue;
}
final TileEntity tileEntity = world.getTileEntity(blockPos.add(reactorFace.x, reactorFace.y, reactorFace.z));
if (tileEntity instanceof TileEntityEnanReactorLaser) {
if (((TileEntityEnanReactorLaser) tileEntity).getReactorFace() == reactorFace) {
((TileEntityEnanReactorLaser) tileEntity).setReactorFace(ReactorFace.UNKNOWN, null);
}
}
}
}
}

View file

@ -11,8 +11,6 @@ import javax.annotation.Nonnull;
import java.lang.ref.WeakReference;
import java.util.Collections;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fml.common.Optional;
public class TileEntityEnanReactorController extends TileEntityAbstractEnergyCoreOrController implements IEnanReactorController {
@ -39,31 +37,10 @@ public class TileEntityEnanReactorController extends TileEntityAbstractEnergyCor
});
CC_scripts = Collections.singletonList("startup");
}
private TileEntityEnanReactorCore findCoreBlock() {
TileEntity tileEntity;
tileEntity = world.getTileEntity(pos.add(1, 0, 0));
if (tileEntity instanceof TileEntityEnanReactorCore) {
return (TileEntityEnanReactorCore) tileEntity;
}
tileEntity = world.getTileEntity(pos.add(-1, 0, 0));
if (tileEntity instanceof TileEntityEnanReactorCore) {
return (TileEntityEnanReactorCore) tileEntity;
}
tileEntity = world.getTileEntity(pos.add(0, 0, 1));
if (tileEntity instanceof TileEntityEnanReactorCore) {
return (TileEntityEnanReactorCore) tileEntity;
}
tileEntity = world.getTileEntity(pos.add(0, 0, -1));
if (tileEntity instanceof TileEntityEnanReactorCore) {
return (TileEntityEnanReactorCore) tileEntity;
}
return null;
@Override
protected void doUpdateParameters(final boolean isDirty) {
// no operation
}
// Common OC/CC methods
@ -82,12 +59,12 @@ public class TileEntityEnanReactorController extends TileEntityAbstractEnergyCor
}
@Override
public Object[] isAssemblyValid() {
public Object[] getAssemblyStatus() {
final TileEntityEnanReactorCore tileEntityEnanReactorCore = tileEntityEnanReactorCoreWeakReference == null ? null : tileEntityEnanReactorCoreWeakReference.get();
if (tileEntityEnanReactorCore == null) {
return new Object[] { false, "No core detected" };
}
return tileEntityEnanReactorCore.isAssemblyValid();
return tileEntityEnanReactorCore.getAssemblyStatus();
}
@Override

View file

@ -2,6 +2,7 @@ package cr0s.warpdrive.block.energy;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.EnergyWrapper;
import cr0s.warpdrive.data.EnumTier;
@ -24,15 +25,15 @@ import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.MutableBlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
private static final int ENAN_REACTOR_SETUP_TICKS = 1200;
// generation & instability is 'per tick'
private static final double INSTABILITY_MIN = 0.004D;
private static final double INSTABILITY_MAX = 0.060D;
@ -68,7 +69,6 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
private int generation_range;
private int updateTicks = 0;
private int setupTicks = 0;
private float lasersReceived = 0;
private int lastGenerationRate = 0;
@ -217,17 +217,11 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
}
if (WarpDriveConfig.LOGGING_ENERGY) {
WarpDrive.logger.info(String.format("updateTicks %d setupTicks %d releasedThisTick %6d lasersReceived %.5f releasedThisCycle %6d containedEnergy %8d",
updateTicks, setupTicks, releasedThisTick, lasersReceived, releasedThisCycle, containedEnergy));
WarpDrive.logger.info(String.format("updateTicks %d releasedThisTick %6d lasersReceived %.5f releasedThisCycle %6d containedEnergy %8d",
updateTicks, releasedThisTick, lasersReceived, releasedThisCycle, containedEnergy));
}
releasedThisTick = 0;
setupTicks--;
if (setupTicks <= 0) {
setupTicks = ENAN_REACTOR_SETUP_TICKS;
scanSetup();
}
lasersReceived = Math.max(0.0F, lasersReceived - 0.05F);
updateTicks--;
if (updateTicks > 0) {
@ -502,14 +496,38 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
public void onBlockUpdateDetected() {
super.onBlockUpdateDetected();
setupTicks = 0;
markDirtyAssembly();
}
private void scanSetup() {
final MutableBlockPos mutableBlockPos = new MutableBlockPos(pos);
@Override
public void onBlockBroken(@Nonnull final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
final MutableBlockPos mutableBlockPos = new MutableBlockPos();
for (final ReactorFace reactorFace : ReactorFace.getLasers(enumTier)) {
if (reactorFace.indexStability < 0) {
continue;
}
mutableBlockPos.setPos(blockPos.getX() + reactorFace.x,
blockPos.getY() + reactorFace.y,
blockPos.getZ() + reactorFace.z );
final TileEntity tileEntity = world.getTileEntity(mutableBlockPos);
if (tileEntity instanceof TileEntityEnanReactorLaser) {
if (((TileEntityEnanReactorLaser) tileEntity).getReactorFace() == reactorFace) {
((TileEntityEnanReactorLaser) tileEntity).setReactorFace(ReactorFace.UNKNOWN, null);
}
}
}
super.onBlockBroken(world, blockPos, blockState);
}
@Override
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
boolean isValid = super.doScanAssembly(isDirty, textReason);
final MutableBlockPos mutableBlockPos = new MutableBlockPos();
// first check if we have the required 'air' blocks
boolean isValid = true;
for (final ReactorFace reactorFace : ReactorFace.get(enumTier)) {
assert reactorFace.enumTier == enumTier;
if (reactorFace.indexStability < 0) {
@ -519,6 +537,8 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
final IBlockState blockState = world.getBlockState(mutableBlockPos);
final boolean isAir = blockState.getBlock().isAir(blockState, world, mutableBlockPos);
if (!isAir) {
textReason.append(Commons.styleWarning, "warpdrive.enan_reactor.status_line.non_air_block",
Commons.format(world, mutableBlockPos) );
isValid = false;
final Vector3 vPosition = new Vector3(mutableBlockPos).translate(0.5D);
PacketHandler.sendSpawnParticlePacket(world, "jammed", (byte) 5, vPosition,
@ -537,12 +557,11 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
pos.getZ() + reactorFace.z);
final TileEntity tileEntity = world.getTileEntity(mutableBlockPos);
if (tileEntity instanceof TileEntityEnanReactorLaser) {
if (isValid) {
((TileEntityEnanReactorLaser) tileEntity).setReactorFace(reactorFace, this);
} else {
((TileEntityEnanReactorLaser) tileEntity).setReactorFace(ReactorFace.UNKNOWN, null);
}
((TileEntityEnanReactorLaser) tileEntity).setReactorFace(reactorFace, this);
} else {
textReason.append(Commons.styleWarning, "warpdrive.enan_reactor.status_line.missing_stabilization_laser",
Commons.format(world, mutableBlockPos) );
isValid = false;
final Vector3 vPosition = new Vector3(mutableBlockPos).translate(0.5D);
PacketHandler.sendSpawnParticlePacket(world, "jammed", (byte) 5, vPosition,
new Vector3(0.0D, 0.0D, 0.0D),
@ -551,6 +570,8 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
32);
}
}
return isValid;
}
// Common OC/CC methods
@ -565,11 +586,6 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
EnergyWrapper.convert(energyReleasedLastCycle, units) / WarpDriveConfig.ENAN_REACTOR_UPDATE_INTERVAL_TICKS };
}
@Override
public Object[] isAssemblyValid() {
return null; // @TODO isAssemblyValid()
}
@Override
public Double[] getInstabilities() {
// computer is alive => start updating reactor

View file

@ -2,6 +2,7 @@ package cr0s.warpdrive.block.energy;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.api.computer.IEnanReactorLaser;
import cr0s.warpdrive.block.TileEntityAbstractLaser;
import cr0s.warpdrive.config.WarpDriveConfig;
@ -51,7 +52,6 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser implemen
peripheralName = "warpdriveEnanReactorLaser";
laserMedium_maxCount = 1;
laserMedium_directionsValid = new EnumFacing[] { EnumFacing.UP, EnumFacing.DOWN };
updateInterval_ticks = WarpDriveConfig.ENAN_REACTOR_UPDATE_INTERVAL_TICKS;
}
@Override
@ -59,23 +59,8 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser implemen
super.onFirstUpdateTick();
if (reactorFace == ReactorFace.UNKNOWN) {
final MutableBlockPos mutableBlockPos = new MutableBlockPos(pos);
// laser isn't linked yet, let's try to update nearby reactors
for (final ReactorFace reactorFace : ReactorFace.getLasers()) {
if (reactorFace.indexStability < 0) {
continue;
}
mutableBlockPos.setPos(pos.getX() - reactorFace.x,
pos.getY() - reactorFace.y,
pos.getZ() - reactorFace.z);
if (world.isBlockLoaded(mutableBlockPos, true)) {
final TileEntity tileEntity = world.getTileEntity(mutableBlockPos);
if (tileEntity instanceof TileEntityEnanReactorCore) {
((TileEntityEnanReactorCore) tileEntity).onBlockUpdateDetected();
}
}
}
onBlockUpdateDetected();
}
vLaser = new Vector3(this).translate(0.5);
@ -97,6 +82,12 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser implemen
}
public void setReactorFace(@Nonnull final ReactorFace reactorFace, final TileEntityEnanReactorCore reactorCore) {
// skip if it's already set to another reactor
if ( this.reactorFace != reactorFace
&& this.reactorFace != ReactorFace.UNKNOWN ) {
return;
}
// always update cached signature name
reactorSignatureName = reactorCore != null ? reactorCore.getSignatureName() : "";
@ -157,9 +148,38 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser implemen
final TileEntityEnanReactorCore reactorCore = getReactorCore();
if (reactorCore != null) {
reactorCore.onBlockUpdateDetected();
} else {
final MutableBlockPos mutableBlockPos = new MutableBlockPos(pos);
for (final ReactorFace reactorFace : ReactorFace.getLasers()) {
if (reactorFace.indexStability < 0) {
continue;
}
mutableBlockPos.setPos(pos.getX() - reactorFace.x,
pos.getY() - reactorFace.y,
pos.getZ() - reactorFace.z);
if (world.isBlockLoaded(mutableBlockPos, true)) {
final TileEntity tileEntity = world.getTileEntity(mutableBlockPos);
if (tileEntity instanceof TileEntityEnanReactorCore) {
((TileEntityEnanReactorCore) tileEntity).onBlockUpdateDetected();
}
}
}
}
}
@Override
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
final boolean isValid = super.doScanAssembly(isDirty, textReason);
if (reactorFace == ReactorFace.UNKNOWN) {
textReason.append(Commons.styleWarning, "warpdrive.enan_reactor.status_line.missing_reactor_core");
return false;
}
return isValid;
}
protected int stabilize(final int energy) {
if (energy <= 0) {
return 0;
@ -244,14 +264,6 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser implemen
// Common OC/CC methods
@Override
public Object[] isAssemblyValid() {
if (reactorFace == ReactorFace.UNKNOWN) {
return new Object[] { false, "No reactor detected" };
}
return super.isAssemblyValid();
}
@Override
public Object[] getEnergyRequired() {
final String units = energy_getDisplayUnits();

View file

@ -205,7 +205,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
markDirty();
}
final boolean isEnabledAndValid = isEnabled && isValid();
final boolean isEnabledAndValid = isEnabled && isAssemblyValid;
final boolean isOn = isEnabledAndValid && cooldownTicks <= 0 && isPowered;
if (isOn) {
if (!legacy_isOn) {
@ -296,8 +296,16 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
super.onBlockBroken(world, blockPos, blockState);
}
public boolean isValid() {
return getShape() != EnumForceFieldShape.NONE;
@Override
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
final boolean isValid = super.doScanAssembly(isDirty, textReason);
if (getShape() != EnumForceFieldShape.NONE) {
textReason.append(Commons.styleWarning, "warpdrive.force_field.shape.status_line.none");
return false;
}
return isValid;
}
@Override
@ -338,7 +346,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
}
boolean isPartOfForceField(final VectorI vector) {
if (!isEnabled || !isValid()) {
if (!isEnabled || !isAssemblyValid) {
return false;
}
if (!isCalculated()) {
@ -349,7 +357,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
}
private boolean isPartOfInterior(final VectorI vector) {
if (!isEnabled || !isValid()) {
if (!isEnabled || !isAssemblyValid) {
return false;
}
if (!isCalculated()) {
@ -946,7 +954,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
public EnumForceFieldState getState() {
EnumForceFieldState forceFieldState = EnumForceFieldState.NOT_CONNECTED;
if (isConnected && isValid()) {
if (isConnected && isAssemblyValid) {
if (isPowered) {
if (isOn()) {
forceFieldState = EnumForceFieldState.CONNECTED_POWERED;
@ -1282,7 +1290,9 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
try {
projector = weakProjector.get();
if ( projector != null
&& projector.isValid() ) {
&& !projector.isInvalid()
&& projector.isEnabled
&& projector.isAssemblyValid ) {
// collect what we need, then release the object
final ForceFieldSetup forceFieldSetup = projector.getForceFieldSetup();
final int heightWorld = projector.world.getHeight();

View file

@ -12,7 +12,6 @@ import cr0s.warpdrive.render.EntityFXBoundingBox;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.UUID;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
@ -20,8 +19,6 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.relauncher.Side;
@ -32,7 +29,6 @@ public class TileEntityJumpGateCore extends TileEntityAbstractEnergyCoreOrContro
private static final int BOUNDING_BOX_INTERVAL_TICKS = 60;
// persistent properties
private UUID uuid = null;
private int maxX, maxY, maxZ;
private int minX, minY, minZ;
@ -45,8 +41,6 @@ public class TileEntityJumpGateCore extends TileEntityAbstractEnergyCoreOrContro
public int volume;
public double occupancy;
private int registryUpdateTicks = 0;
public TileEntityJumpGateCore() {
super();
@ -85,17 +79,6 @@ public class TileEntityJumpGateCore extends TileEntityAbstractEnergyCoreOrContro
return;
}
// periodically update starmap registry
registryUpdateTicks--;
if (registryUpdateTicks <= 0) {
registryUpdateTicks = 20 * WarpDriveConfig.STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS;
if (uuid == null || (uuid.getMostSignificantBits() == 0 && uuid.getLeastSignificantBits() == 0)) {
uuid = UUID.randomUUID();
}
// recover registration, shouldn't be needed, in theory...
WarpDrive.starMap.updateInRegistry(this);
}
// scan ship content progressively
if (timeLastScanDone <= 0L) {
timeLastScanDone = world.getTotalWorldTime();
@ -121,6 +104,11 @@ public class TileEntityJumpGateCore extends TileEntityAbstractEnergyCoreOrContro
}
}
@Override
protected void doUpdateParameters(final boolean isDirty) {
// no operation
}
public boolean isBusy() {
return timeLastScanDone < 0 || jumpGateScanner != null;
}
@ -189,25 +177,6 @@ public class TileEntityJumpGateCore extends TileEntityAbstractEnergyCoreOrContro
readFromNBT(tagCompound);
}
@Override
public void validate() {
super.validate();
if (world.isRemote) {
return;
}
WarpDrive.starMap.updateInRegistry(this);
}
@Override
public void onBlockBroken(@Nonnull final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
if (!world.isRemote) {
WarpDrive.starMap.removeFromRegistry(this);
}
super.onBlockBroken(world, blockPos, blockState);
}
// IStarMapRegistryTileEntity overrides
@Override
public EnumStarMapEntryType getStarMapType() {

View file

@ -3,13 +3,11 @@ package cr0s.warpdrive.block.movement;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.CelestialObjectManager;
import cr0s.warpdrive.data.EnumStarMapEntryType;
import cr0s.warpdrive.data.StarMapRegistryItem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Collections;
@ -23,10 +21,7 @@ public class TileEntityShipController extends TileEntityAbstractShipController {
// (none)
// computed properties
private final int updateInterval_ticks = 20 * WarpDriveConfig.SHIP_CONTROLLER_UPDATE_INTERVAL_SECONDS;
private int updateTicks = updateInterval_ticks;
private int bootTicks = 20;
private WarpDriveText reason = new WarpDriveText();
private int tickBooting = 20;
private WeakReference<TileEntityShipCore> tileEntityShipCoreWeakReference = null;
@ -47,21 +42,70 @@ public class TileEntityShipController extends TileEntityAbstractShipController {
}
// accelerate update ticks during boot
if (bootTicks > 0) {
bootTicks--;
if (tickBooting > 0) {
tickBooting--;
if (tileEntityShipCoreWeakReference == null) {
updateTicks = 1;
markDirtyAssembly();
}
}
updateTicks--;
if (updateTicks <= 0) {
updateTicks = updateInterval_ticks;
reason = new WarpDriveText();
final TileEntityShipCore tileEntityShipCore = updateLink(reason);
updateBlockState(null, BlockShipController.COMMAND, enumShipCommand);
}
@Override
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
final boolean isValid = super.doScanAssembly(isDirty, textReason);
// validate existing link
TileEntityShipCore tileEntityShipCore = tileEntityShipCoreWeakReference != null ? tileEntityShipCoreWeakReference.get() : null;
if ( tileEntityShipCore == null
|| tileEntityShipCore.isInvalid()
|| !tileEntityShipCore.getSignatureUUID().equals(uuid) ) {
tileEntityShipCore = null;
tileEntityShipCoreWeakReference = null;
}
// refresh as needed
// note: it's up to players to break the link, so if the world is partially restored we won't lose the link
if (tileEntityShipCore == null) {
final StarMapRegistryItem starMapRegistryItem = WarpDrive.starMap.getByUUID(EnumStarMapEntryType.SHIP, uuid);
if (starMapRegistryItem == null) {
textReason.append(Commons.styleWarning, "warpdrive.core_signature.status_line.unknown_core_signature");
return false;
}
final WorldServer worldServer = starMapRegistryItem.getWorldServerIfLoaded();
if (worldServer == null) {
textReason.append(Commons.styleWarning, "warpdrive.core_signature.status_line.world_not_loaded");
return false;
}
final TileEntity tileEntity = worldServer.getTileEntity(starMapRegistryItem.getBlockPos());
if ( !(tileEntity instanceof TileEntityShipCore)
|| tileEntity.isInvalid()
|| !((TileEntityShipCore) tileEntity).getSignatureUUID().equals(uuid) ) {
textReason.append(Commons.styleWarning, "warpdrive.core_signature.status_line.unknown_core_signature");
return false;
}
tileEntityShipCore = (TileEntityShipCore) tileEntity;
tileEntityShipCoreWeakReference = new WeakReference<>(tileEntityShipCore);
}
// (tileEntityShipCore is defined and valid)
final boolean isSynchronized = tileEntityShipCore.refreshLink(this);
if (isSynchronized) {
onCoreUpdated(tileEntityShipCore);
// send command as soon as link is re-established
if ( !tileEntityShipCore.isCommandConfirmed
&& isCommandConfirmed ) {
tileEntityShipCore.command(new Object[] { enumShipCommand.getName(), true });
}
}
updateBlockState(null, BlockShipController.COMMAND, enumShipCommand);
return isValid;
}
@Override
protected void doUpdateParameters(final boolean isDirty) {
// no operation
}
@Override
@ -84,55 +128,6 @@ public class TileEntityShipController extends TileEntityAbstractShipController {
return tagCompound;
}
@Nullable
private TileEntityShipCore updateLink(final WarpDriveText reason) {
// validate existing link
TileEntityShipCore tileEntityShipCore = tileEntityShipCoreWeakReference != null ? tileEntityShipCoreWeakReference.get() : null;
if ( tileEntityShipCore == null
|| tileEntityShipCore.isInvalid()
|| !tileEntityShipCore.getSignatureUUID().equals(uuid) ) {
tileEntityShipCore = null;
tileEntityShipCoreWeakReference = null;
}
// refresh as needed
// note: it's up to players to break the link, so if the world is partially restored we won't lose the link
if (tileEntityShipCore == null) {
final StarMapRegistryItem starMapRegistryItem = WarpDrive.starMap.getByUUID(EnumStarMapEntryType.SHIP, uuid);
if (starMapRegistryItem == null) {
reason.append(Commons.styleWarning, "warpdrive.core_signature.status_line.unknown_core_signature");
return null;
}
final WorldServer worldServer = starMapRegistryItem.getWorldServerIfLoaded();
if (worldServer == null) {
reason.append(Commons.styleWarning, "warpdrive.core_signature.status_line.world_not_loaded");
return null;
}
final TileEntity tileEntity = worldServer.getTileEntity(starMapRegistryItem.getBlockPos());
if ( !(tileEntity instanceof TileEntityShipCore)
|| tileEntity.isInvalid()
|| !((TileEntityShipCore) tileEntity).getSignatureUUID().equals(uuid) ) {
reason.append(Commons.styleWarning, "warpdrive.core_signature.status_line.unknown_core_signature");
return null;
}
tileEntityShipCore = (TileEntityShipCore) tileEntity;
tileEntityShipCoreWeakReference = new WeakReference<>(tileEntityShipCore);
}
// (tileEntityShipCore is defined and valid)
final boolean isSynchronized = tileEntityShipCore.refreshLink(this);
if (isSynchronized) {
onCoreUpdated(tileEntityShipCore);
// send command as soon as link is re-established
if ( !tileEntityShipCore.isCommandConfirmed
&& isCommandConfirmed ) {
tileEntityShipCore.command(new Object[] { enumShipCommand.getName(), true });
}
}
return tileEntityShipCore;
}
@Nonnull
@Override
protected WarpDriveText getCoreSignatureStatus(final String nameSignature) {
@ -142,15 +137,6 @@ public class TileEntityShipController extends TileEntityAbstractShipController {
return super.getCoreSignatureStatus(nameSignature);
}
@Override
public WarpDriveText getStatus() {
if (reason.getUnformattedText().isEmpty()) {
return super.getStatus();
} else {
return super.getStatus().append(reason);
}
}
// Common OC/CC methods
@Override
public Object[] getLocalPosition() {
@ -162,12 +148,12 @@ public class TileEntityShipController extends TileEntityAbstractShipController {
}
@Override
public Object[] isAssemblyValid() {
public Object[] getAssemblyStatus() {
final TileEntityShipCore tileEntityShipCore = tileEntityShipCoreWeakReference == null ? null : tileEntityShipCoreWeakReference.get();
if (tileEntityShipCore == null) {
return new Object[] { false, "No core detected" };
}
return tileEntityShipCore.isAssemblyValid();
return tileEntityShipCore.getAssemblyStatus();
}
@Override

View file

@ -8,6 +8,7 @@ import cr0s.warpdrive.api.IStarMapRegistryTileEntity;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.api.computer.IMultiBlockCoreOrController;
import cr0s.warpdrive.api.computer.IMultiBlockCore;
import cr0s.warpdrive.block.detection.BlockWarpIsolation;
import cr0s.warpdrive.config.Dictionary;
import cr0s.warpdrive.config.ShipMovementCosts;
import cr0s.warpdrive.config.WarpDriveConfig;
@ -29,7 +30,6 @@ import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
import net.minecraft.block.Block;
@ -49,12 +49,12 @@ import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.MutableBlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.FMLClientHandler;
@ -73,8 +73,6 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
private int ticksCooldown = 0;
private int warmupTime_ticks = 0;
protected int jumpCount = 0;
private boolean isValid = false;
private WarpDriveText reasonInvalid = new WarpDriveText();
// computed properties
public int maxX, maxY, maxZ;
@ -102,11 +100,9 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
private boolean isWarmupReported = false;
protected int randomWarmupAddition_ticks = 0;
private int registryUpdateTicks = 0;
private int logTicks = 120;
private int isolationBlocksCount = 0;
private int isolationUpdateTicks = 0;
public TileEntityShipCore() {
@ -191,17 +187,6 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
stateCurrent = EnumShipCoreState.IDLE;
}
// periodically update starmap registry
registryUpdateTicks--;
if (registryUpdateTicks <= 0) {
registryUpdateTicks = 20 * WarpDriveConfig.STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS;
if (uuid == null || (uuid.getMostSignificantBits() == 0 && uuid.getLeastSignificantBits() == 0)) {
uuid = UUID.randomUUID();
}
// recover registration, shouldn't be needed, in theory...
WarpDrive.starMap.updateInRegistry(this);
}
// periodically log the ship state
logTicks--;
if (logTicks <= 0) {
@ -217,13 +202,6 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
}
}
// periodically check isolation blocks
isolationUpdateTicks--;
if (isolationUpdateTicks <= 0) {
isolationUpdateTicks = WarpDriveConfig.SHIP_CORE_ISOLATION_UPDATE_INTERVAL_SECONDS * 20;
updateIsolationState();
}
// refresh rendering
final boolean isActive = commandCurrent != EnumShipCommand.OFFLINE;
updateBlockState(null, BlockProperties.ACTIVE, isActive);
@ -236,16 +214,16 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
if ( getBack() == 0 && getFront() == 0
&& getLeft() == 0 && getRight() == 0
&& getDown() == 0 && getUp() == 0 ) {
reasonInvalid = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.no_dimension_set");
isValid = false;
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.no_dimension_set");
isAssemblyValid = false;
return;
}
if ( (getBack() + getFront()) > WarpDriveConfig.SHIP_SIZE_MAX_PER_SIDE_BY_TIER[enumTier.getIndex()]
|| (getLeft() + getRight()) > WarpDriveConfig.SHIP_SIZE_MAX_PER_SIDE_BY_TIER[enumTier.getIndex()]
|| (getDown() + getUp() ) > WarpDriveConfig.SHIP_SIZE_MAX_PER_SIDE_BY_TIER[enumTier.getIndex()] ) {
reasonInvalid = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.too_large_side_for_tier",
WarpDriveConfig.SHIP_SIZE_MAX_PER_SIDE_BY_TIER[enumTier.getIndex()]);
isValid = false;
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.too_large_side_for_tier",
WarpDriveConfig.SHIP_SIZE_MAX_PER_SIDE_BY_TIER[enumTier.getIndex()]);
isAssemblyValid = false;
return;
}
@ -287,45 +265,45 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
if (!isUnlimited) {
if ( shipMass > WarpDriveConfig.SHIP_MASS_MAX_ON_PLANET_SURFACE
&& CelestialObjectManager.isPlanet(world, pos.getX(), pos.getZ()) ) {
reasonInvalid = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.too_much_mass_for_planet",
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.too_much_mass_for_planet",
WarpDriveConfig.SHIP_MASS_MAX_ON_PLANET_SURFACE, shipMass);
isValid = false;
isAssemblyValid = false;
if (isEnabled) {
commandDone(false, reasonInvalid);
commandDone(false, textValidityIssues);
}
return;
}
if ( shipMass < WarpDriveConfig.SHIP_MASS_MIN_FOR_HYPERSPACE
&& CelestialObjectManager.isInHyperspace(world, pos.getX(), pos.getZ()) ) {
reasonInvalid = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.insufficient_mass_for_hyperspace",
WarpDriveConfig.SHIP_MASS_MIN_FOR_HYPERSPACE, shipMass);
isValid = false;
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.insufficient_mass_for_hyperspace",
WarpDriveConfig.SHIP_MASS_MIN_FOR_HYPERSPACE, shipMass);
isAssemblyValid = false;
if (isEnabled) {
commandDone(false, reasonInvalid);
commandDone(false, textValidityIssues);
}
return;
}
if (shipMass < WarpDriveConfig.SHIP_MASS_MIN_BY_TIER[enumTier.getIndex()]) {
reasonInvalid = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.insufficient_mass_for_tier",
WarpDriveConfig.SHIP_MASS_MIN_BY_TIER[enumTier.getIndex()], shipMass);
isValid = false;
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.insufficient_mass_for_tier",
WarpDriveConfig.SHIP_MASS_MIN_BY_TIER[enumTier.getIndex()], shipMass);
isAssemblyValid = false;
if (isEnabled) {
commandDone(false, reasonInvalid);
commandDone(false, textValidityIssues);
}
return;
}
if (shipMass > WarpDriveConfig.SHIP_MASS_MAX_BY_TIER[enumTier.getIndex()]) {
reasonInvalid = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.too_much_mass_for_tier",
WarpDriveConfig.SHIP_MASS_MAX_BY_TIER[enumTier.getIndex()], shipMass);
isValid = false;
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.ship.guide.too_much_mass_for_tier",
WarpDriveConfig.SHIP_MASS_MAX_BY_TIER[enumTier.getIndex()], shipMass);
isAssemblyValid = false;
if (isEnabled) {
commandDone(false, reasonInvalid);
commandDone(false, textValidityIssues);
}
return;
}
}
reasonInvalid = new WarpDriveText();
isValid = true;
textValidityIssues = new WarpDriveText();
isAssemblyValid = true;
}
// skip state handling while cooling down
@ -374,8 +352,8 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
Commons.messageToAllPlayersInArea(this, new WarpDriveText(null, "warpdrive.ship.guide.pre_jumping"));
// update ship spatial parameters
if (!isValid) {
commandDone(false, reasonInvalid);
if (!isAssemblyValid) {
commandDone(false, textValidityIssues);
return;
}
@ -462,8 +440,8 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
isSoundPlayed = false;
isWarmupReported = false;
if (!isValid) {
commandDone(false, reasonInvalid);
if (!isAssemblyValid) {
commandDone(false, textValidityIssues);
return;
}
@ -492,10 +470,6 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
}
}
public boolean isValid() {
return isValid;
}
public boolean isOffline() {
return enumShipCommand == EnumShipCommand.OFFLINE;
}
@ -618,7 +592,10 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
return ((TileEntitySecurityStation) tileEntity).getFirstOnlinePlayer();
}
private void updateIsolationState() {
@Override
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
final boolean isValid = super.doScanAssembly(isDirty, textReason);
// Search block in cube around core
final int xMin = pos.getX() - WarpDriveConfig.RADAR_MAX_ISOLATION_RANGE;
final int xMax = pos.getX() + WarpDriveConfig.RADAR_MAX_ISOLATION_RANGE;
@ -634,10 +611,12 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
int newCount = 0;
// Search for warp isolation blocks
final MutableBlockPos mutableBlockPos = new MutableBlockPos();
for (int y = yMin; y <= yMax; y++) {
for (int x = xMin; x <= xMax; x++) {
for (int z = zMin; z <= zMax; z++) {
if (world.getBlockState(new BlockPos(x, y, z)).getBlock() == WarpDrive.blockWarpIsolation) {
mutableBlockPos.setPos(x, y, z);
if (world.getBlockState(mutableBlockPos).getBlock() instanceof BlockWarpIsolation) {
newCount++;
}
}
@ -653,10 +632,20 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
} else {
isolationRate = 0.0D;
}
if (WarpDriveConfig.LOGGING_RADAR && (WarpDrive.isDev || legacy_isolationRate != isolationRate)) {
WarpDrive.logger.info(String.format("%s Isolation updated to %d (%.1f%%)",
this, isolationBlocksCount , isolationRate * 100.0));
if (legacy_isolationRate != isolationRate) {
markDirtyStarMapEntry();
if (WarpDriveConfig.LOGGING_RADAR && WarpDrive.isDev) {
WarpDrive.logger.info(String.format("%s Isolation updated to %d (%.1f%%)",
this, isolationBlocksCount , isolationRate * 100.0));
}
}
return isValid;
}
@Override
protected void doUpdateParameters(final boolean isDirty) {
// no operation
}
private void makePlayersOnShipDrunk(final int tickDuration) {
@ -684,9 +673,9 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
return false;
}
updateAfterResize();
if (!isValid) {
if (!isAssemblyValid) {
Commons.addChatMessage(entityPlayerMP, new TextComponentString(!name.isEmpty() ? name : "ShipCore").setStyle(Commons.styleHeader)
.appendSibling(reasonInvalid));
.appendSibling(textValidityIssues));
return false;
}
@ -1115,13 +1104,13 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
@Override
public WarpDriveText getStatus() {
final String strIsolationRate = String.format("%.1f", isolationRate * 100.0D);
final WarpDriveText textStatus = super.getStatus();
if (ticksCooldown > 0) {
textStatus.append(null, "warpdrive.ship.status_line.cooling",
ticksCooldown / 20);
}
if (isolationBlocksCount > 0) {
final String strIsolationRate = String.format("%.1f", isolationRate * 100.0D);
textStatus.append(null, "warpdrive.ship.status_line.isolation",
isolationBlocksCount, strIsolationRate);
}
@ -1187,27 +1176,6 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
cache_aabbArea = null;
}
@Override
public void validate() {
super.validate();
if (world.isRemote) {
return;
}
if (uuid != null) {
WarpDrive.starMap.updateInRegistry(this);
}
}
@Override
public void onBlockBroken(@Nonnull final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
if (!world.isRemote) {
WarpDrive.starMap.removeFromRegistry(this);
}
super.onBlockBroken(world, blockPos, blockState);
}
@Override
public String getSignatureName() {
return name;
@ -1243,14 +1211,6 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
}
// Common OC/CC methods
@Override
public Object[] isAssemblyValid() {
if (!isValid) {
return new Object[] { false, Commons.removeFormatting( reasonInvalid.getUnformattedText() ) };
}
return super.isAssemblyValid();
}
@Override
public Object[] getOrientation() {
return new Object[] { facing.getXOffset(), 0, facing.getZOffset() };

View file

@ -96,9 +96,6 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
// computed properties
private ArrayList<BlockPos> vLocalContainments = null;
private AxisAlignedBB aabbLocalScanners = null;
private boolean isBlockUpdated = false;
private int tickUpdateRegistry = 0;
private int tickUpdateParameters = 0;
private int tickComputerPulse = 0;
private boolean isConnected = false;
private GlobalPosition globalPositionBeacon = null;
@ -147,7 +144,6 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
protected void onFirstUpdateTick() {
super.onFirstUpdateTick();
tickUpdateParameters = 0;
globalPositionLocal = new GlobalPosition(this);
}
@ -205,24 +201,6 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
// WarpDrive.logger.info(String.format("Transporter strength %.5f -> %.5f", lockStrengthPrevious, lockStrengthActual));
}
// periodically update starmap registry & scanners location
if (isBlockUpdated) {
tickUpdateRegistry = Math.min(10, tickUpdateRegistry);
}
tickUpdateRegistry--;
if (tickUpdateRegistry <= 0) {
tickUpdateRegistry = 20 * WarpDriveConfig.STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS;
isBlockUpdated = false;
updateScanners();
if (uuid == null || (uuid.getMostSignificantBits() == 0 && uuid.getLeastSignificantBits() == 0)) {
uuid = UUID.randomUUID();
}
// recover registration, shouldn't be needed, in theory...
WarpDrive.starMap.updateInRegistry(this);
}
// state feedback
updateBlockState(null, BlockTransporterCore.VARIANT, !isConnected ? EnumTransporterState.DISABLED
: !isEnabled ? EnumTransporterState.IDLE
@ -253,13 +231,6 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
}
}
// periodically update parameters from main thread
tickUpdateParameters--;
if (tickUpdateParameters <= 0) {
tickUpdateParameters = WarpDriveConfig.TRANSPORTER_SETUP_UPDATE_PARAMETERS_TICKS;
updateParameters();
}
// execute state transitions
switch (transporterState) {
case DISABLED:
@ -276,7 +247,7 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
if ( isLockRequested
&& tickCooldown == 0 ) {
// force parameters validation for next tick
tickUpdateParameters = 0;
markDirtyParameters();
transporterState = EnumTransporterState.ACQUIRING;
} else {
releaseChunks();
@ -299,7 +270,7 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
} else if (isEnergizeRequested) {
// force parameters validation for next tick
tickUpdateParameters = 0;
markDirtyParameters();
tickEnergizing = WarpDriveConfig.TRANSPORTER_ENERGIZING_CHARGING_TICKS;
transporterState = EnumTransporterState.ENERGIZING;
@ -340,7 +311,6 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
public void onBlockBroken(@Nonnull final World world, @Nonnull final BlockPos blockPos, @Nonnull final IBlockState blockState) {
if (!world.isRemote) {
rebootTransporter();
WarpDrive.starMap.removeFromRegistry(this);
}
super.onBlockBroken(world, blockPos, blockState);
}
@ -350,7 +320,7 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
if (vLocalScanners != null) {
for (final BlockPos vScanner : vLocalScanners) {
final IBlockState blockState = world.getBlockState(vScanner);
if (blockState.getBlock() == WarpDrive.blockTransporterScanner) {
if (blockState.getBlock() instanceof BlockTransporterScanner) {
world.setBlockState(vScanner, blockState.withProperty(BlockProperties.ACTIVE, false), 2);
}
}
@ -407,7 +377,7 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
// clear entities, cancel transfer, cool down, loose a bit of strength
isEnergizeRequested = false;
tickUpdateParameters = 0;
markDirtyParameters();
tickCooldown += WarpDriveConfig.TRANSPORTER_ENERGIZING_COOLDOWN_TICKS;
lockStrengthActual = Math.max(0.0D, lockStrengthActual - WarpDriveConfig.TRANSPORTER_ENERGIZING_LOCKING_LOST);
transporterState = EnumTransporterState.ACQUIRING;
@ -521,7 +491,7 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
ForceFieldRegistry.removeFromRegistry(this);
}
this.beamFrequency = beamFrequency;
tickUpdateParameters = 0;
markDirtyParameters();
}
markDirty();
}
@ -556,7 +526,7 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
@Override
public void onBlockUpdatedInArea(final VectorI vector, final IBlockState blockState) {
// skip in case of explosion, etc.
if (isBlockUpdated) {
if (isDirtyAssembly()) {
return;
}
@ -564,7 +534,7 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
final Block block = blockState.getBlock();
if ( block instanceof BlockTransporterScanner
|| block instanceof BlockTransporterContainment) {
isBlockUpdated = true;
markDirtyAssembly();
return;
}
if ( aabbLocalScanners != null
@ -574,7 +544,7 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
&& vector.x < aabbLocalScanners.maxX
&& vector.y < aabbLocalScanners.maxY
&& vector.z < aabbLocalScanners.maxZ ) {
isBlockUpdated = true;
markDirtyAssembly();
}
if (WarpDriveConfig.LOGGING_TRANSPORTER) {
@ -582,7 +552,10 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
}
}
private void updateScanners() {
@Override
protected boolean doScanAssembly(final boolean isDirty, final WarpDriveText textReason) {
final boolean isValid = super.doScanAssembly(isDirty, textReason);
// scan the whole area for scanners
final int xMin = pos.getX() - WarpDriveConfig.TRANSPORTER_SETUP_SCANNER_RANGE_XZ_BLOCKS;
final int xMax = pos.getX() + WarpDriveConfig.TRANSPORTER_SETUP_SCANNER_RANGE_XZ_BLOCKS;
@ -609,6 +582,8 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
// only accept valid ones, spawn particles on others
final Collection<BlockPos> vValidContainments = ((BlockTransporterScanner) block).getValidContainment(world, mutableBlockPos);
if (vValidContainments == null || vValidContainments.isEmpty()) {
textReason.append(Commons.styleWarning, "warpdrive.transporter.status_line.missing_containment",
Commons.format(world, mutableBlockPos) );
world.setBlockState(mutableBlockPos, blockState.withProperty(BlockProperties.ACTIVE, false), 2);
PacketHandler.sendSpawnParticlePacket(world, "jammed", (byte) 5,
new Vector3(x + 0.5D, y + 1.5D, z + 0.5D),
@ -626,6 +601,12 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
}
}
setLocalScanners(vScanners, vContainments);
// cascade updates
markDirtyParameters();
markDirtyStarMapEntry();
return isValid;
}
private void setLocalScanners(final ArrayList<BlockPos> vScanners, final Collection<BlockPos> vContainments) {
@ -697,7 +678,8 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
}
}
private void updateParameters() {
@Override
protected void doUpdateParameters(final boolean isDirty) {
isJammed = false;
reasonJammed = "";
@ -1688,14 +1670,14 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
final VectorI vNew = computer_getVectorI((VectorI) remoteLocationRequested, arguments);
if (!vNew.equals(remoteLocationRequested)) {
remoteLocationRequested = vNew;
tickUpdateParameters = 0;
markDirtyParameters();
}
} else {
final VectorI vNew = computer_getVectorI(null, arguments);
if (vNew != null) {
remoteLocationRequested = vNew;
tickUpdateParameters = 0;
markDirtyParameters();
}
}
} else if (arguments.length == 1 && arguments[0] != null) {
@ -1705,18 +1687,18 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon
if (remoteLocationRequested instanceof UUID) {
if (!uuidNew.equals(remoteLocationRequested)) {// replacing existing UUID
remoteLocationRequested = uuidNew;
tickUpdateParameters = 0;
markDirtyParameters();
}
} else {
remoteLocationRequested = uuidNew;
tickUpdateParameters = 0;
markDirtyParameters();
}
} else {// new player name
final String playerNameNew = (String) arguments[0];
if ( playerNameNew != null
&& !playerNameNew.equals(remoteLocationRequested) ) {
remoteLocationRequested = playerNameNew;
tickUpdateParameters = 0;
markDirtyParameters();
}
}
}

View file

@ -170,9 +170,14 @@ public class WarpDriveConfig {
public static final int LUA_SCRIPTS_ALL = 2;
public static int G_LUA_SCRIPTS = LUA_SCRIPTS_ALL;
public static String G_SCHEMATICS_LOCATION = "warpDrive_schematics";
private static int G_ASSEMBLY_SCAN_INTERVAL_SECONDS = 10;
public static int G_ASSEMBLY_SCAN_INTERVAL_TICKS = 20 * WarpDriveConfig.G_ASSEMBLY_SCAN_INTERVAL_SECONDS;
public static int G_PARAMETERS_UPDATE_INTERVAL_TICKS = 20;
public static int G_BLOCKS_PER_TICK = 3500;
public static boolean G_ENABLE_FAST_SET_BLOCKSTATE = false;
public static boolean G_ENABLE_PROTECTION_CHECKS = true;
public static float G_BLAST_RESISTANCE_CAP = 60.0F;
// Client
@ -253,7 +258,8 @@ public class WarpDriveConfig {
public static int ENERGY_SCAN_INTERVAL_TICKS = 20;
// Starmap
public static int STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS = 10;
private static int STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS = 10;
public static int STARMAP_REGISTRY_UPDATE_INTERVAL_TICKS = 20 * WarpDriveConfig.STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS;
public static boolean STARMAP_ALLOW_OVERLAPPING_CELESTIAL_OBJECTS = false;
// Space generator
@ -274,8 +280,6 @@ public class WarpDriveConfig {
public static int[] SHIP_SIZE_MAX_PER_SIDE_BY_TIER = { 127, 24, 48, 96 };
public static int SHIP_COLLISION_TOLERANCE_BLOCKS = 3;
public static int SHIP_WARMUP_RANDOM_TICKS = 60;
public static int SHIP_CONTROLLER_UPDATE_INTERVAL_SECONDS = 2;
public static int SHIP_CORE_ISOLATION_UPDATE_INTERVAL_SECONDS = 10;
public static int SHIP_VOLUME_SCAN_BLOCKS_PER_TICK = 1000;
public static int SHIP_VOLUME_SCAN_AGE_TOLERANCE_SECONDS = 120;
public static String[] SHIP_MASS_UNLIMITED_PLAYER_NAMES = { "notch", "someone" };
@ -762,6 +766,12 @@ public class WarpDriveConfig {
config.get("general", "lua_scripts", G_LUA_SCRIPTS,
"LUA scripts to load when connecting machines: 0 = none, 1 = templates in a subfolder, 2 = ready to roll (templates are still provided)").getInt());
G_SCHEMATICS_LOCATION = config.get("general", "schematics_location", G_SCHEMATICS_LOCATION, "Root folder where to load and save ship schematics").getString();
G_ASSEMBLY_SCAN_INTERVAL_SECONDS = Commons.clamp(0, 300,
config.get("general", "assembly_scanning_interval", G_ASSEMBLY_SCAN_INTERVAL_SECONDS, "(measured in seconds)").getInt());
G_ASSEMBLY_SCAN_INTERVAL_TICKS = 20 * WarpDriveConfig.G_ASSEMBLY_SCAN_INTERVAL_SECONDS;
G_PARAMETERS_UPDATE_INTERVAL_TICKS = Commons.clamp(0, 300,
config.get("general", "parameters_update_interval", G_PARAMETERS_UPDATE_INTERVAL_TICKS, "(measured in ticks)").getInt());
G_BLOCKS_PER_TICK = Commons.clamp(100, 100000,
config.get("general", "blocks_per_tick", G_BLOCKS_PER_TICK,
"Number of blocks to move per ticks, too high will cause lag spikes on ship jumping or deployment, too low may break the ship wirings").getInt());
@ -769,6 +779,7 @@ public class WarpDriveConfig {
"Enable fast blockstate placement, skipping light computation. Disable if you have world implementations conflicts").getBoolean(G_ENABLE_FAST_SET_BLOCKSTATE);
G_ENABLE_PROTECTION_CHECKS = config.get("general", "enable_protection_checks", G_ENABLE_PROTECTION_CHECKS,
"Enable area protection checks from other mods or plugins, disable if you use the event system exclusively").getBoolean(G_ENABLE_PROTECTION_CHECKS);
G_BLAST_RESISTANCE_CAP = Commons.clamp(10.0F, 6000.0F,
(float) config.get("general", "blast_resistance_cap", G_BLAST_RESISTANCE_CAP,
"Maximum allowed blast resistance for non-hull, breakable blocks from other mods. Required to fix non-sense scaling in modded fluids, etc. Default is basic hull resistance (60).").getDouble(G_BLAST_RESISTANCE_CAP));
@ -900,6 +911,7 @@ public class WarpDriveConfig {
// Starmap registry
STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS = Commons.clamp(0, 300,
config.get("starmap", "registry_update_interval", STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS, "(measured in seconds)").getInt());
STARMAP_REGISTRY_UPDATE_INTERVAL_TICKS = 20 * WarpDriveConfig.STARMAP_REGISTRY_UPDATE_INTERVAL_SECONDS;
STARMAP_ALLOW_OVERLAPPING_CELESTIAL_OBJECTS =
config.get("starmap", "allow_overlapping_celestial_objects", STARMAP_ALLOW_OVERLAPPING_CELESTIAL_OBJECTS, "Enable to bypass the check at boot. Use at your own risk!").getBoolean();
@ -947,14 +959,10 @@ public class WarpDriveConfig {
SHIP_WARMUP_RANDOM_TICKS = Commons.clamp(10, 200,
config.get("ship", "warmup_random_ticks", SHIP_WARMUP_RANDOM_TICKS, "Random variation added to warm-up (measured in ticks)").getInt());
SHIP_CORE_ISOLATION_UPDATE_INTERVAL_SECONDS = Commons.clamp(0, 300,
config.get("ship", "core_isolation_update_interval", SHIP_CORE_ISOLATION_UPDATE_INTERVAL_SECONDS, "(measured in seconds)").getInt());
SHIP_VOLUME_SCAN_BLOCKS_PER_TICK = Commons.clamp(100, 100000,
config.get("ship", "volume_scan_blocks_per_tick", SHIP_VOLUME_SCAN_BLOCKS_PER_TICK, "Number of blocks to scan per tick when getting ship bounds, too high will cause lag spikes when resizing a ship").getInt());
SHIP_VOLUME_SCAN_AGE_TOLERANCE_SECONDS = Commons.clamp(0, 300,
config.get("ship", "volume_scan_age_tolerance", SHIP_VOLUME_SCAN_AGE_TOLERANCE_SECONDS, "Ship volume won't be refreshed unless it's older than that many seconds").getInt());
SHIP_CONTROLLER_UPDATE_INTERVAL_SECONDS = Commons.clamp(0, 300,
config.get("ship", "controller_update_interval", SHIP_CONTROLLER_UPDATE_INTERVAL_SECONDS, "(measured in seconds)").getInt());
// Jump gate
JUMP_GATE_SIZE_MAX_PER_SIDE_BY_TIER =

View file

@ -5,6 +5,7 @@ import cr0s.warpdrive.Commons;
import cr0s.warpdrive.LocalProfiler;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IControlChannel;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.block.atomic.BlockAcceleratorControlPoint;
import cr0s.warpdrive.block.atomic.BlockChiller;
import cr0s.warpdrive.block.atomic.BlockElectromagnetPlain;
@ -78,6 +79,9 @@ public class AcceleratorSetup extends GlobalPosition {
public double[] temperatures_sustainEnergyCost_perTick = new double[3];
public double particleEnergy_energyCost_perTick;
protected boolean isAssemblyValid = true;
protected WarpDriveText textValidityIssues = new WarpDriveText(Commons.styleWarning, "-undefined accelerator setup-");
public AcceleratorSetup(final int dimensionId, @Nonnull final BlockPos blockPos) {
super(dimensionId, blockPos.getX(), blockPos.getY(), blockPos.getZ());
@ -146,6 +150,7 @@ public class AcceleratorSetup extends GlobalPosition {
// get all accelerator and transfer trajectory points
fillTrajectoryPoints(world);
if (trajectoryAccelerator == null) {
assert !isAssemblyValid;
return;
}
@ -195,7 +200,8 @@ public class AcceleratorSetup extends GlobalPosition {
WarpDrive.logger.info(String.format("First void shell is %s", firstVoidShell));
}
if (firstVoidShell == null) {
WarpDrive.logger.warn("No void shell connection found");
isAssemblyValid = false;
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_void_shell_connection");
return;
}
@ -219,6 +225,8 @@ public class AcceleratorSetup extends GlobalPosition {
WarpDrive.logger.info(String.format("First one is %s", trajectoryPoint));
}
if (trajectoryPoint == null) {
isAssemblyValid = false;
textValidityIssues = new WarpDriveText(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_void_shell_connection");
return;
}
@ -320,14 +328,15 @@ public class AcceleratorSetup extends GlobalPosition {
}
}
private void computeVectorArrays(final WorldServer world) {
private void computeVectorArrays(@Nonnull final WorldServer world) {
final WarpDriveText textReason = new WarpDriveText();
boolean isValid = true;
// check for chillers, injectors and colliders blocks
for (final TrajectoryPoint trajectoryPoint : trajectoryAccelerator.values()) {
// check for invalid setup
if (trajectoryPoint.isJammed()) {
if (!trajectoryPoint.getStatus(textReason)) {
setJammed.add(trajectoryPoint);
WarpDrive.logger.info(String.format("Jammed point %s",
trajectoryPoint ));
isValid = false;
}
// check for injectors
@ -364,6 +373,30 @@ public class AcceleratorSetup extends GlobalPosition {
}
}
}
// check counts
if (mapInjectors.isEmpty()) {
isValid = false;
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_injector");
}
if (listColliders.isEmpty()) {
isValid = false;
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_collider_node");
}
if (countMagnets[2] > 0 && countChillers[2] == 0) {
isValid = false;
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_superior_chiller");
} else if (countMagnets[1] > 0 && countChillers[1] == 0) {
isValid = false;
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_advanced_chiller");
} else if (countMagnets[0] > 0 && countChillers[0] == 0) {
isValid = false;
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_basic_chiller");
}
// update validity status
isAssemblyValid = isValid;
textValidityIssues = textReason;
}
private void scanCorners(@Nonnull final WorldServer world, @Nonnull final VectorI vCenter, @Nonnull final EnumFacing forgeDirection) {
@ -509,7 +542,7 @@ public class AcceleratorSetup extends GlobalPosition {
}
// sanity check
public boolean isValid() {
public boolean isDirty() {
if (trajectoryAccelerator == null) {
return false;
}
@ -521,6 +554,11 @@ public class AcceleratorSetup extends GlobalPosition {
return true;
}
public boolean getAssemblyStatus(@Nonnull final WarpDriveText textReason) {
textReason.append(textValidityIssues);
return isAssemblyValid;
}
// Pseudo-API for energy
public long energy_getEnergyStored() {
long energyStored = 0;

View file

@ -8,6 +8,7 @@ public class BlockProperties {
// Common block properties
public static final PropertyBool ACTIVE = PropertyBool.create("active");
public static final UnlistedPropertyBlockState CAMOUFLAGE = new UnlistedPropertyBlockState("camouflage");
public static final PropertyBool CONNECTED = PropertyBool.create("connected");
public static final PropertyDirection FACING = PropertyDirection.create("facing");
}

View file

@ -172,7 +172,7 @@ public class ForceFieldSetup extends GlobalPosition {
} else {
if ( ((TileEntityForceFieldProjector) tileEntity).getIsEnabled()
&& ((TileEntityForceFieldProjector) tileEntity).isCalculated()
&& ((TileEntityForceFieldProjector) tileEntity).isValid() ) {
&& ((TileEntityForceFieldProjector) tileEntity).isAssemblyValid() ) {
projectors.add((TileEntityForceFieldProjector) tileEntity);
}
}

View file

@ -447,7 +447,7 @@ public class StarMapRegistry {
public TileEntityShipCore getIntersectingShipCore(@Nonnull final TileEntityShipCore shipCore1) {
cleanup();
if (!shipCore1.isValid()) {
if (!shipCore1.isAssemblyValid()) {
WarpDrive.logger.error(String.format("isShipCoreIntersectingWithOthers() with invalid ship %s, assuming intersection",
shipCore1));
return null;
@ -487,7 +487,7 @@ public class StarMapRegistry {
final TileEntityShipCore shipCore2 = (TileEntityShipCore) tileEntity;
// Skip invalid ships
if (!shipCore2.isValid()) {
if (!shipCore2.isAssemblyValid()) {
continue;
}

View file

@ -1,5 +1,7 @@
package cr0s.warpdrive.data;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.api.WarpDriveText;
import cr0s.warpdrive.block.atomic.BlockAcceleratorControlPoint;
import cr0s.warpdrive.block.atomic.BlockElectromagnetPlain;
import cr0s.warpdrive.block.atomic.BlockParticlesCollider;
@ -408,8 +410,51 @@ public class TrajectoryPoint extends VectorI {
return isCollider(type);
}
public boolean isJammed() {
return (type & MASK_ERRORS) != ERROR_NONE;
public boolean getStatus(final WarpDriveText textReason) {
final int errorCode = type & MASK_ERRORS;
if (errorCode != ERROR_NONE) {
final String strReasonBefore = textReason.getUnformattedText();
final String strPosition = String.format("(%d %d %d)",
x, y, z );
if ((errorCode & ERROR_DOUBLE_JUNCTION) != 0) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.invalid_double_junction",
strPosition );
}
if ((errorCode & ERROR_VERTICAL_JUNCTION) != 0) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.invalid_vertical_junction",
strPosition );
}
if ((errorCode & ERROR_MISSING_TURNING_MAGNET) != 0) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_turning_magnet",
strPosition );
}
if ((errorCode & ERROR_MISSING_MAIN_MAGNET) != 0) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_main_magnets",
strPosition );
}
if ((errorCode & ERROR_MISSING_CORNER_MAGNET) != 0) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_corner_magnets",
strPosition );
}
if ((errorCode & ERROR_MISSING_COLLIDER) != 0) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_collider_block",
strPosition );
}
if ((errorCode & ERROR_MISSING_VOID_SHELL) != 0) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.missing_void_shell",
strPosition);
}
if ((errorCode & ERROR_TOO_MANY_VOID_SHELLS) != 0) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.too_many_void_shells",
strPosition );
}
if (strReasonBefore.equals(textReason.getUnformattedText())) {
textReason.append(Commons.styleWarning, "warpdrive.accelerator.status_line.invalid_error_code",
errorCode, strPosition);
}
return false;
}
return true;
}
public static boolean isCollider(final int type) {
@ -581,8 +626,10 @@ public class TrajectoryPoint extends VectorI {
isCollider = true;
}
}
if (countLowerMagnet > 8 || countHigherMagnet > 8) {
if (countLowerMagnet < 12 && countHigherMagnet < 12) {// need at least 12 corner magnets
if (tierMain != 0 && (countLowerMagnet > 8 || countHigherMagnet > 8)) {
if (countMainMagnet < 9) {// at least 9 main magnets
typeNew |= ERROR_MISSING_MAIN_MAGNET;
} else if (countLowerMagnet < 12 && countHigherMagnet < 12) {// need at least 12 corner magnets
typeNew |= ERROR_MISSING_CORNER_MAGNET;
} else if (countLowerMagnet != 0 && countHigherMagnet != 0) {// only one type of corner magnets
typeNew |= ERROR_MISSING_CORNER_MAGNET;
@ -594,14 +641,11 @@ public class TrajectoryPoint extends VectorI {
typeNew |= ERROR_MISSING_VOID_SHELL;
} else if ((!isTurning) && countVoidShell > 6) {// a straight junction requires at most 6 void shells
typeNew |= ERROR_TOO_MANY_VOID_SHELLS;
} else if (countMainMagnet < 9) {// at 9 main magnets
typeNew |= ERROR_MISSING_MAIN_MAGNET;
} else if (countVoidShell + countMainMagnet != 15) {// exactly 15 void shells + main magnets
typeNew |= ERROR_MISSING_MAIN_MAGNET;
} else {
isInput = countLowerMagnet > 0;
isOutput = countHigherMagnet > 0;
assert isInput || isOutput;
}
}
}

View file

@ -2,7 +2,9 @@
"forge_marker": 1,
"variants": {
"normal": [{}],
"inventory": [{ "model": "minecraft:cube", "textures": {
"inventory": [{
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
@ -12,127 +14,202 @@
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_active"
} }],
"active=false,facing=down,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
"active=false,connected=false,facing=down,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=up,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
"active=false,connected=false,facing=up,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=north,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
"active=false,connected=false,facing=north,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=south,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
"active=false,connected=false,facing=south,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=west,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
"active=false,connected=false,facing=west,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=east,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
"active=false,connected=false,facing=east,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,facing=down,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"north" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"south" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"west" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-channeling_active"
"active=true,connected=false,facing=down,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,facing=up,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"north" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"south" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"west" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-channeling_active"
"active=true,connected=false,facing=up,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,facing=north,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"north" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"south" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"west" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-channeling_active"
"active=true,connected=false,facing=north,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,facing=south,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"north" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"south" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"west" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-channeling_active"
"active=true,connected=false,facing=south,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,facing=west,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"north" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"south" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"west" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-channeling_active"
"active=true,connected=false,facing=west,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,facing=east,outer=false": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"north" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"south" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"west" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-channeling_active"
"active=true,connected=false,facing=east,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=down,outer=true": { "model": "minecraft:cube", "textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
"active=false,connected=false,facing=down,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=up,outer=true": { "model": "minecraft:cube", "textures": {
"active=false,connected=false,facing=up,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,connected=false,facing=north,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,connected=false,facing=south,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,connected=false,facing=west,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,connected=false,facing=east,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,connected=false,facing=down,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,connected=false,facing=up,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,connected=false,facing=north,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,connected=false,facing=south,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,connected=false,facing=west,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,connected=false,facing=east,outer=true": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,connected=true,facing=down,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_inactive"
} },
"active=false,connected=true,facing=up,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_inactive"
} },
"active=false,connected=true,facing=north,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_inactive"
} },
"active=false,connected=true,facing=south,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_inactive"
} },
"active=false,connected=true,facing=west,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_inactive"
} },
"active=false,connected=true,facing=east,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_inactive"
} },
"active=true,connected=true,facing=down,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_active"
} },
"active=true,connected=true,facing=up,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_active"
} },
"active=true,connected=true,facing=north,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_active"
} },
"active=true,connected=true,facing=south,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_active"
} },
"active=true,connected=true,facing=west,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_active"
} },
"active=true,connected=true,facing=east,outer=false": {
"model": "minecraft:cube_all",
"textures": {
"all": "warpdrive:blocks/detection/cloaking_coil-channeling_active"
} },
"active=false,connected=true,facing=down,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-channeling_inactive",
@ -141,16 +218,20 @@
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=north,outer=true": { "model": "minecraft:cube", "textures": {
"active=false,connected=true,facing=up,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-channeling_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=south,outer=true": { "model": "minecraft:cube", "textures": {
"active=false,connected=true,facing=north,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
@ -159,16 +240,20 @@
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=west,outer=true": { "model": "minecraft:cube", "textures": {
"active=false,connected=true,facing=south,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-channeling_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-channeling_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=false,facing=east,outer=true": { "model": "minecraft:cube", "textures": {
"active=false,connected=true,facing=west,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
@ -177,8 +262,21 @@
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-channeling_inactive"
} },
"active=true,facing=down,outer=true": { "model": "minecraft:cube", "textures": {
"active=false,connected=true,facing=east,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"north" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"south" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive",
"west" : "warpdrive:blocks/detection/cloaking_coil-channeling_inactive",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_inactive"
} },
"active=true,connected=true,facing=down,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
@ -187,7 +285,9 @@
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_active"
} },
"active=true,facing=up,outer=true": { "model": "minecraft:cube", "textures": {
"active=true,connected=true,facing=up,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-channeling_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
@ -196,7 +296,9 @@
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_active"
} },
"active=true,facing=north,outer=true": { "model": "minecraft:cube", "textures": {
"active=true,connected=true,facing=north,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
@ -205,7 +307,9 @@
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_active"
} },
"active=true,facing=south,outer=true": { "model": "minecraft:cube", "textures": {
"active=true,connected=true,facing=south,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
@ -214,7 +318,9 @@
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-projecting_active"
} },
"active=true,facing=west,outer=true": { "model": "minecraft:cube", "textures": {
"active=true,connected=true,facing=west,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
@ -223,7 +329,9 @@
"west" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"east" : "warpdrive:blocks/detection/cloaking_coil-channeling_active"
} },
"active=true,facing=east,outer=true": { "model": "minecraft:cube", "textures": {
"active=true,connected=true,facing=east,outer=true": {
"model": "minecraft:cube",
"textures": {
"particle": "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"down" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",
"up" : "warpdrive:blocks/detection/cloaking_coil-projecting_active",

View file

@ -741,6 +741,21 @@ warpdrive.accelerator.guide.low_power.not_enough_storage=Energiespeicher zu klei
warpdrive.accelerator.guide.low_power.accelerating=Uns geht der Strom aus (%1$s > %2$s %3$s), Chef, Teilchen werden frei, auf massiven Strahlungsaustritt vorbereiten!
warpdrive.accelerator.guide.low_power.no_particles=Wir brauchen mehr Strom um den Beschleuniger zu starten!
warpdrive.accelerator.guide.no_chiller=Für diesen Beschleuniger konnte kein Kühler gefunden werden!
warpdrive.accelerator.status_line.missing_void_shell_connection=Missing void shell connection.
warpdrive.accelerator.status_line.invalid_double_junction=Invalid void shell with double junction at %1$s.
warpdrive.accelerator.status_line.invalid_vertical_junction=Invalid void shell with vertical movement at %1$s.
warpdrive.accelerator.status_line.missing_turning_magnet=Missing main magnets at turning point %1$s.
warpdrive.accelerator.status_line.missing_main_magnets=Missing main magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_corner_magnets=Missing corner magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_collider_block=Missing Particles collider block at %1$s.
warpdrive.accelerator.status_line.missing_void_shell=Missing void shell at %1$s.
warpdrive.accelerator.status_line.too_many_void_shells=Too many void shells at %1$s.
warpdrive.accelerator.status_line.invalid_error_code=Invalid accelerator error code %1$d at %2$s, please report to mod author.
warpdrive.accelerator.status_line.missing_basic_chiller=Missing basic chiller.
warpdrive.accelerator.status_line.missing_advanced_chiller=Missing advanced chiller.
warpdrive.accelerator.status_line.missing_superior_chiller=Missing superior chiller.
warpdrive.accelerator.status_line.missing_injector=Missing accelerator injector node.
warpdrive.accelerator.status_line.missing_collider_node=Missing accelerator collider node.
warpdrive.breathing.alarm=Atemalarm
warpdrive.breathing.invalid_setup=Kein Atemhelm und/oder unvollständige Rüstung
@ -781,6 +796,10 @@ warpdrive.compat.guide.quantum_field_interference=Quantum field interference det
warpdrive.compat.guide.draconic_evolution_portal=Portal detected!
warpdrive.compat.guide.stargate_is_active=Stargate is active (%1$s)!
warpdrive.enan_reactor.status_line.missing_reactor_core=Missing Enantiomorphic reactor core.
warpdrive.enan_reactor.status_line.missing_stabilization_laser=Missing stabilization laser %1$d.
warpdrive.enan_reactor.status_line.non_air_block=Non-air block detected %1$d.
warpdrive.energy.status_line.charge=Charge ist
warpdrive.energy.status_line.input_rate=Input rate is
warpdrive.energy.status_line.output_rate=Output rate is
@ -823,6 +842,8 @@ warpdrive.force_field.upgrade.status_line.translation=Translations
warpdrive.ic2_reactor_laser_cooler.no_reactor=Kein Reaktor gefunden!
warpdrive.ic2_reactor_laser_cooler.reactor_found=Reactor connected on %1$s.
warpdrive.laser.status_line.missing_laser_medium=No laser medium detected, valid sides are %1$d.
warpdrive.laser_tree_farm.status_line.idle=IDLE (not farming)
warpdrive.laser_tree_farm.status_line.warming_up=Warming up...
warpdrive.laser_tree_farm.status_line.scanning_all=Scanning all
@ -932,6 +953,7 @@ warpdrive.ship.status_line.isolation=%1$d aktive Isolations Blöcke bieten %2$s%
warpdrive.teleportation.guide.no_safe_spot=No safe spot found to summon player %1$s
warpdrive.transporter.status_line.from_to=Von (%1$.0f %2$.0f %3$.0f) zu (%4$.0f %5$.0f %6$.0f)
warpdrive.transporter.status_line.missing_containment=Missing or invalid containment for scanner %1$s.
warpdrive.transporter_signature.status_line.invalid=No transporter room linked
warpdrive.transporter_signature.status_line.valid=Linked to transporter room %1$s\n§8%2$s
warpdrive.transporter_signature.get_missing=Transporter room has no signature yet!

View file

@ -741,6 +741,21 @@ warpdrive.accelerator.guide.low_power.not_enough_storage=Energy storage is too l
warpdrive.accelerator.guide.low_power.accelerating=We're running out of power chief (%1$s > %2$s %3$s), particles are on the loose, prepare for massive irradiation!
warpdrive.accelerator.guide.low_power.no_particles=We need more power to start the accelerator!
warpdrive.accelerator.guide.no_chiller=No chiller could be found for this accelerator!
warpdrive.accelerator.status_line.missing_void_shell_connection=Missing void shell connection.
warpdrive.accelerator.status_line.invalid_double_junction=Invalid void shell with double junction at %1$s.
warpdrive.accelerator.status_line.invalid_vertical_junction=Invalid void shell with vertical movement at %1$s.
warpdrive.accelerator.status_line.missing_turning_magnet=Missing main magnets at turning point %1$s.
warpdrive.accelerator.status_line.missing_main_magnets=Missing main magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_corner_magnets=Missing corner magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_collider_block=Missing Particles collider block at %1$s.
warpdrive.accelerator.status_line.missing_void_shell=Missing void shell at %1$s.
warpdrive.accelerator.status_line.too_many_void_shells=Too many void shells at %1$s.
warpdrive.accelerator.status_line.invalid_error_code=Invalid accelerator error code %1$d at %2$s, please report to mod author.
warpdrive.accelerator.status_line.missing_basic_chiller=Missing basic chiller.
warpdrive.accelerator.status_line.missing_advanced_chiller=Missing advanced chiller.
warpdrive.accelerator.status_line.missing_superior_chiller=Missing superior chiller.
warpdrive.accelerator.status_line.missing_injector=Missing accelerator injector node.
warpdrive.accelerator.status_line.missing_collider_node=Missing accelerator collider node.
warpdrive.breathing.alarm=Breathing alarm
warpdrive.breathing.invalid_setup=No breathing helmet\nor incomplete armor
@ -781,6 +796,10 @@ warpdrive.compat.guide.quantum_field_interference=Quantum field interference det
warpdrive.compat.guide.draconic_evolution_portal=Portal detected!
warpdrive.compat.guide.stargate_is_active=Stargate is active (%1$s)!
warpdrive.enan_reactor.status_line.missing_reactor_core=Missing Enantiomorphic reactor core.
warpdrive.enan_reactor.status_line.missing_stabilization_laser=Missing stabilization laser %1$d.
warpdrive.enan_reactor.status_line.non_air_block=Non-air block detected %1$d.
warpdrive.energy.status_line.charge=Charge is
warpdrive.energy.status_line.input_rate=Input rate is
warpdrive.energy.status_line.output_rate=Output rate is
@ -823,6 +842,8 @@ warpdrive.force_field.upgrade.status_line.translation=translation
warpdrive.ic2_reactor_laser_cooler.no_reactor=No reactor found!
warpdrive.ic2_reactor_laser_cooler.reactor_found=Reactor connected on %1$s.
warpdrive.laser.status_line.missing_laser_medium=No laser medium detected, valid sides are %1$d.
warpdrive.laser_tree_farm.status_line.idle=IDLE (not farming)
warpdrive.laser_tree_farm.status_line.warming_up=Warming up...
warpdrive.laser_tree_farm.status_line.scanning_all=Scanning all
@ -932,6 +953,7 @@ warpdrive.ship.status_line.isolation=%1$d active isolation blocks providing %2$s
warpdrive.teleportation.guide.no_safe_spot=No safe spot found to summon player %1$s
warpdrive.transporter.status_line.from_to=From (%1$.0f %2$.0f %3$.0f) to (%4$.0f %5$.0f %6$.0f)
warpdrive.transporter.status_line.missing_containment=Missing or invalid containment for scanner %1$s.
warpdrive.transporter_signature.status_line.invalid=No transporter room linked
warpdrive.transporter_signature.status_line.valid=Linked to transporter room %1$s\n§8%2$s
warpdrive.transporter_signature.get_missing=Transporter room has no signature yet!

View file

@ -741,6 +741,21 @@ warpdrive.accelerator.guide.low_power.not_enough_storage=La capacité de stockag
warpdrive.accelerator.guide.low_power.accelerating=Nous sommes à court d'énergie chef (%1$s > %2$s %3$s), les bunches de particules s'échappent, préparez-vous à une irradiation de masse!
warpdrive.accelerator.guide.low_power.no_particles=Il nous faut plus d'énergie pour démarrer l'accélérateur!
warpdrive.accelerator.guide.no_chiller=Cet accélérateur n'a aucun refroidisseur!
warpdrive.accelerator.status_line.missing_void_shell_connection=Connection manquante avec coquille sous vide.
warpdrive.accelerator.status_line.invalid_double_junction=Coquille sous vide invalide avec double jonction à %1$s.
warpdrive.accelerator.status_line.invalid_vertical_junction=Coquille sous vide invalide avec mouvement vertical à %1$s.
warpdrive.accelerator.status_line.missing_turning_magnet=Electroaimant principal manquant au point de rotation %1$s.
warpdrive.accelerator.status_line.missing_main_magnets=Electroaimant principal manquant au point de contrôle %1$s.
warpdrive.accelerator.status_line.missing_corner_magnets=Electroaimant d'angle manquant au point de contrôle %1$s.
warpdrive.accelerator.status_line.missing_collider_block=Bloc Collisionneur de particules manquant à %1$s.
warpdrive.accelerator.status_line.missing_void_shell=Coquille sous vide manquante à %1$s.
warpdrive.accelerator.status_line.too_many_void_shells=Trop de coquilles sous vide à %1$s.
warpdrive.accelerator.status_line.invalid_error_code=Invalid accelerator error code %1$d at %2$s, please report to mod author.
warpdrive.accelerator.status_line.missing_basic_chiller=Refroidisseur élémentaire manquant.
warpdrive.accelerator.status_line.missing_advanced_chiller=Refroidisseur avancé manquant.
warpdrive.accelerator.status_line.missing_superior_chiller=Refroidisseur supérieur manquant.
warpdrive.accelerator.status_line.missing_injector=Noeud injecteur d'accélérateur manquant.
warpdrive.accelerator.status_line.missing_collider_node=Noeud collisionneur d'accélérateur manquant.
warpdrive.breathing.alarm=Alarme de respiration
warpdrive.breathing.invalid_setup=Pas de casque respiratoire\nou armure incomplète
@ -781,6 +796,10 @@ warpdrive.compat.guide.quantum_field_interference=Interférence de champ quantiq
warpdrive.compat.guide.draconic_evolution_portal=Portail détecté!
warpdrive.compat.guide.stargate_is_active=Porte des étoiles active (%1$s)!
warpdrive.enan_reactor.status_line.missing_reactor_core=Noyau de réacteur Enantiomorphic manquant.
warpdrive.enan_reactor.status_line.missing_stabilization_laser=Laser de stabilisation manquant %1$d.
warpdrive.enan_reactor.status_line.non_air_block=Bloc non-aérien détecté %1$d.
warpdrive.energy.status_line.charge=Chargé à
warpdrive.energy.status_line.input_rate=Entrée à
warpdrive.energy.status_line.output_rate=Sortie à
@ -823,6 +842,8 @@ warpdrive.force_field.upgrade.status_line.translation=translation
warpdrive.ic2_reactor_laser_cooler.no_reactor=Pas de réacteur IC2 trouvé!
warpdrive.ic2_reactor_laser_cooler.reactor_found=Réacteur connecté au %1$s.
warpdrive.laser.status_line.missing_laser_medium=Aucun milieu amplificateur détecté, les côtés valides sont %1$d.
warpdrive.laser_tree_farm.status_line.idle=IDLE (not farming)
warpdrive.laser_tree_farm.status_line.warming_up=Warming up...
warpdrive.laser_tree_farm.status_line.scanning_all=Scanning all
@ -932,6 +953,7 @@ warpdrive.ship.status_line.isolation=Les %1$d blocs d'isolations actifs fourniss
warpdrive.teleportation.guide.no_safe_spot=No safe spot found to summon player %1$s
warpdrive.transporter.status_line.from_to=De (%1$.0f %2$.0f %3$.0f) à (%4$.0f %5$.0f %6$.0f)
warpdrive.transporter.status_line.missing_containment=Confinement manquant ou invalide pour le scanneur %1$s.
warpdrive.transporter_signature.status_line.invalid=No transporter room linked
warpdrive.transporter_signature.status_line.valid=Linked to transporter room %1$s\n§8%2$s
warpdrive.transporter_signature.get_missing=Transporter room has no signature yet!

View file

@ -741,6 +741,21 @@ warpdrive.accelerator.guide.low_power.not_enough_storage=Energie-opslagcapacitei
warpdrive.accelerator.guide.low_power.accelerating=We verliezen stroom baas (%1$s > %2$s %3$s), deeltjes vliegen in het rond, bereid je voor op grote bestraling!
warpdrive.accelerator.guide.low_power.no_particles=We hebben meer stroom nodig om de versneller te activeren!
warpdrive.accelerator.guide.no_chiller=Geen koeler gevonden voor deze versneller!
warpdrive.accelerator.status_line.missing_void_shell_connection=Missing void shell connection.
warpdrive.accelerator.status_line.invalid_double_junction=Invalid void shell with double junction at %1$s.
warpdrive.accelerator.status_line.invalid_vertical_junction=Invalid void shell with vertical movement at %1$s.
warpdrive.accelerator.status_line.missing_turning_magnet=Missing main magnets at turning point %1$s.
warpdrive.accelerator.status_line.missing_main_magnets=Missing main magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_corner_magnets=Missing corner magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_collider_block=Missing Particles collider block at %1$s.
warpdrive.accelerator.status_line.missing_void_shell=Missing void shell at %1$s.
warpdrive.accelerator.status_line.too_many_void_shells=Too many void shells at %1$s.
warpdrive.accelerator.status_line.invalid_error_code=Invalid accelerator error code %1$d at %2$s, please report to mod author.
warpdrive.accelerator.status_line.missing_basic_chiller=Missing basic chiller.
warpdrive.accelerator.status_line.missing_advanced_chiller=Missing advanced chiller.
warpdrive.accelerator.status_line.missing_superior_chiller=Missing superior chiller.
warpdrive.accelerator.status_line.missing_injector=Missing accelerator injector node.
warpdrive.accelerator.status_line.missing_collider_node=Missing accelerator collider node.
warpdrive.breathing.alarm=Ademhalings-alarm
warpdrive.breathing.invalid_setup=Geen helm om in te ademen\of verkeerde armor!
@ -780,6 +795,10 @@ warpdrive.compat.guide.quantum_field_interference=Quantum field interference det
warpdrive.compat.guide.draconic_evolution_portal=Portal detected!
warpdrive.compat.guide.stargate_is_active=Stargate is active (%1$s)!
warpdrive.enan_reactor.status_line.missing_reactor_core=Missing Enantiomorphic reactor core.
warpdrive.enan_reactor.status_line.missing_stabilization_laser=Missing stabilization laser %1$d.
warpdrive.enan_reactor.status_line.non_air_block=Non-air block detected %1$d.
warpdrive.energy.status_line.charge=Charge is
warpdrive.energy.status_line.input_rate=Input rate is
warpdrive.energy.status_line.output_rate=Output rate is
@ -822,6 +841,8 @@ warpdrive.force_field.upgrade.status_line.translation=verandering
warpdrive.ic2_reactor_laser_cooler.no_reactor=Geen reactor gevonden!
warpdrive.ic2_reactor_laser_cooler.reactor_found=Reactor connected on %1$s.
warpdrive.laser.status_line.missing_laser_medium=No laser medium detected, valid sides are %1$d.
warpdrive.laser_tree_farm.status_line.idle=IDLE (not farming)
warpdrive.laser_tree_farm.status_line.warming_up=Warming up...
warpdrive.laser_tree_farm.status_line.scanning_all=Scanning all
@ -931,6 +952,7 @@ warpdrive.ship.status_line.isolation=%1$d actieve isolatie-blokken geven %2$s%%
warpdrive.teleportation.guide.no_safe_spot=No safe spot found to summon player %1$s
warpdrive.transporter.status_line.from_to=Van (%1$.0f %2$.0f %3$.0f) naar (%4$.0f %5$.0f %6$.0f)
warpdrive.transporter.status_line.missing_containment=Missing or invalid containment for scanner %1$s.
warpdrive.transporter_signature.status_line.invalid=No transporter room linked
warpdrive.transporter_signature.status_line.valid=Linked to transporter room %1$s\n§8%2$s
warpdrive.transporter_signature.get_missing=Transporter room has no signature yet!

View file

@ -741,6 +741,21 @@ warpdrive.accelerator.guide.low_power.not_enough_storage=Energy storage is too l
warpdrive.accelerator.guide.low_power.accelerating=We're running out of power chief (%1$s > %2$s %3$s), particles are on the loose, prepare for massive irradiation!
warpdrive.accelerator.guide.low_power.no_particles=We need more power to start the accelerator!
warpdrive.accelerator.guide.no_chiller=No chiller could be found for this accelerator!
warpdrive.accelerator.status_line.missing_void_shell_connection=Missing void shell connection.
warpdrive.accelerator.status_line.invalid_double_junction=Invalid void shell with double junction at %1$s.
warpdrive.accelerator.status_line.invalid_vertical_junction=Invalid void shell with vertical movement at %1$s.
warpdrive.accelerator.status_line.missing_turning_magnet=Missing main magnets at turning point %1$s.
warpdrive.accelerator.status_line.missing_main_magnets=Missing main magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_corner_magnets=Missing corner magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_collider_block=Missing Particles collider block at %1$s.
warpdrive.accelerator.status_line.missing_void_shell=Missing void shell at %1$s.
warpdrive.accelerator.status_line.too_many_void_shells=Too many void shells at %1$s.
warpdrive.accelerator.status_line.invalid_error_code=Invalid accelerator error code %1$d at %2$s, please report to mod author.
warpdrive.accelerator.status_line.missing_basic_chiller=Missing basic chiller.
warpdrive.accelerator.status_line.missing_advanced_chiller=Missing advanced chiller.
warpdrive.accelerator.status_line.missing_superior_chiller=Missing superior chiller.
warpdrive.accelerator.status_line.missing_injector=Missing accelerator injector node.
warpdrive.accelerator.status_line.missing_collider_node=Missing accelerator collider node.
warpdrive.breathing.alarm=Breathing alarm
warpdrive.breathing.invalid_setup=No breathing helmet\nor incomplete armor
@ -781,6 +796,10 @@ warpdrive.compat.guide.quantum_field_interference=Quantum field interference det
warpdrive.compat.guide.draconic_evolution_portal=Portal detected!
warpdrive.compat.guide.stargate_is_active=Stargate is active (%1$s)!
warpdrive.enan_reactor.status_line.missing_reactor_core=Missing Enantiomorphic reactor core.
warpdrive.enan_reactor.status_line.missing_stabilization_laser=Missing stabilization laser %1$d.
warpdrive.enan_reactor.status_line.non_air_block=Non-air block detected %1$d.
warpdrive.energy.status_line.charge=Содержит энергии:
warpdrive.energy.status_line.input_rate=Input rate is
warpdrive.energy.status_line.output_rate=Output rate is
@ -823,6 +842,8 @@ warpdrive.force_field.upgrade.status_line.translation=translation
warpdrive.ic2_reactor_laser_cooler.no_reactor=Реактор не найден!
warpdrive.ic2_reactor_laser_cooler.reactor_found=Reactor connected on %1$s.
warpdrive.laser.status_line.missing_laser_medium=No laser medium detected, valid sides are %1$d.
warpdrive.laser_tree_farm.status_line.idle=IDLE (not farming)
warpdrive.laser_tree_farm.status_line.warming_up=Warming up...
warpdrive.laser_tree_farm.status_line.scanning_all=Scanning all
@ -932,6 +953,7 @@ warpdrive.ship.status_line.isolation=%1$d активных блоков изол
warpdrive.teleportation.guide.no_safe_spot=No safe spot found to summon player %1$s
warpdrive.transporter.status_line.from_to=Из (%1$.0f %2$.0f %3$.0f) в (%4$.0f %5$.0f %6$.0f)
warpdrive.transporter.status_line.missing_containment=Missing or invalid containment for scanner %1$s.
warpdrive.transporter_signature.status_line.invalid=No transporter room linked
warpdrive.transporter_signature.status_line.valid=Linked to transporter room %1$s\n§8%2$s
warpdrive.transporter_signature.get_missing=Transporter room has no signature yet!

View file

@ -746,6 +746,21 @@ warpdrive.accelerator.guide.low_power.not_enough_storage=能量不足;我们需
warpdrive.accelerator.guide.low_power.accelerating=我们的主能量储备耗尽 (%1$s > %2$s %3$s), 粒子正在泄漏,准备承受巨量辐射!
warpdrive.accelerator.guide.low_power.no_particles=需要更多能量以启动加速器!
warpdrive.accelerator.guide.no_chiller=这台加速器没有冷却设备!
warpdrive.accelerator.status_line.missing_void_shell_connection=Missing void shell connection.
warpdrive.accelerator.status_line.invalid_double_junction=Invalid void shell with double junction at %1$s.
warpdrive.accelerator.status_line.invalid_vertical_junction=Invalid void shell with vertical movement at %1$s.
warpdrive.accelerator.status_line.missing_turning_magnet=Missing main magnets at turning point %1$s.
warpdrive.accelerator.status_line.missing_main_magnets=Missing main magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_corner_magnets=Missing corner magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_collider_block=Missing Particles collider block at %1$s.
warpdrive.accelerator.status_line.missing_void_shell=Missing void shell at %1$s.
warpdrive.accelerator.status_line.too_many_void_shells=Too many void shells at %1$s.
warpdrive.accelerator.status_line.invalid_error_code=Invalid accelerator error code %1$d at %2$s, please report to mod author.
warpdrive.accelerator.status_line.missing_basic_chiller=Missing basic chiller.
warpdrive.accelerator.status_line.missing_advanced_chiller=Missing advanced chiller.
warpdrive.accelerator.status_line.missing_superior_chiller=Missing superior chiller.
warpdrive.accelerator.status_line.missing_injector=Missing accelerator injector node.
warpdrive.accelerator.status_line.missing_collider_node=Missing accelerator collider node.
warpdrive.breathing.alarm=呼吸警报
warpdrive.breathing.invalid_setup=无呼吸头盔\未完成盔甲
@ -786,6 +801,10 @@ warpdrive.compat.guide.quantum_field_interference=Quantum field interference det
warpdrive.compat.guide.draconic_evolution_portal=Portal detected!
warpdrive.compat.guide.stargate_is_active=Stargate is active (%1$s)!
warpdrive.enan_reactor.status_line.missing_reactor_core=Missing Enantiomorphic reactor core.
warpdrive.enan_reactor.status_line.missing_stabilization_laser=Missing stabilization laser %1$d.
warpdrive.enan_reactor.status_line.non_air_block=Non-air block detected %1$d.
warpdrive.energy.status_line.charge=能量水平
warpdrive.energy.status_line.input_rate=Input rate is
warpdrive.energy.status_line.output_rate=Output rate is
@ -828,6 +847,8 @@ warpdrive.force_field.upgrade.status_line.translation=转化
warpdrive.ic2_reactor_laser_cooler.no_reactor=未发现反应堆!
warpdrive.ic2_reactor_laser_cooler.reactor_found=Reactor connected on %1$s.
warpdrive.laser.status_line.missing_laser_medium=No laser medium detected, valid sides are %1$d.
warpdrive.laser_tree_farm.status_line.idle=IDLE (not farming)
warpdrive.laser_tree_farm.status_line.warming_up=Warming up...
warpdrive.laser_tree_farm.status_line.scanning_all=Scanning all
@ -937,6 +958,7 @@ warpdrive.ship.status_line.isolation=%1$d有效的隔离方块提供%2$s%%吸收
warpdrive.teleportation.guide.no_safe_spot=No safe spot found to summon player %1$s
warpdrive.transporter.status_line.from_to=从 (%1$.0f %2$.0f %3$.0f) 到 (%4$.0f %5$.0f %6$.0f)
warpdrive.transporter.status_line.missing_containment=Missing or invalid containment for scanner %1$s.
warpdrive.transporter_signature.status_line.invalid=No transporter room linked
warpdrive.transporter_signature.status_line.valid=Linked to transporter room %1$s\n§8%2$s
warpdrive.transporter_signature.get_missing=Transporter room has no signature yet!

View file

@ -740,6 +740,21 @@ warpdrive.accelerator.guide.low_power.not_enough_storage=Energy storage is too l
warpdrive.accelerator.guide.low_power.accelerating=We're running out of power chief (%1$s > %2$s %3$s), particles are on the loose, prepare for massive irradiation!
warpdrive.accelerator.guide.low_power.no_particles=We need more power to start the accelerator!
warpdrive.accelerator.guide.no_chiller=No chiller could be found for this accelerator!
warpdrive.accelerator.status_line.missing_void_shell_connection=Missing void shell connection.
warpdrive.accelerator.status_line.invalid_double_junction=Invalid void shell with double junction at %1$s.
warpdrive.accelerator.status_line.invalid_vertical_junction=Invalid void shell with vertical movement at %1$s.
warpdrive.accelerator.status_line.missing_turning_magnet=Missing main magnets at turning point %1$s.
warpdrive.accelerator.status_line.missing_main_magnets=Missing main magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_corner_magnets=Missing corner magnets at control point %1$s.
warpdrive.accelerator.status_line.missing_collider_block=Missing Particles collider block at %1$s.
warpdrive.accelerator.status_line.missing_void_shell=Missing void shell at %1$s.
warpdrive.accelerator.status_line.too_many_void_shells=Too many void shells at %1$s.
warpdrive.accelerator.status_line.invalid_error_code=Invalid accelerator error code %1$d at %2$s, please report to mod author.
warpdrive.accelerator.status_line.missing_basic_chiller=Missing basic chiller.
warpdrive.accelerator.status_line.missing_advanced_chiller=Missing advanced chiller.
warpdrive.accelerator.status_line.missing_superior_chiller=Missing superior chiller.
warpdrive.accelerator.status_line.missing_injector=Missing accelerator injector node.
warpdrive.accelerator.status_line.missing_collider_node=Missing accelerator collider node.
warpdrive.breathing.alarm=Breathing alarm
warpdrive.breathing.invalid_setup=No breathing helmet\nor incomplete armor
@ -780,6 +795,10 @@ warpdrive.compat.guide.quantum_field_interference=Quantum field interference det
warpdrive.compat.guide.draconic_evolution_portal=Portal detected!
warpdrive.compat.guide.stargate_is_active=Stargate is active (%1$s)!
warpdrive.enan_reactor.status_line.missing_reactor_core=Missing Enantiomorphic reactor core.
warpdrive.enan_reactor.status_line.missing_stabilization_laser=Missing stabilization laser %1$d.
warpdrive.enan_reactor.status_line.non_air_block=Non-air block detected %1$d.
warpdrive.energy.status_line.charge=能量填充
warpdrive.energy.status_line.input_rate=Input rate is
warpdrive.energy.status_line.output_rate=Output rate is
@ -822,6 +841,8 @@ warpdrive.force_field.upgrade.status_line.translation=轉換
warpdrive.ic2_reactor_laser_cooler.no_reactor=沒有反應堆!
warpdrive.ic2_reactor_laser_cooler.reactor_found=Reactor connected on %1$s.
warpdrive.laser.status_line.missing_laser_medium=No laser medium detected, valid sides are %1$d.
warpdrive.laser_tree_farm.status_line.idle=IDLE (not farming)
warpdrive.laser_tree_farm.status_line.warming_up=Warming up...
warpdrive.laser_tree_farm.status_line.scanning_all=Scanning all
@ -931,6 +952,7 @@ warpdrive.ship.status_line.isolation=%1$d 主動隔離塊由 %2$s%% 吸收。
warpdrive.teleportation.guide.no_safe_spot=No safe spot found to summon player %1$s
warpdrive.transporter.status_line.from_to=From (%1$.0f %2$.0f %3$.0f) to (%4$.0f %5$.0f %6$.0f)
warpdrive.transporter.status_line.missing_containment=Missing or invalid containment for scanner %1$s.
warpdrive.transporter_signature.status_line.invalid=No transporter room linked
warpdrive.transporter_signature.status_line.valid=Linked to transporter room %1$s\n§8%2$s
warpdrive.transporter_signature.get_missing=Transporter room has no signature yet!

View file

@ -20,7 +20,7 @@ if cloakingCore == nil or cloakingCore.isInterfaced() ~= true then
else
cloakingCore.enable(true)
os.sleep(1)
local isValid, message = cloakingCore.isAssemblyValid()
local isValid, message = cloakingCore.getAssemblyStatus()
if isValid then
term.setBackgroundColor(colors.lime)
term.setTextColor(colors.blue)

View file

@ -154,7 +154,7 @@ function reactor_page()
energyStored = -1
end
local energy_k = math.floor(energyStored / 100) / 10.0
if not reactorlaser.wrap.isAssemblyValid() then
if not reactorlaser.wrap.getAssemblyStatus() then
w.setColorDisabled()
elseif energyStored > 3 * reactor_laserAmount then
w.setColorSuccess()
@ -290,7 +290,7 @@ function reactor_pulse(output)
energyStored = -1
end
local energy_k = math.floor(energyStored / 100) / 10.0
if not reactorlaser.wrap.isAssemblyValid() then
if not reactorlaser.wrap.getAssemblyStatus() then
w.setColorDisabled()
elseif energyStored > 3 * reactor_laserAmount then
w.setColorSuccess()

View file

@ -474,7 +474,7 @@ function cloaking_page()
else
SetColorDefault()
Write("Cloaking core " .. cloaking_currentKey .. " of " .. #cloakingcores)
local isAssemblyValid = cloakingcore.isAssemblyValid()
local isAssemblyValid = cloakingcore.getAssemblyStatus()
local energyStored, energyMax, energyUnits = cloakingcore.getEnergyStatus()
local isEnabled = cloakingcore.enable()
@ -1280,7 +1280,7 @@ function reactor_page()
Write("Side " .. side .. ":")
SetCursorPos(30, 3 + side)
local energyStored, _, _ = reactorlaser.wrap.getEnergyStatus()
if not reactorlaser.wrap.isAssemblyValid() then
if not reactorlaser.wrap.getAssemblyStatus() then
SetColorDisabled()
elseif energyStored > 3 * data.reactor_laserAmount then
SetColorSuccess()
@ -1421,7 +1421,7 @@ function reactor_pulse(output)
side = side % 4
SetCursorPos(30, 3 + side)
local energyStored, _, _ = reactorlaser.wrap.getEnergyStatus()
if not reactorlaser.wrap.isAssemblyValid() then
if not reactorlaser.wrap.getAssemblyStatus() then
SetColorDisabled()
elseif energyStored > 3 * data.reactor_laserAmount then
SetColorSuccess()

View file

@ -58,7 +58,7 @@ function ship_boot()
local timeout = 10
local isValid, message
repeat
isValid, message = ship.isAssemblyValid()
isValid, message = ship.getAssemblyStatus()
w.sleep(0.05)
timeout = timeout - 1
until isValid == true or timeout < 0
@ -408,7 +408,7 @@ function ship_page_controls()
if ship == nil or ship.isInterfaced() == nil then
w.status_showWarning("No ship controller detected")
else
local isValid, message = ship.isAssemblyValid()
local isValid, message = ship.getAssemblyStatus()
if isValid ~= true then
w.status_showWarning(message)
else
@ -538,7 +538,7 @@ function ship_page_crew()
if ship == nil or ship.isInterfaced() == nil then
w.status_showWarning("No ship controller detected")
else
local isValid, message = ship.isAssemblyValid()
local isValid, message = ship.getAssemblyStatus()
if isValid ~= true then
w.status_showWarning(message)
else
@ -586,7 +586,7 @@ function ship_page_navigation()
if ship == nil or ship.isInterfaced() == nil then
w.status_showWarning("No ship controller detected")
else
local isValid, message = ship.isAssemblyValid()
local isValid, message = ship.getAssemblyStatus()
if isValid ~= true then
w.status_showWarning(message)
else

View file

@ -15,7 +15,7 @@ else
else
cloakingCore.enable(true)
os.sleep(1)
local isValid, message = cloakingCore.isAssemblyValid()
local isValid, message = cloakingCore.getAssemblyStatus()
if isValid then
print("Tier 1 cloaking is enabled")
else

View file

@ -153,7 +153,7 @@ function reactor_page()
energyStored = -1
end
local energy_k = math.floor(energyStored / 100) / 10.0
if not reactorlaser.wrap.isAssemblyValid() then
if not reactorlaser.wrap.getAssemblyStatus() then
w.setColorDisabled()
elseif energyStored > 3 * reactor_laserAmount then
w.setColorSuccess()
@ -293,7 +293,7 @@ function reactor_pulse(output)
energyStored = -1
end
local energy_k = math.floor(energyStored / 100) / 10.0
if not reactorlaser.wrap.isAssemblyValid() then
if not reactorlaser.wrap.getAssemblyStatus() then
w.setColorDisabled()
elseif energyStored > 3 * reactor_laserAmount then
w.setColorSuccess()

View file

@ -59,7 +59,7 @@ function ship_boot()
local timeout = 10
local isValid, message
repeat
isValid, message = ship.isAssemblyValid()
isValid, message = ship.getAssemblyStatus()
w.sleep(0.05)
timeout = timeout - 1
until isValid == true or timeout < 0
@ -412,7 +412,7 @@ function ship_page_controls()
if ship == nil or ship.isInterfaced() == nil then
w.status_showWarning("No ship controller detected")
else
local isValid, message = ship.isAssemblyValid()
local isValid, message = ship.getAssemblyStatus()
if isValid ~= true then
w.status_showWarning(message)
else
@ -542,7 +542,7 @@ function ship_page_crew()
if ship == nil or ship.isInterfaced() == nil then
w.status_showWarning("No ship controller detected")
else
local isValid, message = ship.isAssemblyValid()
local isValid, message = ship.getAssemblyStatus()
if isValid ~= true then
w.status_showWarning(message)
else
@ -590,7 +590,7 @@ function ship_page_navigation()
if ship == nil or ship.isInterfaced() == nil then
w.status_showWarning("No ship controller detected")
else
local isValid, message = ship.isAssemblyValid()
local isValid, message = ship.getAssemblyStatus()
if isValid ~= true then
w.status_showWarning(message)
else