diff --git a/src/main/java/cr0s/warpdrive/api/computer/IMachine.java b/src/main/java/cr0s/warpdrive/api/computer/IMachine.java index d9e96409..07a833e6 100644 --- a/src/main/java/cr0s/warpdrive/api/computer/IMachine.java +++ b/src/main/java/cr0s/warpdrive/api/computer/IMachine.java @@ -6,5 +6,7 @@ public interface IMachine extends IInterfaced { Object[] enable(final Object[] arguments); - Object[] isAssemblyValid(); + Object[] getAssemblyStatus(); + + boolean isAssemblyValid(); } diff --git a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractEnergyCoreOrController.java b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractEnergyCoreOrController.java index 8dfbe953..61e25db9 100644 --- a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractEnergyCoreOrController.java +++ b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractEnergyCoreOrController.java @@ -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; diff --git a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractLaser.java b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractLaser.java index cdd8e90f..9d8e0808 100644 --- a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractLaser.java +++ b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractLaser.java @@ -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(); diff --git a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractMachine.java b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractMachine.java index d08fb5cd..67ba0994 100644 --- a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractMachine.java +++ b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractMachine.java @@ -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); diff --git a/src/main/java/cr0s/warpdrive/block/atomic/TileEntityAcceleratorCore.java b/src/main/java/cr0s/warpdrive/block/atomic/TileEntityAcceleratorCore.java index 0485c0b4..668c6fe1 100644 --- a/src/main/java/cr0s/warpdrive/block/atomic/TileEntityAcceleratorCore.java +++ b/src/main/java/cr0s/warpdrive/block/atomic/TileEntityAcceleratorCore.java @@ -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 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) { diff --git a/src/main/java/cr0s/warpdrive/block/building/TileEntityShipScanner.java b/src/main/java/cr0s/warpdrive/block/building/TileEntityShipScanner.java index aa756d9d..7b7baa13 100644 --- a/src/main/java/cr0s/warpdrive/block/building/TileEntityShipScanner.java +++ b/src/main/java/cr0s/warpdrive/block/building/TileEntityShipScanner.java @@ -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); diff --git a/src/main/java/cr0s/warpdrive/block/detection/BlockCloakingCoil.java b/src/main/java/cr0s/warpdrive/block/detection/BlockCloakingCoil.java index 3a8392a0..3c71dcb4 100644 --- a/src/main/java/cr0s/warpdrive/block/detection/BlockCloakingCoil.java +++ b/src/main/java/cr0s/warpdrive/block/detection/BlockCloakingCoil.java @@ -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); } diff --git a/src/main/java/cr0s/warpdrive/block/detection/BlockCloakingCore.java b/src/main/java/cr0s/warpdrive/block/detection/BlockCloakingCore.java index a8cecabe..e7e745d5 100644 --- a/src/main/java/cr0s/warpdrive/block/detection/BlockCloakingCore.java +++ b/src/main/java/cr0s/warpdrive/block/detection/BlockCloakingCore.java @@ -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); - } } diff --git a/src/main/java/cr0s/warpdrive/block/detection/TileEntityCloakingCore.java b/src/main/java/cr0s/warpdrive/block/detection/TileEntityCloakingCore.java index 15311774..41cc1fee 100644 --- a/src/main/java/cr0s/warpdrive/block/detection/TileEntityCloakingCore.java +++ b/src/main/java/cr0s/warpdrive/block/detection/TileEntityCloakingCore.java @@ -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) diff --git a/src/main/java/cr0s/warpdrive/block/energy/BlockEnanReactorCore.java b/src/main/java/cr0s/warpdrive/block/energy/BlockEnanReactorCore.java index 1db2aa1e..b97530be 100644 --- a/src/main/java/cr0s/warpdrive/block/energy/BlockEnanReactorCore.java +++ b/src/main/java/cr0s/warpdrive/block/energy/BlockEnanReactorCore.java @@ -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); - } - } - } - } } \ No newline at end of file diff --git a/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorController.java b/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorController.java index 2d838970..d34a5703 100644 --- a/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorController.java +++ b/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorController.java @@ -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 diff --git a/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorCore.java b/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorCore.java index 2271b5fd..a89d4497 100644 --- a/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorCore.java +++ b/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorCore.java @@ -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 diff --git a/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorLaser.java b/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorLaser.java index 33bd3e18..47cda850 100644 --- a/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorLaser.java +++ b/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnanReactorLaser.java @@ -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(); diff --git a/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java b/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java index f7cf41af..74d63742 100644 --- a/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java +++ b/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java @@ -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(); diff --git a/src/main/java/cr0s/warpdrive/block/movement/TileEntityJumpGateCore.java b/src/main/java/cr0s/warpdrive/block/movement/TileEntityJumpGateCore.java index b90ba759..3d0632ac 100644 --- a/src/main/java/cr0s/warpdrive/block/movement/TileEntityJumpGateCore.java +++ b/src/main/java/cr0s/warpdrive/block/movement/TileEntityJumpGateCore.java @@ -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() { diff --git a/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipController.java b/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipController.java index 3f33e3b1..be63649b 100644 --- a/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipController.java +++ b/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipController.java @@ -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 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 diff --git a/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipCore.java b/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipCore.java index b86707df..6a1b1aa7 100644 --- a/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipCore.java +++ b/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipCore.java @@ -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() }; diff --git a/src/main/java/cr0s/warpdrive/block/movement/TileEntityTransporterCore.java b/src/main/java/cr0s/warpdrive/block/movement/TileEntityTransporterCore.java index d6ec4f1a..f6e9c06b 100644 --- a/src/main/java/cr0s/warpdrive/block/movement/TileEntityTransporterCore.java +++ b/src/main/java/cr0s/warpdrive/block/movement/TileEntityTransporterCore.java @@ -96,9 +96,6 @@ public class TileEntityTransporterCore extends TileEntityAbstractEnergyCoreOrCon // computed properties private ArrayList 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 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 vScanners, final Collection 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(); } } } diff --git a/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java b/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java index 23766621..a0adf254 100644 --- a/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java +++ b/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java @@ -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 = diff --git a/src/main/java/cr0s/warpdrive/data/AcceleratorSetup.java b/src/main/java/cr0s/warpdrive/data/AcceleratorSetup.java index a505803b..280bd4c5 100644 --- a/src/main/java/cr0s/warpdrive/data/AcceleratorSetup.java +++ b/src/main/java/cr0s/warpdrive/data/AcceleratorSetup.java @@ -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; diff --git a/src/main/java/cr0s/warpdrive/data/BlockProperties.java b/src/main/java/cr0s/warpdrive/data/BlockProperties.java index 547431a8..9a3b24d9 100644 --- a/src/main/java/cr0s/warpdrive/data/BlockProperties.java +++ b/src/main/java/cr0s/warpdrive/data/BlockProperties.java @@ -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"); } diff --git a/src/main/java/cr0s/warpdrive/data/ForceFieldSetup.java b/src/main/java/cr0s/warpdrive/data/ForceFieldSetup.java index e9dc6c3c..b15242de 100644 --- a/src/main/java/cr0s/warpdrive/data/ForceFieldSetup.java +++ b/src/main/java/cr0s/warpdrive/data/ForceFieldSetup.java @@ -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); } } diff --git a/src/main/java/cr0s/warpdrive/data/StarMapRegistry.java b/src/main/java/cr0s/warpdrive/data/StarMapRegistry.java index 70b2eb7c..50fb4fde 100644 --- a/src/main/java/cr0s/warpdrive/data/StarMapRegistry.java +++ b/src/main/java/cr0s/warpdrive/data/StarMapRegistry.java @@ -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; } diff --git a/src/main/java/cr0s/warpdrive/data/TrajectoryPoint.java b/src/main/java/cr0s/warpdrive/data/TrajectoryPoint.java index cec197b4..6b4a59fa 100644 --- a/src/main/java/cr0s/warpdrive/data/TrajectoryPoint.java +++ b/src/main/java/cr0s/warpdrive/data/TrajectoryPoint.java @@ -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; } } } diff --git a/src/main/resources/assets/warpdrive/blockstates/cloaking_coil.json b/src/main/resources/assets/warpdrive/blockstates/cloaking_coil.json index 558c1ea6..67318a8e 100644 --- a/src/main/resources/assets/warpdrive/blockstates/cloaking_coil.json +++ b/src/main/resources/assets/warpdrive/blockstates/cloaking_coil.json @@ -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", diff --git a/src/main/resources/assets/warpdrive/lang/de_de.lang b/src/main/resources/assets/warpdrive/lang/de_de.lang index 3e68ba63..a974f445 100644 --- a/src/main/resources/assets/warpdrive/lang/de_de.lang +++ b/src/main/resources/assets/warpdrive/lang/de_de.lang @@ -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! diff --git a/src/main/resources/assets/warpdrive/lang/en_us.lang b/src/main/resources/assets/warpdrive/lang/en_us.lang index 4b1a9c9d..70319a8c 100644 --- a/src/main/resources/assets/warpdrive/lang/en_us.lang +++ b/src/main/resources/assets/warpdrive/lang/en_us.lang @@ -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! diff --git a/src/main/resources/assets/warpdrive/lang/fr_fr.lang b/src/main/resources/assets/warpdrive/lang/fr_fr.lang index ef387867..a0432cda 100644 --- a/src/main/resources/assets/warpdrive/lang/fr_fr.lang +++ b/src/main/resources/assets/warpdrive/lang/fr_fr.lang @@ -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! diff --git a/src/main/resources/assets/warpdrive/lang/nl_nl.lang b/src/main/resources/assets/warpdrive/lang/nl_nl.lang index 9655c23c..1b5ec434 100644 --- a/src/main/resources/assets/warpdrive/lang/nl_nl.lang +++ b/src/main/resources/assets/warpdrive/lang/nl_nl.lang @@ -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! diff --git a/src/main/resources/assets/warpdrive/lang/ru_ru.lang b/src/main/resources/assets/warpdrive/lang/ru_ru.lang index 255e7613..a5671c76 100644 --- a/src/main/resources/assets/warpdrive/lang/ru_ru.lang +++ b/src/main/resources/assets/warpdrive/lang/ru_ru.lang @@ -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! diff --git a/src/main/resources/assets/warpdrive/lang/zh_cn.lang b/src/main/resources/assets/warpdrive/lang/zh_cn.lang index 9062f394..520135de 100644 --- a/src/main/resources/assets/warpdrive/lang/zh_cn.lang +++ b/src/main/resources/assets/warpdrive/lang/zh_cn.lang @@ -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! diff --git a/src/main/resources/assets/warpdrive/lang/zh_tw.lang b/src/main/resources/assets/warpdrive/lang/zh_tw.lang index 01500fd0..8d7d4cbd 100644 --- a/src/main/resources/assets/warpdrive/lang/zh_tw.lang +++ b/src/main/resources/assets/warpdrive/lang/zh_tw.lang @@ -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! diff --git a/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveCloakingCore/enable b/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveCloakingCore/enable index 913e3f77..fb824113 100644 --- a/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveCloakingCore/enable +++ b/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveCloakingCore/enable @@ -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) diff --git a/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveEnanReactorCore/startup b/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveEnanReactorCore/startup index 4d53b928..f3de6700 100644 --- a/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveEnanReactorCore/startup +++ b/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveEnanReactorCore/startup @@ -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() diff --git a/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveMainframe/startup b/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveMainframe/startup index 3cb85614..2fea816d 100644 --- a/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveMainframe/startup +++ b/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveMainframe/startup @@ -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() diff --git a/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveShipController/startup b/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveShipController/startup index 22dc5ce9..1245c88f 100644 --- a/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveShipController/startup +++ b/src/main/resources/assets/warpdrive/lua.ComputerCraft/warpdriveShipController/startup @@ -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 diff --git a/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveCloakingCore/enable b/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveCloakingCore/enable index a3268ec1..c7980048 100644 --- a/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveCloakingCore/enable +++ b/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveCloakingCore/enable @@ -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 diff --git a/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveEnanReactorCore/startup b/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveEnanReactorCore/startup index 7de49b8c..d24c11c8 100644 --- a/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveEnanReactorCore/startup +++ b/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveEnanReactorCore/startup @@ -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() diff --git a/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveShipController/startup b/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveShipController/startup index 616c604f..5605b5dc 100644 --- a/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveShipController/startup +++ b/src/main/resources/assets/warpdrive/lua.OpenComputers/warpdriveShipController/startup @@ -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