Merge 1.7.10 on 1.10

This commit is contained in:
Unknown 2018-01-31 21:43:42 +01:00
commit be8943e8d6
98 changed files with 2835 additions and 1598 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -73,8 +73,8 @@ public class BreathingManager {
}
if (WarpDriveConfig.LOGGING_BREATHING) {
WarpDrive.logger.warn(String.format("Entity spawn denied at DIM%d @ (%d %d %d) entityId '%s'",
entityLivingBase.worldObj.provider.getDimension(),
WarpDrive.logger.warn(String.format("Entity spawn denied @ %s (%d %d %d) entityId '%s'",
entityLivingBase.worldObj.provider.getSaveFolder(),
x, y, z, idEntity));
}
return false;
@ -100,8 +100,9 @@ public class BreathingManager {
vAirBlock = vPosition;
break;
} else if (block != Blocks.AIR) {
StateAir stateAir = ChunkHandler.getStateAir(entityLivingBase.worldObj, vPosition.x, vPosition.y, vPosition.z);
if (stateAir.concentration > 0) {
final StateAir stateAir = ChunkHandler.getStateAir(entityLivingBase.worldObj, vPosition.x, vPosition.y, vPosition.z);
if ( stateAir == null
|| stateAir.concentration > 0 ) {
vAirBlock = vPosition;
break;
}

View file

@ -1,6 +1,7 @@
package cr0s.warpdrive;
import cr0s.warpdrive.config.Dictionary;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.BlockProperties;
import cr0s.warpdrive.data.VectorI;
@ -15,6 +16,7 @@ import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.util.EnumBlockRenderType;
@ -29,6 +31,8 @@ import net.minecraft.world.World;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.fml.server.FMLServerHandler;
import java.io.File;
@ -543,6 +547,12 @@ public class Commons {
return null;
}
public static EntityPlayerMP getOnlinePlayerByName(final String playerName) {
final MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
assert(server != null);
return server.getPlayerList().getPlayerByUsername(playerName);
}
public static int colorARGBtoInt(final int alpha, final int red, final int green, final int blue) {
return (clamp(0, 255, alpha) << 24)
+ (clamp(0, 255, red ) << 16)
@ -550,6 +560,17 @@ public class Commons {
+ clamp(0, 255, blue );
}
@Optional.Method(modid = "NotEnoughItems")
public static void NEI_hideItemStack(final ItemStack itemStack) {
// @TODO MC1.10: codechicken.nei.api.API.hideItem(itemStack);
}
public static void hideItemStack(final ItemStack itemStack) {
if (WarpDriveConfig.isNotEnoughItemsLoaded) {
NEI_hideItemStack(itemStack);
}
}
public static EnumFacing getDirection(final int index) {
if (index < 0 || index > 5) {
return null;

View file

@ -46,7 +46,7 @@ public class LocalProfiler {
}
}
private static void printCallStats() {
public static void printCallStats() {
WarpDrive.logger.info("Dumping chunk stats:");
for (Entry<String, Integer> entryStat : stats.entrySet()) {
WarpDrive.logger.info(String.format("%10d x %s",

View file

@ -76,6 +76,7 @@ import cr0s.warpdrive.data.*;
import cr0s.warpdrive.event.ChunkHandler;
import cr0s.warpdrive.event.ClientHandler;
import cr0s.warpdrive.event.CommonWorldGenerator;
import cr0s.warpdrive.event.ItemHandler;
import cr0s.warpdrive.event.LivingHandler;
import cr0s.warpdrive.event.ModelBakeEventHandler;
import cr0s.warpdrive.event.WorldHandler;
@ -536,10 +537,9 @@ public class WarpDrive implements LoadingCallback {
// Event handlers
MinecraftForge.EVENT_BUS.register(new ClientHandler());
MinecraftForge.EVENT_BUS.register(ModelBakeEventHandler.instance);
MinecraftForge.EVENT_BUS.register(new ItemHandler());
MinecraftForge.EVENT_BUS.register(new LivingHandler());
MinecraftForge.EVENT_BUS.register(ModelBakeEventHandler.instance);
if (WarpDriveConfig.isComputerCraftLoaded) {
peripheralHandler = new WarpDrivePeripheralHandler();

View file

@ -0,0 +1,9 @@
package cr0s.warpdrive.api;
public class ExceptionChunkNotLoaded extends Exception {
public ExceptionChunkNotLoaded(final String message) {
super(message);
}
}

View file

@ -49,4 +49,13 @@ public interface ICelestialObject {
*/
boolean isInsideBorder(final double x, final double z);
/**
* Check if given position is in this object orbit.
*
* @param dimensionId current position in parent dimension
* @param x current position in parent dimension
* @param z current position in parent dimension
* @return true if we're in orbit of the object
*/
boolean isInOrbit(final int dimensionId, final double x, final double z);
}

View file

@ -1,6 +1,7 @@
package cr0s.warpdrive.api;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@ -8,7 +9,11 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
public interface IItemBase {
// wrapper for Forge ItemExpireEvent
void onEntityExpireEvent(EntityItem entityItem, ItemStack itemStack);
@Nonnull
@SideOnly(Side.CLIENT)
ModelResourceLocation getModelResourceLocation(ItemStack itemStack);
}
}

View file

@ -0,0 +1,9 @@
package cr0s.warpdrive.api;
/**
* For internal use only
*/
public interface ISequencerCallbacks {
void sequencer_finished();
}

View file

@ -1,11 +1,15 @@
package cr0s.warpdrive.api;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.data.Vector3;
import java.util.Locale;
import net.minecraft.item.EnumRarity;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@ -16,6 +20,9 @@ public class Particle {
protected int colorIndex;
protected EnumRarity enumRarity = EnumRarity.COMMON;
private int entityLifespan;
private float radiationLevel = 0.0F;
private float explosionStrength = 0.0F;
public Particle(final String registryName) {
this.registryName = registryName.toLowerCase(Locale.ENGLISH);
@ -41,6 +48,21 @@ public class Particle {
return this;
}
public Particle setEntityLifespan(final int entityLifespan) {
this.entityLifespan = entityLifespan;
return this;
}
public Particle setRadiationLevel(final float radiationLevel) {
this.radiationLevel = radiationLevel;
return this;
}
public Particle setExplosionStrength(final float explosionStrength) {
this.explosionStrength = explosionStrength;
return this;
}
public final String getRegistryName()
{
return this.registryName;
@ -79,5 +101,26 @@ public class Particle {
{
return color;
}
public int getEntityLifespan() {
return entityLifespan;
}
/* Effector */
public void onWorldEffect(final World world, final Vector3 v3Position, final int amount) {
if (world.isRemote) {
return;
}
if (radiationLevel > 0.0F) {
final float strength = radiationLevel * amount / 1000.0F;
WarpDrive.damageIrradiation.onWorldEffect(world, v3Position, strength);
}
if (explosionStrength > 0.0F) {
final float amountFactor = Math.max(1.25F, amount / 1000.0F);
world.newExplosion(null, v3Position.x, v3Position.y, v3Position.z, explosionStrength * amountFactor, true, true);
WarpDrive.logger.info("Particle caused explosion at " + v3Position.x + " " + v3Position.y + " " + v3Position.z + " with strength " + explosionStrength * amountFactor);
}
}
}

View file

@ -18,10 +18,14 @@ public class ParticleRegistry {
private static BiMap<String, Particle> particles = HashBiMap.create();
public static final Particle ION = new Particle("ion") { }.setColor(0xE5FF54).setRarity(EnumRarity.COMMON).setColorIndex(0);
public static final Particle PROTON = new Particle("proton") { }.setColor(0xE5FF54).setRarity(EnumRarity.COMMON).setColorIndex(1);
public static final Particle ANTIMATTER = new Particle("antimatter") { }.setColor(0x1C3CAF).setRarity(EnumRarity.UNCOMMON).setColorIndex(2);
public static final Particle STRANGE_MATTER = new Particle("strange_matter") { }.setColor(0xE2414C).setRarity(EnumRarity.RARE).setColorIndex(3);
public static final Particle ION = new Particle("ion") { }.setColor(0xE5FF54).setRarity(EnumRarity.COMMON).setColorIndex(0)
.setEntityLifespan(200).setRadiationLevel(2.0F).setExplosionStrength(0.3F);
public static final Particle PROTON = new Particle("proton") { }.setColor(0xE5FF54).setRarity(EnumRarity.COMMON).setColorIndex(1)
.setEntityLifespan(200).setRadiationLevel(4.0F).setExplosionStrength(0.5F);
public static final Particle ANTIMATTER = new Particle("antimatter") { }.setColor(0x1C3CAF).setRarity(EnumRarity.UNCOMMON).setColorIndex(2)
.setEntityLifespan(60).setRadiationLevel(10.0F).setExplosionStrength(1.0F);
public static final Particle STRANGE_MATTER = new Particle("strange_matter") { }.setColor(0xE2414C).setRarity(EnumRarity.RARE).setColorIndex(3)
.setEntityLifespan(40).setRadiationLevel(14.0F).setExplosionStrength(0.8F);
// public static final Particle TACHYONS = new Particle("tachyons") { }.setColor(0xE5FF54).setRarity(EnumRarity.EPIC).setColorIndex(4);
static {

View file

@ -1,10 +1,13 @@
package cr0s.warpdrive.api;
import cr0s.warpdrive.data.Vector3;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraft.world.World;
public class ParticleStack {
private final Particle particle;
@ -76,6 +79,20 @@ public class ParticleStack {
amount += amountAdded;
}
public int getEntityLifespan() {
if (particle == null) {
return -1;
}
return particle.getEntityLifespan();
}
public void onWorldEffect(@Nonnull final World world, @Nonnull final Vector3 v3Position) {
if (particle == null) {
return;
}
particle.onWorldEffect(world, v3Position, amount);
}
public String getLocalizedName() {
return this.getParticle().getLocalizedName();
}

View file

@ -0,0 +1,10 @@
package cr0s.warpdrive.api.computer;
public interface IAbstractLaser extends IInterfaced {
Object[] energy();
Object[] laserMediumDirection();
Object[] laserMediumCount();
}

View file

@ -1,5 +1,6 @@
package cr0s.warpdrive.block;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IBlockBase;
import cr0s.warpdrive.api.IBlockUpdateDetector;
@ -38,7 +39,8 @@ import javax.annotation.Nullable;
})
public abstract class BlockAbstractContainer extends BlockContainer implements IBlockBase, defense.api.IEMPBlock, resonant.api.explosion.IEMPBlock {
protected boolean hasSubBlocks = false; // @TODO: code review
protected boolean hasSubBlocks = false;
private static boolean isInvalidEMPreported = false;
protected BlockAbstractContainer(final String registryName, final Material material) {
super(material);
@ -155,8 +157,8 @@ public abstract class BlockAbstractContainer extends BlockContainer implements I
@Optional.Method(modid = "DefenseTech")
public void onEMP(World world, int x, int y, int z, defense.api.IExplosion explosiveEMP) {
if (WarpDriveConfig.LOGGING_WEAPON) {
WarpDrive.logger.info(String.format("EMP received @ DIM%d (%d %d %d) from %s with energy %d and radius %.1f",
world.provider.getDimension(), x, y, z,
WarpDrive.logger.info(String.format("EMP received @ %s (%d %d %d) from %s with energy %d and radius %.1f",
world.provider.getSaveFolder(), x, y, z,
explosiveEMP, explosiveEMP.getEnergy(), explosiveEMP.getRadius()));
}
// EMP tower = 3k Energy, 60 radius
@ -166,9 +168,13 @@ public abstract class BlockAbstractContainer extends BlockContainer implements I
} else if (explosiveEMP.getRadius() == 50.0F) {
onEMP(world, new BlockPos(x, y, z), 0.70F);
} else {
WarpDrive.logger.warn(String.format("EMP received @ DIM%d (%d %d %d) from %s with energy %d and unsupported radius %.1f",
world.provider.getDimension(), x, y, z,
explosiveEMP, explosiveEMP.getEnergy(), explosiveEMP.getRadius()));
if (!isInvalidEMPreported) {
isInvalidEMPreported = true;
WarpDrive.logger.warn(String.format("EMP received @ %s (%d %d %d) from %s with energy %d and unsupported radius %.1f",
world.provider.getSaveFolder(), x, y, z,
explosiveEMP, explosiveEMP.getEnergy(), explosiveEMP.getRadius()));
Commons.dumpAllThreads();
}
onEMP(world, new BlockPos(x, y, z), 0.02F);
}
}
@ -177,8 +183,8 @@ public abstract class BlockAbstractContainer extends BlockContainer implements I
@Optional.Method(modid = "icbmclassic")
public void onEMP(World world, int x, int y, int z, resonant.api.explosion.IExplosion explosiveEMP) {
if (WarpDriveConfig.LOGGING_WEAPON) {
WarpDrive.logger.info(String.format("EMP received @ DIM%d (%d %d %d) from %s with energy %d and radius %.1f",
world.provider.getDimension(), x, y, z,
WarpDrive.logger.info(String.format("EMP received @ %s (%d %d %d) from %s with energy %d and radius %.1f",
world.provider.getSaveFolder(), x, y, z,
explosiveEMP, explosiveEMP.getEnergy(), explosiveEMP.getRadius()));
}
// EMP tower = 3k Energy, 60 radius
@ -188,9 +194,13 @@ public abstract class BlockAbstractContainer extends BlockContainer implements I
} else if (explosiveEMP.getRadius() == 50.0F) {
onEMP(world, new BlockPos(x, y, z), 0.70F);
} else {
WarpDrive.logger.warn(String.format("EMP received @ DIM%d (%d %d %d) from %s with energy %d and unsupported radius %.1f",
world.provider.getDimension(), x, y, z,
explosiveEMP, explosiveEMP.getEnergy(), explosiveEMP.getRadius()));
if (!isInvalidEMPreported) {
isInvalidEMPreported = true;
WarpDrive.logger.warn(String.format("EMP received @ %s (%d %d %d) from %s with energy %d and unsupported radius %.1f",
world.provider.getSaveFolder(), x, y, z,
explosiveEMP, explosiveEMP.getEnergy(), explosiveEMP.getRadius()));
Commons.dumpAllThreads();
}
onEMP(world, new BlockPos(x, y, z), 0.02F);
}
}

View file

@ -14,6 +14,7 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.ItemBlock;
@ -70,6 +71,10 @@ public class ItemBlockAbstractBase extends ItemBlock implements IItemBase {
}
}
@Override
public void onEntityExpireEvent(EntityItem entityItem, ItemStack itemStack) {
}
@Nonnull
@Override
public ModelResourceLocation getModelResourceLocation(final ItemStack itemStack) {

View file

@ -1,5 +1,6 @@
package cr0s.warpdrive.block;
import cr0s.warpdrive.api.computer.IAbstractLaser;
import cr0s.warpdrive.config.WarpDriveConfig;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
@ -16,12 +17,17 @@ import net.minecraft.util.EnumFacing;
import net.minecraftforge.fml.common.Optional;
// Abstract class to manage laser mediums
public abstract class TileEntityAbstractLaser extends TileEntityAbstractInterfaced {
// direction of the laser medium stack
protected EnumFacing facingLaserMedium = null;
protected EnumFacing[] directionsValidLaserMedium = EnumFacing.values();
protected int laserMediumMaxCount = 0;
protected int laserMediumCount = 0;
public abstract class TileEntityAbstractLaser extends TileEntityAbstractInterfaced implements IAbstractLaser {
// configuration overridden by derived classes
protected EnumFacing[] laserMedium_directionsValid = EnumFacing.values();
protected int laserMedium_maxCount = 0;
// computed properties
protected EnumFacing laserMedium_direction = null;
protected int cache_laserMedium_count = 0;
protected int cache_laserMedium_energyStored = 0;
protected int cache_laserMedium_maxStorage = 0;
private final int updateInterval_ticks = 20 * WarpDriveConfig.SHIP_CONTROLLER_UPDATE_INTERVAL_SECONDS;
private int updateTicks = updateInterval_ticks;
@ -48,7 +54,7 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractInterfac
// accelerate update ticks during boot
if (bootTicks > 0) {
bootTicks--;
if (facingLaserMedium == null) {
if (laserMedium_direction == null) {
updateTicks = 1;
}
}
@ -56,53 +62,74 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractInterfac
if (updateTicks <= 0) {
updateTicks = updateInterval_ticks;
updateLaserMediumStatus();
updateLaserMediumDirection();
}
}
private void updateLaserMediumStatus() {
for(EnumFacing facing : directionsValidLaserMedium) {
private void updateLaserMediumDirection() {
assert(laserMedium_maxCount != 0);
for (final EnumFacing facing : laserMedium_directionsValid) {
TileEntity tileEntity = worldObj.getTileEntity(pos.offset(facing));
if (tileEntity != null && tileEntity instanceof TileEntityLaserMedium) {
facingLaserMedium = facing;
laserMediumCount = 0;
while(tileEntity != null && (tileEntity instanceof TileEntityLaserMedium) && laserMediumCount < laserMediumMaxCount) {
laserMediumCount++;
tileEntity = worldObj.getTileEntity(pos.offset(facing, laserMediumCount + 1));
if (tileEntity instanceof TileEntityLaserMedium) {
// at least one found
int energyStored = 0;
int maxStorage = 0;
int count = 1;
while ( (tileEntity instanceof TileEntityLaserMedium)
&& count <= laserMedium_maxCount) {
// add current one
energyStored += ((TileEntityLaserMedium) tileEntity).energy_getEnergyStored();
maxStorage += ((TileEntityLaserMedium) tileEntity).energy_getMaxStorage();
count++;
// check next one
tileEntity = worldObj.getTileEntity(pos.offset(facing, count + 1));
}
// save results
laserMedium_direction = facing;
cache_laserMedium_count = count;
cache_laserMedium_energyStored = energyStored;
cache_laserMedium_maxStorage = maxStorage;
return;
}
}
facingLaserMedium = null;
// nothing found
laserMedium_direction = null;
cache_laserMedium_count = 0;
cache_laserMedium_energyStored = 0;
cache_laserMedium_maxStorage = 0;
}
protected int getEnergyStored() {
return consumeCappedEnergyFromLaserMediums(Integer.MAX_VALUE, true);
protected int laserMedium_getEnergyStored() {
return laserMedium_consumeUpTo(Integer.MAX_VALUE, true);
}
protected boolean consumeEnergyFromLaserMediums(final int amount, final boolean simulate) {
protected boolean laserMedium_consumeExactly(final int amountRequested, final boolean simulate) {
final int amountSimulated = laserMedium_consumeUpTo(amountRequested, true);
if (simulate) {
return amount <= consumeCappedEnergyFromLaserMediums(amount, true);
} else {
if (amount > consumeCappedEnergyFromLaserMediums(amount, true)) {
return false;
} else {
return amount <= consumeCappedEnergyFromLaserMediums(amount, false);
}
return amountRequested <= amountSimulated;
}
if (amountRequested > amountSimulated) {
return false;
}
return amountRequested <= laserMedium_consumeUpTo(amountRequested, false);
}
protected int consumeCappedEnergyFromLaserMediums(final int amount, final boolean simulate) {
if (facingLaserMedium == null) {
protected int laserMedium_consumeUpTo(final int amount, final boolean simulate) {
if (laserMedium_direction == null) {
return 0;
}
// Primary scan of all laser mediums
int totalEnergy = 0;
int count = 1;
List<TileEntityLaserMedium> laserMediums = new LinkedList<>();
for (; count <= laserMediumMaxCount; count++) {
TileEntity tileEntity = worldObj.getTileEntity(pos.offset(facingLaserMedium, count));
final List<TileEntityLaserMedium> laserMediums = new LinkedList<>();
for (; count <= laserMedium_maxCount; count++) {
final TileEntity tileEntity = worldObj.getTileEntity(pos.offset(laserMedium_direction, count));
if (!(tileEntity instanceof TileEntityLaserMedium)) {
break;
}
@ -145,33 +172,24 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractInterfac
return energyTotalConsumed;
}
protected Object[] energy() {
if (facingLaserMedium == null) {
return new Object[] { 0, 0 };
} else {
int energyStored = 0;
int energyStoredMax = 0;
int count = 1;
// List<TileEntityLaserMedium> laserMediums = new LinkedList();
for (; count <= laserMediumMaxCount; count++) {
TileEntity tileEntity = worldObj.getTileEntity(pos.offset(facingLaserMedium, count));
if (!(tileEntity instanceof TileEntityLaserMedium)) {
break;
}
// laserMediums.add((TileEntityLaserMedium) tileEntity);
energyStored += ((TileEntityLaserMedium) tileEntity).energy_getEnergyStored();
energyStoredMax += ((TileEntityLaserMedium) tileEntity).energy_getMaxStorage();
}
return new Object[] { energyStored, energyStoredMax };
}
// IAbstractLaser overrides
@Override
public Object[] energy() {
return new Object[] { cache_laserMedium_energyStored, cache_laserMedium_maxStorage };
}
protected Object[] laserMediumDirection() {
return new Object[] { facingLaserMedium.name(), facingLaserMedium.getFrontOffsetX(), facingLaserMedium.getFrontOffsetY(), facingLaserMedium.getFrontOffsetZ() };
@Override
public Object[] laserMediumDirection() {
return new Object[] {
laserMedium_direction.name(),
laserMedium_direction.getFrontOffsetX(),
laserMedium_direction.getFrontOffsetY(),
laserMedium_direction.getFrontOffsetZ() };
}
protected Object[] laserMediumCount() {
return new Object[] { laserMediumCount };
@Override
public Object[] laserMediumCount() {
return new Object[] { cache_laserMedium_count };
}
// OpenComputers callback methods
@ -187,6 +205,12 @@ public abstract class TileEntityAbstractLaser extends TileEntityAbstractInterfac
return laserMediumDirection();
}
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] laserMediumCount(Context context, Arguments arguments) {
return laserMediumCount();
}
// ComputerCraft IPeripheral methods
@Override
@Optional.Method(modid = "ComputerCraft")

View file

@ -82,7 +82,7 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
"beamFrequency",
"getScanResult"
});
laserMediumMaxCount = WarpDriveConfig.LASER_CANNON_MAX_MEDIUMS_COUNT;
laserMedium_maxCount = WarpDriveConfig.LASER_CANNON_MAX_MEDIUMS_COUNT;
}
@Override
@ -122,8 +122,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|| (beamFrequency == BEAM_FREQUENCY_SCANNING && delayTicks > WarpDriveConfig.LASER_CANNON_EMIT_SCAN_DELAY_TICKS))) {
delayTicks = 0;
isEmitting = false;
int beamEnergy = Math.min(
consumeCappedEnergyFromLaserMediums(Integer.MAX_VALUE, false) + MathHelper.floor_double(energyFromOtherBeams * WarpDriveConfig.LASER_CANNON_BOOSTER_BEAM_ENERGY_EFFICIENCY),
final int beamEnergy = Math.min(
laserMedium_consumeUpTo(Integer.MAX_VALUE, false) + MathHelper.floor_double(energyFromOtherBeams * WarpDriveConfig.LASER_CANNON_BOOSTER_BEAM_ENERGY_EFFICIENCY),
WarpDriveConfig.LASER_CANNON_MAX_LASER_ENERGY);
emitBeam(beamEnergy);
energyFromOtherBeams = 0;
@ -674,7 +674,10 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
@Override
public String toString() {
return String.format("%s Beam \'%d\' @ \'%s\' (%d %d %d)", getClass().getSimpleName(),
beamFrequency, worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ());
return String.format("%s Beam \'%d\' @ %s (%d %d %d)",
getClass().getSimpleName(),
beamFrequency,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());
}
}

View file

@ -1,11 +1,13 @@
package cr0s.warpdrive.block.breathing;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.block.BlockAbstractBase;
import cr0s.warpdrive.config.WarpDriveConfig;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Random;
import net.minecraft.block.Block;
@ -13,7 +15,9 @@ import net.minecraft.block.material.EnumPushReaction;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
@ -69,6 +73,15 @@ public abstract class BlockAbstractAir extends BlockAbstractBase {
return true;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(@Nonnull Item item, CreativeTabs creativeTab, List list) {
// hide in NEI
for (int i = 0; i < 16; i++) {
Commons.hideItemStack(new ItemStack(item, 1, i));
}
}
@SideOnly(Side.CLIENT)
@Override
public boolean canPlaceBlockAt(World world, @Nonnull BlockPos blockPos) {

View file

@ -21,8 +21,9 @@ public class BlockAirFlow extends BlockAbstractAir {
@Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, @Nonnull World world, @Nonnull BlockPos blockPos) {
if (!world.isRemote) {
StateAir stateAir = ChunkHandler.getStateAir(world, blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (!stateAir.isAirSource() || stateAir.concentration == 0) {
final StateAir stateAir = ChunkHandler.getStateAir(world, blockPos.getX(), blockPos.getY(), blockPos.getZ());
if ( stateAir != null
&& (!stateAir.isAirFlow() || stateAir.concentration == 0) ) {
world.setBlockToAir(blockPos);
}
}

View file

@ -45,8 +45,9 @@ public class BlockAirSource extends BlockAbstractAir {
@Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, @Nonnull World world, @Nonnull BlockPos blockPos) {
if (!world.isRemote) {
StateAir stateAir = ChunkHandler.getStateAir(world, blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (!stateAir.isAirSource() || stateAir.concentration == 0) {
final StateAir stateAir = ChunkHandler.getStateAir(world, blockPos.getX(), blockPos.getY(), blockPos.getZ());
if ( stateAir != null
&& (!stateAir.isAirSource() || stateAir.concentration == 0) ) {
world.setBlockToAir(blockPos);
}
}

View file

@ -2,12 +2,12 @@ package cr0s.warpdrive.block.breathing;
import cr0s.warpdrive.block.ItemBlockAbstractBase;
import javax.annotation.Nonnull;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
public class ItemBlockAirShield extends ItemBlockAbstractBase {
@ -24,12 +24,13 @@ public class ItemBlockAirShield extends ItemBlockAbstractBase {
}
@Override
public void getSubItems(Item item, CreativeTabs creativeTabs, List list) {
public void getSubItems(@Nonnull Item item, @Nonnull CreativeTabs creativeTabs, @Nonnull List<ItemStack> list) {
for (int metadata = 0; metadata < 16; metadata++) {
list.add(new ItemStack(item, 1, metadata));
}
}
@Nonnull
@Override
public String getUnlocalizedName(ItemStack itemstack) {
return getUnlocalizedName();

View file

@ -129,7 +129,7 @@ public class TileEntityAirGenerator extends TileEntityAbstractEnergy {
@Override
public String toString() {
return String.format("%s @ \'%s\' (%d %d %d)",
return String.format("%s @ %s (%d %d %d)",
getClass().getSimpleName(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());

View file

@ -97,7 +97,10 @@ public class TileEntityAirGeneratorTiered extends TileEntityAbstractEnergy {
final int y = pos.getY() + direction.getFrontOffsetY();
final int z = pos.getZ() + direction.getFrontOffsetZ();
StateAir stateAir = ChunkHandler.getStateAir(worldObj, x, y, z);
final StateAir stateAir = ChunkHandler.getStateAir(worldObj, x, y, z);
if (stateAir == null) {// chunk isn't loaded
return;
}
stateAir.updateBlockCache(worldObj);
if (stateAir.isAir()) {// can be air
final short range = (short) (WarpDriveConfig.BREATHING_AIR_GENERATION_RANGE_BLOCKS[tier - 1] - 1);
@ -145,9 +148,9 @@ public class TileEntityAirGeneratorTiered extends TileEntityAbstractEnergy {
@Override
public String toString() {
return String.format("%s @ \'%s\' (%d %d %d)",
getClass().getSimpleName(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
return String.format("%s @ %s (%d %d %d)",
getClass().getSimpleName(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());
}

View file

@ -1,16 +1,13 @@
package cr0s.warpdrive.block.building;
import java.util.Random;
import cr0s.warpdrive.Commons;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
@ -18,7 +15,6 @@ import net.minecraft.world.World;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.block.BlockAbstractContainer;
import cr0s.warpdrive.render.RenderBlockShipScanner;
import net.minecraftforge.fml.common.registry.GameRegistry;
import javax.annotation.Nonnull;
@ -26,8 +22,6 @@ import javax.annotation.Nullable;
public class BlockShipScanner extends BlockAbstractContainer {
public static int passCurrent;
public BlockShipScanner(final String registryName) {
super(registryName, Material.IRON);
setUnlocalizedName("warpdrive.building.ShipScanner");
@ -68,8 +62,11 @@ public class BlockShipScanner extends BlockAbstractContainer {
}
@Override
public int quantityDropped(Random par1Random) {
return 1;
public byte getTier(ItemStack itemStack) {
if (itemStack == null || itemStack.getItem() != Item.getItemFromBlock(this)) {
return 1;
}
return 0;
}
@Override

View file

@ -2,7 +2,8 @@ package cr0s.warpdrive.block.building;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.block.TileEntityAbstractEnergy;
import cr0s.warpdrive.api.ISequencerCallbacks;
import cr0s.warpdrive.block.TileEntityAbstractInterfaced;
import cr0s.warpdrive.block.movement.TileEntityShipCore;
import cr0s.warpdrive.config.Dictionary;
import cr0s.warpdrive.config.WarpDriveConfig;
@ -12,6 +13,7 @@ import cr0s.warpdrive.data.JumpShip;
import cr0s.warpdrive.data.SoundEvents;
import cr0s.warpdrive.data.Transformation;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.event.DeploySequencer;
import cr0s.warpdrive.item.ItemShipToken;
import cr0s.warpdrive.network.PacketHandler;
import dan200.computercraft.api.lua.ILuaContext;
@ -30,7 +32,6 @@ import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@ -39,7 +40,6 @@ import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
@ -50,13 +50,10 @@ import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.fml.server.FMLServerHandler;
import javax.annotation.Nonnull;
public class TileEntityShipScanner extends TileEntityAbstractEnergy {
private static final int SHIP_TOKEN_MAX_RETRY_COUNT = 5;
public class TileEntityShipScanner extends TileEntityAbstractInterfaced implements ISequencerCallbacks {
// persistent properties
private String schematicFileName = "";
@ -68,20 +65,19 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
protected int lightCamouflage;
// computed properties
private boolean isShipToken;
private EnumShipScannerState enumShipScannerState = EnumShipScannerState.IDLE;
private TileEntityShipCore shipCore = null;
private int laserTicks = 0;
private int scanTicks = 0;
private int deployDelayTicks = 0;
private int deployRetryCounts = 0;
private int deployTicks = 0;
private int searchTicks = 0;
private String playerName = "";
private JumpShip jumpShip;
private int currentDeployIndex;
private int blocksToDeployCount;
public TileEntityShipScanner() {
@ -172,131 +168,34 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
scanTicks++;
if (scanTicks > 20 * (1 + shipCore.shipMass / WarpDriveConfig.SS_SCAN_BLOCKS_PER_SECOND)) {
setState(EnumShipScannerState.IDLE); // disable scanner
scanTicks = 0;
}
break;
case DEPLOYING:// active and deploying
deployDelayTicks++;
if (deployDelayTicks > WarpDriveConfig.SS_DEPLOY_INTERVAL_TICKS) {
deployDelayTicks = 0;
// refresh player object
final EntityPlayerMP entityPlayerMP = FMLServerHandler.instance().getServer().getPlayerList().getPlayerByUsername(playerName);
if (deployTicks == 0) {
final DeploySequencer sequencer = new DeploySequencer(jumpShip, getWorld(), isShipToken, targetX, targetY, targetZ, rotationSteps);
// deploy at most (jump speed / 4), at least (deploy speed), optimally in 10 seconds
final int optimumSpeed = Math.round(blocksToDeployCount * WarpDriveConfig.SS_DEPLOY_INTERVAL_TICKS / (20 * 10.0F));
final int optimumSpeed = Math.round(blocksToDeployCount * WarpDriveConfig.SS_DEPLOY_INTERVAL_TICKS / (20.0F * 10.0F));
final int blockToDeployPerTick = Math.max(WarpDriveConfig.SS_DEPLOY_BLOCKS_PER_INTERVAL,
Math.min(WarpDriveConfig.G_BLOCKS_PER_TICK / 4, optimumSpeed));
final int blocksToDeployCurrentTick = Math.min(blockToDeployPerTick, blocksToDeployCount - currentDeployIndex);
final int periodLaserEffect = Math.max(1, (blocksToDeployCurrentTick / 10));
Math.min(WarpDriveConfig.G_BLOCKS_PER_TICK / 4, optimumSpeed));
if (WarpDrive.isDev && WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info("optimumSpeed " + optimumSpeed + " blockToDeployPerTick " + blockToDeployPerTick + " blocksToDeployCurrentTick " + blocksToDeployCurrentTick + " currentDeployIndex " + currentDeployIndex);
}
// deployment done?
if (blocksToDeployCurrentTick == 0) {
if (playerName != null && !playerName.isEmpty()) {
final TileEntity tileEntity = worldObj.getTileEntity(new BlockPos(targetX, targetY, targetZ));
if (tileEntity instanceof TileEntityShipCore) {
final boolean isSuccess = ((TileEntityShipCore) tileEntity).summonOwnerOnDeploy(entityPlayerMP);
if (isSuccess) {
if (entityPlayerMP != null) {
Commons.addChatMessage(entityPlayerMP, new TextComponentString("§6" + "Welcome aboard captain. Use the computer to get moving..."));
}
} else {
deployRetryCounts--;
WarpDrive.logger.warn(String.format("Ship scanner failed to assign new captain, %d retries left",
deployRetryCounts));
if (deployRetryCounts > 0) {
return;
}
}
} else {
WarpDrive.logger.warn(String.format("Ship scanner unable to detect ship core after deployment, found %s",
tileEntity));
deployRetryCounts--;
if (deployRetryCounts > 0) {
return;
}
}
}
setState(EnumShipScannerState.IDLE); // disable scanner
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info(this + " Deployment done");
}
shipToken_nextUpdate_ticks = SHIP_TOKEN_UPDATE_PERIOD_TICKS * 3;
return;
}
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info(this + " Deploying " + blocksToDeployCurrentTick + " more blocks");
}
Transformation transformation = new Transformation(jumpShip, worldObj, targetX - jumpShip.core.getX(), targetY - jumpShip.core.getY(), targetZ - jumpShip.core.getZ(), rotationSteps);
int index = 0;
while (index < blocksToDeployCurrentTick && currentDeployIndex < blocksToDeployCount) {
// Deploy single block
JumpBlock jumpBlock = jumpShip.jumpBlocks[currentDeployIndex];
if (jumpBlock == null) {
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info("At index " + currentDeployIndex + ", skipping undefined block");
}
} else if (jumpBlock.block == Blocks.AIR) {
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info("At index " + currentDeployIndex + ", skipping air block");
}
} else if (Dictionary.BLOCKS_ANCHOR.contains(jumpBlock.block)) {
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info("At index " + currentDeployIndex + ", skipping anchor block " + jumpBlock.block);
}
} else {
index++;
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info("At index " + currentDeployIndex + ", deploying block " + Block.REGISTRY.getNameForObject(jumpBlock.block) + ":" + jumpBlock.blockMeta
+ " tileEntity " + jumpBlock.blockTileEntity + " NBT " + jumpBlock.blockNBT);
}
// clear computers unique identifiers when using token
if (!playerName.isEmpty()) {
jumpBlock.removeUniqueIDs();
}
BlockPos targetLocation = transformation.apply(jumpBlock.x, jumpBlock.y, jumpBlock.z);
Block blockAtTarget = worldObj.getBlockState(targetLocation).getBlock();
if (blockAtTarget == Blocks.AIR || Dictionary.BLOCKS_EXPANDABLE.contains(blockAtTarget)) {
jumpBlock.deploy(worldObj, transformation);
if (index % periodLaserEffect == 0) {
worldObj.playSound(null, pos, SoundEvents.LASER_LOW, SoundCategory.HOSTILE, 0.5F, 1.0F);
PacketHandler.sendBeamPacket(worldObj,
new Vector3(this).translate(0.5D),
new Vector3(targetLocation).translate(0.5D),
0f, 1f, 0f, 15, 0, 100);
}
worldObj.playSound(null, targetLocation, jumpBlock.block.getSoundType().getPlaceSound(), SoundCategory.BLOCKS,
(jumpBlock.block.getSoundType().getVolume() + 1.0F) / 2.0F, jumpBlock.block.getSoundType().getPitch() * 0.8F);
} else {
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info("Target position is occupied, skipping");
}
worldObj.newExplosion(null, targetX + jumpBlock.x, targetY + jumpBlock.y, targetZ + jumpBlock.z, 3, false, false);
WarpDrive.logger.info("Deployment collision detected at " + (targetX + jumpBlock.x) + " " + (targetY + jumpBlock.y) + " " + (targetZ + jumpBlock.z));
}
}
currentDeployIndex++;
// Warn owner if deployment done but wait next tick for teleportation
if (currentDeployIndex >= blocksToDeployCount) {
if (entityPlayerMP != null) {
Commons.addChatMessage(entityPlayerMP, new TextComponentString("Ship complete. Teleporting captain to the main deck"));
}
}
WarpDrive.logger.info("optimumSpeed " + optimumSpeed + " blockToDeployPerTick " + blockToDeployPerTick);
}
sequencer.setBlocksPerTick(blockToDeployPerTick);
sequencer.setCaptain(playerName);
sequencer.setEffectSource(new Vector3(this).translate(0.5D));
sequencer.setCallback(this);
sequencer.enable();
}
deployTicks++;
if (deployTicks > 20.0F * 60.0F) {
// timeout in sequencer?
WarpDrive.logger.info(this + " Deployment timeout?");
deployTicks = 0;
setState(EnumShipScannerState.IDLE); // disable scanner
shipToken_nextUpdate_ticks = SHIP_TOKEN_UPDATE_PERIOD_TICKS * 3;
}
break;
@ -323,6 +222,30 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
}
}
@Override
public void sequencer_finished() {
switch (enumShipScannerState) {
// case IDLE:// inactive
// break;
// case SCANNING:// active and scanning
// break;
case DEPLOYING:// active and deploying
setState(EnumShipScannerState.IDLE); // disable scanner
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info(this + " Deployment done");
}
shipToken_nextUpdate_ticks = SHIP_TOKEN_UPDATE_PERIOD_TICKS * 3;
break;
default:
WarpDrive.logger.error(this + " Invalid ship scanner state, forcing to IDLE...");
setState(EnumShipScannerState.IDLE);
break;
}
}
private TileEntityShipCore searchShipCore() {
StringBuilder reason = new StringBuilder();
TileEntityShipCore tileEntityShipCore = null;
@ -347,22 +270,6 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
return tileEntityShipCore;
}
private int getScanningEnergyCost(int size) {
if (WarpDriveConfig.SS_ENERGY_PER_BLOCK_SCAN >= 0) {
return size * WarpDriveConfig.SS_ENERGY_PER_BLOCK_SCAN;
} else {
return WarpDriveConfig.SS_MAX_ENERGY_STORED;
}
}
private int getDeploymentEnergyCost(int size) {
if (WarpDriveConfig.SS_ENERGY_PER_BLOCK_DEPLOY >= 0) {
return size * WarpDriveConfig.SS_ENERGY_PER_BLOCK_DEPLOY;
} else {
return WarpDriveConfig.SS_MAX_ENERGY_STORED;
}
}
private boolean saveShipToSchematic(String fileName, StringBuilder reason) {
if (!shipCore.validateShipSpatialParameters(reason)) {
return false;
@ -377,13 +284,6 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
return false;
}
// Consume energy
int energyCost = getScanningEnergyCost(shipCore.shipMass);
if (!energy_consume(energyCost, false)) {
reason.append(String.format("Insufficient energy (%d required)", energyCost));
return false;
}
// Save header
NBTTagCompound schematic = new NBTTagCompound();
@ -533,13 +433,6 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
return 5;
}
// Consume energy
int energyCost = getDeploymentEnergyCost(blocksToDeployCount);
if (!energy_consume(energyCost, false)) {
reason.append(String.format("Insufficient energy (%d required)", energyCost));
return 1;
}
// Compute target area
Transformation transformation = new Transformation(jumpShip, worldObj, targetX - jumpShip.core.getX(), targetY - jumpShip.core.getY(), targetZ - jumpShip.core.getZ(), rotationSteps);
BlockPos targetLocation1 = transformation.apply(jumpShip.minX, jumpShip.minY, jumpShip.minZ);
@ -557,10 +450,10 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
if (!worldObj.isAirBlock(new BlockPos(targetX, targetY, targetZ))) {
worldObj.newExplosion(null, targetX, targetY, targetZ, 1, false, false);
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.info(String.format("Deployment collision detected at %d %d %d",
WarpDrive.logger.info(String.format("Deployment collision detected at (%d %d %d)",
targetX, targetY, targetZ));
}
reason.append(String.format("Deployment area occupied with existing ship.\nCan't deploy new ship at %d %d %d",
reason.append(String.format("Deployment area occupied with existing ship.\nCan't deploy new ship at (%d %d %d)",
targetX, targetY, targetZ));
return 2;
}
@ -602,28 +495,28 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
}
// initiate deployment sequencer
currentDeployIndex = 0;
deployRetryCounts = SHIP_TOKEN_MAX_RETRY_COUNT;
deployTicks = 0;
isShipToken = isForced;
setState(EnumShipScannerState.DEPLOYING);
reason.append(String.format("Deploying ship '%s'...", fileName));
return 3;
}
@Override
public void readFromNBT(NBTTagCompound tatagCompound) {
super.readFromNBT(tatagCompound);
schematicFileName = tatagCompound.getString("schematic");
targetX = tatagCompound.getInteger("targetX");
targetY = tatagCompound.getInteger("targetY");
targetZ = tatagCompound.getInteger("targetZ");
rotationSteps = tatagCompound.getByte("rotationSteps");
if (tatagCompound.hasKey("camouflageBlock")) {
public void readFromNBT(NBTTagCompound tagCompound) {
super.readFromNBT(tagCompound);
schematicFileName = tagCompound.getString("schematic");
targetX = tagCompound.getInteger("targetX");
targetY = tagCompound.getInteger("targetY");
targetZ = tagCompound.getInteger("targetZ");
rotationSteps = tagCompound.getByte("rotationSteps");
if (tagCompound.hasKey("camouflageBlock")) {
try {
blockCamouflage = Block.getBlockFromName(tatagCompound.getString("camouflageBlock"));
metadataCamouflage = tatagCompound.getByte("camouflageMeta");
colorMultiplierCamouflage = tatagCompound.getInteger("camouflageColorMultiplier");
lightCamouflage = tatagCompound.getByte("camouflageLight");
blockCamouflage = Block.getBlockFromName(tagCompound.getString("camouflageBlock"));
metadataCamouflage = tagCompound.getByte("camouflageMeta");
colorMultiplierCamouflage = tagCompound.getInteger("camouflageColorMultiplier");
lightCamouflage = tagCompound.getByte("camouflageLight");
if (Dictionary.BLOCKS_NOCAMOUFLAGE.contains(blockCamouflage)) {
blockCamouflage = null;
metadataCamouflage = 0;
@ -704,14 +597,9 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
if (shipCore == null) {
return new Object[] { false, 1, "Ship-Core not found" };
}
int energyCost = getScanningEnergyCost(shipCore.shipMass);
if (!energy_consume(energyCost, true)) {
return new Object[] { false, 2, "Not enough energy! " + energyCost + " required." };
} else {
StringBuilder reason = new StringBuilder();
boolean success = scanShip(reason);
return new Object[] { success, 3, reason.toString() };
}
StringBuilder reason = new StringBuilder();
boolean success = scanShip(reason);
return new Object[] { success, 3, reason.toString() };
}
private Object[] filename() {
@ -727,24 +615,34 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
}
private Object[] deploy(Object[] arguments) {
if (arguments.length == 5) {
String fileName = (String) arguments[0];
int x = Commons.toInt(arguments[1]);
int y = Commons.toInt(arguments[2]);
int z = Commons.toInt(arguments[3]);
byte rotationSteps = (byte) Commons.toInt(arguments[4]);
if (!new File(WarpDriveConfig.G_SCHEMALOCATION + "/" + fileName + ".schematic").exists()) {
return new Object[] { 0, "Specified schematic file was not found!" };
} else {
final StringBuilder reason = new StringBuilder();
final int result = deployShip(fileName, x, y, z, rotationSteps, false, reason);
playerName = "";
return new Object[] { result, reason.toString() };
}
} else {
return new Object[] { 4, "Invalid arguments count, you need .schematic file name, offsetX, offsetY, offsetZ, rotationSteps!" };
if (arguments.length != 5) {
return new Object[] { 4, "Invalid arguments count, you need <.schematic file name>, <offsetX>, <offsetY>, <offsetZ>, <rotationSteps>!" };
}
final String fileName = (String) arguments[0];
final int x = Commons.toInt(arguments[1]);
final int y = Commons.toInt(arguments[2]);
final int z = Commons.toInt(arguments[3]);
final byte rotationSteps = (byte) Commons.toInt(arguments[4]);
if (!new File(WarpDriveConfig.G_SCHEMALOCATION + "/" + fileName + ".schematic").exists()) {
return new Object[] { 0, "Specified schematic file was not found!" };
}
final StringBuilder reason = new StringBuilder();
final int result = deployShip(fileName, x, y, z, rotationSteps, false, reason);
// don't force captain when deploying from LUA
playerName = null;
/*
final EntityPlayer entityPlayer = worldObj.getClosestPlayer(xCoord, yCoord, zCoord, 8);
if (entityPlayer != null) {
playerName = entityPlayer.getCommandSenderName();
} else {
playerName = "";
}
/**/
return new Object[] { result, reason.toString() };
}
private Object[] state() {
@ -755,7 +653,7 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
case SCANNING:
return new Object[] { true, "Scanning", 0, 0 };
case DEPLOYING:
return new Object[] { true, "Deploying", currentDeployIndex, blocksToDeployCount };
return new Object[] { true, "Deploying", 0, blocksToDeployCount };
}
}
@ -866,7 +764,7 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
deployShip(ItemShipToken.getSchematicName(itemStack), targetX - pos.getX(), targetY - pos.getY(), targetZ - pos.getZ(), rotationSteps, true, reason);
if (enumShipScannerState == EnumShipScannerState.IDLE) {
// failed
Commons.addChatMessage(entityPlayer, new TextComponentString(reason.toString()).setStyle(new Style().setColor(TextFormatting.RED)));;
Commons.addChatMessage(entityPlayer, new TextComponentString(reason.toString()).setStyle(new Style().setColor(TextFormatting.RED)));
shipToken_nextUpdate_ticks = SHIP_TOKEN_UPDATE_DELAY_FAILED_DEPLOY_TICKS;
return;
}
@ -884,20 +782,11 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
}
}
// IEnergySink methods implementation
@Override
public int energy_getMaxStorage() {
return WarpDriveConfig.SS_MAX_ENERGY_STORED;
}
@Override
public boolean energy_canInput(EnumFacing from) {
return true;
}
@Override
public String toString() {
return String.format("%s @ \'%s\' (%d %d %d)", getClass().getSimpleName(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ());
return String.format("%s @ %s (%d %d %d)",
getClass().getSimpleName(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());
}
}

View file

@ -97,7 +97,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
"silktouch",
"tapTrees"
});
laserMediumMaxCount = WarpDriveConfig.TREE_FARM_MAX_MEDIUMS_COUNT;
laserMedium_maxCount = WarpDriveConfig.TREE_FARM_MAX_MEDIUMS_COUNT;
CC_scripts = Arrays.asList("farm", "stop");
}
@ -147,13 +147,33 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
} else if (currentState == STATE_SCAN) {
int energyCost = TREE_FARM_ENERGY_PER_SURFACE * (1 + 2 * radiusX) * (1 + 2 * radiusZ);
final int energyCost = TREE_FARM_ENERGY_PER_SURFACE * (1 + 2 * radiusX) * (1 + 2 * radiusZ);
if (delayTicks == 1) {
if (WarpDriveConfig.LOGGING_COLLECTION) {
WarpDrive.logger.debug("Scan pre-tick");
}
// validate environment: clearance above
final IBlockState blockStateAbove = worldObj.getBlockState(pos.up());
final Block blockAbove = blockStateAbove.getBlock();
if ( !isLog(blockAbove)
&& !isLeaf(blockAbove)
&& !blockAbove.isAir(blockStateAbove, worldObj, pos.up()) ) {
PacketHandler.sendSpawnParticlePacket(worldObj, "jammed", (byte) 5, new Vector3(this).translate(0.5F),
new Vector3(0.0D, 0.0D, 0.0D),
1.0F, 1.0F, 1.0F,
1.0F, 1.0F, 1.0F,
32);
currentState = STATE_WARMUP; // going back to warmup state to show the animation when it'll be back online
delayTicks = 0;
delayTargetTicks = TREE_FARM_LOW_POWER_DELAY_TICKS;
updateBlockState(blockState, BlockLaserTreeFarm.MODE, EnumLaserTreeFarmMode.SCANNING_LOW_POWER);
return;
}
// check power level
enoughPower = consumeEnergyFromLaserMediums(energyCost, true);
enoughPower = laserMedium_consumeExactly(energyCost, true);
if (!enoughPower) {
currentState = STATE_WARMUP; // going back to warmup state to show the animation when it'll be back online
delayTicks = 0;
@ -183,7 +203,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
delayTicks = 0;
// consume power
enoughPower = consumeEnergyFromLaserMediums(energyCost, false);
enoughPower = laserMedium_consumeExactly(energyCost, false);
if (!enoughPower) {
delayTargetTicks = TREE_FARM_LOW_POWER_DELAY_TICKS;
updateBlockState(blockState, BlockLaserTreeFarm.MODE, EnumLaserTreeFarmMode.SCANNING_LOW_POWER);
@ -262,8 +282,8 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
// consume power
int energyCost = TREE_FARM_ENERGY_PER_WET_SPOT;
enoughPower = consumeEnergyFromLaserMediums(energyCost, false);
final int energyCost = TREE_FARM_ENERGY_PER_WET_SPOT;
enoughPower = laserMedium_consumeExactly(energyCost, false);
if (!enoughPower) {
delayTargetTicks = TREE_FARM_LOW_POWER_DELAY_TICKS;
updateBlockState(blockState, BlockLaserTreeFarm.MODE, EnumLaserTreeFarmMode.FARMING_LOW_POWER);
@ -301,7 +321,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
if (enableSilktouch) {
energyCost *= TREE_FARM_SILKTOUCH_ENERGY_FACTOR;
}
enoughPower = consumeEnergyFromLaserMediums((int) Math.round(energyCost), false);
enoughPower = laserMedium_consumeExactly((int) Math.round(energyCost), false);
if (!enoughPower) {
delayTargetTicks = TREE_FARM_LOW_POWER_DELAY_TICKS;
updateBlockState(blockState, BlockLaserTreeFarm.MODE, EnumLaserTreeFarmMode.FARMING_LOW_POWER);
@ -418,8 +438,8 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
// consume power
double energyCost = TREE_FARM_ENERGY_PER_SAPLING;
enoughPower = consumeEnergyFromLaserMediums((int) Math.round(energyCost), false);
final int energyCost = TREE_FARM_ENERGY_PER_SAPLING;
enoughPower = laserMedium_consumeExactly(energyCost, false);
if (!enoughPower) {
delayTargetTicks = TREE_FARM_LOW_POWER_DELAY_TICKS;
updateBlockState(blockState, BlockLaserTreeFarm.MODE, EnumLaserTreeFarmMode.PLANTING_LOW_POWER);
@ -465,7 +485,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
private LinkedList<BlockPos> scanSoils() {
int maxRadius = WarpDriveConfig.TREE_FARM_MAX_SCAN_RADIUS_NO_LASER_MEDIUM + laserMediumCount * WarpDriveConfig.TREE_FARM_MAX_SCAN_RADIUS_PER_LASER_MEDIUM;
int maxRadius = WarpDriveConfig.TREE_FARM_MAX_SCAN_RADIUS_NO_LASER_MEDIUM + cache_laserMedium_count * WarpDriveConfig.TREE_FARM_MAX_SCAN_RADIUS_PER_LASER_MEDIUM;
int xMin = pos.getX() - Math.min(radiusX, maxRadius);
int xMax = pos.getX() + Math.min(radiusX, maxRadius);
int yMin = pos.getY();
@ -498,13 +518,13 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
private Collection<BlockPos> scanTrees() {
int maxRadius = WarpDriveConfig.TREE_FARM_MAX_SCAN_RADIUS_NO_LASER_MEDIUM + laserMediumCount * WarpDriveConfig.TREE_FARM_MAX_SCAN_RADIUS_PER_LASER_MEDIUM;
int xMin = pos.getX() - Math.min(radiusX, maxRadius);
int xMax = pos.getX() + Math.min(radiusX, maxRadius);
int yMin = pos.getY() + 1;
int yMax = pos.getY() + 1 + (tapTrees ? 8 : 0);
int zMin = pos.getZ() - Math.min(radiusZ, maxRadius);
int zMax = pos.getZ() + Math.min(radiusZ, maxRadius);
final int maxScanRadius = WarpDriveConfig.TREE_FARM_MAX_SCAN_RADIUS_NO_LASER_MEDIUM + cache_laserMedium_count * WarpDriveConfig.TREE_FARM_MAX_SCAN_RADIUS_PER_LASER_MEDIUM;
final int xMin = pos.getX() - Math.min(radiusX, maxScanRadius);
final int xMax = pos.getX() + Math.min(radiusX, maxScanRadius);
final int yMin = pos.getY() + 1;
final int yMax = pos.getY() + 1 + (tapTrees ? 8 : 0);
final int zMin = pos.getZ() - Math.min(radiusZ, maxScanRadius);
final int zMax = pos.getZ() + Math.min(radiusZ, maxScanRadius);
Collection<BlockPos> logPositions = new HashSet<>();
@ -526,11 +546,12 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
if (!logPositions.isEmpty()) {
@SuppressWarnings("unchecked")
HashSet<Block> whitelist = (HashSet<Block>) Dictionary.BLOCKS_LOGS.clone();
final HashSet<Block> whitelist = (HashSet<Block>) Dictionary.BLOCKS_LOGS.clone();
if (breakLeaves) {
whitelist.addAll(Dictionary.BLOCKS_LEAVES);
}
logPositions = Commons.getConnectedBlocks(worldObj, logPositions, Commons.UP_DIRECTIONS, whitelist, WarpDriveConfig.TREE_FARM_MAX_LOG_DISTANCE + laserMediumCount * WarpDriveConfig.TREE_FARM_MAX_LOG_DISTANCE_PER_MEDIUM);
final int maxLogDistance = WarpDriveConfig.TREE_FARM_MAX_LOG_DISTANCE + cache_laserMedium_count * WarpDriveConfig.TREE_FARM_MAX_LOG_DISTANCE_PER_MEDIUM;
logPositions = Commons.getConnectedBlocks(worldObj, logPositions, Commons.UP_DIRECTIONS, whitelist, maxLogDistance);
}
if (WarpDriveConfig.LOGGING_COLLECTION) {
WarpDrive.logger.info("Found " + logPositions.size() + " valuables");
@ -629,7 +650,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
private Object[] state() {
final int energy = getEnergyStored();
final int energy = laserMedium_getEnergyStored();
final String status = getStatusHeaderInPureText();
final Integer retValuables, retValuablesIndex;
if (isFarming() && valuables != null) {
@ -729,8 +750,8 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
@Override
public ITextComponent getStatus() {
final int energy = getEnergyStored();
public ITextComponent getStatusHeader() {
final int energy = laserMedium_getEnergyStored();
String state = "IDLE (not farming)";
if (currentState == STATE_IDLE) {
state = "IDLE (not farming)";

View file

@ -52,6 +52,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
private boolean enoughPower = false;
private int currentLayer;
private int radiusCapacity = WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS;
private final ArrayList<BlockPos> valuablesInLayer = new ArrayList<>();
private int valuableIndex = 0;
@ -68,7 +69,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
"silktouch"
});
CC_scripts = Arrays.asList("mine", "stop");
laserMediumMaxCount = WarpDriveConfig.MINING_LASER_MAX_MEDIUMS_COUNT;
laserMedium_maxCount = WarpDriveConfig.MINING_LASER_MAX_MEDIUMS_COUNT;
}
@SuppressWarnings("UnnecessaryReturnStatement")
@ -96,6 +97,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
}
final boolean isOnPlanet = CelestialObjectManager.hasAtmosphere(worldObj, pos.getX(), pos.getZ());
radiusCapacity = WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS + cache_laserMedium_count - 1;
delayTicks--;
if (currentState == STATE_WARMUP) {
@ -110,7 +112,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
} else if (currentState == STATE_SCANNING) {
if (delayTicks == WarpDriveConfig.MINING_LASER_SCAN_DELAY_TICKS - 1) {
// check power level
enoughPower = consumeEnergyFromLaserMediums(isOnPlanet ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_LAYER : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_LAYER, true);
enoughPower = laserMedium_consumeExactly(isOnPlanet ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_LAYER : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_LAYER, true);
if (!enoughPower) {
updateBlockState(blockState, BlockMiningLaser.MODE, EnumMiningLaserMode.SCANNING_LOW_POWER);
delayTicks = WarpDriveConfig.MINING_LASER_WARMUP_DELAY_TICKS;
@ -121,10 +123,10 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
// show current layer
int age = Math.max(40, 5 * WarpDriveConfig.MINING_LASER_SCAN_DELAY_TICKS);
double xMax = pos.getX() + WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS + 1.0D;
double xMin = pos.getX() - WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS + 0.0D;
double zMax = pos.getZ() + WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS + 1.0D;
double zMin = pos.getZ() - WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS + 0.0D;
double xMax = pos.getX() + radiusCapacity + 1.0D;
double xMin = pos.getX() - radiusCapacity + 0.0D;
double zMax = pos.getZ() + radiusCapacity + 1.0D;
double zMin = pos.getZ() - radiusCapacity + 0.0D;
double y = currentLayer + 1.0D;
PacketHandler.sendBeamPacket(worldObj, new Vector3(xMin, y, zMin), new Vector3(xMax, y, zMin), 0.3F, 0.0F, 1.0F, age, 0, 50);
PacketHandler.sendBeamPacket(worldObj, new Vector3(xMax, y, zMin), new Vector3(xMax, y, zMax), 0.3F, 0.0F, 1.0F, age, 0, 50);
@ -139,7 +141,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
}
// consume power
enoughPower = consumeEnergyFromLaserMediums(isOnPlanet ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_LAYER : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_LAYER, false);
enoughPower = laserMedium_consumeExactly(isOnPlanet ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_LAYER : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_LAYER, false);
if (!enoughPower) {
updateBlockState(blockState, BlockMiningLaser.MODE, EnumMiningLaserMode.SCANNING_LOW_POWER);
delayTicks = WarpDriveConfig.MINING_LASER_WARMUP_DELAY_TICKS;
@ -151,7 +153,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
// scan
scanLayer();
if (!valuablesInLayer.isEmpty()) {
int r = (int) Math.ceil(WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS / 2.0D);
int r = (int) Math.ceil(radiusCapacity / 2.0D);
int offset = (pos.getY() - currentLayer) % (2 * r);
int age = Math.max(20, Math.round(2.5F * WarpDriveConfig.MINING_LASER_SCAN_DELAY_TICKS));
double y = currentLayer + 1.0D;
@ -199,7 +201,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
if (enableSilktouch) {
requiredPower *= WarpDriveConfig.MINING_LASER_SILKTOUCH_ENERGY_FACTOR;
}
enoughPower = consumeEnergyFromLaserMediums(requiredPower, false);
enoughPower = laserMedium_consumeExactly(requiredPower, false);
if (!enoughPower) {
updateBlockState(blockState, BlockMiningLaser.MODE, EnumMiningLaserMode.MINING_LOW_POWER);
return;
@ -304,7 +306,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
valuablesInLayer.add(blockPos);
}
}
for (radius = 1; radius <= WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS; radius++) {
for (radius = 1; radius <= radiusCapacity; radius++) {
xMax = pos.getX() + radius;
xMin = pos.getX() - radius;
zMax = pos.getZ() + radius;
@ -446,7 +448,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
}
private Object[] state() {
final int energy = getEnergyStored();
final int energy = laserMedium_getEnergyStored();
final String status = getStatusHeaderInPureText();
final Integer retValuablesInLayer, retValuablesMined;
if (isActive()) {
@ -534,8 +536,8 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
}
@Override
public ITextComponent getStatus() {
final int energy = getEnergyStored();
public ITextComponent getStatusHeader() {
final int energy = laserMedium_getEnergyStored();
ITextComponent state = new TextComponentTranslation("IDLE (not mining)");
if (currentState == STATE_IDLE) {
state = new TextComponentTranslation("IDLE (not mining)");

View file

@ -192,7 +192,7 @@ public class TileEntityCamera extends TileEntityAbstractInterfaced implements IV
@Override
public String toString() {
return String.format("%s %d @ \'%s\' (%d %d %d)",
return String.format("%s %d @ %s (%d %d %d)",
getClass().getSimpleName(),
videoChannel,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),

View file

@ -152,7 +152,7 @@ public class TileEntityMonitor extends TileEntityAbstractInterfaced implements I
@Override
public String toString() {
return String.format("%s %d @ \'%s\' (%d %d %d)",
return String.format("%s %d @ %s (%d %d %d)",
getClass().getSimpleName(),
videoChannel,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),

View file

@ -6,6 +6,7 @@ import cr0s.warpdrive.block.BlockAbstractContainer;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@ -15,8 +16,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -35,6 +34,12 @@ public class BlockIC2reactorLaserMonitor extends BlockAbstractContainer {
return new TileEntityIC2reactorLaserMonitor();
}
@Override
public void onBlockPlacedBy(World world, BlockPos blockPos, IBlockState blockState, EntityLivingBase entityLiving, ItemStack itemStack) {
super.onBlockPlacedBy(world, blockPos, blockState, entityLiving, itemStack);
// @TODO MC1.10 world.setBlockMetadataWithNotify(x, y, z, 6, 3);
}
@Override
public boolean onBlockActivated(World world, BlockPos blockPos, IBlockState blockState, EntityPlayer entityPlayer, EnumHand hand, @Nullable ItemStack itemStackHeld, EnumFacing side, float hitX, float hitY, float hitZ) {
if (world.isRemote) {

View file

@ -597,7 +597,7 @@ public class TileEntityEnanReactorCore extends TileEntityAbstractEnergy implemen
@Override
public String toString() {
return String.format("%s \'%s\' @ \'%s\' (%d %d %d)",
return String.format("%s %s @ %s (%d %d %d)",
getClass().getSimpleName(),
connectedComputers == null ? "~NULL~" : connectedComputers,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),

View file

@ -36,14 +36,15 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser {
"stabilize"
});
peripheralName = "warpdriveEnanReactorLaser";
laserMediumMaxCount = 1;
directionsValidLaserMedium = new EnumFacing[] { EnumFacing.UP, EnumFacing.DOWN };
laserMedium_maxCount = 1;
laserMedium_directionsValid = new EnumFacing[] { EnumFacing.UP, EnumFacing.DOWN };
}
public TileEntityEnanReactorCore scanForReactor() {
public void scanForReactor() {
reactor = null;
TileEntity tileEntity;
side = null;
TileEntity tileEntity;
// I AM ON THE NORTH SIDE
tileEntity = worldObj.getTileEntity(pos.add(0, 0, 2));
if (tileEntity instanceof TileEntityEnanReactorCore && worldObj.isAirBlock(pos.add(0, 0, 1))) {
@ -77,7 +78,6 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser {
if (reactor != null) {
reactorVec = new Vector3(reactor).translate(0.5);
}
return reactor;
}
private void setMetadata() {
@ -119,13 +119,13 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser {
}
scanForReactor();
if (facingLaserMedium == null) {
if (laserMedium_direction == null) {
return;
}
if (reactor == null) {
return;
}
if (consumeEnergyFromLaserMediums(energy, false)) {
if (laserMedium_consumeExactly(energy, false)) {
if (WarpDriveConfig.LOGGING_ENERGY && WarpDriveConfig.LOGGING_LUA) {
WarpDrive.logger.info("ReactorLaser on " + side + " side sending " + energy);
}
@ -148,7 +148,7 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser {
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] hasReactor(Context context, Arguments arguments) {
return new Object[] { scanForReactor() != null };
return new Object[] { reactor != null };
}
@Callback
@ -175,7 +175,7 @@ public class TileEntityEnanReactorLaser extends TileEntityAbstractLaser {
switch (methodName) {
case "hasReactor":
return new Object[] { scanForReactor() != null };
return new Object[] { reactor != null };
case "stabilize":
if (arguments.length >= 1) {

View file

@ -191,8 +191,8 @@ public class TileEntityEnergyBank extends TileEntityAbstractEnergy {
@Override
public String toString() {
return String.format("%s @ \'%s\' (%d %d %d) %8d",
getClass().getSimpleName(),
return String.format("%s @ %s (%d %d %d) %8d",
getClass().getSimpleName(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ(),
energy_getEnergyStored());

View file

@ -1,7 +1,6 @@
package cr0s.warpdrive.block.energy;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.block.TileEntityAbstractEnergy;
import cr0s.warpdrive.block.TileEntityAbstractLaser;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.item.ItemIC2reactorLaserFocus;
@ -10,111 +9,108 @@ import ic2.api.reactor.IReactor;
import ic2.api.reactor.IReactorChamber;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraftforge.fml.common.Optional;
public class TileEntityIC2reactorLaserMonitor extends TileEntityAbstractEnergy {
import net.minecraftforge.fluids.BlockFluidBase;
public class TileEntityIC2reactorLaserMonitor extends TileEntityAbstractLaser {
// persistent properties
private int ticks = WarpDriveConfig.IC2_REACTOR_COOLING_INTERVAL_TICKS;
private byte activeSides = 0;
private boolean updateFlag = false;
private boolean isFirstTick = true;
// computed properties
public EnumFacing facing = null;
private boolean isValid = false;
public TileEntityIC2reactorLaserMonitor() {
super();
IC2_sinkTier = 2;
IC2_sourceTier = 2;
}
private static final int[] deltaX = {-2, 2, 0, 0, 0, 0};
private static final int[] deltaY = { 0, 0,-2, 2, 0, 0};
private static final int[] deltaZ = { 0, 0, 0, 0,-2, 2};
private static final byte[] deltaSides = { 1, 2, 4, 8, 16, 32 };
protected boolean isSideActive(int side) {
switch (side) {
case 4: return (deltaSides[0] & activeSides) != 0;
case 5: return (deltaSides[1] & activeSides) != 0;
case 0: return (deltaSides[2] & activeSides) != 0;
case 1: return (deltaSides[3] & activeSides) != 0;
case 2: return (deltaSides[4] & activeSides) != 0;
case 3: return (deltaSides[5] & activeSides) != 0;
default: return false;
}
laserMedium_maxCount = 1;
peripheralName = "warpdriveIC2reactorLaserCooler";
}
// returns IReactor tile entities
@Optional.Method(modid = "IC2")
private Set<IReactor> findReactors() {
Set<IReactor> output = new HashSet<>();
byte newActiveSides = 0;
for(int i = 0; i < deltaX.length; i++) {
TileEntity tileEntity = worldObj.getTileEntity(pos.add(deltaX[i], deltaY[i], deltaZ[i]));
private IReactor findReactor() {
for(final EnumFacing facing : EnumFacing.values()) {
final TileEntity tileEntity = worldObj.getTileEntity(pos.offset(facing, 2));
if (tileEntity == null) {
continue;
}
IReactor output = null;
if (tileEntity instanceof IReactor) {
newActiveSides |= deltaSides[i];
output.add((IReactor)tileEntity);
output = (IReactor) tileEntity;
} else if (tileEntity instanceof IReactorChamber) {
IReactor reactor = ((IReactorChamber)tileEntity).getReactorInstance();
final IReactor reactor = ((IReactorChamber) tileEntity).getReactorInstance();
if (reactor == null) {
continue;
}
// ignore if we're right next to the reactor
// ignore if we're not aligned with the reactor
BlockPos blockPos = reactor.getReactorPos();
if ( Math.abs(blockPos.getX() - pos.getX()) == 1
|| Math.abs(blockPos.getY() - pos.getY()) == 1
|| Math.abs(blockPos.getZ() - pos.getZ()) == 1) {
if ( blockPos.getX() != pos.getX() + 3 * facing.getFrontOffsetX()
|| blockPos.getY() != pos.getY() + 3 * facing.getFrontOffsetY()
|| blockPos.getZ() != pos.getZ() + 3 * facing.getFrontOffsetZ() ) {
continue;
}
newActiveSides |= deltaSides[i];
output.add(reactor);
output = reactor;
}
// if reactor or chamber was found, check the space in between
if (output != null) {
final BlockPos blockPos = pos.offset(facing);
final IBlockState blockState = worldObj.getBlockState(blockPos);
final Block block = blockState.getBlock();
final boolean isAir = block.isAir(blockState, worldObj, blockPos);
isValid = ( isAir
|| block instanceof BlockFluidBase
|| block instanceof IReactorChamber
|| !blockState.getMaterial().isOpaque() );
this.facing = facing;
return output;
}
}
if (activeSides != newActiveSides) {
updateFlag = !updateFlag;
activeSides = newActiveSides;
}
return output;
isValid = false;
this.facing = null;
return null;
}
@Optional.Method(modid = "IC2")
private boolean coolReactor(IReactor reactor) {
boolean didCoolReactor = false;
for(int x = 0; x < 9 && !didCoolReactor; x++) {
for(int y = 0; y < 6 && !didCoolReactor; y++) {
ItemStack item = reactor.getItemAt(x, y);
if (item != null) {
if (item.getItem() instanceof ItemIC2reactorLaserFocus) {
int heatInLaserFocus = item.getItemDamage();
int heatRemovable = (int) Math.floor(Math.min(energy_getEnergyStored() / WarpDriveConfig.IC2_REACTOR_ENERGY_PER_HEAT, heatInLaserFocus));
if (heatRemovable > 0) {
didCoolReactor = true;
if (energy_consume((int) Math.ceil(heatRemovable * WarpDriveConfig.IC2_REACTOR_ENERGY_PER_HEAT), false)) {
item.setItemDamage(heatInLaserFocus - heatRemovable);
}
private boolean coolReactor(final IReactor reactor) {
for(int x = 0; x < 9; x++) {
for(int y = 0; y < 6; y++) {
final ItemStack itemStack = reactor.getItemAt(x, y);
if ( itemStack != null
&& itemStack.getItem() instanceof ItemIC2reactorLaserFocus ) {
final int heatInLaserFocus = itemStack.getItemDamage();
final int heatEnergyCap = (int) Math.floor(Math.min(laserMedium_getEnergyStored() / WarpDriveConfig.IC2_REACTOR_ENERGY_PER_HEAT, heatInLaserFocus));
final int heatToTransfer = Math.min(heatEnergyCap, WarpDriveConfig.IC2_REACTOR_COOLING_PER_INTERVAL);
if (heatToTransfer > 0) {
if (laserMedium_consumeExactly((int) Math.ceil(heatToTransfer * WarpDriveConfig.IC2_REACTOR_ENERGY_PER_HEAT), false)) {
ItemIC2reactorLaserFocus.addHeat(itemStack, -heatToTransfer);
return true;
}
}
return false;
}
}
}
return didCoolReactor;
return false;
}
@Override
@ -126,33 +122,29 @@ public class TileEntityIC2reactorLaserMonitor extends TileEntityAbstractEnergy {
return;
}
if (isFirstTick) {
isFirstTick = false;
updateFlag = (getBlockMetadata() & 1) == 0;
WarpDrive.logger.info("" + this + " isFirstTick " + activeSides + " " + updateFlag);
}
ticks--;
if (ticks <= 0) {
ticks = WarpDriveConfig.IC2_REACTOR_COOLING_INTERVAL_TICKS;
Vector3 myPos = new Vector3(this).translate(0.5);
Set<IReactor> reactors = findReactors();
final IReactor reactor = findReactor();
setMetadata();
if (reactors.isEmpty()) {
if (reactor == null) {
return;
}
for(IReactor reactor : reactors) {
if (coolReactor(reactor)) {
PacketHandler.sendBeamPacket(worldObj, myPos, new Vector3(reactor.getReactorPos()).translate(0.5D), 0.0f, 0.8f, 1.0f, 20, 0, 20);
}
if (coolReactor(reactor)) {
final Vector3 vMonitor = new Vector3(this).translate(0.5);
PacketHandler.sendBeamPacket(worldObj,
vMonitor,
new Vector3(reactor.getPosition()).translate(0.5D),
0.0f, 0.8f, 1.0f, 20, 0, 20);
}
}
}
private void setMetadata() {
int metadata = (updateFlag ? 0 : 1) | (activeSides != 0 ? 2 : 0);
if (energy_getEnergyStored() >= WarpDriveConfig.IC2_REACTOR_ENERGY_PER_HEAT) {
int metadata = (facing != null ? facing.ordinal() : 6);
if ( isValid
&& cache_laserMedium_energyStored >= WarpDriveConfig.IC2_REACTOR_ENERGY_PER_HEAT) {
metadata |= 8;
}
if (getBlockMetadata() != metadata) {
@ -161,29 +153,29 @@ public class TileEntityIC2reactorLaserMonitor extends TileEntityAbstractEnergy {
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
tag = super.writeToNBT(tag);
tag.setByte("activeSides", activeSides);
return tag;
public NBTTagCompound writeToNBT(NBTTagCompound tagCompound) {
super.writeToNBT(tagCompound);
tagCompound.setInteger("ticks", ticks);
return tagCompound;
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
activeSides = tag.getByte("activeSides");
public void readFromNBT(final NBTTagCompound tagCompound) {
super.readFromNBT(tagCompound);
ticks = tagCompound.getInteger("ticks");
}
@Nonnull
@Override
public NBTTagCompound getUpdateTag() {
NBTTagCompound tagCompound = new NBTTagCompound();
final NBTTagCompound tagCompound = new NBTTagCompound();
writeToNBT(tagCompound);
return tagCompound;
}
@Override
public void onDataPacket(NetworkManager networkManager, SPacketUpdateTileEntity packet) {
NBTTagCompound tagCompound = packet.getNbtCompound();
public void onDataPacket(final NetworkManager networkManager, final SPacketUpdateTileEntity packet) {
final NBTTagCompound tagCompound = packet.getNbtCompound();
readFromNBT(tagCompound);
}
@ -194,24 +186,14 @@ public class TileEntityIC2reactorLaserMonitor extends TileEntityAbstractEnergy {
return super.getStatus();
}
final Set<IReactor> reactors = findReactors();
if (reactors != null && !reactors.isEmpty()) {
return super.getStatus()
final IReactor reactor = findReactor();
if (reactor != null) {
return super.getStatus()
.appendSibling(new TextComponentTranslation("warpdrive.IC2reactorLaserMonitor.multipleReactors",
reactors.size()));
1));
} else {
return super.getStatus()
.appendSibling(new TextComponentTranslation("warpdrive.IC2reactorLaserMonitor.noReactor"));
}
}
@Override
public int energy_getMaxStorage() {
return WarpDriveConfig.IC2_REACTOR_MAX_ENERGY_STORED;
}
@Override
public boolean energy_canInput(EnumFacing from) {
return true;
}
}

View file

@ -131,6 +131,15 @@ public class BlockForceField extends BlockAbstractForceField implements IDamageR
return new ItemBlockForceField(this);
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(@Nonnull Item item, CreativeTabs creativeTab, List<ItemStack> list) {
// hide in NEI
for (int i = 0; i < 16; i++) {
Commons.hideItemStack(new ItemStack(item, 1, i));
}
}
@Nonnull
@Override
public TileEntity createNewTileEntity(@Nonnull World world, int metadata) {
@ -178,15 +187,6 @@ public class BlockForceField extends BlockAbstractForceField implements IDamageR
return 0;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(@Nonnull Item item, CreativeTabs creativeTab, List<ItemStack> list) {
// @TODO: Hide in NEI
for (int i = 0; i < 16; i++) {
list.add(new ItemStack(item, 1, i));
}
}
@Nonnull
@Override
public EnumBlockRenderType getRenderType(IBlockState state) {

View file

@ -219,7 +219,10 @@ public class TileEntityAbstractForceField extends TileEntityAbstractEnergy imple
@Override
public String toString() {
return String.format("%s Beam \'%d\' @ \'%s\' (%d %d %d)", getClass().getSimpleName(),
beamFrequency, worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ());
return String.format("%s Beam \'%d\' @ %s (%d %d %d)",
getClass().getSimpleName(),
beamFrequency,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());
}
}

View file

@ -705,8 +705,11 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
markDirty();
}
if (!vForceFields.isEmpty()) {
for (Iterator<VectorI> iterator = vForceFields.iterator(); iterator.hasNext();) {
VectorI vector = iterator.next();
// invalidate() can be multi-threaded, so we're working with a copy of the collection
final VectorI[] vForceFields_cache = vForceFields.toArray(new VectorI[0]);
vForceFields.clear();
for (VectorI vector : vForceFields_cache) {
if (!isChunkLoading) {
if (!(worldObj.isBlockLoaded(vector.getBlockPos(), false))) {// chunk is not loaded, skip it
continue;
@ -715,12 +718,11 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
continue;
}
}
IBlockState blockState = vector.getBlockState(worldObj);
final IBlockState blockState = vector.getBlockState(worldObj);
if (blockState.getBlock() == WarpDrive.blockForceFields[tier - 1]) {
worldObj.setBlockToAir(vector.getBlockPos());
}
iterator.remove();
}
}
@ -1006,7 +1008,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
// reset field in case of major changes
if (legacy_forceFieldSetup != null) {
int energyRequired = (int)Math.max(0, Math.round(cache_forceFieldSetup.startupEnergyCost - legacy_forceFieldSetup.startupEnergyCost));
final int energyRequired = (int) Math.max(0, Math.round(cache_forceFieldSetup.startupEnergyCost - legacy_forceFieldSetup.startupEnergyCost));
if (!legacy_forceFieldSetup.getCamouflageBlockState().equals(cache_forceFieldSetup.getCamouflageBlockState())
|| legacy_forceFieldSetup.beamFrequency != cache_forceFieldSetup.beamFrequency
|| !energy_consume(energyRequired, false)) {
@ -1186,7 +1188,8 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
// calculation start is done synchronously, by caller
try {
if (projector.isValid()) {
if ( projector != null
&& projector.isValid() ) {
ForceFieldSetup forceFieldSetup = projector.getForceFieldSetup();
if (WarpDriveConfig.LOGGING_FORCEFIELD) {
WarpDrive.logger.debug(this + " Calculation started for " + projector);
@ -1236,7 +1239,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
vInteriorBlocks = null;
vPerimeterBlocks = null;
exception.printStackTrace();
WarpDrive.logger.error(this + " Calculation failed");
WarpDrive.logger.error(this + " Calculation failed for " + (projector == null ? "-null-" : projector.toString()));
}
projector.calculation_done(vInteriorBlocks, vPerimeterBlocks);

View file

@ -74,7 +74,7 @@ public class BlockShipCore extends BlockAbstractContainer {
ArrayList<ItemStack> itemStacks = new ArrayList<>();
if (world instanceof WorldServer) {
// trigger explosion
EntityTNTPrimed entityTNTPrimed = new EntityTNTPrimed(((WorldServer) world),
final EntityTNTPrimed entityTNTPrimed = new EntityTNTPrimed(((WorldServer) world),
blockPos.getX() + 0.5F, blockPos.getY() + 0.5F, blockPos.getZ() + 0.5F, null);
entityTNTPrimed.setFuse(10 + ((WorldServer) world).rand.nextInt(10));
((WorldServer) world).spawnEntityInWorld(entityTNTPrimed);

View file

@ -363,7 +363,7 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced imple
}
}
protected void commandDone(final boolean success, final String reason) {
void commandDone(final boolean success, final String reason) {
isEnabled = false;
command = EnumShipControllerCommand.IDLE;
if (!success) {
@ -402,7 +402,7 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced imple
}
}
protected String getTargetName() {
String getTargetName() {
return nameTarget;
}
@ -797,7 +797,8 @@ public class TileEntityShipController extends TileEntityAbstractInterfaced imple
@Override
public String toString() {
final TileEntityShipCore tileEntityShipCore = tileEntityShipCoreWeakReference == null ? null : tileEntityShipCoreWeakReference.get();
return String.format("%s \'%s\' @ \'%s\' (%d %d %d)", getClass().getSimpleName(),
return String.format("%s \'%s\' @ %s (%d %d %d)",
getClass().getSimpleName(),
tileEntityShipCore == null ? "-NULL-" : tileEntityShipCore.shipName,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());

View file

@ -56,7 +56,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
public EnumFacing facing;
public UUID uuid = null;
public String shipName = "default";
public double isolationRate = 0.0D;
private double isolationRate = 0.0D;
private int cooldownTime_ticks = 0;
private int warmupTime_ticks = 0;
protected int jumpCount = 0;
@ -91,7 +91,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
private int isolationUpdateTicks = 0;
public WeakReference<TileEntityShipController> tileEntityShipControllerWeakReference;
private WeakReference<TileEntityShipController> tileEntityShipControllerWeakReference;
public TileEntityShipCore() {
@ -263,7 +263,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
case SUMMON:
final String targetName = tileEntityShipController.getTargetName();
if ( targetName == null
|| targetName.isEmpty()) {
|| targetName.isEmpty()) {
summonPlayers(tileEntityShipController);
} else {
summonSinglePlayer(tileEntityShipController, targetName);
@ -418,8 +418,10 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
messageToAllPlayersOnShip(new TextComponentString(string));
}
public void messageToAllPlayersOnShip(ITextComponent textComponent) {
AxisAlignedBB axisalignedbb = new AxisAlignedBB(minX, minY, minZ, maxX + 0.99D, maxY + 0.99D, maxZ + 0.99D);
List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
final AxisAlignedBB axisalignedbb = new AxisAlignedBB(minX, minY, minZ, maxX + 0.99D, maxY + 0.99D, maxZ + 0.99D);
final List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
final ITextComponent messageFormatted = new TextComponentString("[" + (!shipName.isEmpty() ? shipName : "ShipCore") + "] ")
.appendSibling(textComponent);
WarpDrive.logger.info(this + " messageToAllPlayersOnShip: " + textComponent.getFormattedText());
for (final Entity entity : list) {
@ -427,7 +429,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
continue;
}
Commons.addChatMessage(entity, new TextComponentString("[" + (!shipName.isEmpty() ? shipName : "ShipCore") + "] ").appendSibling(textComponent));
Commons.addChatMessage(entity, messageFormatted);
}
}
@ -511,13 +513,11 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
private void summonPlayers(final TileEntityShipController tileEntityShipController) {
final AxisAlignedBB aabb = new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
final MinecraftServer server = worldObj.getMinecraftServer();
assert(server != null);
for (int i = 0; i < tileEntityShipController.players.size(); i++) {
final String playerName = tileEntityShipController.players.get(i);
final EntityPlayerMP entityPlayerMP = server.getPlayerList().getPlayerByUsername(playerName);
final EntityPlayerMP entityPlayerMP = Commons.getOnlinePlayerByName(playerName);
if ( entityPlayerMP != null
&& isOutsideBB(aabb, MathHelper.floor_double(entityPlayerMP.posX), MathHelper.floor_double(entityPlayerMP.posY), MathHelper.floor_double(entityPlayerMP.posZ)) ) {
summonPlayer(entityPlayerMP);
@ -532,7 +532,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
for (int i = 0; i < tileEntityShipController.players.size(); i++) {
final String playerName = tileEntityShipController.players.get(i);
final EntityPlayerMP entityPlayerMP = server.getPlayerList().getPlayerByUsername(playerName);
final EntityPlayerMP entityPlayerMP = Commons.getOnlinePlayerByName(playerName);
if ( entityPlayerMP != null && playerName.equals(nickname)
&& isOutsideBB(aabb, MathHelper.floor_double(entityPlayerMP.posX), MathHelper.floor_double(entityPlayerMP.posY), MathHelper.floor_double(entityPlayerMP.posZ)) ) {
@ -935,7 +935,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
// Consume energy
if (energy_consume(shipMovementCosts.energyRequired, false)) {
WarpDrive.logger.info(this + " Moving ship to a place around gate '" + targetGate.name + "' (" + destX + "; " + destY + "; " + destZ + ")");
JumpSequencer jump = new JumpSequencer(this, EnumShipMovementType.GATE_ACTIVATING, targetName, 0, 0, 0, (byte) 0, destX, destY, destZ);
final JumpSequencer jump = new JumpSequencer(this, EnumShipMovementType.GATE_ACTIVATING, targetName, 0, 0, 0, (byte) 0, destX, destY, destZ);
jump.enable();
} else {
messageToAllPlayersOnShip("Insufficient energy level");
@ -1243,8 +1243,10 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta
@Override
public String toString() {
return String.format(
"%s \'%s\' @ \'%s\' (%d %d %d)",
getClass().getSimpleName(), shipName, worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
"%s \'%s\' @ %s (%d %d %d)",
getClass().getSimpleName(),
shipName,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());
}
}

View file

@ -33,7 +33,7 @@ public class BlockLaserCamera extends BlockAbstractContainer {
@Nonnull
@Override
public TileEntity createNewTileEntity(@Nonnull World world, int metadata) {
public TileEntity createNewTileEntity(@Nonnull final World world, final int metadata) {
return new TileEntityLaserCamera();
}

View file

@ -189,7 +189,11 @@ public class TileEntityLaserCamera extends TileEntityLaser implements IVideoChan
@Override
public String toString() {
return String.format("%s Beam \'%d\' Camera \'%d\' @ \'%s\' (%d %d %d)", getClass().getSimpleName(),
beamFrequency, videoChannel, worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ());
return String.format("%s Beam \'%d\' Camera \'%d\' @ %s (%d %d %d)",
getClass().getSimpleName(),
beamFrequency,
videoChannel,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());
}
}

View file

@ -34,7 +34,9 @@ public class TileEntityWeaponController extends TileEntityAbstractInterfaced {
@Override
public String toString() {
return String.format("%s @ \'%s\' (%d %d %d)", getClass().getSimpleName(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(), pos.getX(), pos.getY(), pos.getZ());
return String.format("%s @ %s (%d %d %d)",
getClass().getSimpleName(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
pos.getX(), pos.getY(), pos.getZ());
}
}

View file

@ -70,8 +70,9 @@ public class CommandDump extends CommandBase {
}
// actually dump
WarpDrive.logger.info(String.format("Dumping content from container at %s (%d %d %d):",
world.provider.getDimensionType().getName(), x, y, z));
WarpDrive.logger.info(String.format("Dumping content from container @ %s (%d %d %d):",
world.provider.getDimensionType().getName(),
x, y, z));
for (int indexSlot = 0; indexSlot < inventory.getSizeInventory(); indexSlot++) {
final ItemStack itemStack = inventory.getStackInSlot(indexSlot);
if (itemStack != null) {

View file

@ -134,26 +134,26 @@ public class CompatArsMagica2 implements IBlockTransformer {
if (!(tileEntity instanceof IPowerNode) || nbtBase == null) {
return;
}
NBTTagCompound nbtTagCompound = (NBTTagCompound) nbtBase;
final NBTTagCompound nbtTagCompound = (NBTTagCompound) nbtBase;
// powerAmounts
// (no changes)
// powerPathList
NBTTagList powerPathList = nbtTagCompound.getTagList("powerPathList", Constants.NBT.TAG_COMPOUND);
final NBTTagList powerPathList = nbtTagCompound.getTagList("powerPathList", Constants.NBT.TAG_COMPOUND);
if (powerPathList != null) {
for (int powerPathIndex = 0; powerPathIndex < powerPathList.tagCount(); powerPathIndex++) {
NBTTagCompound powerPathEntry = (NBTTagCompound) powerPathList.removeTag(0);
final NBTTagCompound powerPathEntry = (NBTTagCompound) powerPathList.removeTag(0);
// powerPathList[powerPathIndex].powerType
// (no change)
// powerPathList[powerPathIndex].nodePaths
NBTTagList nodePaths = powerPathEntry.getTagList("nodePaths", Constants.NBT.TAG_LIST);
final NBTTagList nodePaths = powerPathEntry.getTagList("nodePaths", Constants.NBT.TAG_LIST);
if (nodePaths != null) {
for (int nodePathIndex = 0; nodePathIndex < nodePaths.tagCount(); nodePathIndex++) {
// we can't directly access it, hence removing then adding back later on
NBTTagList nodeList = (NBTTagList) nodePaths.removeTag(0);
final NBTTagList nodeList = (NBTTagList) nodePaths.removeTag(0);
if (nodeList != null) {
for (int nodeIndex = 0; nodeIndex < nodeList.tagCount(); nodeIndex++) {
NBTTagCompound node = (NBTTagCompound) nodeList.removeTag(0);
@ -162,7 +162,7 @@ public class CompatArsMagica2 implements IBlockTransformer {
node.setFloat("Vec3_x", (float)target.xCoord);
node.setFloat("Vec3_y", (float)target.yCoord);
node.setFloat("Vec3_z", (float)target.zCoord);
//tack the node on to the power path
// add the node on to the power path
nodeList.appendTag(node);
}
nodePaths.appendTag(nodeList);
@ -175,9 +175,9 @@ public class CompatArsMagica2 implements IBlockTransformer {
nbtTagCompound.setTag("powerPathList", powerPathList);
}
World targetWorld = transformation.getTargetWorld();
BlockPos target = transformation.apply(tileEntity);
TileEntity tileEntityTarget = targetWorld.getTileEntity(target);
final World targetWorld = transformation.getTargetWorld();
final BlockPos target = transformation.apply(tileEntity);
final TileEntity tileEntityTarget = targetWorld.getTileEntity(target);
if (tileEntityTarget == null) {
WarpDrive.logger.error("ArsMagica2 compat: No tile entity found at target location " + target + ". We might loose mana network " + nbtBase + ".");
} else if (!(tileEntityTarget instanceof IPowerNode)) {

View file

@ -0,0 +1,329 @@
package cr0s.warpdrive.compat;
import cr0s.warpdrive.api.IBlockTransformer;
import cr0s.warpdrive.api.ITransformation;
import cr0s.warpdrive.config.WarpDriveConfig;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
public class CompatDraconicEvolution implements IBlockTransformer {
private static Class<?> classBlockBlockDE;
private static Class<?> classBlockDraconiumBlock;
private static Class<?> classBlockGenerator;
private static Class<?> classBlockTeleporterStand;
private static Class<?> classBlockPlacedItem;
public static void register() {
try {
classBlockBlockDE = Class.forName("com.brandon3055.draconicevolution.common.blocks.BlockDE");
classBlockDraconiumBlock = Class.forName("com.brandon3055.draconicevolution.common.blocks.DraconiumBlock");
classBlockGenerator = Class.forName("com.brandon3055.draconicevolution.common.blocks.machine.Generator");
classBlockPlacedItem = Class.forName("com.brandon3055.draconicevolution.common.blocks.PlacedItem");
classBlockTeleporterStand = Class.forName("com.brandon3055.draconicevolution.common.blocks.TeleporterStand");
WarpDriveConfig.registerBlockTransformer("DraconicEvolution", new CompatDraconicEvolution());
} catch(ClassNotFoundException exception) {
exception.printStackTrace();
}
}
@Override
public boolean isApplicable(final Block block, final int metadata, final TileEntity tileEntity) {
return classBlockBlockDE.isInstance(block);
}
@Override
public boolean isJumpReady(final Block block, final int metadata, final TileEntity tileEntity, StringBuilder reason) {
if ( classBlockDraconiumBlock.isInstance(block)
&& metadata == 1) {
reason.append("Ender resurrection anchor detected!");
return false;
}
return true;
}
@Override
public NBTBase saveExternals(final World world, final int x, final int y, final int z, final Block block, final int blockMeta, final TileEntity tileEntity) {
// nothing to do
return null;
}
@Override
public void removeExternals(final World world, final int x, final int y, final int z,
final Block block, final int blockMeta, final TileEntity tileEntity) {
// nothing to do
}
/*
Blacklisted for movement:
DraconicEvolution:draconium@1
TileEntityId = draconicevolution:TileEnderResurrection
BlockClass = com.brandon3055.draconicevolution.common.blocks.DraconiumBlock
Metadata = 0 is valid, consequently we can't use the dictionary for that one
Whitelisted for movement:
Generator
metadata 1 2 3 0
com.brandon3055.draconicevolution.common.tileentities.energynet.TileEnergyTransceiver
int Facing 0 1 5 3 4 2
int LinkCount
int X_LinkedDevice_0 Y_LinkedDevice_0 Z_LinkedDevice_0
com.brandon3055.draconicevolution.common.tileentities.energynet.TileRemoteEnergyBase (TileEnergyTransceiver, TileWirelessEnergyTransceiver & TileEnergyRelay)
int LinkCount
int X_LinkedDevice_0 Y_LinkedDevice_0 Z_LinkedDevice_0
com.brandon3055.draconicevolution.common.tileentities.TilePlacedItem
float Rotation (x + 270.0F) % 360.0F only when metadata is 0 or 1
metadata 0 1 5 3 4 2
com.brandon3055.draconicevolution.common.tileentities.TileTeleporterStand
int Rotation (degrees?)
com.brandon3055.draconicevolution.common.tileentities.TileDraconiumChest
byte facing 0 1 5 3 4 2
com.brandon3055.draconicevolution.common.tileentities.multiblocktiles.reactor.TileReactorStabilizer
int Facing 0 1 5 3 4 2
int X_Master Y_Master Z_Master
com.brandon3055.draconicevolution.common.tileentities.multiblocktiles.reactor.TileReactorEnergyInjector
int Facing 0 1 5 3 4 2
int X_Master Y_Master Z_Master
com.brandon3055.draconicevolution.common.tileentities.multiblocktiles.reactor.TileReactorCore
list Stabilizers (optional)
int X_tag Y_tag Z_tag
com.brandon3055.draconicevolution.common.tileentities.TileParticleGenerator
int X_Key Y_Key Z_Key
com.brandon3055.draconicevolution.common.tileentities.multiblocktiles.TileInvisibleMultiblock
int X_Key Y_Key Z_Key
com.brandon3055.draconicevolution.common.tileentities.multiblocktiles.TileEnergyPylon
int Cores
int X_Core0 Y_Core0 Z_Core0
com.brandon3055.draconicevolution.common.tileentities.multiblocktiles.TileEnergyStorageCore
int X_0 Y_0 Z_0 (optional)
int X_1 Y_1 Z_1 (optional)
int X_2 Y_2 Z_2 (optional)
int X_3 Y_3 Z_3 (optional)
*/
private static final int[] rotRotation = { 0, 1, 5, 4, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
private static final int[] rotGenerator = { 1, 2, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
@Override
public int rotate(final Block block, final int metadata, NBTTagCompound nbtTileEntity, final ITransformation transformation) {
final byte rotationSteps = transformation.getRotationSteps();
if (rotationSteps == 0 && nbtTileEntity == null) {
return metadata;
}
// TileDraconiumChest rotation only has "facing" with no other field => return
if (nbtTileEntity.hasKey("facing")) {
final int facing = nbtTileEntity.getInteger("facing");
switch (rotationSteps) {
case 1:
nbtTileEntity.setInteger("facing", rotRotation[facing]);
return metadata;
case 2:
nbtTileEntity.setInteger("facing", rotRotation[rotRotation[facing]]);
return metadata;
case 3:
nbtTileEntity.setInteger("facing", rotRotation[rotRotation[rotRotation[facing]]]);
return metadata;
default:
return metadata;
}
}
// generator only has metadata with no other field => return
if (classBlockGenerator.isInstance(block)) {
switch (rotationSteps) {
case 1:
return rotGenerator[metadata];
case 2:
return rotGenerator[rotGenerator[metadata]];
case 3:
return rotGenerator[rotGenerator[rotGenerator[metadata]]];
default:
return metadata;
}
}
// generic tile entity rotations for TileEnergyTransceiver, TileReactorStabilizer, TileReactorEnergyInjector
if (nbtTileEntity.hasKey("Facing")) {
final int facing = nbtTileEntity.getInteger("Facing");
switch (rotationSteps) {
case 1:
nbtTileEntity.setInteger("Facing", rotRotation[facing]);
break;
case 2:
nbtTileEntity.setInteger("Facing", rotRotation[rotRotation[facing]]);
break;
case 3:
nbtTileEntity.setInteger("Facing", rotRotation[rotRotation[rotRotation[facing]]]);
break;
default:
break;
}
}
// generic linked devices for TileEnergyTransceiver and derived from TileRemoteEnergyBase (TileEnergyTransceiver, TileWirelessEnergyTransceiver & TileEnergyRelay)
if (nbtTileEntity.hasKey("LinkCount")) {
final int countLinks = nbtTileEntity.getInteger("LinkCount");
if (countLinks > 0) {
for (int indexLink = 0; indexLink < countLinks; indexLink++) {
final BlockPos targetLink = transformation.apply(
nbtTileEntity.getInteger(String.format("X_LinkedDevice_%d", indexLink)),
nbtTileEntity.getInteger(String.format("Y_LinkedDevice_%d", indexLink)),
nbtTileEntity.getInteger(String.format("Z_LinkedDevice_%d", indexLink)) );
nbtTileEntity.setInteger(String.format("X_LinkedDevice_%d", indexLink), targetLink.getX());
nbtTileEntity.setInteger(String.format("Y_LinkedDevice_%d", indexLink), targetLink.getY());
nbtTileEntity.setInteger(String.format("Z_LinkedDevice_%d", indexLink), targetLink.getZ());
}
}
}
// generic link to master for TileReactorStabilizer and TileReactorEnergyInjector
if (nbtTileEntity.hasKey("X_Master")) {
final BlockPos targetLink = transformation.apply(
nbtTileEntity.getInteger("X_Master"),
nbtTileEntity.getInteger("Y_Master"),
nbtTileEntity.getInteger("Z_Master") );
nbtTileEntity.setInteger("X_Master", targetLink.getX());
nbtTileEntity.setInteger("Y_Master", targetLink.getY());
nbtTileEntity.setInteger("Z_Master", targetLink.getZ());
}
// generic link to master for TileParticleGenerator and TileInvisibleMultiblock
if (nbtTileEntity.hasKey("X_Key")) {
final BlockPos targetLink = transformation.apply(
nbtTileEntity.getInteger("X_Key"),
nbtTileEntity.getInteger("Y_Key"),
nbtTileEntity.getInteger("Z_Key") );
nbtTileEntity.setInteger("X_Key", targetLink.getX());
nbtTileEntity.setInteger("Y_Key", targetLink.getY());
nbtTileEntity.setInteger("Z_Key", targetLink.getZ());
}
// linked stabilizers for TileReactorCore
if (nbtTileEntity.hasKey("Stabilizers")) {
// we can't directly access it, hence removing then adding back later on
final NBTTagList stabilizers = nbtTileEntity.getTagList("Stabilizers", Constants.NBT.TAG_COMPOUND);
if (stabilizers != null) {
for (int nodeIndex = 0; nodeIndex < stabilizers.tagCount(); nodeIndex++) {
// remove
final NBTTagCompound stabilizer = (NBTTagCompound) stabilizers.removeTag(0);
// update coordinates
final BlockPos target = transformation.apply(
stabilizer.getInteger("X_tag"),
stabilizer.getInteger("Y_tag"),
stabilizer.getInteger("Z_tag"));
stabilizer.setInteger("X_tag", target.getX());
stabilizer.setInteger("Y_tag", target.getY());
stabilizer.setInteger("Z_tag", target.getZ());
// add
stabilizers.appendTag(stabilizer);
}
}
}
// linked cores for TileEnergyPylon
if (nbtTileEntity.hasKey("Cores")) {
final int countCores = nbtTileEntity.getInteger("Cores");
if (countCores > 0) {
for (int indexCore = 0; indexCore < countCores; indexCore++) {
final BlockPos targetLink = transformation.apply(
nbtTileEntity.getInteger(String.format("X_Core%d", indexCore)),
nbtTileEntity.getInteger(String.format("Y_Core%d", indexCore)),
nbtTileEntity.getInteger(String.format("Z_Core%d", indexCore)) );
nbtTileEntity.setInteger(String.format("X_Core%d", indexCore), targetLink.getX());
nbtTileEntity.setInteger(String.format("Y_Core%d", indexCore), targetLink.getY());
nbtTileEntity.setInteger(String.format("Z_Core%d", indexCore), targetLink.getZ());
}
}
}
// linked emitters for TileEnergyStorageCore
if (nbtTileEntity.hasKey("X_0")) {
final BlockPos targetLink = transformation.apply(
nbtTileEntity.getInteger("X_0"),
nbtTileEntity.getInteger("Y_0"),
nbtTileEntity.getInteger("Z_0") );
nbtTileEntity.setInteger("X_0", targetLink.getX());
nbtTileEntity.setInteger("Y_0", targetLink.getY());
nbtTileEntity.setInteger("Z_0", targetLink.getZ());
}
if (nbtTileEntity.hasKey("X_1")) {
final BlockPos targetLink = transformation.apply(
nbtTileEntity.getInteger("X_1"),
nbtTileEntity.getInteger("Y_1"),
nbtTileEntity.getInteger("Z_1") );
nbtTileEntity.setInteger("X_1", targetLink.getX());
nbtTileEntity.setInteger("Y_1", targetLink.getY());
nbtTileEntity.setInteger("Z_1", targetLink.getZ());
}
if (nbtTileEntity.hasKey("X_2")) {
final BlockPos targetLink = transformation.apply(
nbtTileEntity.getInteger("X_2"),
nbtTileEntity.getInteger("Y_2"),
nbtTileEntity.getInteger("Z_2") );
nbtTileEntity.setInteger("X_2", targetLink.getX());
nbtTileEntity.setInteger("Y_2", targetLink.getY());
nbtTileEntity.setInteger("Z_2", targetLink.getZ());
}
if (nbtTileEntity.hasKey("X_3")) {
final BlockPos targetLink = transformation.apply(
nbtTileEntity.getInteger("X_3"),
nbtTileEntity.getInteger("Y_3"),
nbtTileEntity.getInteger("Z_3") );
nbtTileEntity.setInteger("X_3", targetLink.getX());
nbtTileEntity.setInteger("Y_3", targetLink.getY());
nbtTileEntity.setInteger("Z_3", targetLink.getZ());
}
// rotation for placed item only applies for top/bottom position
if (classBlockPlacedItem.isInstance(block)) {
if (rotationSteps > 0) {
if (metadata == 0) {
final float rotation = nbtTileEntity.getInteger("Rotation");
nbtTileEntity.setFloat("Rotation", (rotation + rotationSteps * 90.0F) % 360.0F);
} else if (metadata == 1) {
final float rotation = nbtTileEntity.getInteger("Rotation");
nbtTileEntity.setFloat("Rotation", (rotation + rotationSteps * 270.0F) % 360.0F);
}
}
switch (rotationSteps) {
case 1:
return rotRotation[metadata];
case 2:
return rotRotation[rotRotation[metadata]];
case 3:
return rotRotation[rotRotation[rotRotation[metadata]]];
default:
return metadata;
}
}
// rotation for dislocator stand / TileTeleporterStand
if (classBlockTeleporterStand.isInstance(block)) {
if (rotationSteps > 0) {
final float rotation = nbtTileEntity.getInteger("Rotation");
nbtTileEntity.setFloat("Rotation", (rotation + rotationSteps * 90.0F) % 360.0F);
}
return metadata;
}
return metadata;
}
@Override
public void restoreExternals(final World world, final int x, final int y, final int z,
final Block block, final int blockMeta, final TileEntity tileEntity,
final ITransformation transformation, final NBTBase nbtBase) {
// nothing to do
}
}

View file

@ -46,11 +46,9 @@ public class CompatWarpDrive implements IBlockTransformer {
public NBTBase saveExternals(final World world, final int x, final int y, final int z,
final Block block, final int blockMeta, final TileEntity tileEntity) {
if (block instanceof BlockAirFlow || block instanceof BlockAirSource) {
final ChunkData chunkData = ChunkHandler.getChunkData(world, x, y, z, false);
final ChunkData chunkData = ChunkHandler.getChunkData(world, x, y, z);
if (chunkData == null) {
WarpDrive.logger.error(String.format("CompatWarpDrive trying to get data from an non-loaded chunk in %s @ (%d %d %d)",
world.provider.getDimensionType().getName(), x, y, z));
assert(false);
// chunk isn't loaded, skip it
return null;
}
final int dataAir = chunkData.getDataAir(x, y, z);
@ -68,11 +66,9 @@ public class CompatWarpDrive implements IBlockTransformer {
public void removeExternals(final World world, final int x, final int y, final int z,
final Block block, final int blockMeta, final TileEntity tileEntity) {
if (block instanceof BlockAirFlow || block instanceof BlockAirSource) {
final ChunkData chunkData = ChunkHandler.getChunkData(world, x, y, z, false);
final ChunkData chunkData = ChunkHandler.getChunkData(world, x, y, z);
if (chunkData == null) {
WarpDrive.logger.error(String.format("CompatWarpDrive trying to get data from an non-loaded chunk in %s @ (%d %d %d)",
world.provider.getDimensionType().getName(), x, y, z));
assert(false);
// chunk isn't loaded, skip it
return;
}
chunkData.setDataAir(x, y, z, StateAir.AIR_DEFAULT);
@ -188,11 +184,9 @@ public class CompatWarpDrive implements IBlockTransformer {
if (((NBTTagCompound) nbtBase).hasKey("dataAir")) {
final byte rotationSteps = transformation.getRotationSteps();
final int dataAir = ((NBTTagCompound) nbtBase).getInteger("dataAir");
final ChunkData chunkData = ChunkHandler.getChunkData(world, x, y, z, false);
final ChunkData chunkData = ChunkHandler.getChunkData(world, x, y, z);
if (chunkData == null) {
WarpDrive.logger.error(String.format("CompatWarpDrive trying to set data from an non-loaded chunk in %s @ (%d %d %d)",
world.provider.getDimensionType().getName(), x, y, z));
assert(false);
// chunk isn't loaded, skip it
return;
}
final int dataAirRotated = StateAir.rotate(dataAir, rotationSteps);

View file

@ -121,7 +121,7 @@ public class Dictionary {
config.get("block_tags", "ComputerCraft:command_computer" , "Anchor SkipMining").getString();
config.get("block_tags", "IC2:blockPersonal" , "Anchor SkipMining").getString();
config.get("block_tags", "malisisdoors:rustyHatch" , "Anchor").getString();
config.get("block_tags", "warpdrive:blockBedrockGlass" , "Anchor SkipMining").getString();
config.get("block_tags", "WarpDrive:blockBedrockGlass" , "Anchor SkipMining").getString();
// placement priorities
config.get("block_tags", "minecraft:lever" , "PlaceLatest").getString();
@ -295,6 +295,7 @@ public class Dictionary {
config.get("item_tags", "IC2:itemSolarHelmet", "BreathingHelmet").getString();
config.get("item_tags", "IC2:itemArmorNanoHelmet", "BreathingHelmet").getString();
config.get("item_tags", "IC2:itemArmorQuantumHelmet", "BreathingHelmet").getString();
config.get("item_tags", "PneumaticCraft:pneumaticHelmet", "BreathingHelmet").getString();
config.get("item_tags", "RedstoneArsenal:armor.helmetFlux", "BreathingHelmet").getString();
config.get("item_tags", "Techguns:t3_exo_helmet", "BreathingHelmet").getString();
config.get("item_tags", "Techguns:t3_miner_helmet", "BreathingHelmet").getString();

View file

@ -89,8 +89,9 @@ public class Filler implements IXmlRepresentableUnit {
if (nbtTagCompound != null) {
TileEntity tileEntity = world.getTileEntity(blockPos);
if (tileEntity == null) {
WarpDrive.logger.error(String.format("No TileEntity found for Filler %s at (%d %d %d)",
getName(), blockPos.getX(), blockPos.getY(), blockPos.getZ() ));
WarpDrive.logger.error("No TileEntity found for Filler %s at (%d %d %d)",
getName(),
blockPos.getX(), blockPos.getY(), blockPos.getZ() );
return;
}

View file

@ -18,6 +18,7 @@ import cr0s.warpdrive.item.ItemUpgrade;
import java.util.List;
import net.minecraft.block.BlockColored;
import net.minecraft.item.EnumDyeColor;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraft.init.Blocks;
@ -366,12 +367,6 @@ public class Recipes {
'c', advancedCircuit,
'g', Blocks.GLASS);
GameRegistry.addRecipe(new ItemStack(WarpDrive.blockShipScanner), "sgs", "mma", "amm",
'm', advancedMachine,
'a', advancedAlloy,
's', advancedCircuit,
'g', Blocks.GLASS);
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockLaserTreeFarm), false, new Object[] { "cwc", "wmw", "cwc",
'c', circuit,
'w', "logWood",
@ -513,12 +508,6 @@ public class Recipes {
'c', "circuitAdvanced",
'g', "paneGlassColorless" }));
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockShipScanner), false, new Object[] { "ici", "isi", "mcm",
'm', mfsu,
'i', iridiumAlloy,
'c', "circuitAdvanced",
's', WarpDriveConfig.getModItemStack("ic2", "te", 64) })); // Scanner
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockLaserTreeFarm), false, new Object[] { "awa", "cmc", "asa",
'a', advancedAlloy,
'c', "circuitAdvanced",
@ -568,8 +557,11 @@ public class Recipes {
}
// Add Reinforced iridium plate to ore registry as applicable (it's missing in IC2 without GregTech)
if (WarpDriveConfig.isIndustrialCraft2Loaded && (!OreDictionary.doesOreNameExist("plateAlloyIridium") || OreDictionary.getOres("plateAlloyIridium").isEmpty())) {
ItemStack iridiumAlloy = WarpDriveConfig.getModItemStack("ic2", "crafting", 4); // Iridium reinforced place
if ( WarpDriveConfig.isIndustrialCraft2Loaded
&& (!OreDictionary.doesOreNameExist("plateAlloyIridium") || OreDictionary.getOres("plateAlloyIridium").isEmpty()) ) {
ItemStack iridiumAlloy = WarpDriveConfig.getModItemStack("IC2", "itemPartIridium", 0, // IC2 Experimental Iridium alloy plate
"IC2", "item.itemPartIridium", 0); // IC2 Classic Iridium alloy plate
// ItemStack iridiumAlloy = WarpDriveConfig.getModItemStack("ic2", "crafting", 4); // Iridium reinforced place @TODO MC1.10 merge
OreDictionary.registerOre("plateAlloyIridium", iridiumAlloy);
}
@ -583,7 +575,18 @@ public class Recipes {
ItemStack itemStackMotorHV = ItemComponent.getItemStack(EnumComponentType.MOTOR);
ItemStack itemStackMotorEV = ItemComponent.getItemStack(EnumComponentType.MOTOR);
if (WarpDriveConfig.isGregTech5Loaded) {
if (WarpDriveConfig.isGregTech6Loaded) {
itemStackMachineCasingLV = WarpDriveConfig.getModItemStack("gregtech", "gt.meta.machine", 8651); // ore:casingMachineSteelGalvanized
itemStackMachineCasingMV = WarpDriveConfig.getModItemStack("gregtech", "gt.meta.machine", 130); // ore:casingMachineAluminium
itemStackMachineCasingHV = WarpDriveConfig.getModItemStack("gregtech", "gt.meta.machine", 8636); // ore:casingMachineStainlessSteel
itemStackMachineCasingEV = WarpDriveConfig.getModItemStack("gregtech", "gt.meta.machine", 240); // ore:casingMachineChromium
itemStackMotorLV = WarpDriveConfig.getModItemStack("gregtech", "gt.multiitem.technological", 12001); // LV Motor
itemStackMotorMV = WarpDriveConfig.getModItemStack("gregtech", "gt.multiitem.technological", 12002); // MV Motor
itemStackMotorHV = WarpDriveConfig.getModItemStack("gregtech", "gt.multiitem.technological", 12003); // HV Motor
itemStackMotorEV = WarpDriveConfig.getModItemStack("gregtech", "gt.multiitem.technological", 12004); // EV Motor
} else if (WarpDriveConfig.isGregTech5Loaded) {
itemStackMachineCasingLV = WarpDriveConfig.getModItemStack("gregtech", "gt.blockcasings", 1);
itemStackMachineCasingMV = WarpDriveConfig.getModItemStack("gregtech", "gt.blockcasings", 2);
itemStackMachineCasingHV = WarpDriveConfig.getModItemStack("gregtech", "gt.blockcasings", 3);
@ -600,13 +603,14 @@ public class Recipes {
itemStackMachineCasingHV = new ItemStack(WarpDrive.blockHighlyAdvancedMachine);
itemStackMachineCasingEV = new ItemStack(WarpDrive.blockHighlyAdvancedMachine);
itemStackMotorHV = WarpDriveConfig.getModItemStack("ic2", "crafting", 6); // Electric motor
itemStackMotorEV = WarpDriveConfig.getModItemStack("ic2", "crafting", 6); // Electric motor
ItemStack itemStackMotor = WarpDriveConfig.getModItemStack("ic2", "itemRecipePart", 1, // IC2 Experimental Electric motor @MC1.10 update
"ic2", "item.itemToolDrill", 0); // IC2 Classic Mining drill @MC1.10 update
itemStackMotorHV = itemStackMotor;
itemStackMotorEV = itemStackMotor;
ItemStack iridiumAlloy = WarpDriveConfig.getModItemStack("ic2", "crafting", 4); // Iridium reinforced place
GameRegistry.addRecipe(new ItemStack(WarpDrive.blockHighlyAdvancedMachine), "iii", "imi", "iii",
'i', iridiumAlloy,
'm', itemStackMachineCasingMV);
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockHighlyAdvancedMachine), false, "iii", "imi", "iii",
'i', "plateAlloyIridium",
'm', itemStackMachineCasingMV));
} else if (WarpDriveConfig.isThermalExpansionLoaded) {
itemStackMachineCasingLV = WarpDriveConfig.getModItemStack("ThermalExpansion", "Frame", 0);
@ -909,7 +913,8 @@ public class Recipes {
if (WarpDriveConfig.isThermalExpansionLoaded) {
oreCoolant = "dustCryotheum";
} else if (WarpDriveConfig.isIndustrialCraft2Loaded) {
oreCoolant = WarpDriveConfig.getModItemStack("ic2", "heat_storage", -1); // 10k Coolant Cell
oreCoolant = WarpDriveConfig.getModItemStack("IC2", "reactorCoolantSimple", 1, // IC2 Experimental 10k Coolant Cell @TODO MC1.10 update
"IC2", "item.reactorCoolantSimple", 0); // IC2 Classic 10k Coolant Cell @TODO MC1.10 update
}
GameRegistry.addRecipe(new ShapedOreRecipe(ItemComponent.getItemStack(EnumComponentType.SUPERCONDUCTOR), false, "pcp", "cec", "pcp",
'p', ItemComponent.getItemStack(EnumComponentType.POWER_INTERFACE),
@ -1083,8 +1088,10 @@ public class Recipes {
// Air generator is 1 power interface, 4 activated carbon, 1 motor, 1 MV Machine casing, 2 tanks
ItemStack itemStackCompressorOrTank = ItemComponent.getItemStack(EnumComponentType.GLASS_TANK);
if (WarpDriveConfig.isGregTech5Loaded) {
itemStackCompressorOrTank = WarpDriveConfig.getModItemStack("gregtech", "gt.metaitem.02", 21300); // Bronze rotor
if (WarpDriveConfig.isGregTech6Loaded) {
itemStackCompressorOrTank = WarpDriveConfig.getModItemStack("gregtech", "gt.meta.rotor", 8610); // GT6 Bronze rotor, ore:rotorBronze
} else if (WarpDriveConfig.isGregTech5Loaded) {
itemStackCompressorOrTank = WarpDriveConfig.getModItemStack("gregtech", "gt.metaitem.02", 21300); // GT5 Bronze rotor
} else if (WarpDriveConfig.isIndustrialCraft2Loaded) {
itemStackCompressorOrTank = WarpDriveConfig.getModItemStack("ic2", "te", 43); // Compressor
} else if (WarpDriveConfig.isThermalExpansionLoaded) {
@ -1115,14 +1122,14 @@ public class Recipes {
't', itemStackMotors[3],
'm', itemStackMachineCasings[3]));
// Air shield is 4 glowstones, 4 omnipanels and 1 coil crystal
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockAirShield, 4, 4), false, "gog", "oco", "gog",
'g', Items.GLOWSTONE_DUST,
'o', "blockHull1_omnipanel",
'c', ItemComponent.getItemStack(EnumComponentType.COIL_CRYSTAL) ));
// Air shield is 4 glowstones, 4 omnipanels and 1 coil crystal
for (EnumDyeColor enumDyeColor : EnumDyeColor.values()) {
final int woolColor = enumDyeColor.getDyeDamage(); // @TODO sounds about wrong
OreDictionary.registerOre("blockAirShield", new ItemStack(WarpDrive.blockAirShield, 1, enumDyeColor.getDyeDamage()));
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockAirShield, 4, woolColor), false, "gog", "oco", "gog",
'g', Items.GLOWSTONE_DUST,
'o', new ItemStack(WarpDrive.blockHulls_omnipanel[0], 1, woolColor),
'c', ItemComponent.getItemStack(EnumComponentType.COIL_CRYSTAL) ));
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockAirShield, 6, enumDyeColor.getDyeDamage()), false, "###", "gXg", "###",
'#', "blockAirShield",
'g', Items.GOLD_NUGGET,
@ -1144,10 +1151,10 @@ public class Recipes {
// Mining laser is 2 motors, 1 diffraction grating, 1 lens, 1 computer interface, 1 MV Machine casing, 1 diamond pick, 2 glass pane
ItemStack itemStackDiamondPick = new ItemStack(Items.DIAMOND_PICKAXE);
if (WarpDriveConfig.isGregTech5Loaded) {
itemStackDiamondPick = WarpDriveConfig.getModItemStack("ic2", "mining_laser", 1); // Mining laser
// } else if (WarpDriveConfig.isIndustrialCraft2Loaded) {
// itemStackDiamondPick = WarpDriveConfig.getModItemStack("ic2", "te", 57); // Advanced Miner
if ( WarpDriveConfig.isGregTech6Loaded
|| WarpDriveConfig.isGregTech5Loaded ) {
itemStackDiamondPick = WarpDriveConfig.getModItemStack("IC2", "itemToolMiningLaser", 1, // IC2 Experimental Mining laser @TODO MC1.10 update
"IC2", "item.itemToolMiningLaser", 0); // IC2 Classic Mining laser @TODO MC1.10 update
}
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockMiningLaser), false, "cmr", "tdt", "glg",
't', itemStackMotors[1],
@ -1167,7 +1174,9 @@ public class Recipes {
// Laser lift is ...
Object oreMagnetizer = itemStackMachineCasings[0];
if (WarpDriveConfig.isGregTech5Loaded) {
if (WarpDriveConfig.isGregTech6Loaded) {
oreMagnetizer = WarpDriveConfig.getModItemStack("gregtech", "gt.multitileentity", 20221); // Basic polarizer
} else if (WarpDriveConfig.isGregTech5Loaded) {
oreMagnetizer = WarpDriveConfig.getModItemStack("gregtech", "gt.blockmachines", 551); // Basic polarizer
} else if (WarpDriveConfig.isIndustrialCraft2Loaded) {
oreMagnetizer = WarpDriveConfig.getModItemStack("ic2", "te", 37); // Magnetizer
@ -1186,16 +1195,22 @@ public class Recipes {
'g', "paneGlassColorless"));
// Iridium block is just that
if (WarpDriveConfig.isGregTech5Loaded) {
if (WarpDriveConfig.isGregTech6Loaded) {
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockIridium), "iii", "iii", "iii",
'i', "xxx"));
ItemStack itemStackIridiumAlloy = WarpDriveConfig.getModItemStack("gregtech", "gt.meta.plate", 770); // ore:plateIridium
GameRegistry.addShapelessRecipe(new ItemStack(itemStackIridiumAlloy.getItem(), 9), new ItemStack(WarpDrive.blockIridium));
} else if (WarpDriveConfig.isGregTech5Loaded) {
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockIridium), "iii", "iii", "iii",
'i', "plateAlloyIridium"));
ItemStack itemStackIridiumAlloy = WarpDriveConfig.getModItemStack("ic2", "crafting", 4); // Iridium reinforced place
ItemStack itemStackIridiumAlloy = WarpDriveConfig.getOreDictionaryEntry("plateAlloyIridium");
GameRegistry.addShapelessRecipe(new ItemStack(itemStackIridiumAlloy.getItem(), 9), new ItemStack(WarpDrive.blockIridium));
} else if (WarpDriveConfig.isIndustrialCraft2Loaded) {
ItemStack itemStackIridiumAlloy = WarpDriveConfig.getModItemStack("ic2", "crafting", 4); // Iridium reinforced place
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockIridium), "iii", "iii", "iii",
'i', itemStackIridiumAlloy));
'i', "plateAlloyIridium"));
ItemStack itemStackIridiumAlloy = WarpDriveConfig.getOreDictionaryEntry("plateAlloyIridium");
GameRegistry.addShapelessRecipe(new ItemStack(itemStackIridiumAlloy.getItem(), 9), new ItemStack(WarpDrive.blockIridium));
} else if (WarpDriveConfig.isThermalExpansionLoaded) {
@ -1290,15 +1305,18 @@ public class Recipes {
't', WarpDriveConfig.getModItemStack("ic2", "te", 39) )); // Teleporter
/**/
// IC2 needs to loaded for the following 2 recipes
// IC2 needs to be loaded for the following 2 recipes
if (WarpDriveConfig.isIndustrialCraft2Loaded) {
ItemStack itemStackOverclockedHeatVent = WarpDriveConfig.getModItemStack("ic2", "overclocked_heat_vent", 1);
ItemStack itemStackReactorCoolant1 = WarpDriveConfig.getModItemStack("ic2", "hex_heat_storage", -1);
ItemStack itemStackReactorCoolant2 = itemStackReactorCoolant1;
if (WarpDriveConfig.isGregTech5Loaded) {
itemStackReactorCoolant1 = WarpDriveConfig.getModItemStack("gregtech", "gt.360k_Helium_Coolantcell", -1);
itemStackReactorCoolant2 = WarpDriveConfig.getModItemStack("gregtech", "gt.360k_NaK_Coolantcell", -1);
}
ItemStack itemStackOverclockedHeatVent = WarpDriveConfig.getModItemStack("ic2", "overclocked_heat_vent", 1, // IC2 Experimental Overclocked heat vent
"ic2", "item.reactorVentGold", 0); // IC2 Classic Overclocked heat vent
// (there's no coolant in GT6 as of 6.06.05, so we're falling back to IC2)
ItemStack itemStackReactorCoolant1 = WarpDriveConfig.getModItemStack("gregtech", "gt.360k_Helium_Coolantcell", 1, // GT5
"ic2", "hex_heat_storage", 1, // IC2 Experimental 60k coolant cell
"ic2", "item.reactorCoolantSix", 0); // IC2 Classic 60k coolant cell
ItemStack itemStackReactorCoolant2 = WarpDriveConfig.getModItemStack("gregtech", "gt.360k_NaK_Coolantcell", 1, // GT5
"ic2", "reactorCoolantSix", 1, // IC2 Experimental 60k coolant cell
"ic2", "item.reactorCoolantSix", 0); // IC2 Classic 60k coolant cell
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.itemIC2reactorLaserFocus), false, "cld", "lhl", "dlc",
'l', ItemComponent.getItemStack(EnumComponentType.LENS),
'h', itemStackOverclockedHeatVent,
@ -1324,10 +1342,13 @@ public class Recipes {
// Cloaking coil is 1 Titanium plate, 4 reinforced iridium plate, 1 EV Machine casing (Ti) or 1 Beacon, 4 emerald, 4 diamond
ItemStack itemStackGoldIngotOrCoil = new ItemStack(Items.GOLD_INGOT);
if (WarpDriveConfig.isGregTech5Loaded) {
if (WarpDriveConfig.isGregTech6Loaded) {
itemStackGoldIngotOrCoil = WarpDriveConfig.getModItemStack("gregtech", "gt.meta.storage.plate", 8663); // Nichrome Coil block, ore:blockPlateNichrome
} else if (WarpDriveConfig.isGregTech5Loaded) {
itemStackGoldIngotOrCoil = WarpDriveConfig.getModItemStack("gregtech", "gt.blockcasings", 14); // Nichrome Coil block
} else if (WarpDriveConfig.isIndustrialCraft2Loaded) {
itemStackGoldIngotOrCoil = WarpDriveConfig.getModItemStack("ic2", "crafting", 5); // Coil
itemStackGoldIngotOrCoil = WarpDriveConfig.getModItemStack("ic2", "itemRecipePart", 0, // IC2 Experimental Coil
"ic2", "item.reactorPlatingHeat", 0); // IC2 Classic Heat-capacity reactor plating
} else if (WarpDriveConfig.isThermalExpansionLoaded) {
itemStackGoldIngotOrCoil = WarpDriveConfig.getModItemStack("ThermalExpansion", "material", 3); // Redstone conductance coil
} else if (WarpDriveConfig.isImmersiveEngineeringLoaded) {
@ -1669,10 +1690,13 @@ public class Recipes {
// Lower tier coil is iron, copper or coil
Object ironIngotOrCopperIngotOrCoil = new ItemStack(Items.IRON_INGOT);
if (WarpDriveConfig.isGregTech5Loaded) {
if (WarpDriveConfig.isGregTech6Loaded) {
ironIngotOrCopperIngotOrCoil = itemStackGoldIngotOrCoil; // @TODO revise GT recipes
} else if (WarpDriveConfig.isGregTech5Loaded) {
ironIngotOrCopperIngotOrCoil = itemStackGoldIngotOrCoil; // @TODO revise GT recipes
} else if (WarpDriveConfig.isIndustrialCraft2Loaded) {
ironIngotOrCopperIngotOrCoil = WarpDriveConfig.getModItemStack("ic2", "crafting", 5); // Coil
ironIngotOrCopperIngotOrCoil = WarpDriveConfig.getModItemStack("IC2", "itemRecipePart", 0, // IC2 Experimental Coil
"IC2", "item.reactorPlatingHeat", 0); // IC2 Classic Heat-capacity reactor plating
} else if (WarpDriveConfig.isThermalExpansionLoaded) {
ironIngotOrCopperIngotOrCoil = WarpDriveConfig.getModItemStack("ThermalExpansion", "material", 1); // Redstone reception coil
} else if (WarpDriveConfig.isImmersiveEngineeringLoaded) {
@ -1779,7 +1803,9 @@ public class Recipes {
// Tier 1 = 5 stone + 4 bronze ingots gives 5
// Tier 1 = 5 stone + 4 aluminium ingots gives 3
if (WarpDriveConfig.isIndustrialCraft2Loaded) {
ItemStack reinforcedStone = WarpDriveConfig.getModItemStack("ic2", "resource", 11);
ItemStack reinforcedStone = WarpDriveConfig.getModItemStack("ic2", "blockAlloy", 0, // IC2 Experimental reinforced stone
"ic2", "reinforcedStone", 0); // IC2 Classic reinforced stone
// ItemStack reinforcedStone = WarpDriveConfig.getModItemStack("ic2", "resource", 11);
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockHulls_plain[0][0], 10, 0), false, "cbc", "bcb", "cbc",
'b', Blocks.OBSIDIAN,
'c', reinforcedStone ));
@ -1811,7 +1837,17 @@ public class Recipes {
// Tier 2 = 4 Tier 1 + 4 dark steel ingot gives 4
// Tier 2 = 4 Tier 1 + 4 obsidian gives 4
for (EnumDyeColor enumDyeColor : EnumDyeColor.values()) {
if (WarpDriveConfig.isGregTech5Loaded) {
if (WarpDriveConfig.isGregTech6Loaded) {
// ore:casingMachineQuadrupleTungstenSteel or gregtech:gt.meta.machine.quadruple:8635
ItemStack tungstensteelReinforcedBlock = WarpDriveConfig.getModItemStack("gregtech", "gt.meta.machine.quadruple", 8635);
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockHulls_plain[1][0], 4, enumDyeColor.getDyeDamage()), false, " b ", "bcb", " b ",
'b', new ItemStack(WarpDrive.blockHulls_plain[0][0], 4, enumDyeColor.getDyeDamage()),
'c', tungstensteelReinforcedBlock ));
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockHulls_plain[1][0], 4, enumDyeColor.getDyeDamage()), false, "Xb ", "bcb", " b ",
'b', "blockHull1_plain",
'c', tungstensteelReinforcedBlock,
'X', oreDyes[enumDyeColor.getMetadata()] )); // TODO MC1.10 not tested
} else if (WarpDriveConfig.isGregTech5Loaded) {
ItemStack tungstensteelReinforcedBlock = WarpDriveConfig.getModItemStack("gregtech", "gt.blockreinforced", 3);
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockHulls_plain[1][0], 4, enumDyeColor.getDyeDamage()), false, " b ", "bcb", " b ",
'b', new ItemStack(WarpDrive.blockHulls_plain[0][0], 4, enumDyeColor.getDyeDamage()),
@ -1821,7 +1857,8 @@ public class Recipes {
'c', tungstensteelReinforcedBlock,
'X', oreDyes[enumDyeColor.getMetadata()] )); // TODO MC1.10 not tested
} else if (WarpDriveConfig.isIndustrialCraft2Loaded) {
ItemStack carbonPlate = WarpDriveConfig.getModItemStack("ic2", "crafting", 15); // Carbon plate
ItemStack carbonPlate = WarpDriveConfig.getModItemStack("ic2", "itemPartCarbonPlate", 0, // IC2 Experimental carbon plate
"ic2", "item.itemPartCarbonPlate", 0); // IC2 Classic carbon plate
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockHulls_plain[1][0], 4, enumDyeColor.getDyeDamage()), false, "cbc", "b b", "cbc",
'b', new ItemStack(WarpDrive.blockHulls_plain[0][0], 4, enumDyeColor.getDyeDamage()),
'c', carbonPlate ));

View file

@ -12,6 +12,7 @@ import cr0s.warpdrive.compat.CompatBuildCraft;
import cr0s.warpdrive.compat.CompatCarpentersBlocks;
import cr0s.warpdrive.compat.CompatComputerCraft;
import cr0s.warpdrive.compat.CompatCustomNpcs;
import cr0s.warpdrive.compat.CompatDraconicEvolution;
import cr0s.warpdrive.compat.CompatEnderIO;
import cr0s.warpdrive.compat.CompatEvilCraft;
import cr0s.warpdrive.compat.CompatForgeMultipart;
@ -37,9 +38,24 @@ import cr0s.warpdrive.data.CelestialObject;
import cr0s.warpdrive.data.CelestialObjectManager;
import cr0s.warpdrive.data.EnumShipMovementType;
import cr0s.warpdrive.data.EnumDisplayAlignment;
import cr0s.warpdrive.data.EnumTooltipCondition;
import cr0s.warpdrive.network.PacketHandler;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.server.FMLServerHandler;
import net.minecraftforge.oredict.OreDictionary;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
@ -56,21 +72,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.util.FakePlayer;
public class WarpDriveConfig {
private static final boolean unused = false; // TODO
@ -114,8 +115,10 @@ public class WarpDriveConfig {
public static boolean isArsMagica2Loaded = false;
public static boolean isImmersiveEngineeringLoaded = false;
public static boolean isGregTech5Loaded = false;
public static boolean isGregTech6Loaded = false;
public static boolean isEnderIOLoaded = false;
public static boolean isAdvancedRepulsionSystemLoaded = false;
public static boolean isNotEnoughItemsLoaded = false;
public static ItemStack IC2_compressedAir;
public static ItemStack IC2_emptyCell;
@ -158,6 +161,18 @@ public class WarpDriveConfig {
public static float CLIENT_LOCATION_WIDTH_RATIO = 0.0F;
public static int CLIENT_LOCATION_WIDTH_MIN = 90;
public static EnumTooltipCondition CLIENT_TOOLTIP_REGISTRY_NAME = EnumTooltipCondition.ADVANCED_TOOLTIPS;
public static EnumTooltipCondition CLIENT_TOOLTIP_ORE_DICTIONARY_NAME = EnumTooltipCondition.ALWAYS;
public static EnumTooltipCondition CLIENT_TOOLTIP_ARMOR = EnumTooltipCondition.ALWAYS;
public static EnumTooltipCondition CLIENT_TOOLTIP_BURN_TIME = EnumTooltipCondition.ADVANCED_TOOLTIPS;
public static EnumTooltipCondition CLIENT_TOOLTIP_DURABILITY = EnumTooltipCondition.ALWAYS;
public static EnumTooltipCondition CLIENT_TOOLTIP_FLAMMABILITY = EnumTooltipCondition.ADVANCED_TOOLTIPS;
public static EnumTooltipCondition CLIENT_TOOLTIP_FLUID = EnumTooltipCondition.ALWAYS;
public static EnumTooltipCondition CLIENT_TOOLTIP_HARDNESS = EnumTooltipCondition.ADVANCED_TOOLTIPS;
public static EnumTooltipCondition CLIENT_TOOLTIP_HARVESTING = EnumTooltipCondition.ALWAYS;
public static EnumTooltipCondition CLIENT_TOOLTIP_OPACITY = EnumTooltipCondition.ADVANCED_TOOLTIPS;
public static EnumTooltipCondition CLIENT_TOOLTIP_REPAIR_WITH = EnumTooltipCondition.ON_SNEAK;
// Logging
public static boolean LOGGING_JUMP = false;
public static boolean LOGGING_JUMPBLOCKS = false;
@ -176,6 +191,7 @@ public class WarpDriveConfig {
public static boolean LOGGING_BREATHING = false;
public static boolean LOGGING_WORLD_GENERATION = false;
public static boolean LOGGING_PROFILING_CPU_USAGE = true;
public static boolean LOGGING_PROFILING_MEMORY_ALLOCATION = false;
public static boolean LOGGING_PROFILING_THREAD_SAFETY = false;
public static boolean LOGGING_DICTIONARY = false;
public static boolean LOGGING_STARMAP = false;
@ -204,8 +220,8 @@ public class WarpDriveConfig {
// Ship
public static int SHIP_MAX_ENERGY_STORED = 100000000;
public static int SHIP_TELEPORT_ENERGY_PER_ENTITY = 1000000;
public static int SHIP_VOLUME_MAX_ON_PLANET_SURFACE = 3000;
public static int SHIP_VOLUME_MIN_FOR_HYPERSPACE = 1200;
public static int SHIP_VOLUME_MAX_ON_PLANET_SURFACE = 1200;
public static int SHIP_VOLUME_MIN_FOR_HYPERSPACE = 3000;
public static int SHIP_MAX_SIDE_SIZE = 127;
public static int SHIP_COLLISION_TOLERANCE_BLOCKS = 3;
public static int SHIP_WARMUP_RANDOM_TICKS = 60;
@ -229,9 +245,6 @@ public class WarpDriveConfig {
public static double RADAR_MAX_ISOLATION_EFFECT = 1.00;
// Ship Scanner
public static int SS_MAX_ENERGY_STORED = 500000000;
public static int SS_ENERGY_PER_BLOCK_SCAN = 100;
public static int SS_ENERGY_PER_BLOCK_DEPLOY = 5000;
public static int SS_MAX_DEPLOY_RADIUS_BLOCKS = 50;
public static int SS_SEARCH_INTERVAL_TICKS = 20;
public static int SS_SCAN_BLOCKS_PER_SECOND = 10;
@ -332,9 +345,13 @@ public class WarpDriveConfig {
public static final boolean BREATHING_AIR_BLOCK_DEBUG = false;
public static boolean BREATHING_AIR_AT_ENTITY_DEBUG = false;
// IC2 Reactor monitor
public static int IC2_REACTOR_MAX_ENERGY_STORED = 1000000;
public static double IC2_REACTOR_ENERGY_PER_HEAT = 2;
// IC2 Reactor cooler
public static int IC2_REACTOR_MAX_HEAT_STORED = 30000;
public static int IC2_REACTOR_FOCUS_HEAT_TRANSFER_PER_TICK = 648;
public static int IC2_REACTOR_COMPONENT_HEAT_TRANSFER_PER_TICK = 54;
public static int IC2_REACTOR_REACTOR_HEAT_TRANSFER_PER_TICK = 54;
public static int IC2_REACTOR_COOLING_PER_INTERVAL = 1080;
public static double IC2_REACTOR_ENERGY_PER_HEAT = 2.0D;
public static int IC2_REACTOR_COOLING_INTERVAL_TICKS = 10;
// Transporter
@ -382,13 +399,52 @@ public class WarpDriveConfig {
try {
return Block.REGISTRY.getObject(new ResourceLocation(mod, id));
} catch (Exception exception) {
WarpDrive.logger.info("Failed to get mod block for " + mod + ":" + id);
WarpDrive.logger.info(String.format("Failed to get mod block for %s:%s", mod, id));
exception.printStackTrace();
}
return Blocks.FIRE;
}
public static ItemStack getModItemStack(final String mod, final String id, final int meta) {
final ItemStack itemStack = getModItemStackOrNull(mod, id, meta);
if (itemStack != null) {
return itemStack;
}
return new ItemStack(Blocks.FIRE);
}
public static ItemStack getModItemStack(final String mod1, final String id1, final int meta1,
final String mod2, final String id2, final int meta2) {
ItemStack itemStack = getModItemStackOrNull(mod1, id1, meta1);
if (itemStack != null) {
return itemStack;
}
itemStack = getModItemStackOrNull(mod2, id2, meta2);
if (itemStack != null) {
return itemStack;
}
return new ItemStack(Blocks.FIRE);
}
public static ItemStack getModItemStack(final String mod1, final String id1, final int meta1,
final String mod2, final String id2, final int meta2,
final String mod3, final String id3, final int meta3) {
ItemStack itemStack = getModItemStackOrNull(mod1, id1, meta1);
if (itemStack != null) {
return itemStack;
}
itemStack = getModItemStackOrNull(mod2, id2, meta2);
if (itemStack != null) {
return itemStack;
}
itemStack = getModItemStackOrNull(mod3, id3, meta3);
if (itemStack != null) {
return itemStack;
}
return new ItemStack(Blocks.FIRE);
}
private static ItemStack getModItemStackOrNull(final String mod, final String id, final int meta) {
try {
Item item = Item.REGISTRY.getObject(new ResourceLocation(mod + ":" + id));
if (item == null) {
@ -401,14 +457,26 @@ public class WarpDriveConfig {
}
return itemStack;
} catch (Exception exception) {
exception.printStackTrace();
WarpDrive.logger.info("Failed to get mod item for " + mod + ":" + id + "@" + meta);
WarpDrive.logger.info(String.format("Failed to get mod item for %s:%s@%d", mod, id, meta));
return null;
}
return new ItemStack(Blocks.FIRE);
}
protected static double[] getDoubleList(final Configuration config, final String categoy, final String key, final String comment, final double[] valuesDefault) {
double[] valuesRead = config.get(categoy, key, valuesDefault, comment).getDoubleList();
public static ItemStack getOreDictionaryEntry(final String ore) {
if (!OreDictionary.doesOreNameExist(ore)) {
WarpDrive.logger.info("Failed to get ore named " + ore);
return new ItemStack(Blocks.FIRE);
}
final List<ItemStack> itemStacks = OreDictionary.getOres(ore);
if (itemStacks.isEmpty()) {
WarpDrive.logger.info(String.format("Failed to get item from empty ore dictionary '%s'", ore));
return new ItemStack(Blocks.FIRE);
}
return itemStacks.get(0);
}
protected static double[] getDoubleList(final Configuration config, final String category, final String key, final String comment, final double[] valuesDefault) {
double[] valuesRead = config.get(category, key, valuesDefault, comment).getDoubleList();
if (valuesRead.length != valuesDefault.length) {
valuesRead = valuesDefault.clone();
}
@ -543,6 +611,30 @@ public class WarpDriveConfig {
CLIENT_LOCATION_WIDTH_MIN = config.get("client", "location_width_min", CLIENT_LOCATION_WIDTH_MIN,
"Text width as a minimum 'pixel' count").getInt();
final String commentTooltip = "When to show %s in tooltips. Valid values are " + EnumTooltipCondition.formatAllValues() + ".";
CLIENT_TOOLTIP_REGISTRY_NAME = EnumTooltipCondition.valueOf(config.get("client", "tooltip_registry_name", CLIENT_TOOLTIP_REGISTRY_NAME.name(),
String.format(commentTooltip, "registry name")).getString());
CLIENT_TOOLTIP_ORE_DICTIONARY_NAME = EnumTooltipCondition.valueOf(config.get("client", "tooltip_ore_dictionary_name", CLIENT_TOOLTIP_ORE_DICTIONARY_NAME.name(),
String.format(commentTooltip, "ore dictionary names")).getString());
CLIENT_TOOLTIP_ARMOR = EnumTooltipCondition.valueOf(config.get("client", "tooltip_armor_stats", CLIENT_TOOLTIP_ARMOR.name(),
String.format(commentTooltip, "armor stats")).getString());
CLIENT_TOOLTIP_BURN_TIME = EnumTooltipCondition.valueOf(config.get("client", "tooltip_burn_time", CLIENT_TOOLTIP_BURN_TIME.name(),
String.format(commentTooltip, "burn time")).getString());
CLIENT_TOOLTIP_DURABILITY = EnumTooltipCondition.valueOf(config.get("client", "tooltip_durability", CLIENT_TOOLTIP_DURABILITY.name(),
String.format(commentTooltip, "durability")).getString());
CLIENT_TOOLTIP_FLAMMABILITY = EnumTooltipCondition.valueOf(config.get("client", "tooltip_flammability", CLIENT_TOOLTIP_FLAMMABILITY.name(),
String.format(commentTooltip, "flammability")).getString());
CLIENT_TOOLTIP_FLUID = EnumTooltipCondition.valueOf(config.get("client", "tooltip_fluid_stats", CLIENT_TOOLTIP_FLUID.name(),
String.format(commentTooltip, "fluid stats")).getString());
CLIENT_TOOLTIP_HARDNESS = EnumTooltipCondition.valueOf(config.get("client", "tooltip_hardness", CLIENT_TOOLTIP_HARDNESS.name(),
String.format(commentTooltip, "hardness & explosion resistance")).getString());
CLIENT_TOOLTIP_HARVESTING = EnumTooltipCondition.valueOf(config.get("client", "tooltip_harvesting_stats", CLIENT_TOOLTIP_HARVESTING.name(),
String.format(commentTooltip, "harvesting stats")).getString());
CLIENT_TOOLTIP_OPACITY = EnumTooltipCondition.valueOf(config.get("client", "tooltip_opacity", CLIENT_TOOLTIP_OPACITY.name(),
String.format(commentTooltip, "opacity")).getString());
CLIENT_TOOLTIP_REPAIR_WITH = EnumTooltipCondition.valueOf(config.get("client", "tooltip_repair_material", CLIENT_TOOLTIP_REPAIR_WITH.name(),
String.format(commentTooltip, "repair material")).getString());
// Logging
LOGGING_JUMP = config.get("logging", "enable_jump_logs", LOGGING_JUMP, "Basic jump logs, should always be enabled").getBoolean(true);
LOGGING_JUMPBLOCKS = config.get("logging", "enable_jumpblocks_logs", LOGGING_JUMPBLOCKS, "Detailed jump logs to help debug the mod, will spam your logs...").getBoolean(false);
@ -570,6 +662,7 @@ public class WarpDriveConfig {
LOGGING_BREATHING = config.get("logging", "enable_breathing_logs", LOGGING_BREATHING, "Detailed breathing logs to help debug the mod, enable it before reporting a bug").getBoolean(false);
LOGGING_WORLD_GENERATION = config.get("logging", "enable_world_generation_logs", LOGGING_WORLD_GENERATION, "Detailed world generation logs to help debug the mod, enable it before reporting a bug").getBoolean(false);
LOGGING_PROFILING_CPU_USAGE = config.get("logging", "enable_profiling_CPU_time", LOGGING_PROFILING_CPU_USAGE, "Profiling logs for CPU time, enable it to check for lag").getBoolean(true);
LOGGING_PROFILING_MEMORY_ALLOCATION = config.get("logging", "enable_profiling_memory_allocation", LOGGING_PROFILING_MEMORY_ALLOCATION, "Profiling logs for memory allocation, enable it to check for lag").getBoolean(true);
LOGGING_PROFILING_THREAD_SAFETY = config.get("logging", "enable_profiling_thread_safety", LOGGING_PROFILING_THREAD_SAFETY, "Profiling logs for multi-threading, enable it to check for ConcurrentModificationException").getBoolean(false);
LOGGING_DICTIONARY = config.get("logging", "enable_dictionary_logs", LOGGING_DICTIONARY, "Dictionary logs, enable it to dump blocks hardness and blast resistance at boot").getBoolean(true);
LOGGING_STARMAP = config.get("logging", "enable_starmap_logs", LOGGING_STARMAP, "Starmap logs, enable it to dump starmap registry updates").getBoolean(false);
@ -591,11 +684,11 @@ public class WarpDriveConfig {
SHIP_MOVEMENT_COSTS_FACTORS = new ShipMovementCosts.Factors[EnumShipMovementType.length];
for (EnumShipMovementType shipMovementType : EnumShipMovementType.values()) {
SHIP_MOVEMENT_COSTS_FACTORS[shipMovementType.ordinal()] = new ShipMovementCosts.Factors(
shipMovementType.warmupDefault,
shipMovementType.maximumDistanceDefault,
shipMovementType.energyRequiredDefault,
shipMovementType.cooldownDefault,
shipMovementType.warmupDefault,
shipMovementType.sicknessDefault,
shipMovementType.maximumDistanceDefault);
shipMovementType.cooldownDefault);
if (shipMovementType.hasConfiguration) {
SHIP_MOVEMENT_COSTS_FACTORS[shipMovementType.ordinal()].load(config, "ship_movement_costs", shipMovementType.getName(), shipMovementType.getDescription());
}
@ -670,21 +763,6 @@ public class WarpDriveConfig {
config.get("radar", "max_isolation_effect", RADAR_MAX_ISOLATION_EFFECT, "isolation effect achieved with max number of isolation blocks (0.01 to 1.00)").getDouble(1.00D));
// Ship Scanner
SS_MAX_ENERGY_STORED = Commons.clamp(1, Integer.MAX_VALUE,
config.get("ship_scanner", "max_energy_stored", SS_MAX_ENERGY_STORED, "Maximum energy stored").getInt());
SS_ENERGY_PER_BLOCK_SCAN = config.get("ship_scanner", "energy_per_block_when_scanning", SS_ENERGY_PER_BLOCK_SCAN,
"Energy consumed per block when scanning a ship (use -1 to consume everything)").getInt();
if (SS_ENERGY_PER_BLOCK_SCAN != -1) {
SS_ENERGY_PER_BLOCK_SCAN = Commons.clamp(0, SS_MAX_ENERGY_STORED, SS_ENERGY_PER_BLOCK_SCAN);
}
SS_ENERGY_PER_BLOCK_DEPLOY = config.get("ship_scanner", "energy_per_block_when_deploying", SS_ENERGY_PER_BLOCK_DEPLOY,
"Energy consumed per block when deploying a ship (use -1 to consume everything)").getInt();
if (SS_ENERGY_PER_BLOCK_DEPLOY != -1) {
SS_ENERGY_PER_BLOCK_DEPLOY = Commons.clamp(0, SS_MAX_ENERGY_STORED, SS_ENERGY_PER_BLOCK_DEPLOY);
}
SS_MAX_DEPLOY_RADIUS_BLOCKS = Commons.clamp(5, 150,
config.get("ship_scanner", "max_deploy_radius_blocks", SS_MAX_DEPLOY_RADIUS_BLOCKS, "Max distance from ship scanner to ship core, measured in blocks (5-150)").getInt());
SS_SEARCH_INTERVAL_TICKS = Commons.clamp(5, 150,
@ -865,13 +943,21 @@ public class WarpDriveConfig {
config.get("breathing", "simulation_delay_ticks", BREATHING_AIR_SIMULATION_DELAY_TICKS, "Minimum delay between consecutive air propagation updates of the same block.").getInt());
BREATHING_AIR_AT_ENTITY_DEBUG = config.get("breathing", "enable_air_at_entity_debug", BREATHING_AIR_AT_ENTITY_DEBUG, "Spam creative players with air status around them, use at your own risk.").getBoolean(false);
// IC2 Reactor monitor
IC2_REACTOR_MAX_ENERGY_STORED = Commons.clamp(1, Integer.MAX_VALUE,
config.get("ic2_reactor_laser", "max_energy_stored", IC2_REACTOR_MAX_ENERGY_STORED, "Maximum energy stored").getInt());
// IC2 Reactor cooler
IC2_REACTOR_MAX_HEAT_STORED = Commons.clamp(1, 32767,
config.get("ic2_reactor_laser", "max_heat_stored", IC2_REACTOR_MAX_HEAT_STORED, "Maximum heat stored in the focus").getInt());
IC2_REACTOR_COMPONENT_HEAT_TRANSFER_PER_TICK = Commons.clamp(0, 32767,
config.get("ic2_reactor_laser", "component_heat_transfer_per_tick", IC2_REACTOR_COMPONENT_HEAT_TRANSFER_PER_TICK, "Maximum component heat added to the focus every reactor tick").getInt());
IC2_REACTOR_FOCUS_HEAT_TRANSFER_PER_TICK = Commons.clamp(0, 32767,
config.get("ic2_reactor_laser", "focus_heat_transfer_per_tick", IC2_REACTOR_FOCUS_HEAT_TRANSFER_PER_TICK, "Maximum heat transferred between 2 connected focus every reactor tick").getInt());
IC2_REACTOR_REACTOR_HEAT_TRANSFER_PER_TICK = Commons.clamp(0, 32767,
config.get("ic2_reactor_laser", "reactor_heat_transfer_per_tick", IC2_REACTOR_REACTOR_HEAT_TRANSFER_PER_TICK, "Maximum reactor heat added to the focus every reactor tick").getInt());
IC2_REACTOR_COOLING_PER_INTERVAL = Commons.clamp(1, 32767,
config.get("ic2_reactor_laser", "cooling_per_interval", IC2_REACTOR_COOLING_PER_INTERVAL, "Heat extracted from the focus by interval").getInt());
IC2_REACTOR_ENERGY_PER_HEAT = Commons.clamp(2.0D, 100000.0D,
config.get("ic2_reactor_laser", "energy_per_heat", IC2_REACTOR_ENERGY_PER_HEAT, "Energy cost per heat absorbed").getDouble(2));
config.get("ic2_reactor_laser", "energy_per_heat", IC2_REACTOR_ENERGY_PER_HEAT, "Energy cost per heat absorbed").getDouble());
IC2_REACTOR_COOLING_INTERVAL_TICKS = Commons.clamp(0, 1200,
config.get("ic2_reactor_laser", "cooling_interval_ticks", IC2_REACTOR_COOLING_INTERVAL_TICKS, "Update speed of the check for reactors to cooldown").getInt());
config.get("ic2_reactor_laser", "cooling_interval_ticks", IC2_REACTOR_COOLING_INTERVAL_TICKS, "Update speed of the check for reactors to cooldown. Use 10 to tick as fast as the reactor simulation").getInt());
// Transporter
TRANSPORTER_MAX_ENERGY_STORED = Commons.clamp(1, Integer.MAX_VALUE,
@ -984,12 +1070,25 @@ public class WarpDriveConfig {
if (isImmersiveEngineeringLoaded) {
CompatImmersiveEngineering.register();
}
isGregTech5Loaded = false;
isGregTech6Loaded = false;
if (Loader.isModLoaded("gregtech")) {
final String gregTechVersion = FMLCommonHandler.instance().findContainerFor("gregtech").getVersion();
isGregTech5Loaded = gregTechVersion.equalsIgnoreCase("MC1710") || gregTechVersion.startsWith("5.");
isGregTech6Loaded = gregTechVersion.startsWith("GT6-MC1710");
if ( (isGregTech5Loaded && isGregTech6Loaded)
|| (!isGregTech5Loaded && !isGregTech6Loaded) ) {
throw new RuntimeException(String.format("Unsupported gregtech version '%s', please report to mod author", gregTechVersion));
}
}
isEnderIOLoaded = Loader.isModLoaded("EnderIO");
if (isEnderIOLoaded) {
CompatEnderIO.register();
}
if (isAdvancedRepulsionSystemLoaded) {
CompatAdvancedRepulsionSystems.register();
}
isNotEnoughItemsLoaded = Loader.isModLoaded("NotEnoughItems");
boolean isBotaniaLoaded = Loader.isModLoaded("Botania");
if (isBotaniaLoaded) {
@ -1011,6 +1110,10 @@ public class WarpDriveConfig {
if (isCustomNpcsLoaded) {
CompatCustomNpcs.register();
}
boolean isDraconicEvolutionLoaded = Loader.isModLoaded("DraconicEvolution");
if (isDraconicEvolutionLoaded) {
CompatDraconicEvolution.register();
}
boolean isEvilCraftLoaded = Loader.isModLoaded("evilcraft");
if (isEvilCraftLoaded) {
CompatEvilCraft.register();

View file

@ -30,8 +30,10 @@ public class StructureGroup implements IStringSerializable {
}
final AbstractStructure abstractStructure = StructureManager.getStructure(random, group, name);
if (abstractStructure == null) {
WarpDrive.logger.warn(String.format("Dimension %d @ %d %d %d refers to unknown structure %s. Probably a bad configuration. Skipping for now.",
world.provider.getDimension(), x, y, z, getName()));
WarpDrive.logger.warn(String.format("Celestial object @ %s (%d %d %d) refers to unknown structure %s. Probably a bad configuration. Skipping for now.",
world.provider.getSaveFolder(),
x, y, z,
getName()));
return;
}
final AbstractStructureInstance abstractStructureInstance = abstractStructure.instantiate(random);

View file

@ -1,6 +1,18 @@
package cr0s.warpdrive.damage;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.network.PacketHandler;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.DamageSource;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
public class DamageIrradiation extends DamageSource {
@ -10,4 +22,54 @@ public class DamageIrradiation extends DamageSource {
setDamageIsAbsolute();
}
public void onWorldEffect(final World world, final Vector3 v3Position, final float strength) {
// only search up to distance where damage applied is 0.5
final double radius = Math.sqrt(2.0D * strength);
final AxisAlignedBB axisAlignedBB = new AxisAlignedBB(
v3Position.x - radius, v3Position.y - radius, v3Position.z - radius,
v3Position.x + radius, v3Position.y + radius, v3Position.z + radius);
final List<EntityLivingBase> listEntityLivingBase = world.getEntitiesWithinAABB(EntityLivingBase.class, axisAlignedBB);
if (listEntityLivingBase != null) {
for (EntityLivingBase entityLivingBase : listEntityLivingBase) {
// cap damage below 1 m distance, since the entity is never really inside the source and damage tends to +INF
final float distance = Math.min(1.0F, (float) Math.sqrt(v3Position.distanceTo_square(entityLivingBase)));
onEntityEffect(strength / (distance * distance), world, v3Position, entityLivingBase);
}
}
}
public void onEntityEffect(final float strength, final World world, final Vector3 v3Source, final Entity entity) {
if ( strength <= 0.0F
|| !(entity instanceof EntityLivingBase)
|| entity.isDead ) {
return;
}
// common particle effects properties
final Vector3 v3Entity = new Vector3(entity);
final Vector3 v3Direction = new Vector3(entity).subtract(v3Source).normalize();
final Vector3 v3From = v3Source.clone();
v3From.translateFactor(v3Direction, 0.6D);
v3Entity.translateFactor(v3Direction, -0.6D);
final double speed = Math.abs(strength);
final Vector3 v3Motion = v3Direction.clone().scale(speed); // new Vector3(entity.motionX, entity.motionY, entity.motionZ);
if (WarpDriveConfig.LOGGING_ACCELERATOR && WarpDrive.isDev) {
PacketHandler.sendBeamPacket(world, v3From, v3Entity,
0.25F, 0.75F, 0.38F, 10, 0, 50);
WarpDrive.logger.info(String.format("%s strength %.1f speed %.3f entity %s source %s direction %s motion %s entity %s",
this, strength, speed, v3Entity, v3Source, v3Direction, v3Motion, entity));
}
// apply damages and particle effects
entity.attackEntityFrom(this, strength);
// visual effect
v3Direction.scale(0.20D);
PacketHandler.sendSpawnParticlePacket(world, "mobSpell", (byte) Commons.clamp(3, 10, strength), v3Entity, v3Direction,
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);
}
}

View file

@ -287,7 +287,7 @@ public class AcceleratorSetup extends GlobalPosition {
addToBoundingBox(trajectoryPoint, 2);
// count main magnets
final int indexTier = trajectoryPoint.type & TrajectoryPoint.MASK_TIERS - 1;
final int indexTier = (trajectoryPoint.type & TrajectoryPoint.MASK_TIERS) - 1;
if ((trajectoryPoint.type & TrajectoryPoint.MAGNETS_HORIZONTAL) != 0) {
countMagnets[indexTier] += 2;
}
@ -548,7 +548,7 @@ public class AcceleratorSetup extends GlobalPosition {
// Pseudo-API for computers
public Object[][] getControlPoints(final IBlockAccess blockAccess) {
final Object[][] objectResults = new Object[controlPoints.size() + keyInjectors.length][];
final Object[][] objectResults = new Object[controlPoints.size() + (keyInjectors == null ? 0 : keyInjectors.length)][];
int index = 0;
for (final Entry<VectorI, Integer> entryControlPoint : controlPoints.entrySet()) {
final Integer tier = TrajectoryPoint.getTier(entryControlPoint.getValue());

View file

@ -2,6 +2,7 @@ package cr0s.warpdrive.data;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.ExceptionChunkNotLoaded;
import cr0s.warpdrive.block.breathing.BlockAirGeneratorTiered;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.network.PacketHandler;
@ -19,7 +20,7 @@ public class AirSpreader {
new StateAir(null), new StateAir(null), new StateAir(null) };
private static StateAir stateAirParent = new StateAir(null);
protected static void execute(final World world, final int x, final int y, final int z) {
protected static void execute(final World world, final int x, final int y, final int z) throws ExceptionChunkNotLoaded {
// note: compared to the pure block implementation, 0 really means no air, so we no longer offset by 1 on read/write
// get central block state

View file

@ -141,7 +141,7 @@ public class CamerasRegistry {
if (world == null) {
return;
}
WarpDrive.logger.info("Cameras registry for dimension " + world.provider.getDimension() + ":");
WarpDrive.logger.info("Cameras registry for dimension " + world.provider.getSaveFolder() + ":");
for (CameraRegistryItem cam : registry) {
WarpDrive.logger.info("- " + cam.videoChannel + " (" + cam.position.getX() + ", " + cam.position.getY() + ", " + cam.position.getZ() + ")");

View file

@ -547,6 +547,25 @@ public class CelestialObject implements Cloneable, IStringSerializable, ICelesti
return dx * dx + dz * dz;
}
/**
* Check if given position is in this object orbit.
*
* @param dimensionId current position in parent dimension
* @param x current position in parent dimension
* @param z current position in parent dimension
* @return true if we're in orbit of the object
*/
@Override
public boolean isInOrbit(final int dimensionId, final double x, final double z) {
// are we in another dimension?
if (!isParentResolved || parent == null || dimensionId != parent.dimensionId) {
return false;
}
// are we in orbit?
return (Math.abs(x - parentCenterX) <= borderRadiusX)
&& (Math.abs(z - parentCenterZ) <= borderRadiusZ);
}
public void readFromNBT(NBTTagCompound nbtTagCompound) {
isParentResolved = false;

View file

@ -2,6 +2,7 @@ package cr0s.warpdrive.data;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.ExceptionChunkNotLoaded;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.event.ChunkHandler;
@ -369,7 +370,7 @@ public class ChunkData {
tickAirSegment[indexData & 0xFFF] = (byte) ((tickCurrent + delay) & 0x7F);
}
public StateAir getStateAir(final World world, final int x, final int y, final int z) {
public StateAir getStateAir(final World world, final int x, final int y, final int z) throws ExceptionChunkNotLoaded {
final StateAir stateAir = new StateAir(this);
stateAir.refresh(world, x, y, z);
return stateAir;
@ -447,7 +448,14 @@ public class ChunkData {
final int x = (chunkCoordIntPair.chunkXPos << 4) + ((indexBlock & 0x00F0) >> 4);
final int y = (indexSegment << 4) + ((indexBlock & 0x0F00) >> 8);
final int z = (chunkCoordIntPair.chunkZPos << 4) + (indexBlock & 0x000F);
AirSpreader.execute(world, x, y, z);
try {
AirSpreader.execute(world, x, y, z);
} catch (ExceptionChunkNotLoaded exceptionChunkNotLoaded) {
// no operation
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
WarpDrive.logger.error(exceptionChunkNotLoaded.getMessage());
}
}
}
// clear empty segment

View file

@ -1,8 +1,9 @@
package cr0s.warpdrive.data;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IForceFieldShape;
import cr0s.warpdrive.config.WarpDriveConfig;
import net.minecraft.util.IStringSerializable;
import javax.annotation.Nonnull;
@ -50,40 +51,48 @@ public enum EnumForceFieldShape implements IStringSerializable, IForceFieldShape
public Map<VectorI, Boolean> getVertexes(ForceFieldSetup forceFieldSetup) {
final VectorI vScale = forceFieldSetup.vMax.clone().translateBack(forceFieldSetup.vMin);
final boolean isFusionOrInverted = forceFieldSetup.hasFusion || forceFieldSetup.isInverted;
final float thickness = Commons.clamp(1.0F, 2.0F, forceFieldSetup.thickness);
final int sizeEstimation;
if (!isFusionOrInverted) {// surface only
// plane surface is r^2
// sphere surface is 4*PI*r^2
// cylinder surface is 2*PI*r^2 + 2*PI*r*h = 2*PI*r^2 * 1.5
// cube surface is 4*6*r^2
final int maxRadius = 1 + (int) Math.ceil(Math.max(vScale.x, Math.max(vScale.y, vScale.z)) / 2.0F);
// plane surface is r^2
// sphere surface is 4*PI*r^2
// open cylinder surface is 2*PI*r * 2*r
// cube surface is 4*6*r^2
// in practice, 'r' is adjusted to account for overlaps and rounding
final int maxRadius = (int) Math.ceil(Math.max(vScale.x, Math.max(vScale.y, vScale.z)) / 2.0F);
switch(this) {
case SPHERE:
sizeEstimation = (int) Math.ceil(4 * Math.PI * maxRadius * maxRadius);
sizeEstimation = (int) Math.ceil(thickness * 4 * Math.PI * maxRadius * (maxRadius + 1));
break;
case CYLINDER_H:
case CYLINDER_V:
case TUBE:
sizeEstimation = (int) Math.ceil(4 * Math.PI * maxRadius * maxRadius * 1.5F);
sizeEstimation = (int) Math.ceil(thickness * 4 * Math.PI * (maxRadius + 2) * (maxRadius + 2));
break;
case CUBE:
sizeEstimation = (int) Math.ceil((int) thickness * 6 * (2 * maxRadius) * (2 * maxRadius + 1));
break;
case TUNNEL:
sizeEstimation = 4 * 6 * maxRadius * maxRadius;
sizeEstimation = (int) Math.ceil((int) thickness * 4 * (2 * maxRadius) * (2 * maxRadius + 1));
break;
case PLANE:
sizeEstimation = maxRadius * maxRadius;
sizeEstimation = (int) Math.ceil((int) thickness * 2 * (2 * maxRadius + 1) * (2 * maxRadius + 1));
break;
default:
assert(false);
sizeEstimation = 8;
WarpDrive.logger.error(String.format("Invalid object %s for shape %s with size %s. Please report this to the mod author",
this,
name,
vScale));
break;
}
} else {
sizeEstimation = vScale.x * vScale.y * vScale.z;
sizeEstimation = (vScale.x + 1) * (vScale.y + 1) * (vScale.z + 1);
}
final Map<VectorI, Boolean> mapVertexes = new HashMap<>(sizeEstimation);
@ -235,12 +244,30 @@ public enum EnumForceFieldShape implements IStringSerializable, IForceFieldShape
}
if (mapVertexes.size() > sizeEstimation) {
WarpDrive.logger.warn(String.format("Underestimated memory location lag %d > %d for shape %s with size %s, isFusionOrInverted %s. Please report this to the mod author",
WarpDrive.logger.warn(String.format("Underestimated memory allocation lag %d > %d for shape %s with size %s, isFusionOrInverted %s, thickness %.2f. Please report this to the mod author",
mapVertexes.size(), sizeEstimation,
name,
vScale,
isFusionOrInverted));
isFusionOrInverted,
forceFieldSetup.thickness));
} else if (WarpDriveConfig.LOGGING_PROFILING_MEMORY_ALLOCATION) {
if (mapVertexes.size() * 1.25 < sizeEstimation) {
WarpDrive.logger.warn(String.format("Overestimated memory allocation %d < %d for shape %s with size %s, isFusionOrInverted %s, thickness %.2f. Please report this to the mod author",
mapVertexes.size(), sizeEstimation,
name,
vScale,
isFusionOrInverted,
forceFieldSetup.thickness));
} else {
WarpDrive.logger.warn(String.format("Memory allocation is good: %d vs %d for shape %s with size %s, isFusionOrInverted %s, thickness %.2f. Please report this to the mod author",
mapVertexes.size(), sizeEstimation,
name,
vScale,
isFusionOrInverted,
forceFieldSetup.thickness));
}
}
return mapVertexes;
}
}

View file

@ -9,17 +9,18 @@ import net.minecraft.world.World;
public enum EnumShipMovementType implements IStringSerializable {
// hasConfig name description maximumDistance_blocks energyRequired warmup_seconds sickness_seconds cooldown_seconds
HYPERSPACE_ENTERING ( true , "hyperspace_entering", "entering hyperspace" , new double[] { 128D, 0D, 0D, 0D, 0D }, new double[] { 10000000D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D }, new double[] { 40D, 0D, 0D, 0D, 0D } ),
HYPERSPACE_EXITING ( true , "hyperspace_exiting" , "existing hyperspace" , new double[] { 128D, 0D, 0D, 0D, 0D }, new double[] { 10000000D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D }, new double[] { 40D, 0D, 0D, 0D, 0D } ),
HYPERSPACE_MOVING ( true , "hyperspace_moving" , "moving in hyperspace" , new double[] { 12800D, 0D, 0D, 0D, 0D }, new double[] { 10000D, 1D, 10D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D }, new double[] { 20D, 0D, 0D, 0D, 0D } ),
PLANET_LANDING ( true , "planet_landing" , "landing on a planet" , new double[] { 128D, 0D, 0D, 0D, 0D }, new double[] { 10000D, 10D, 100D, 0D, 0D }, new double[] { 20D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 60D, 0D, 0D, 0D, 0D } ),
PLANET_MOVING ( true , "planet_moving" , "moving on a planet" , new double[] { 128D, 0D, 0D, 0D, 0D }, new double[] { 100D, 10D, 100D, 0D, 0D }, new double[] { 5D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D } ),
PLANET_TAKEOFF ( true , "planet_takeoff" , "taking off a planet" , new double[] { 128D, 0D, 0D, 0D, 0D }, new double[] { 10000D, 10D, 100D, 0D, 0D }, new double[] { 20D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 60D, 0D, 0D, 0D, 0D } ),
SPACE_MOVING ( true , "space_moving" , "moving in space" , new double[] { 256D, 0D, 0D, 0D, 0D }, new double[] { 1000D, 10D, 100D, 0D, 0D }, new double[] { 10D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D } ),
GATE_ACTIVATING ( true , "gate_activating" , "activating a jumpgate", new double[] { 100000D, 0D, 0D, 0D, 0D }, new double[] { 20000D, 10D, 100D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D }, new double[] { 10D, 0D, 0D, 0D, 0D } ),
CREATIVE ( false, "" , "admin command" , new double[] { 999999D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D } ),
NONE ( false, "" , "idle, disabled, etc." , new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D } ),
// hasConfig name description maximumDistance_blocks energyRequired warmup_seconds sickness_seconds cooldown_seconds
HYPERSPACE_ENTERING ( true , "hyperspace_entering", "entering hyperspace" , new double[] { 100D, 0.1D, 0D, 0D, 0D }, new double[] { 10000000D, 0D, 0D, 0D, 0D }, new double[] { 40D, 0D, 0D, 0D, 0D }, new double[] { 10D, 0D, 0D, 0D, 0D }, new double[] { 60D, 0D, 0D, 0D, 0D } ),
HYPERSPACE_EXITING ( true , "hyperspace_exiting" , "existing hyperspace" , new double[] { 100D, 0.1D, 0D, 0D, 0D }, new double[] { 10000000D, 0D, 0D, 0D, 0D }, new double[] { 40D, 0D, 0D, 0D, 0D }, new double[] { 10D, 0D, 0D, 0D, 0D }, new double[] { 60D, 0D, 0D, 0D, 0D } ),
HYPERSPACE_MOVING ( true , "hyperspace_moving" , "moving in hyperspace" , new double[] { 200D, 0.5D, 0D, 0D, 0D }, new double[] { 10000D, 1D, 10D, 0D, 0D }, new double[] { 20D, 0D, 0D, 0D, 0D }, new double[] { 10D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D } ),
PLANET_LANDING ( true , "planet_landing" , "landing on a planet" , new double[] { 50D, 0.1D, 0D, 0D, 0D }, new double[] { 10000D, 10D, 100D, 0D, 0D }, new double[] { 20D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 60D, 0D, 0D, 0D, 0D } ),
PLANET_MOVING ( true , "planet_moving" , "moving on a planet" , new double[] { 50D, 0.1D, 0D, 0D, 0D }, new double[] { 100D, 10D, 100D, 0D, 0D }, new double[] { 20D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 40D, 0D, 0D, 0D, 0D } ),
PLANET_TAKEOFF ( true , "planet_takeoff" , "taking off a planet" , new double[] { 50D, 0.1D, 0D, 0D, 0D }, new double[] { 10000D, 10D, 100D, 0D, 0D }, new double[] { 20D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 90D, 0D, 0D, 0D, 0D } ),
SPACE_MOVING ( true , "space_moving" , "moving in space" , new double[] { 100D, 0.1D, 0D, 0D, 0D }, new double[] { 1000D, 10D, 100D, 0D, 0D }, new double[] { 10D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 30D, 0D, 0D, 0D, 0D } ),
GATE_ACTIVATING ( true , "gate_activating" , "activating a jumpgate", new double[] { 100000D, 0.1D, 0D, 0D, 0D }, new double[] { 20000D, 10D, 100D, 0D, 0D }, new double[] { 10D, 0D, 0D, 0D, 0D }, new double[] { 3D, 0D, 0D, 0D, 0D }, new double[] { 20D, 0D, 0D, 0D, 0D } ),
INSTANTIATE ( false, "" , "generation/ship token", new double[] { 999999D, 0.0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D } ),
RESTORE ( false, "" , "admin command" , new double[] { 999999D, 0.0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D } ),
NONE ( false, "" , "idle, disabled, etc." , new double[] { 0D, 0.0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D }, new double[] { 0D, 0D, 0D, 0D, 0D } ),
;
// nota: empty names won't show up in the configuration file
@ -52,11 +53,11 @@ public enum EnumShipMovementType implements IStringSerializable {
this.hasConfiguration = hasConfiguration;
this.unlocalizedName = unlocalizedName;
this.description = description;
this.warmupDefault = warmupDefault;
this.energyRequiredDefault = energyRequiredDefault;
this.cooldownDefault = cooldownDefault;
this.sicknessDefault = sicknessDefault;
this.maximumDistanceDefault = maximumDistanceDefault;
this.energyRequiredDefault = energyRequiredDefault;
this.warmupDefault = warmupDefault;
this.sicknessDefault = sicknessDefault;
this.cooldownDefault = cooldownDefault;
}
public static EnumShipMovementType get(final int damage) {

View file

@ -0,0 +1,53 @@
package cr0s.warpdrive.data;
import cr0s.warpdrive.api.IStringSerializable;
import javax.annotation.Nonnull;
import net.minecraft.client.Minecraft;
public enum EnumTooltipCondition implements IStringSerializable {
NEVER ("never" ),
ON_SNEAK ("on_sneak" ),
ADVANCED_TOOLTIPS ("advanced_tooltips"),
CREATIVE_ONLY ("creative_only" ),
ALWAYS ("always" );
public final String unlocalizedName;
EnumTooltipCondition(final String unlocalizedName) {
this.unlocalizedName = unlocalizedName;
}
public boolean isEnabled(final boolean isSneaking, final boolean isCreativeMode) {
switch(this) {
case NEVER: return false;
case ON_SNEAK: return isSneaking;
case ADVANCED_TOOLTIPS: return Minecraft.getMinecraft().gameSettings.advancedItemTooltips;
case CREATIVE_ONLY: return isCreativeMode;
case ALWAYS: return true;
default: return false;
}
}
@Override
public String toString() {
return unlocalizedName;
}
@Nonnull
@Override
public String getName() { return unlocalizedName; }
public static String formatAllValues() {
final StringBuilder result = new StringBuilder();
for (EnumTooltipCondition enumTooltipCondition : EnumTooltipCondition.values()) {
if (result.length() > 0) {
result.append(", ");
}
result.append(enumTooltipCondition);
}
return result.toString();
}
}

View file

@ -225,7 +225,7 @@ public class JumpBlock {
}
}
public void deploy(World targetWorld, ITransformation transformation) {
public BlockPos deploy(World targetWorld, ITransformation transformation) {
try {
NBTTagCompound nbtToDeploy = null;
if (blockTileEntity != null) {
@ -327,6 +327,8 @@ public class JumpBlock {
WarpDrive.logger.error("NBT data was " + nbtToDeploy);
}
}
return target;
} catch (Exception exception) {
exception.printStackTrace();
String coordinates;
@ -337,6 +339,7 @@ public class JumpBlock {
}
WarpDrive.logger.error("moveBlockSimple exception at " + coordinates);
}
return null;
}
public static void refreshBlockStateOnClient(World world, BlockPos blockPos) {
@ -344,10 +347,11 @@ public class JumpBlock {
if (tileEntity != null) {
Class<?> teClass = tileEntity.getClass();
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
WarpDrive.logger.info(String.format("Refreshing clients at %d %d %d with %s derived from %s",
WarpDrive.logger.info(String.format("Refreshing clients @ %s (%d %d %d) with %s derived from %s",
world.provider.getSaveFolder(),
blockPos.getX(), blockPos.getY(), blockPos.getZ(),
teClass,
teClass.getSuperclass()));
teClass,
teClass.getSuperclass()));
}
try {
String superClassName = teClass.getSuperclass().getName();
@ -410,19 +414,19 @@ public class JumpBlock {
}
}
public void readFromNBT(NBTTagCompound tag) {
block = Block.getBlockFromName(tag.getString("block"));
public void readFromNBT(final NBTTagCompound tagCompound) {
block = Block.getBlockFromName(tagCompound.getString("block"));
if (block == null) {
if (WarpDriveConfig.LOGGING_BUILDING) {
WarpDrive.logger.warn("Ignoring unknown block " + tag.getString("block") + " from tag " + tag);
WarpDrive.logger.warn("Ignoring unknown block " + tagCompound.getString("block") + " from tag " + tagCompound);
}
block = Blocks.AIR;
return;
}
blockMeta = tag.getByte("blockMeta");
blockMeta = tagCompound.getByte("blockMeta");
blockTileEntity = null;
if (tag.hasKey("blockNBT")) {
blockNBT = tag.getCompoundTag("blockNBT");
if (tagCompound.hasKey("blockNBT")) {
blockNBT = tagCompound.getCompoundTag("blockNBT");
// Clear computer IDs
if (blockNBT.hasKey("computerID")) {
@ -437,11 +441,11 @@ public class JumpBlock {
} else {
blockNBT = null;
}
x = tag.getInteger("x");
y = tag.getInteger("y");
z = tag.getInteger("z");
if (tag.hasKey("externals")) {
NBTTagCompound tagCompoundExternals = tag.getCompoundTag("externals");
x = tagCompound.getInteger("x");
y = tagCompound.getInteger("y");
z = tagCompound.getInteger("z");
if (tagCompound.hasKey("externals")) {
NBTTagCompound tagCompoundExternals = tagCompound.getCompoundTag("externals");
externals = new HashMap<>();
for (Object key : tagCompoundExternals.getKeySet()) {
assert (key instanceof String);
@ -452,19 +456,19 @@ public class JumpBlock {
}
}
public void writeToNBT(NBTTagCompound tag) {
tag.setString("block", Block.REGISTRY.getNameForObject(block).toString());
tag.setByte("blockMeta", (byte) blockMeta);
public void writeToNBT(final NBTTagCompound tagCompound) {
tagCompound.setString("block", Block.REGISTRY.getNameForObject(block).toString());
tagCompound.setByte("blockMeta", (byte) blockMeta);
if (blockTileEntity != null) {
NBTTagCompound tagCompound = new NBTTagCompound();
blockTileEntity.writeToNBT(tagCompound);
tag.setTag("blockNBT", tagCompound);
final NBTTagCompound nbtTileEntity = new NBTTagCompound();
blockTileEntity.writeToNBT(nbtTileEntity);
tagCompound.setTag("blockNBT", nbtTileEntity);
} else if (blockNBT != null) {
tag.setTag("blockNBT", blockNBT);
tagCompound.setTag("blockNBT", blockNBT);
}
tag.setInteger("x", x);
tag.setInteger("y", y);
tag.setInteger("z", z);
tagCompound.setInteger("x", x);
tagCompound.setInteger("y", y);
tagCompound.setInteger("z", z);
if (externals != null && !externals.isEmpty()) {
NBTTagCompound tagCompoundExternals = new NBTTagCompound();
for (Entry<String, NBTBase> entry : externals.entrySet()) {
@ -474,7 +478,7 @@ public class JumpBlock {
tagCompoundExternals.setTag(entry.getKey(), entry.getValue());
}
}
tag.setTag("externals", tagCompoundExternals);
tagCompound.setTag("externals", tagCompoundExternals);
}
}
@ -486,20 +490,24 @@ public class JumpBlock {
if (tagCompound == null) {
return;
}
// ComputerCraft computer
if (tagCompound.hasKey("computerID")) {
tagCompound.removeTag("computerID");
tagCompound.removeTag("label");
}
// WarpDrive UUID
if (tagCompound.hasKey("uuidMost")) {
tagCompound.removeTag("uuidMost");
tagCompound.removeTag("uuidLeast");
}
// WarpDrive any OC connected tile
if (tagCompound.hasKey("oc:node")) {
tagCompound.removeTag("oc:node");
}
// OpenComputers case
if (tagCompound.hasKey("oc:computer")) {
NBTTagCompound tagComputer = tagCompound.getCompoundTag("oc:computer");
@ -510,6 +518,7 @@ public class JumpBlock {
tagComputer.removeTag("node");
tagCompound.setTag("oc:computer", tagComputer);
}
// OpenComputers case
if (tagCompound.hasKey("oc:items")) {
NBTTagList tagListItems = tagCompound.getTagList("oc:items", Constants.NBT.TAG_COMPOUND);
@ -555,24 +564,45 @@ public class JumpBlock {
tagCompoundBattery.setInteger("energy", 0);
}
}
// Gregtech
if (tagCompound.hasKey("mStoredEnergy", NBT.TAG_INT)) {
tagCompound.setInteger("mStoredEnergy", 0);
}
// IC2
if (tagCompound.hasKey("energy", NBT.TAG_DOUBLE)) {
// energy_consume((int)Math.round(blockNBT.getDouble("energy")), true);
tagCompound.setDouble("energy", 0);
}
// Gregtech
if (tagCompound.hasKey("mStoredEnergy", NBT.TAG_INT)) {
tagCompound.setInteger("mStoredEnergy", 0);
}
// Immersive Engineering & Thermal Expansion
if (tagCompound.hasKey("Energy", NBT.TAG_INT)) {
// energy_consume(blockNBT.getInteger("Energy"), true);
tagCompound.setInteger("Energy", 0);
}
// Mekanism
if (tagCompound.hasKey("electricityStored", NBT.TAG_DOUBLE)) {
tagCompound.setDouble("electricityStored", 0);
}
// WarpDrive
if (tagCompound.hasKey("energy", NBT.TAG_LONG)) {
tagCompound.setLong("energy", 0L);
}
}
public void fillEnergyStorage() {
if (block == WarpDrive.blockShipCore) {
blockNBT.setLong("energy", WarpDriveConfig.SHIP_MAX_ENERGY_STORED);
}
if (block == WarpDrive.blockEnergyBank) {
final byte tier = blockNBT.getByte("tier");
if (tier > 0) {
blockNBT.setLong("energy", WarpDriveConfig.ENERGY_BANK_MAX_ENERGY_STORED[tier - 1]);
}
}
}
// IC2 support for updating tile entity fields
@ -582,6 +612,7 @@ public class JumpBlock {
private static void NetworkHelper_init() {
try {
NetworkManager_updateTileEntityField = Class.forName("ic2.core.network.NetworkManager").getMethod("updateTileEntityField", TileEntity.class, String.class);
NetworkManager_instance = Class.forName("ic2.core.IC2").getDeclaredField("network").get(null);
} catch (Exception exception) {
throw new RuntimeException(exception);

View file

@ -16,6 +16,7 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
@ -30,6 +31,7 @@ import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
public class JumpShip {
public World worldObj;
public BlockPos core;
public int dx;
@ -48,7 +50,7 @@ public class JumpShip {
public JumpShip() {
}
public static JumpShip createFromFile(String fileName, StringBuilder reason) {
public static JumpShip createFromFile(final String fileName, final StringBuilder reason) {
NBTTagCompound schematic = Commons.readNBTFromFile(WarpDriveConfig.G_SCHEMALOCATION + "/" + fileName + ".schematic");
if (schematic == null) {
reason.append(String.format("Schematic not found or unknown error reading it: '%s'.", fileName));
@ -112,11 +114,11 @@ public class JumpShip {
if (jumpBlock.block != null) {
if (WarpDriveConfig.LOGGING_BUILDING) {
if (tileEntities[index] == null) {
WarpDrive.logger.info("[ShipScanner] Adding block to deploy: "
WarpDrive.logger.info("Adding block to deploy: "
+ jumpBlock.block.getUnlocalizedName() + ":" + jumpBlock.blockMeta
+ " (no tile entity)");
} else {
WarpDrive.logger.info("[ShipScanner] Adding block to deploy: "
WarpDrive.logger.info("Adding block to deploy: "
+ jumpBlock.block.getUnlocalizedName() + ":" + jumpBlock.blockMeta
+ " with tile entity " + tileEntities[index].getString("id"));
}
@ -133,36 +135,51 @@ public class JumpShip {
}
public void messageToAllPlayersOnShip(final ITextComponent textComponent) {
final ITextComponent messageFormatted = new TextComponentString("["
+ ((shipCore != null && !shipCore.shipName.isEmpty()) ? shipCore.shipName : "ShipCore") + "] ")
.appendSibling(textComponent);
if (entitiesOnShip == null) {
shipCore.messageToAllPlayersOnShip(textComponent);
} else {
WarpDrive.logger.info(this + " messageToAllPlayersOnShip: " + textComponent);
for (MovingEntity movingEntity : entitiesOnShip) {
if (movingEntity.entity instanceof EntityPlayer) {
Commons.addChatMessage(movingEntity.entity, new TextComponentString("["
+ ((shipCore != null && !shipCore.shipName.isEmpty()) ? shipCore.shipName : "WarpCore") + "] ")
.appendSibling(textComponent));
}
// entities not saved yet, get them now
final StringBuilder reason = new StringBuilder();
saveEntities(reason);
}
WarpDrive.logger.info(this + " messageToAllPlayersOnShip: " + textComponent);
for (MovingEntity movingEntity : entitiesOnShip) {
final Entity entity = movingEntity.getEntity();
if (entity instanceof EntityPlayer) {
Commons.addChatMessage(entity, messageFormatted);
}
}
}
public String saveEntities() {
String result = null;
public boolean saveEntities(final StringBuilder reason) {
boolean isSuccess = true;
entitiesOnShip = new ArrayList<>();
AxisAlignedBB axisalignedbb = new AxisAlignedBB(minX, minY, minZ, maxX + 0.99D, maxY + 0.99D, maxZ + 0.99D);
if (worldObj == null) {
reason.append("Invalid call to saveEntities, please report it to mod author");
return false;
}
List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
final AxisAlignedBB axisalignedbb = new AxisAlignedBB(minX, minY, minZ, maxX + 0.99D, maxY + 0.99D, maxZ + 0.99D);
final List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
for (Entity entity : list) {
if (entity == null) {
continue;
}
String id = EntityList.getEntityString(entity);
final String id = EntityList.getEntityString(entity);
if (Dictionary.ENTITIES_ANCHOR.contains(id)) {
result = "Anchor entity " + id + " detected at " + Math.floor(entity.posX) + ", " + Math.floor(entity.posY) + ", " + Math.floor(entity.posZ) + ", aborting jump...";
if (reason.length() > 0) {
reason.append("\n");
}
reason.append(String.format("Anchor entity %s detected at (%d %d %d), aborting jump...",
id,
Math.round(entity.posX), Math.round(entity.posY), Math.round(entity.posZ)));
isSuccess = false;
// we need to continue so players are added so they can see the message...
continue;
}
@ -176,45 +193,40 @@ public class JumpShip {
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
WarpDrive.logger.info("Adding entity " + id + ": " + entity);
}
}
MovingEntity movingEntity = new MovingEntity(entity);
}
final MovingEntity movingEntity = new MovingEntity(entity);
entitiesOnShip.add(movingEntity);
}
return result;
return isSuccess;
}
public void setCaptain(final String playerName) {
entitiesOnShip = new ArrayList<>();
final EntityPlayerMP entityPlayerMP = Commons.getOnlinePlayerByName(playerName);
if (entityPlayerMP == null) {
WarpDrive.logger.error(String.format("%s setCaptain: captain is missing", this));
return;
}
final MovingEntity movingEntity = new MovingEntity(entityPlayerMP);
entitiesOnShip.add(movingEntity);
}
public boolean isUnlimited() {
if (entitiesOnShip == null) {
return false;
}
for (MovingEntity movingEntity : entitiesOnShip) {
if (!(movingEntity.entity instanceof EntityPlayer)) {
continue;
}
String playerName = movingEntity.entity.getName();
for (String unlimitedName : WarpDriveConfig.SHIP_VOLUME_UNLIMITED_PLAYERNAMES) {
if (unlimitedName.equals(playerName)) {
return true;
}
for (final MovingEntity movingEntity : entitiesOnShip) {
if (movingEntity.isUnlimited()) {
return true;
}
}
return false;
}
public void setMinMaxes(int minXV, int maxXV, int minYV, int maxYV, int minZV, int maxZV) {
minX = minXV;
maxX = maxXV;
minY = minYV;
maxY = maxYV;
minZ = minZV;
maxZ = maxZV;
}
@Override
public String toString() {
return String.format("%s/%d \'%s\' @ \'%s\' (%d %d %d)",
return String.format("%s/%d \'%s\' @ %s (%d %d %d)",
getClass().getSimpleName(), hashCode(),
shipCore == null ? "~NULL~" : (shipCore.uuid + ":" + shipCore.shipName),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
@ -254,7 +266,9 @@ public class JumpShip {
continue;
}
reason.append("Ship snagged by " + blockState.getBlock().getLocalizedName() + " at " + x + " " + y + " " + z + ". Damage report pending...");
reason.append(String.format("Ship snagged by %s at (%d %d %d). Sneak right click the ship core to see your ship dimensions, then update your ship dimensions.",
blockState.getBlock().getLocalizedName(),
x, y, z));
worldObj.createExplosion(null, x, y, z, Math.min(4F * 30, 4F * (jumpBlocks.length / 50)), false);
return false;
}
@ -311,7 +325,9 @@ public class JumpShip {
// Stop on non-movable blocks
if (Dictionary.BLOCKS_ANCHOR.contains(blockState.getBlock())) {
reason.append(blockState.getBlock().getLocalizedName() + " detected on board at " + x + " " + y + " " + z + ". Aborting.");
reason.append(String.format("Jump aborted by on-board anchor block %s at (%d %d %d).",
blockState.getBlock().getLocalizedName(),
x, y, z));
return false;
}
@ -323,7 +339,12 @@ public class JumpShip {
IBlockTransformer blockTransformer = WarpDriveConfig.blockTransformers.get(external.getKey());
if (blockTransformer != null) {
if (!blockTransformer.isJumpReady(jumpBlock.block, jumpBlock.blockMeta, jumpBlock.blockTileEntity, reason)) {
reason.append(" Jump aborted by " + jumpBlock.block.getLocalizedName() + " at " + jumpBlock.x + " " + jumpBlock.y + " " + jumpBlock.z);
if (reason.length() > 0) {
reason.append("\n");
}
reason.append(String.format("Jump aborted by on-board block %s at (%d %d %d).",
jumpBlock.block.getLocalizedName(),
jumpBlock.x, jumpBlock.y, jumpBlock.z));
return false;
}
}
@ -359,7 +380,10 @@ public class JumpShip {
actualMass = newMass;
} catch (Exception exception) {
exception.printStackTrace();
reason.append("Exception while saving ship, probably a corrupted block at " + blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ());
final String msg = String.format("Exception while saving ship, probably a corrupted block at (%d %d %d).",
blockPos.getX(), blockPos.getY(), blockPos.getZ());
WarpDrive.logger.error(msg);
reason.append(msg);
return false;
}

View file

@ -1,17 +1,43 @@
package cr0s.warpdrive.data;
import cr0s.warpdrive.config.WarpDriveConfig;
import java.lang.ref.WeakReference;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
public class MovingEntity {
public final Entity entity;
public final double oldX;
public final double oldY;
public final double oldZ;
public MovingEntity(Entity parEntity) {
entity = parEntity;
oldX = parEntity.posX;
oldY = parEntity.posY;
oldZ = parEntity.posZ;
private final WeakReference<Entity> weakEntity;
public final double originalX;
public final double originalY;
public final double originalZ;
public MovingEntity(final Entity entity) {
weakEntity = new WeakReference<>(entity);
originalX = entity.posX;
originalY = entity.posY;
originalZ = entity.posZ;
}
public Entity getEntity() {
return weakEntity.get();
}
public boolean isUnlimited() {
final Entity entity = getEntity();
if (!(entity instanceof EntityPlayer)) {
return false;
}
final String playerName = entity.getName();
for (final String unlimitedName : WarpDriveConfig.SHIP_VOLUME_UNLIMITED_PLAYERNAMES) {
if (unlimitedName.equals(playerName)) {
return true;
}
}
return false;
}
}

View file

@ -7,6 +7,7 @@ import cr0s.warpdrive.block.breathing.BlockAirFlow;
import cr0s.warpdrive.block.breathing.BlockAirSource;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.event.ChunkHandler;
import cr0s.warpdrive.api.ExceptionChunkNotLoaded;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDynamicLiquid;
@ -76,12 +77,12 @@ public class StateAir {
blockPos = new MutableBlockPos();
}
public void refresh(final World world, final int x, final int y, final int z) {
public void refresh(final World world, final int x, final int y, final int z) throws ExceptionChunkNotLoaded {
blockPos.setPos(x, y, z);
refresh(world);
}
public void refresh(final World world, final StateAir stateAir, final EnumFacing forgeDirection) {
public void refresh(final World world, final StateAir stateAir, final EnumFacing forgeDirection) throws ExceptionChunkNotLoaded {
blockPos.setPos(
stateAir.blockPos.getX() + forgeDirection.getFrontOffsetX(),
stateAir.blockPos.getY() + forgeDirection.getFrontOffsetY(),
@ -89,14 +90,15 @@ public class StateAir {
refresh(world);
}
private void refresh(final World world) {
private void refresh(final World world) throws ExceptionChunkNotLoaded {
// update chunk cache
if (chunkData == null || !chunkData.isInside(blockPos.getX(), blockPos.getY(), blockPos.getZ())) {
chunkData = ChunkHandler.getChunkData(world, blockPos.getX(), blockPos.getY(), blockPos.getZ(), false);
chunkData = ChunkHandler.getChunkData(world, blockPos.getX(), blockPos.getY(), blockPos.getZ());
if (chunkData == null) {
WarpDrive.logger.error(String.format("State air trying to get data from an non-loaded chunk in %s @ (%d %d %d)",
world.provider.getDimensionType().getName(), blockPos.getX(), blockPos.getY(), blockPos.getZ()));
assert(false);
// chunk isn't loaded, abort treatment or it'll trigger a CME
throw new ExceptionChunkNotLoaded(String.format("Air refresh aborted @ %s (%d %d %d)",
world.provider.getDimensionType().getName(),
blockPos.getX(), blockPos.getY(), blockPos.getZ()));
}
chunk = null;
}
@ -206,7 +208,11 @@ public class StateAir {
blockState = WarpDrive.blockAirSource.getDefaultState().withProperty(BlockProperties.FACING, direction);
world.setBlockState(blockPos, blockState, 2);
updateBlockType(world);
setGeneratorAndUpdateVoid(world, pressure, direction.getOpposite());
try {
setGeneratorAndUpdateVoid(world, pressure, direction.getOpposite());
} catch (ExceptionChunkNotLoaded exceptionChunkNotLoaded) {
// no operation
}
setConcentration(world, (byte) CONCENTRATION_MAX);
}
return updateRequired;
@ -324,7 +330,8 @@ public class StateAir {
if ((dataAir & BLOCK_MASK) != BLOCK_AIR_PLACEABLE) {
// state was out of sync => skip
if (WarpDrive.isDev) {
WarpDrive.logger.info(String.format("Desynchronized air state detected at %d %d %d: %8x -> %s",
WarpDrive.logger.info(String.format("Desynchronized air state detected @ %s (%d %d %d): %8x -> %s",
world.provider.getSaveFolder(),
blockPos.getX(), blockPos.getY(), blockPos.getZ(), dataAirLegacy, this));
}
return;
@ -349,7 +356,7 @@ public class StateAir {
}
}
protected void setGeneratorAndUpdateVoid(final World world, final short pressureNew, final EnumFacing directionNew) {
protected void setGeneratorAndUpdateVoid(final World world, final short pressureNew, final EnumFacing directionNew) throws ExceptionChunkNotLoaded {
if (pressureNew == 0 && pressureVoid > 0) {
removeGeneratorAndCascade(world);
} else {
@ -379,11 +386,10 @@ public class StateAir {
assert (pressureGenerator == 0 || pressureGenerator == GENERATOR_PRESSURE_MAX || directionGenerator != null);
assert (pressureGenerator == 0 || directionGenerator != null);
}
protected void removeGeneratorAndCascade(final World world) {
protected void removeGeneratorAndCascade(final World world) throws ExceptionChunkNotLoaded {
removeGeneratorAndCascade(world, WarpDriveConfig.BREATHING_VOLUME_UPDATE_DEPTH_BLOCKS);
}
private void removeGeneratorAndCascade(final World world, final int depth) {
private void removeGeneratorAndCascade(final World world, final int depth) throws ExceptionChunkNotLoaded {
if (pressureGenerator != 0) {
assert (directionGenerator != null);
dataAir = (dataAir & ~(GENERATOR_PRESSURE_MASK | GENERATOR_DIRECTION_MASK)) | (Commons.getOrdinal(null) << GENERATOR_DIRECTION_SHIFT);
@ -424,10 +430,10 @@ public class StateAir {
assert (pressureVoid == 0 || directionVoid != null);
assert (pressureVoid == 0 || pressureVoid == VOID_PRESSURE_MAX || directionVoid != null);
}
protected void removeVoidAndCascade(final World world) {
protected void removeVoidAndCascade(final World world) throws ExceptionChunkNotLoaded {
removeVoidAndCascade(world, WarpDriveConfig.BREATHING_VOLUME_UPDATE_DEPTH_BLOCKS);
}
private void removeVoidAndCascade(final World world, final int depth) {
private void removeVoidAndCascade(final World world, final int depth) throws ExceptionChunkNotLoaded {
if (pressureVoid != 0) {
assert (directionVoid != null);
dataAir = (dataAir & ~(VOID_PRESSURE_MASK | VOID_DIRECTION_MASK)) | (Commons.getOrdinal(null) << VOID_DIRECTION_SHIFT);
@ -510,48 +516,53 @@ public class StateAir {
}
public static void dumpAroundEntity(final EntityPlayer entityPlayer) {
StateAir stateAirs[][][] = new StateAir[3][3][3];
for (int dy = -1; dy <= 1; dy++) {
for (int dz = -1; dz <= 1; dz++) {
for (int dx = -1; dx <= 1; dx++) {
StateAir stateAir = new StateAir(null);
stateAir.refresh(entityPlayer.worldObj,
MathHelper.floor_double(entityPlayer.posX) + dx,
MathHelper.floor_double(entityPlayer.posY) + dy,
MathHelper.floor_double(entityPlayer.posZ) + dz);
stateAirs[dx + 1][dy + 1][dz + 1] = stateAir;
try {
final StateAir stateAirs[][][] = new StateAir[3][3][3];
for (int dy = -1; dy <= 1; dy++) {
for (int dz = -1; dz <= 1; dz++) {
for (int dx = -1; dx <= 1; dx++) {
StateAir stateAir = new StateAir(null);
stateAir.refresh(entityPlayer.worldObj,
MathHelper.floor_double(entityPlayer.posX) + dx,
MathHelper.floor_double(entityPlayer.posY) + dy,
MathHelper.floor_double(entityPlayer.posZ) + dz);
stateAirs[dx + 1][dy + 1][dz + 1] = stateAir;
}
}
}
}
StringBuilder message = new StringBuilder("------------------------------------------------\n§3Air, §aGenerator §7and §dVoid §7stats at " + entityPlayer.ticksExisted);
for (int indexY = 2; indexY >= 0; indexY--) {
for (int indexZ = 2; indexZ >= 0; indexZ--) {
message.append("\n");
for (int indexX = 0; indexX <= 2; indexX++) {
StateAir stateAir = stateAirs[indexX][indexY][indexZ];
final String stringValue = String.format("%2d", 100 + stateAir.concentration).substring(1);
message.append(String.format("§3%s ", stringValue));
final StringBuilder message = new StringBuilder("------------------------------------------------\n");
message.append("§3Air, §aGenerator §7and §dVoid §7stats at ").append(entityPlayer.ticksExisted);
for (int indexY = 2; indexY >= 0; indexY--) {
for (int indexZ = 2; indexZ >= 0; indexZ--) {
message.append("\n");
for (int indexX = 0; indexX <= 2; indexX++) {
StateAir stateAir = stateAirs[indexX][indexY][indexZ];
final String stringValue = String.format("%2d", 100 + stateAir.concentration).substring(1);
message.append(String.format("§3%s ", stringValue));
}
message.append("§f| ");
for (int indexX = 0; indexX <= 2; indexX++) {
StateAir stateAir = stateAirs[indexX][indexY][indexZ];
final String stringValue = String.format("%X", 0x100 + stateAir.pressureGenerator).substring(1);
final String stringDirection = directionToChar(stateAir.directionGenerator);
message.append(String.format("§e%s §a%s ", stringValue, stringDirection));
}
message.append("§f| ");
for (int indexX = 0; indexX <= 2; indexX++) {
StateAir stateAir = stateAirs[indexX][indexY][indexZ];
final String stringValue = String.format("%X", 0x100 + stateAir.pressureVoid).substring(1);
final String stringDirection = directionToChar(stateAir.directionVoid);
message.append(String.format("§e%s §d%s ", stringValue, stringDirection));
}
if (indexZ == 2) message.append("§f\\");
else if (indexZ == 1) message.append(String.format("§f > y = %d", stateAirs[1][indexY][indexZ].blockPos.getY()));
else message.append("§f/");
}
message.append("§f| ");
for (int indexX = 0; indexX <= 2; indexX++) {
StateAir stateAir = stateAirs[indexX][indexY][indexZ];
final String stringValue = String.format("%X", 0x100 + stateAir.pressureGenerator).substring(1);
final String stringDirection = directionToChar(stateAir.directionGenerator);
message.append(String.format("§e%s §a%s ", stringValue, stringDirection));
}
message.append("§f| ");
for (int indexX = 0; indexX <= 2; indexX++) {
StateAir stateAir = stateAirs[indexX][indexY][indexZ];
final String stringValue = String.format("%X", 0x100 + stateAir.pressureVoid).substring(1);
final String stringDirection = directionToChar(stateAir.directionVoid);
message.append(String.format("§e%s §d%s ", stringValue, stringDirection));
}
if (indexZ == 2) message.append("§f\\");
else if (indexZ == 1) message.append(String.format("§f > y = %d", stateAirs[1][indexY][indexZ].blockPos.getY()));
else message.append("§f/");
}
Commons.addChatMessage(entityPlayer, new TextComponentString(message.toString())); // @TODO convert formatting chain
} catch (ExceptionChunkNotLoaded exceptionChunkNotLoaded) {
// no operation
}
Commons.addChatMessage(entityPlayer, new TextComponentString(message.toString())); // @TODO convert formatting chain
}
private static String directionToChar(final EnumFacing direction) {

View file

@ -3,10 +3,12 @@ package cr0s.warpdrive.event;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.LocalProfiler;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.ExceptionChunkNotLoaded;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.ChunkData;
import cr0s.warpdrive.data.StateAir;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
@ -68,7 +70,7 @@ public class ChunkHandler {
final ChunkData chunkData = getChunkData(world.isRemote, world.provider.getDimension(), chunkX, chunkZ, true);
assert(chunkData != null);
// (world can load a non-generated chunk, or the chunk be regenerated, so we reset only as needed)
if (!chunkData.isLoaded()) {
if (!chunkData.isLoaded()) {
chunkData.load(new NBTTagCompound());
}
}
@ -88,7 +90,7 @@ public class ChunkHandler {
chunkData.load(event.getData());
}
// (called after data loading, only useful client side)
// (called after data loading, or before a late generation, or on client side)
@SubscribeEvent
public void onLoadChunk(ChunkEvent.Load event) {
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
@ -98,9 +100,9 @@ public class ChunkHandler {
event.getChunk().getChunkCoordIntPair()));
}
if (event.getWorld().isRemote) {
final ChunkData chunkData = getChunkData(event.getWorld().isRemote, event.getWorld().provider.getDimension(), event.getChunk().xPosition, event.getChunk().zPosition, true);
assert(chunkData != null);
final ChunkData chunkData = getChunkData(event.getWorld().isRemote, event.getWorld().provider.getDimension(), event.getChunk().xPosition, event.getChunk().zPosition, true);
assert(chunkData != null);
if (!chunkData.isLoaded()) {
chunkData.load(new NBTTagCompound());
}
}
@ -224,32 +226,49 @@ public class ChunkHandler {
if (event.side != Side.SERVER || event.phase != Phase.END) {
return;
}
// @TODO: add workaround for other mods doing bad multi-threading
updateTick(event.world);
}
public static void onBlockUpdated(final World world, final int x, final int y, final int z) {
if (!world.isRemote) {
final ChunkData chunkData = getChunkData(world, x, y, z, false);
final ChunkData chunkData = getChunkData(world, x, y, z);
if (chunkData != null) {
chunkData.onBlockUpdated(x, y, z);
} else {
WarpDrive.logger.error(String.format("%s world %s block updating at (%d %d %d), while chunk isn't loaded!",
world.isRemote ? "Client" : "Server",
if (WarpDriveConfig.LOGGING_WORLD_GENERATION) {
WarpDrive.logger.error(String.format("%s world %s block updating at (%d %d %d), while chunk isn't loaded!",
world.isRemote ? "Client" : "Server",
world.provider.getDimensionType().getName(),
x, y, z));
x, y, z));
Commons.dumpAllThreads();
}
}
}
}
/* internal access */
public static ChunkData getChunkData(final World world, final int x, final int y, final int z, final boolean doCreate) {
return getChunkData(world.isRemote, world.provider.getDimension(), x, y, z, doCreate);
/**
* Return null and spam logs if chunk isn't already generated or loaded
*/
public static ChunkData getChunkData(final World world, final int x, final int y, final int z) {
final ChunkData chunkData = getChunkData(world.isRemote, world.provider.getDimension(), x, y, z);
if (chunkData == null) {
WarpDrive.logger.error(String.format("Trying to get data from an non-loaded chunk in %s world %s @ (%d %d %d)",
world.isRemote ? "Client" : "Server",
world.provider.getSaveFolder(), x, y, z));
LocalProfiler.printCallStats();
Commons.dumpAllThreads();
assert(false);
}
return chunkData;
}
private static ChunkData getChunkData(final boolean isRemote, final int dimensionId, final int x, final int y, final int z, final boolean doCreate) {
/**
* Return null if chunk isn't already generated or loaded
*/
private static ChunkData getChunkData(final boolean isRemote, final int dimensionId, final int x, final int y, final int z) {
assert (y >= 0 && y <= 255);
return getChunkData(isRemote, dimensionId, x >> 4, z >> 4, doCreate);
return getChunkData(isRemote, dimensionId, x >> 4, z >> 4, false);
}
private static ChunkData getChunkData(final boolean isRemote, final int dimensionId, final int xChunk, final int zChunk, final boolean doCreate) {
@ -275,6 +294,10 @@ public class ChunkHandler {
//noinspection Java8MapApi
if (chunkData == null) {
if (!doCreate) {
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
WarpDrive.logger.info(String.format("getChunkData(%s, %d, %d, %d, false) returning null",
isRemote, dimensionId, xChunk, zChunk));
}
return null;
}
chunkData = new ChunkData(xChunk, zChunk);
@ -284,7 +307,16 @@ public class ChunkHandler {
dimensionId,
chunkData.getChunkCoords()));
}
mapRegistryItems.put(index, chunkData);
if (Commons.isSafeThread()) {
mapRegistryItems.put(index, chunkData);
} else {
WarpDrive.logger.error(String.format("%s world DIM%d chunk %s is being added to the registry outside main thread!",
isRemote ? "Client" : "Server",
dimensionId,
chunkData.getChunkCoords()));
Commons.dumpAllThreads();
mapRegistryItems.put(index, chunkData);
}
}
return chunkData;
}
@ -298,16 +330,28 @@ public class ChunkHandler {
/* commons */
public static boolean isLoaded(final World world, final int x, final int y, final int z) {
final ChunkData chunkData = getChunkData(world, x, y, z, false);
final ChunkData chunkData = getChunkData(world.isRemote, world.provider.getDimension(), x, y, z);
return chunkData != null && chunkData.isLoaded();
}
/* air handling */
public static StateAir getStateAir(final World world, final int x, final int y, final int z) {
return getChunkData(world, x, y, z, true).getStateAir(world, x, y, z);
final ChunkData chunkData = getChunkData(world, x, y, z);
if (chunkData == null) {
// chunk isn't loaded, skip it
return null;
}
try {
return chunkData.getStateAir(world, x, y, z);
} catch (ExceptionChunkNotLoaded exceptionChunkNotLoaded) {
WarpDrive.logger.warn(String.format("Aborting air evaluation: chunk isn't loaded @ %s (%d %d %d)",
world.provider.getSaveFolder(),
x, y, z));
return null;
}
}
public static void updateTick(final World world) {
private static void updateTick(final World world) {
// get dimension data
LocalProfiler.updateCallStat("updateTick");
final Map<Integer, Map<Long, ChunkData>> registry = world.isRemote ? registryClient : registryServer;
@ -318,26 +362,40 @@ public class ChunkHandler {
int countLoaded = 0;
final long timeForRemoval = System.currentTimeMillis() - CHUNK_HANDLER_UNLOADED_CHUNK_MAX_AGE_MS;
final long timeForThrottle = System.currentTimeMillis() + 200;
for(final Iterator<Entry<Long, ChunkData>> entryIterator = mapRegistryItems.entrySet().iterator(); entryIterator.hasNext(); ) {
final Map.Entry<Long, ChunkData> entryChunkData = entryIterator.next();
final ChunkData chunkData = entryChunkData.getValue();
// update loaded chunks, remove old unloaded chunks
if (chunkData.isLoaded()) {
countLoaded++;
if (System.currentTimeMillis() < timeForThrottle) {
updateTickLoopStep(world, mapRegistryItems, entryChunkData.getValue());
final long sizeBefore = mapRegistryItems.size();
try {
for (final Iterator<Entry<Long, ChunkData>> entryIterator = mapRegistryItems.entrySet().iterator(); entryIterator.hasNext(); ) {
final Map.Entry<Long, ChunkData> entryChunkData = entryIterator.next();
final ChunkData chunkData = entryChunkData.getValue();
// update loaded chunks, remove old unloaded chunks
if (chunkData.isLoaded()) {
countLoaded++;
if (System.currentTimeMillis() < timeForThrottle) {
updateTickLoopStep(world, mapRegistryItems, entryChunkData.getValue());
}
} else if (chunkData.timeUnloaded < timeForRemoval) {
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
WarpDrive.logger.info(String.format("%s world %s chunk %s is being removed from updateTick (size is %d)",
world.isRemote ? "Client" : "Server",
world.provider.getSaveFolder(),
chunkData.getChunkCoords(),
mapRegistryItems.size()));
}
entryIterator.remove();
}
} else if (chunkData.timeUnloaded < timeForRemoval) {
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
WarpDrive.logger.info(String.format("%s world %s chunk %s is being removed from updateTick (size is %d)",
world.isRemote ? "Client" : "Server",
world.provider.getDimensionType().getName(),
chunkData.getChunkCoords(),
mapRegistryItems.size()));
}
entryIterator.remove();
}
} catch (ConcurrentModificationException exception) {
WarpDrive.logger.error(String.format("%s world %s had some chunks changed outside main thread? (size %d -> %d)",
world.isRemote ? "Client" : "Server",
world.provider.getSaveFolder(),
sizeBefore, mapRegistryItems.size()));
exception.printStackTrace();
LocalProfiler.printCallStats();
}
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
if (world.provider.getDimension() == 0) {
delayLogging = (delayLogging + 1) % 4096;
@ -351,7 +409,8 @@ public class ChunkHandler {
}
}
public static void updateTickLoopStep(final World world, final Map<Long, ChunkData> mapRegistryItems, final ChunkData chunkData) {
// apparently, the GC triggers sooner when using sub-function here?
private static void updateTickLoopStep(final World world, final Map<Long, ChunkData> mapRegistryItems, final ChunkData chunkData) {
final ChunkPos chunkCoordIntPair = chunkData.getChunkCoords();
// skip empty chunks (faster and more frequent)
// ship chunk with unloaded neighbours

View file

@ -8,15 +8,25 @@ import cr0s.warpdrive.config.WarpDriveConfig;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemArmor.ArmorMaterial;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.oredict.OreDictionary;
public class ClientHandler {
private boolean isSneaking;
private boolean isCreativeMode;
@SubscribeEvent(priority = EventPriority.HIGHEST)
public void onTooltipEvent(ItemTooltipEvent event) {
if (event.getEntityPlayer() == null) {
@ -31,51 +41,166 @@ public class ClientHandler {
if (Dictionary.ITEMS_NOFALLDAMAGE.contains(event.getItemStack().getItem())) {
Commons.addTooltip(event.getToolTip(), new TextComponentTranslation("warpdrive.tooltip.itemTag.noFallDamage").getFormattedText());
}
if (WarpDrive.isDev && event.getEntityPlayer().capabilities.isCreativeMode) {// disabled in production
Block block = Block.getBlockFromItem(event.getItemStack().getItem());
if (block != Blocks.AIR && block != null) {
try {
ResourceLocation resourceLocation = Block.REGISTRY.getNameForObject(block);
Commons.addTooltip(event.getToolTip(), "" + resourceLocation + "");
} catch(Exception exception) {
// no operation
}
try {
IBlockState blockState = block.getStateFromMeta(event.getItemStack().getItemDamage());
String harvestTool = block.getHarvestTool(blockState);
Commons.addTooltip(event.getToolTip(), "Harvest with " + harvestTool + " (" + block.getHarvestLevel(blockState) + ")");
} catch(Exception | AssertionError exception) {
// no operation
}
try {
IBlockState blockState = block.getStateFromMeta(event.getItemStack().getItemDamage());
Commons.addTooltip(event.getToolTip(), "Light opacity is " + block.getLightOpacity(blockState));
} catch(Exception | AssertionError exception) {
// no operation
}
try {
Commons.addTooltip(event.getToolTip(), "Hardness is " + (float) WarpDrive.fieldBlockHardness.get(block));
} catch(Exception exception) {
// no operation
}
try {
Commons.addTooltip(event.getToolTip(), "Explosion resistance is " + block.getExplosionResistance(null));
} catch(Exception exception) {
// no operation
}
Commons.addTooltip(event.getToolTip(), "Explosion resistance is " + block.getExplosionResistance(null));
} else {
try {
String uniqueName = event.getItemStack().getItem().getRegistryName().toString();
Commons.addTooltip(event.getToolTip(), "" + uniqueName + "");
} catch(Exception exception) {
// no operation
isSneaking = event.getEntityPlayer().isSneaking();
isCreativeMode = event.getEntityPlayer().capabilities.isCreativeMode;
// add block/items details
final Block block = Block.getBlockFromItem(event.getItemStack().getItem());
if (block != Blocks.AIR) {
addBlockDetails(event, block);
} else {
addItemDetails(event, event.getItemStack().getItem());
}
// add burn time details (vanilla only register server side?)
if (WarpDriveConfig.CLIENT_TOOLTIP_BURN_TIME.isEnabled(isSneaking, isCreativeMode)) {
final int fuelValue = GameRegistry.getFuelValue(event.getItemStack());
if (fuelValue > 0) {
Commons.addTooltip(event.getToolTip(), String.format("Burn time is %d (%.1f ores)", fuelValue, fuelValue / 200.0F));
}
}
// add ore dictionary names
if (WarpDriveConfig.CLIENT_TOOLTIP_ORE_DICTIONARY_NAME.isEnabled(isSneaking, isCreativeMode)) {
final int[] idOres = OreDictionary.getOreIDs(event.getItemStack());
if (idOres.length != 0) {
Commons.addTooltip(event.getToolTip(), "Ore dictionary names:");
for (final int idOre : idOres) {
final String nameOre = OreDictionary.getOreName(idOre);
Commons.addTooltip(event.getToolTip(), "- " + nameOre);
}
}
}
}
public void addBlockDetails(final ItemTooltipEvent event, final Block block) {
// registry name
if (WarpDriveConfig.CLIENT_TOOLTIP_REGISTRY_NAME.isEnabled(isSneaking, isCreativeMode)) {
try {
final ResourceLocation resourceLocation = Block.REGISTRY.getNameForObject(block);
if (resourceLocation != null) {
Commons.addTooltip(event.getToolTip(), "" + resourceLocation + "");
}
} catch (Exception exception) {
// no operation
}
}
// tool related stats
if (WarpDriveConfig.CLIENT_TOOLTIP_HARVESTING.isEnabled(isSneaking, isCreativeMode)) {
try {
final IBlockState blockState = block.getStateFromMeta(event.getItemStack().getItemDamage());
final String harvestTool = block.getHarvestTool(blockState);
if (harvestTool != null) {
Commons.addTooltip(event.getToolTip(), String.format("Harvest with %s (%d)",
harvestTool,
block.getHarvestLevel(blockState)));
}
} catch (Exception exception) {
// no operation
}
}
// generic properties
if (WarpDriveConfig.CLIENT_TOOLTIP_OPACITY.isEnabled(isSneaking, isCreativeMode)) {
final IBlockState blockState = block.getStateFromMeta(event.getItemStack().getItemDamage());
Commons.addTooltip(event.getToolTip(), String.format("Light opacity is %d", block.getLightOpacity(blockState)));
}
if (WarpDriveConfig.CLIENT_TOOLTIP_HARDNESS.isEnabled(isSneaking, isCreativeMode)) {
try {
Commons.addTooltip(event.getToolTip(), String.format("Hardness is %.1f", (float) WarpDrive.fieldBlockHardness.get(block)));
} catch (Exception exception) {
// no operation
}
Commons.addTooltip(event.getToolTip(), String.format("Explosion resistance is %.1f", + block.getExplosionResistance(null)));
}
// flammability
if (WarpDriveConfig.CLIENT_TOOLTIP_FLAMMABILITY.isEnabled(isSneaking, isCreativeMode)) {
try {
final int flammability = Blocks.FIRE.getFlammability(block);
final int fireSpread = Blocks.FIRE.getEncouragement(block);
if (flammability > 0) {
Commons.addTooltip(event.getToolTip(), String.format("Flammable: %d, spread %d", flammability, fireSpread));
}
} catch (Exception exception) {
// no operation
}
}
// fluid stats
if (WarpDriveConfig.CLIENT_TOOLTIP_FLUID.isEnabled(isSneaking, isCreativeMode)) {
try {
final Fluid fluid = FluidRegistry.lookupFluidForBlock(block);
if (fluid != null) {
if (fluid.isGaseous()) {
Commons.addTooltip(event.getToolTip(), String.format("Gaz viscosity is %d", fluid.getViscosity()));
Commons.addTooltip(event.getToolTip(), String.format("Gaz density is %d", fluid.getDensity()));
} else {
Commons.addTooltip(event.getToolTip(), String.format("Liquid viscosity is %d", fluid.getViscosity()));
Commons.addTooltip(event.getToolTip(), String.format("Liquid density is %d", fluid.getDensity()));
}
Commons.addTooltip(event.getToolTip(), String.format("Temperature is %d K", fluid.getTemperature()));
IBlockState blockState = block.getStateFromMeta(event.getItemStack().getItemDamage());
String harvestTool = block.getHarvestTool(blockState);
}
} catch (Exception exception) {
// no operation
}
}
}
public void addItemDetails(final ItemTooltipEvent event, final Item item) {
// registry name
if (WarpDriveConfig.CLIENT_TOOLTIP_REGISTRY_NAME.isEnabled(isSneaking, isCreativeMode)) {
try {
final ResourceLocation resourceLocation = Item.REGISTRY.getNameForObject(item);
if (resourceLocation != null) {
Commons.addTooltip(event.getToolTip(), "" + resourceLocation + "");
}
} catch (Exception exception) {
// no operation
}
}
// (item duration can't be directly understood => out)
// durability
if (WarpDriveConfig.CLIENT_TOOLTIP_DURABILITY.isEnabled(isSneaking, isCreativeMode)) {
try {
if (event.getItemStack().isItemStackDamageable()) {
Commons.addTooltip(event.getToolTip(), String.format("Durability: %d / %d",
event.getItemStack().getMaxDamage() - event.getItemStack().getItemDamage(),
event.getItemStack().getMaxDamage()));
}
} catch (Exception exception) {
// no operation
}
}
// armor stats
if (WarpDriveConfig.CLIENT_TOOLTIP_ARMOR.isEnabled(isSneaking, isCreativeMode)) {
try {
if (item instanceof ItemArmor) {
Commons.addTooltip(event.getToolTip(), String.format("Armor points: %d",
((ItemArmor) item).damageReduceAmount));
final ArmorMaterial armorMaterial = ((ItemArmor) item).getArmorMaterial();
Commons.addTooltip(event.getToolTip(), String.format("Enchantability: %d",
armorMaterial.getEnchantability()));
if (WarpDriveConfig.CLIENT_TOOLTIP_REPAIR_WITH.isEnabled(isSneaking, isCreativeMode)) {
final Item itemRepair = armorMaterial.getRepairItem();
if (itemRepair != null) {
Commons.addTooltip(event.getToolTip(), String.format("Repair with %s",
armorMaterial.getRepairItem().getUnlocalizedName()));
}
}
}
} catch (Exception exception) {
// no operation
}
}
}
}

View file

@ -32,9 +32,8 @@ public class CommonWorldGenerator implements IWorldGenerator {
// as observed on 1.7.10: during world transition, the generator from the previous world is still called
return;
}
if ( celestialObject.borderRadiusX > 0
&& ( Math.abs(x - celestialObject.dimensionCenterX) > celestialObject.borderRadiusX
|| Math.abs(z - celestialObject.dimensionCenterZ) > celestialObject.borderRadiusZ ) ) {
if ( Math.abs(x - celestialObject.dimensionCenterX) > celestialObject.borderRadiusX
|| Math.abs(z - celestialObject.dimensionCenterZ) > celestialObject.borderRadiusZ ) {
return;
}
final int y = WarpDriveConfig.SPACE_GENERATOR_Y_MIN_CENTER

View file

@ -0,0 +1,85 @@
package cr0s.warpdrive.event;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.ISequencerCallbacks;
import cr0s.warpdrive.block.movement.TileEntityShipCore;
import cr0s.warpdrive.data.EnumShipMovementType;
import cr0s.warpdrive.data.JumpShip;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
public class DeploySequencer extends JumpSequencer {
private String playerName;
private ISequencerCallbacks callback;
/*
public DeploySequencer(final TileEntityShipCore shipCore, final EnumShipMovementType shipMovementType, final String nameTarget,
final int moveX, final int moveY, final int moveZ, final byte rotationSteps,
final int destX, final int destY, final int destZ) {
super(shipCore, shipMovementType, nameTarget, moveX, moveY, moveZ, rotationSteps, destX, destY, destZ);
}
/**/
public DeploySequencer(final JumpShip jumpShip, final World world, final boolean isInstantiated,
final int destX, final int destY, final int destZ, final byte rotationSteps) {
super(jumpShip, world, isInstantiated ? EnumShipMovementType.INSTANTIATE : EnumShipMovementType.RESTORE, destX, destY, destZ, rotationSteps);
}
public void setCaptain(final String playerName) {
this.playerName = playerName;
ship.setCaptain(playerName);
}
public void setCallback(final ISequencerCallbacks object) {
this.callback = object;
}
@Override
public void disableAndMessage(final String reason) {
super.disableAndMessage(reason);
callback.sequencer_finished();
}
@Override
protected void state_chunkReleasing() {
super.state_chunkReleasing();
if (playerName != null) {
// Warn owner if deployment done but wait next tick for teleportation
final EntityPlayerMP entityPlayerMP = Commons.getOnlinePlayerByName(playerName);
if (entityPlayerMP != null) {
Commons.addChatMessage(entityPlayerMP, new TextComponentString("Ship complete. Teleporting captain to the main deck"));
}
}
}
@Override
protected void state_finishing() {
if (playerName != null && !playerName.isEmpty()) {
final EntityPlayerMP entityPlayerMP = Commons.getOnlinePlayerByName(playerName);
if (entityPlayerMP != null) {
final TileEntity tileEntity = targetWorld.getTileEntity(new BlockPos(destX, destY, destZ));
if (tileEntity instanceof TileEntityShipCore) {
final boolean isSuccess = ((TileEntityShipCore) tileEntity).summonOwnerOnDeploy(entityPlayerMP);
if (isSuccess) {
Commons.addChatMessage(entityPlayerMP, new TextComponentString("§6" + "Welcome aboard captain. Use the computer to get moving..."));
} else {
WarpDrive.logger.warn(String.format("Failed to assign new captain %s",
playerName));
}
} else {
WarpDrive.logger.warn(String.format("Unable to detect ship core after deployment, found %s",
tileEntity));
}
}
}
super.state_finishing();
}
}

View file

@ -0,0 +1,28 @@
package cr0s.warpdrive.event;
import cr0s.warpdrive.api.IItemBase;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.event.entity.item.ItemExpireEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class ItemHandler {
@SubscribeEvent
public void onItemExpireEvent(final ItemExpireEvent event) {
if (event.getEntityItem() == null) {
return;
}
final ItemStack itemStack = event.getEntityItem().getEntityItem();
if (itemStack == null) {
return;
}
final Item item = itemStack.getItem();
if (!(item instanceof IItemBase)) {
return;
}
((IItemBase) item).onEntityExpireEvent(event.getEntityItem(), itemStack);
}
}

View file

@ -1,6 +1,7 @@
package cr0s.warpdrive.event;
import cr0s.warpdrive.CommonProxy;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.LocalProfiler;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IBlockTransformer;
@ -14,13 +15,14 @@ import cr0s.warpdrive.data.EnumShipMovementType;
import cr0s.warpdrive.data.JumpBlock;
import cr0s.warpdrive.data.JumpShip;
import cr0s.warpdrive.data.MovingEntity;
import cr0s.warpdrive.data.SoundEvents;
import cr0s.warpdrive.data.Transformation;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.data.VectorI;
import cr0s.warpdrive.network.PacketHandler;
import cr0s.warpdrive.world.SpaceTeleporter;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
@ -30,15 +32,16 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import net.minecraft.block.SoundType;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
@ -57,15 +60,18 @@ import net.minecraftforge.common.ForgeChunkManager.Type;
public class JumpSequencer extends AbstractSequencer {
// Jump vector
private Transformation transformation;
protected Transformation transformation;
private final EnumShipMovementType shipMovementType;
private int moveX, moveY, moveZ;
private final byte rotationSteps;
private String nameTarget;
private final String nameTarget;
private Vector3 v3Source;
private int blocksPerTick = WarpDriveConfig.G_BLOCKS_PER_TICK;
private static final boolean enforceEntitiesPosition = false;
private final World sourceWorld;
private World targetWorld;
protected final World sourceWorld;
protected World targetWorld;
private Ticket sourceWorldTicket;
private Ticket targetWorldTicket;
@ -74,7 +80,7 @@ public class JumpSequencer extends AbstractSequencer {
private ArrayList<Vector3> collisionAtTarget;
private float collisionStrength = 0;
private boolean isEnabled = false;
protected boolean isEnabled = false;
private static final int STATE_IDLE = 0;
private static final int STATE_CHUNKLOADING = 1;
private static final int STATE_SAVING = 2;
@ -89,12 +95,12 @@ public class JumpSequencer extends AbstractSequencer {
private int state = STATE_IDLE;
private int actualIndexInShip = 0;
private final JumpShip ship;
protected final JumpShip ship;
private boolean betweenWorlds;
private final int destX;
private final int destY;
private final int destZ;
protected final int destX;
protected final int destY;
protected final int destZ;
private long msCounter = 0;
private int ticks = 0;
@ -125,6 +131,9 @@ public class JumpSequencer extends AbstractSequencer {
this.destY = destY;
this.destZ = destZ;
// no animation
v3Source = null;
// set when preparing jump
targetWorld = null;
@ -133,20 +142,46 @@ public class JumpSequencer extends AbstractSequencer {
}
}
public JumpSequencer(final JumpShip jumpShip, final World world, final EnumShipMovementType enumShipMovementType,
final int destX, final int destY, final int destZ, final byte rotationSteps) {
this.sourceWorld = null;
this.ship = jumpShip;
this.shipMovementType = enumShipMovementType;
this.rotationSteps = rotationSteps;
this.nameTarget = null;
this.destX = destX;
this.destY = destY;
this.destZ = destZ;
targetWorld = world;
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Sequencer created");
}
}
public void setBlocksPerTick(final int blocksPerTick) {
this.blocksPerTick = Math.min(WarpDriveConfig.G_BLOCKS_PER_TICK, blocksPerTick);
}
public void setEffectSource(final Vector3 v3Source) {
this.v3Source = v3Source;
}
public void enable() {
isEnabled = true;
register();
}
@Deprecated
private void disableAndMessage(String message) {
public void disableAndMessage(String message) {
disableAndMessage(new TextComponentString(message));
}
private void disableAndMessage(ITextComponent textComponent) {
public void disableAndMessage(ITextComponent textComponent) {
disable(textComponent);
ship.messageToAllPlayersOnShip(textComponent);
}
private void disable(ITextComponent textComponent) {
public void disable(ITextComponent textComponent) {
if (!isEnabled) {
return;
}
@ -161,15 +196,14 @@ public class JumpSequencer extends AbstractSequencer {
}
}
unforceChunks();
releaseChunks();
unregister();
}
private static final boolean enforceEntitiesPosition = false;
@Override
public boolean onUpdate() {
if (sourceWorld.isRemote) {
if ( (sourceWorld != null && sourceWorld.isRemote)
|| (targetWorld != null && targetWorld.isRemote) ) {
return false;
}
@ -191,12 +225,17 @@ public class JumpSequencer extends AbstractSequencer {
// blank state in case we got desync
msCounter = System.currentTimeMillis();
if (isEnabled) {
state = STATE_CHUNKLOADING;
if ( shipMovementType != EnumShipMovementType.INSTANTIATE
&& shipMovementType != EnumShipMovementType.RESTORE ) {
state = STATE_CHUNKLOADING;
} else {
state = STATE_TRANSFORMER;
}
}
break;
case STATE_CHUNKLOADING:
state_chunkLoading();
state_chunkLoadingSource();
if (isEnabled) {
actualIndexInShip = 0;
state = STATE_SAVING;
@ -260,7 +299,7 @@ public class JumpSequencer extends AbstractSequencer {
break;
case STATE_CHUNKUNLOADING:
state_chunkUnloading();
state_chunkReleasing();
state = STATE_FINISHING;
break;
@ -282,20 +321,22 @@ public class JumpSequencer extends AbstractSequencer {
}
sourceWorldTicket = ForgeChunkManager.requestTicket(WarpDrive.instance, sourceWorld, Type.NORMAL);
if (sourceWorldTicket == null) {
reason.append(String.format("Chunkloading rejected in source world %s. Aborting.", sourceWorld.getWorldInfo().getWorldName()));
reason.append(String.format("Chunkloading rejected in source world %s. Aborting.",
sourceWorld.getWorldInfo().getWorldName()));
return false;
}
int x1 = ship.minX >> 4;
int x2 = ship.maxX >> 4;
int z1 = ship.minZ >> 4;
int z2 = ship.maxZ >> 4;
final int minX = ship.minX >> 4;
final int maxX = ship.maxX >> 4;
final int minZ = ship.minZ >> 4;
final int maxZ = ship.maxZ >> 4;
int chunkCount = 0;
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
chunkCount++;
if (chunkCount > sourceWorldTicket.getMaxChunkListDepth()) {
reason.append(String.format("Ship is extending over %d chunks in source world, this is too much! Max is currently set to %d in config/forgeChunkLoading.cfg. Aborting.",
(x2 - x1 + 1) * (z2 - z1 + 1),
reason.append(String.format("Ship is extending over %d chunks in source world. Max is currently set to %d in config/forgeChunkLoading.cfg. Aborting.",
(maxX - minX + 1) * (maxZ - minZ + 1),
sourceWorldTicket.getMaxChunkListDepth()));
return false;
}
@ -313,23 +354,23 @@ public class JumpSequencer extends AbstractSequencer {
targetWorldTicket = ForgeChunkManager.requestTicket(WarpDrive.instance, targetWorld, Type.NORMAL);
if (targetWorldTicket == null) {
reason.append(String.format("Chunkloading rejected in target world %s. Aborting.",
sourceWorld.getWorldInfo().getWorldName()));
targetWorld.getWorldInfo().getWorldName()));
return false;
}
BlockPos targetMin = transformation.apply(ship.minX, ship.minY, ship.minZ);
BlockPos targetMax = transformation.apply(ship.maxX, ship.maxY, ship.maxZ);
int x1 = Math.min(targetMin.getX(), targetMax.getX()) >> 4;
int x2 = Math.max(targetMin.getX(), targetMax.getX()) >> 4;
int z1 = Math.min(targetMin.getZ(), targetMax.getZ()) >> 4;
int z2 = Math.max(targetMin.getZ(), targetMax.getZ()) >> 4;
final BlockPos targetMin = transformation.apply(ship.minX, ship.minY, ship.minZ);
final BlockPos targetMax = transformation.apply(ship.maxX, ship.maxY, ship.maxZ);
final int minX = Math.min(targetMin.getX(), targetMax.getX()) >> 4;
final int maxX = Math.max(targetMin.getX(), targetMax.getX()) >> 4;
final int minZ = Math.min(targetMin.getZ(), targetMax.getZ()) >> 4;
final int maxZ = Math.max(targetMin.getZ(), targetMax.getZ()) >> 4;
int chunkCount = 0;
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
chunkCount++;
if (chunkCount > targetWorldTicket.getMaxChunkListDepth()) {
reason.append(String.format("Ship is extending over %d chunks in target world, this is too much! Max is currently set to %d in config/forgeChunkLoading.cfg. Aborting.",
(x2 - x1 + 1) * (z2 - z1 + 1),
reason.append(String.format("Ship is extending over %d chunks in target world. Max is currently set to %d in config/forgeChunkLoading.cfg. Aborting.",
(maxX - minX + 1) * (maxZ - minZ + 1),
targetWorldTicket.getMaxChunkListDepth()));
return false;
}
@ -340,19 +381,19 @@ public class JumpSequencer extends AbstractSequencer {
return true;
}
private void unforceChunks() {
private void releaseChunks() {
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Unforcing chunks");
WarpDrive.logger.info(this + " Releasing chunks");
}
int x1, x2, z1, z2;
int minX, maxX, minZ, maxZ;
if (sourceWorldTicket != null) {
x1 = ship.minX >> 4;
x2 = ship.maxX >> 4;
z1 = ship.minZ >> 4;
z2 = ship.maxZ >> 4;
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
minX = ship.minX >> 4;
maxX = ship.maxX >> 4;
minZ = ship.minZ >> 4;
maxZ = ship.maxZ >> 4;
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
sourceWorld.getChunkFromChunkCoords(x, z).generateSkylightMap();
ForgeChunkManager.unforceChunk(sourceWorldTicket, new ChunkPos(x, z));
}
@ -362,14 +403,14 @@ public class JumpSequencer extends AbstractSequencer {
}
if (targetWorldTicket != null) {
BlockPos targetMin = transformation.apply(ship.minX, ship.minY, ship.minZ);
BlockPos targetMax = transformation.apply(ship.maxX, ship.maxY, ship.maxZ);
x1 = Math.min(targetMin.getX(), targetMax.getX()) >> 4;
x2 = Math.max(targetMin.getX(), targetMax.getX()) >> 4;
z1 = Math.min(targetMin.getZ(), targetMax.getZ()) >> 4;
z2 = Math.max(targetMin.getZ(), targetMax.getZ()) >> 4;
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
final BlockPos targetMin = transformation.apply(ship.minX, ship.minY, ship.minZ);
final BlockPos targetMax = transformation.apply(ship.maxX, ship.maxY, ship.maxZ);
minX = Math.min(targetMin.getX(), targetMax.getX()) >> 4;
maxX = Math.max(targetMin.getX(), targetMax.getX()) >> 4;
minZ = Math.min(targetMin.getZ(), targetMax.getZ()) >> 4;
maxZ = Math.max(targetMin.getZ(), targetMax.getZ()) >> 4;
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
targetWorld.getChunkFromChunkCoords(x, z).generateSkylightMap();
ForgeChunkManager.unforceChunk(targetWorldTicket, new ChunkPos(x, z));
}
@ -379,8 +420,8 @@ public class JumpSequencer extends AbstractSequencer {
}
}
private void state_chunkLoading() {
LocalProfiler.start("Jump.chunkLoading");
protected void state_chunkLoadingSource() {
LocalProfiler.start("Jump.chunkLoadingSource");
StringBuilder reason = new StringBuilder();
@ -393,16 +434,18 @@ public class JumpSequencer extends AbstractSequencer {
LocalProfiler.stop();
}
private void state_saving() {
protected void state_saving() {
LocalProfiler.start("Jump.saving");
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Saving ship...");
}
StringBuilder reason = new StringBuilder();
final StringBuilder reason = new StringBuilder();
if (!ship.save(reason)) {
disableAndMessage(reason.toString());
final ITextComponent msg = new TextComponentString(reason.toString());
disable(msg);
ship.messageToAllPlayersOnShip(msg);
LocalProfiler.stop();
return;
}
@ -410,22 +453,24 @@ public class JumpSequencer extends AbstractSequencer {
LocalProfiler.stop();
}
private void state_borders() {
protected void state_borders() {
LocalProfiler.start("Jump.borders");
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Checking ship borders...");
}
StringBuilder reason = new StringBuilder();
final StringBuilder reason = new StringBuilder();
if (!ship.checkBorders(reason)) {
disableAndMessage(reason.toString());
final ITextComponent msg = new TextComponentString(reason.toString());
disable(msg);
ship.messageToAllPlayersOnShip(msg);
LocalProfiler.stop();
return;
}
File file = new File(WarpDriveConfig.G_SCHEMALOCATION + "/auto");
final File file = new File(WarpDriveConfig.G_SCHEMALOCATION + "/auto");
if (!file.exists() || !file.isDirectory()) {
if (!file.mkdirs()) {
WarpDrive.logger.warn("Unable to create auto-backup folder, skipping...");
@ -436,8 +481,8 @@ public class JumpSequencer extends AbstractSequencer {
try {
// Generate unique file name
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd_HH'h'mm'm'ss's'SSS");
String shipName = ship.shipCore.shipName.replaceAll("[^ -~]", "").replaceAll("[:/\\\\]", "");
final SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd_HH'h'mm'm'ss's'SSS");
final String shipName = ship.shipCore.shipName.replaceAll("[^ -~]", "").replaceAll("[:/\\\\]", "");
String schematicFileName;
do {
Date now = new Date();
@ -445,21 +490,22 @@ public class JumpSequencer extends AbstractSequencer {
} while (new File(schematicFileName).exists());
// Save header
NBTTagCompound schematic = new NBTTagCompound();
final NBTTagCompound schematic = new NBTTagCompound();
short width = (short) (ship.shipCore.maxX - ship.shipCore.minX + 1);
short length = (short) (ship.shipCore.maxZ - ship.shipCore.minZ + 1);
short height = (short) (ship.shipCore.maxY - ship.shipCore.minY + 1);
final short width = (short) (ship.shipCore.maxX - ship.shipCore.minX + 1);
final short length = (short) (ship.shipCore.maxZ - ship.shipCore.minZ + 1);
final short height = (short) (ship.shipCore.maxY - ship.shipCore.minY + 1);
schematic.setShort("Width", width);
schematic.setShort("Length", length);
schematic.setShort("Height", height);
schematic.setInteger("shipMass", ship.shipCore.shipMass);
schematic.setString("shipName", ship.shipCore.shipName);
schematic.setInteger("shipVolume", ship.shipCore.shipVolume);
NBTTagCompound tagCompoundShip = new NBTTagCompound();
final NBTTagCompound tagCompoundShip = new NBTTagCompound();
ship.writeToNBT(tagCompoundShip);
schematic.setTag("ship", tagCompoundShip);
writeNBTToFile(schematicFileName, schematic);
WarpDrive.logger.info(this + " Saving ship state prior to jump in " + schematicFileName);
Commons.writeNBTToFile(schematicFileName, schematic);
if (WarpDriveConfig.LOGGING_JUMP && WarpDrive.isDev) {
WarpDrive.logger.info(this + " Ship saved as " + schematicFileName);
}
@ -471,38 +517,19 @@ public class JumpSequencer extends AbstractSequencer {
LocalProfiler.stop();
}
private void writeNBTToFile(String fileName, NBTTagCompound nbttagcompound) {
WarpDrive.logger.info(this + " Saving ship state prior to jump in " + fileName);
try {
File file = new File(fileName);
if (!file.exists()) {
//noinspection ResultOfMethodCallIgnored
file.createNewFile();
}
FileOutputStream fileoutputstream = new FileOutputStream(file);
CompressedStreamTools.writeCompressed(nbttagcompound, fileoutputstream);
fileoutputstream.close();
} catch (Exception exception) {
exception.printStackTrace();
}
}
private void state_transformer() {
protected void state_transformer() {
LocalProfiler.start("Jump.transformer");
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Transformer evaluation...");
}
StringBuilder reason = new StringBuilder();
final StringBuilder reason = new StringBuilder();
betweenWorlds = shipMovementType == EnumShipMovementType.PLANET_TAKEOFF
|| shipMovementType == EnumShipMovementType.PLANET_LANDING
|| shipMovementType == EnumShipMovementType.HYPERSPACE_EXITING
|| shipMovementType == EnumShipMovementType.HYPERSPACE_ENTERING;
// note: when deploying from scanner shipMovementType is CREATIVE, so betweenWorlds is false
{// compute targetWorld and movement vector (moveX, moveY, moveZ)
final CelestialObject celestialObjectSource = CelestialObjectManager.get(sourceWorld, ship.core.getX(), ship.core.getZ());
@ -516,11 +543,13 @@ public class JumpSequencer extends AbstractSequencer {
}
// Check mass constrains
if ( CelestialObjectManager.isPlanet(sourceWorld, ship.core.getX(), ship.core.getZ())
if ( ( sourceWorld != null
&& CelestialObjectManager.isPlanet(sourceWorld, ship.core.getX(), ship.core.getZ()) )
|| CelestialObjectManager.isPlanet(targetWorld, ship.core.getX() + moveX, ship.core.getZ() + moveZ) ) {
if (!ship.isUnlimited() && ship.actualMass > WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE) {
LocalProfiler.stop();
ITextComponent message = new TextComponentString("Ship is too big for a planet (max is " + WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE + " blocks)");
final ITextComponent message = new TextComponentString(String.format("Ship is too big for a planet (max is %d blocks while ship is %d blocks)",
WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE, ship.actualMass));
ship.messageToAllPlayersOnShip(message);
disable(message);
return;
@ -532,16 +561,23 @@ public class JumpSequencer extends AbstractSequencer {
}
// Calculate jump vector
Boolean isPluginCheckDone = false;
boolean isPluginCheckDone = false;
String firstAdjustmentReason = "";
switch (shipMovementType) {
case GATE_ACTIVATING:
case CREATIVE:
moveX = destX - ship.core.getX();
moveY = destY - ship.core.getY();
moveZ = destZ - ship.core.getZ();
break;
case INSTANTIATE:
case RESTORE:
moveX = destX - ship.core.getX();
moveY = destY - ship.core.getY();
moveZ = destZ - ship.core.getZ();
isPluginCheckDone = true;
break;
case PLANET_TAKEOFF:
// enter space at current altitude
moveY = 0;
@ -587,15 +623,18 @@ public class JumpSequencer extends AbstractSequencer {
}
{
BlockPos target1 = transformation.apply(ship.minX, ship.minY, ship.minZ);
BlockPos target2 = transformation.apply(ship.maxX, ship.maxY, ship.maxZ);
AxisAlignedBB aabbSource = new AxisAlignedBB(ship.minX, ship.minY, ship.minZ, ship.maxX, ship.maxY, ship.maxZ);
final BlockPos target1 = transformation.apply(ship.minX, ship.minY, ship.minZ);
final BlockPos target2 = transformation.apply(ship.maxX, ship.maxY, ship.maxZ);
final AxisAlignedBB aabbSource = new AxisAlignedBB(ship.minX, ship.minY, ship.minZ, ship.maxX, ship.maxY, ship.maxZ);
aabbSource.expand(1.0D, 1.0D, 1.0D);
AxisAlignedBB aabbTarget = new AxisAlignedBB(
final AxisAlignedBB aabbTarget = new AxisAlignedBB(
Math.min(target1.getX(), target2.getX()), Math.min(target1.getY(), target2.getY()), Math.min(target1.getZ(), target2.getZ()),
Math.max(target1.getX(), target2.getX()), Math.max(target1.getY(), target2.getY()), Math.max(target1.getZ(), target2.getZ()));
// Validate positions aren't overlapping
if (!betweenWorlds && aabbSource.intersectsWith(aabbTarget)) {
if ( shipMovementType != EnumShipMovementType.INSTANTIATE
&& shipMovementType != EnumShipMovementType.RESTORE
&& !betweenWorlds
&& aabbSource.intersectsWith(aabbTarget) ) {
// render fake explosions
doCollisionDamage(false);
@ -616,7 +655,7 @@ public class JumpSequencer extends AbstractSequencer {
if (celestialObjectTarget == null) {
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.error(String.format("There's no world border defined for dimension %s (%d)",
targetWorld.provider.getDimensionType().getName(), targetWorld.provider.getDimension()));
targetWorld.provider.getSaveFolder(), targetWorld.provider.getDimension()));
}
} else {
@ -636,7 +675,7 @@ public class JumpSequencer extends AbstractSequencer {
}
}
if (!isPluginCheckDone) {
CheckMovementResult checkMovementResult = checkCollisionAndProtection(transformation, true, "target");
final CheckMovementResult checkMovementResult = checkCollisionAndProtection(transformation, true, "target");
if (checkMovementResult != null) {
String msg = checkMovementResult.reason + "\nJump aborted!";
disableAndMessage(msg);
@ -646,17 +685,23 @@ public class JumpSequencer extends AbstractSequencer {
}
if (!forceTargetChunks(reason)) {
disableAndMessage(reason.toString());
final ITextComponent msg = new TextComponentString(reason.toString());
disable(msg);
ship.messageToAllPlayersOnShip(msg);
LocalProfiler.stop();
return;
}
{
String msg = ship.saveEntities();
if (msg != null) {
disableAndMessage(msg);
LocalProfiler.stop();
return;
if ( shipMovementType != EnumShipMovementType.INSTANTIATE
&& shipMovementType != EnumShipMovementType.RESTORE ) {
if (!ship.saveEntities(reason)) {
final ITextComponent msg = new TextComponentString(reason.toString());
disable(msg);
ship.messageToAllPlayersOnShip(msg);
LocalProfiler.stop();
return;
}
}
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Saved " + ship.entitiesOnShip.size() + " entities from ship");
@ -667,17 +712,26 @@ public class JumpSequencer extends AbstractSequencer {
case HYPERSPACE_ENTERING:
ship.messageToAllPlayersOnShip(new TextComponentString("Entering hyperspace..."));
break;
case HYPERSPACE_EXITING:
ship.messageToAllPlayersOnShip(new TextComponentString("Leaving hyperspace.."));
break;
case GATE_ACTIVATING:
ship.messageToAllPlayersOnShip(new TextComponentString(String.format("Engaging jumpgate towards %s!",
nameTarget)));
break;
// case GATE_ACTIVATING:
// ship.messageToAllPlayersOnShip(new TextComponentString(String.format("Jumping to coordinates (%d %d %d)!",
// destX, destY, destZ)));
// break;
case INSTANTIATE:
case RESTORE:
// no messages in creative
break;
default:
ship.messageToAllPlayersOnShip(new TextComponentString(String.format("Jumping of %d blocks (XYZ %d %d %d)",
(int) Math.ceil(Math.sqrt(moveX * moveX + moveY * moveY + moveZ * moveZ)),
@ -685,7 +739,9 @@ public class JumpSequencer extends AbstractSequencer {
break;
}
switch (rotationSteps) {
if ( shipMovementType != EnumShipMovementType.INSTANTIATE
&& shipMovementType != EnumShipMovementType.RESTORE ) {
switch (rotationSteps) {
case 1:
ship.messageToAllPlayersOnShip(new TextComponentString("Turning to the right"));
break;
@ -697,6 +753,7 @@ public class JumpSequencer extends AbstractSequencer {
break;
default:
break;
}
}
LocalProfiler.stop();
@ -706,14 +763,19 @@ public class JumpSequencer extends AbstractSequencer {
}
}
private boolean computeTargetWorld(final CelestialObject celestialObjectSource, final EnumShipMovementType shipMovementType, final StringBuilder reason) {
protected boolean computeTargetWorld(final CelestialObject celestialObjectSource, final EnumShipMovementType shipMovementType, final StringBuilder reason) {
switch (shipMovementType) {
case INSTANTIATE:
case RESTORE:
// already defined, nothing to do
break;
case HYPERSPACE_EXITING: {
CelestialObject celestialObject = CelestialObjectManager.getClosestChild(sourceWorld, ship.core.getX(), ship.core.getZ());
// anything defined?
if (celestialObject == null) {
reason.append(String.format("Unable to reach space from this location!\nThere's no celestial object defined for current dimension %s (%d).",
sourceWorld.provider.getDimensionType().getName(), sourceWorld.provider.getDimension()));
sourceWorld.provider.getSaveFolder(), sourceWorld.provider.getDimension()));
return false;
}
@ -754,7 +816,7 @@ public class JumpSequencer extends AbstractSequencer {
// anything defined?
if (celestialObjectSource.parent == null) {
reason.append(String.format("Unable to reach hyperspace!\nThere's no parent defined for current dimension %s (%d).",
sourceWorld.provider.getDimensionType().getName(), sourceWorld.provider.getDimension()));
sourceWorld.provider.getSaveFolder(), sourceWorld.provider.getDimension()));
return false;
}
// (target world border is checked systematically after movement checks)
@ -783,7 +845,7 @@ public class JumpSequencer extends AbstractSequencer {
// anything defined?
if (celestialObjectSource.parent == null) {
reason.append(String.format("Unable to take off!\nThere's no parent defined for current dimension %s (%d).",
sourceWorld.provider.getDimensionType().getName(), sourceWorld.provider.getDimension()));
sourceWorld.provider.getSaveFolder(), sourceWorld.provider.getDimension()));
return false;
}
@ -841,6 +903,13 @@ public class JumpSequencer extends AbstractSequencer {
return false;
}
// is it defined?
if (celestialObject.isVirtual()) {
reason.append(String.format("Sorry, we can't go to %s. This is a virtual celestial object. It's either a decorative planet or a server misconfiguration",
celestialObject.getDisplayName()));
return false;
}
// validate world availability
final MinecraftServer server = sourceWorld.getMinecraftServer();
assert(server != null);
@ -876,26 +945,42 @@ public class JumpSequencer extends AbstractSequencer {
return true;
}
private void state_moveBlocks() {
protected void state_moveBlocks() {
LocalProfiler.start("Jump.moveBlocks");
int blocksToMove = Math.min(WarpDriveConfig.G_BLOCKS_PER_TICK, ship.jumpBlocks.length - actualIndexInShip);
if (WarpDriveConfig.LOGGING_JUMP) {
final int blocksToMove = Math.min(blocksPerTick, ship.jumpBlocks.length - actualIndexInShip);
final int periodEffect = Math.max(1, blocksToMove / 10);
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
WarpDrive.logger.info(this + " Moving ship blocks " + actualIndexInShip + " to " + (actualIndexInShip + blocksToMove - 1) + " / " + (ship.jumpBlocks.length - 1));
}
int indexEffect = targetWorld.rand.nextInt(periodEffect);
for (int index = 0; index < blocksToMove; index++) {
if (actualIndexInShip >= ship.jumpBlocks.length) {
break;
}
JumpBlock jumpBlock = ship.jumpBlocks[actualIndexInShip];
final JumpBlock jumpBlock = ship.jumpBlocks[actualIndexInShip];
if (jumpBlock != null) {
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
WarpDrive.logger.info("Deploying from " + jumpBlock.x + " " + jumpBlock.y + " " + jumpBlock.z + " of " + jumpBlock.block + "@" + jumpBlock.blockMeta);
}
jumpBlock.deploy(targetWorld, transformation);
if (shipMovementType == EnumShipMovementType.INSTANTIATE) {
jumpBlock.removeUniqueIDs();
jumpBlock.fillEnergyStorage();
}
sourceWorld.removeTileEntity(new BlockPos(jumpBlock.x, jumpBlock.y, jumpBlock.z));
final BlockPos target = jumpBlock.deploy(targetWorld, transformation);
if ( shipMovementType != EnumShipMovementType.INSTANTIATE
&& shipMovementType != EnumShipMovementType.RESTORE ) {
sourceWorld.removeTileEntity(new BlockPos(jumpBlock.x, jumpBlock.y, jumpBlock.z));
}
indexEffect--;
if (indexEffect <= 0) {
indexEffect = periodEffect;
doBlockEffect(jumpBlock, target);
}
}
actualIndexInShip++;
}
@ -903,9 +988,71 @@ public class JumpSequencer extends AbstractSequencer {
LocalProfiler.stop();
}
private void state_moveExternals() {
protected void doBlockEffect(final JumpBlock jumpBlock, final BlockPos target) {
switch (shipMovementType) {
case HYPERSPACE_ENTERING:
case PLANET_TAKEOFF:
PacketHandler.sendBeamPacket(sourceWorld,
new Vector3(jumpBlock.x + 0.5D, jumpBlock.y + 0.5D, jumpBlock.z + 0.5D),
new Vector3(target.getX() + 0.5D, target.getY() + 32.5D + targetWorld.rand.nextInt(5), target.getZ() + 0.5D),
0.5F, 0.7F, 0.2F, 30, 0, 100);
PacketHandler.sendBeamPacket(targetWorld,
new Vector3(target.getX() + 0.5D, target.getY() - 31.5D - targetWorld.rand.nextInt(5), target.getZ() + 0.5D),
new Vector3(target.getX() + 0.5D, target.getY() + 0.5D, target.getZ() + 0.5D),
0.5F, 0.7F, 0.2F, 30, 0, 100);
break;
case HYPERSPACE_EXITING:
case PLANET_LANDING:
PacketHandler.sendBeamPacket(sourceWorld,
new Vector3(jumpBlock.x + 0.5D, jumpBlock.y + 0.5D, jumpBlock.z + 0.5D),
new Vector3(target.getX() + 0.5D, target.getY() - 31.5D - targetWorld.rand.nextInt(5), target.getZ() + 0.5D),
0.7F, 0.1F, 0.6F, 30, 0, 100);
PacketHandler.sendBeamPacket(targetWorld,
new Vector3(target.getX() + 0.5D, target.getY() + 32.5D + targetWorld.rand.nextInt(5), target.getZ() + 0.5D),
new Vector3(target.getX() + 0.5D, target.getY() + 0.5D, target.getZ() + 0.5D),
0.7F, 0.1F, 0.6F, 30, 0, 100);
break;
case HYPERSPACE_MOVING:
case PLANET_MOVING:
case SPACE_MOVING:
PacketHandler.sendBeamPacket(targetWorld,
new Vector3(jumpBlock.x + 0.5D, jumpBlock.y + 0.5D, jumpBlock.z + 0.5D),
new Vector3(target.getX() + 0.5D, target.getY() + 0.5D, target.getZ() + 0.5D),
0.6F, 0.1F, 0.7F, 30, 0, 100);
break;
case GATE_ACTIVATING:
break;
case INSTANTIATE:
case RESTORE:
if (v3Source != null) {
// play the builder effect
targetWorld.playSound(null, target, SoundEvents.LASER_LOW, SoundCategory.BLOCKS, 0.5F, 1.0F);
PacketHandler.sendBeamPacket(targetWorld,
v3Source,
new Vector3(target.getX() + 0.5D, target.getY() + 0.5D, target.getZ() + 0.5D),
0.0F, 1.0F, 0.0F, 15, 0, 100);
}
// play the placement sound effect
final SoundType soundtype = jumpBlock.block.getSoundType(targetWorld.getBlockState(target), targetWorld, target, null);
targetWorld.playSound(null, target, soundtype.getPlaceSound(), SoundCategory.BLOCKS,
(soundtype.getVolume() + 1.0F) / 2.0F,
soundtype.getPitch() * 0.8F);
break;
case NONE:
break;
}
}
protected void state_moveExternals() {
LocalProfiler.start("Jump.moveExternals");
int blocksToMove = Math.min(WarpDriveConfig.G_BLOCKS_PER_TICK, ship.jumpBlocks.length - actualIndexInShip);
int blocksToMove = Math.min(blocksPerTick, ship.jumpBlocks.length - actualIndexInShip);
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Moving ship externals from " + actualIndexInShip + " / " + (ship.jumpBlocks.length - 1));
}
@ -927,8 +1074,11 @@ public class JumpSequencer extends AbstractSequencer {
for (Entry<String, NBTBase> external : jumpBlock.externals.entrySet()) {
final IBlockTransformer blockTransformer = WarpDriveConfig.blockTransformers.get(external.getKey());
if (blockTransformer != null) {
blockTransformer.removeExternals(sourceWorld, jumpBlock.x, jumpBlock.y, jumpBlock.z,
jumpBlock.block, jumpBlock.blockMeta, jumpBlock.blockTileEntity);
if ( shipMovementType != EnumShipMovementType.INSTANTIATE
&& shipMovementType != EnumShipMovementType.RESTORE ) {
blockTransformer.removeExternals(sourceWorld, jumpBlock.x, jumpBlock.y, jumpBlock.z,
jumpBlock.block, jumpBlock.blockMeta, jumpBlock.blockTileEntity);
}
final BlockPos target = transformation.apply(jumpBlock.x, jumpBlock.y, jumpBlock.z);
final TileEntity newTileEntity = jumpBlock.blockTileEntity == null ? null : targetWorld.getTileEntity(target);
@ -943,27 +1093,27 @@ public class JumpSequencer extends AbstractSequencer {
LocalProfiler.stop();
}
private void state_moveEntities() {
protected void state_moveEntities() {
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Moving entities");
}
LocalProfiler.start("Jump.moveEntities");
if (ship.entitiesOnShip != null) {
for (MovingEntity me : ship.entitiesOnShip) {
Entity entity = me.entity;
if ( shipMovementType != EnumShipMovementType.INSTANTIATE
&& shipMovementType != EnumShipMovementType.RESTORE ) {
for (MovingEntity movingEntity : ship.entitiesOnShip) {
final Entity entity = movingEntity.getEntity();
if (entity == null) {
continue;
}
double oldEntityX = me.oldX;
double oldEntityY = me.oldY;
double oldEntityZ = me.oldZ;
final double oldEntityX = movingEntity.originalX;
final double oldEntityY = movingEntity.originalY;
final double oldEntityZ = movingEntity.originalZ;
Vec3d target = transformation.apply(oldEntityX, oldEntityY, oldEntityZ);
double newEntityX = target.xCoord;
double newEntityY = target.yCoord;
double newEntityZ = target.zCoord;
final double newEntityX = target.xCoord;
final double newEntityY = target.yCoord;
final double newEntityZ = target.zCoord;
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(String.format("Entity moving: (%.2f %.2f %.2f) -> (%.2f %.2f %.2f) entity %s",
@ -1014,9 +1164,9 @@ public class JumpSequencer extends AbstractSequencer {
LocalProfiler.stop();
}
private void state_removeBlocks() {
protected void state_removeBlocks() {
LocalProfiler.start("Jump.removeBlocks");
int blocksToMove = Math.min(WarpDriveConfig.G_BLOCKS_PER_TICK, ship.jumpBlocks.length - actualIndexInShip);
int blocksToMove = Math.min(blocksPerTick, ship.jumpBlocks.length - actualIndexInShip);
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Removing ship blocks " + actualIndexInShip + " to " + (actualIndexInShip + blocksToMove - 1) + " / " + (ship.jumpBlocks.length - 1));
}
@ -1024,7 +1174,7 @@ public class JumpSequencer extends AbstractSequencer {
if (actualIndexInShip >= ship.jumpBlocks.length) {
break;
}
JumpBlock jumpBlock = ship.jumpBlocks[ship.jumpBlocks.length - actualIndexInShip - 1];
final JumpBlock jumpBlock = ship.jumpBlocks[ship.jumpBlocks.length - actualIndexInShip - 1];
if (jumpBlock == null) {
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info(this + " Removing ship part: unexpected null found at ship[" + actualIndexInShip + "]");
@ -1036,22 +1186,24 @@ public class JumpSequencer extends AbstractSequencer {
WarpDrive.logger.info("Removing block " + jumpBlock.block + "@" + jumpBlock.blockMeta + " at " + jumpBlock.x + " " + jumpBlock.y + " " + jumpBlock.z);
}
if (jumpBlock.blockTileEntity != null) {
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
WarpDrive.logger.info("Removing tile entity at " + jumpBlock.x + " " + jumpBlock.y + " " + jumpBlock.z);
if (sourceWorld != null) {
if (jumpBlock.blockTileEntity != null) {
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
WarpDrive.logger.info("Removing tile entity at " + jumpBlock.x + " " + jumpBlock.y + " " + jumpBlock.z);
}
sourceWorld.removeTileEntity(new BlockPos(jumpBlock.x, jumpBlock.y, jumpBlock.z));
}
sourceWorld.removeTileEntity(new BlockPos(jumpBlock.x, jumpBlock.y, jumpBlock.z));
}
try {
JumpBlock.setBlockNoLight(sourceWorld, new BlockPos(jumpBlock.x, jumpBlock.y, jumpBlock.z), Blocks.AIR.getDefaultState(), 2);
} catch (Exception exception) {
WarpDrive.logger.info("Exception while removing " + jumpBlock.block + "@" + jumpBlock.blockMeta + " at " + jumpBlock.x + " " + jumpBlock.y + " " + jumpBlock.z);
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
exception.printStackTrace();
try {
JumpBlock.setBlockNoLight(sourceWorld, new BlockPos(jumpBlock.x, jumpBlock.y, jumpBlock.z), Blocks.AIR.getDefaultState(), 2);
} catch (Exception exception) {
WarpDrive.logger.info("Exception while removing " + jumpBlock.block + "@" + jumpBlock.blockMeta + " at " + jumpBlock.x + " " + jumpBlock.y + " " + jumpBlock.z);
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
exception.printStackTrace();
}
}
}
BlockPos target = transformation.apply(jumpBlock.x, jumpBlock.y, jumpBlock.z);
final BlockPos target = transformation.apply(jumpBlock.x, jumpBlock.y, jumpBlock.z);
JumpBlock.refreshBlockStateOnClient(targetWorld, target);
actualIndexInShip++;
@ -1059,10 +1211,10 @@ public class JumpSequencer extends AbstractSequencer {
LocalProfiler.stop();
}
private void state_chunkUnloading() {
LocalProfiler.start("Jump.chunkUnloading");
protected void state_chunkReleasing() {
LocalProfiler.start("Jump.chunkReleasing");
unforceChunks();
releaseChunks();
LocalProfiler.stop();
}
@ -1071,7 +1223,7 @@ public class JumpSequencer extends AbstractSequencer {
* Finishing jump: cleanup, collision effects and delete self
**/
@SuppressWarnings("unchecked")
private void state_finishing() {
protected void state_finishing() {
LocalProfiler.start("Jump.finishing()");
// FIXME TileEntity duplication workaround
if (WarpDriveConfig.LOGGING_JUMP) {
@ -1089,6 +1241,8 @@ public class JumpSequencer extends AbstractSequencer {
}
}
doCollisionDamage(true);
disable(new TextComponentString("Jump done"));
@ -1238,25 +1392,26 @@ public class JumpSequencer extends AbstractSequencer {
}
LocalProfiler.start("Jump.restoreEntitiesPosition");
if (ship.entitiesOnShip != null) {
if ( shipMovementType != EnumShipMovementType.INSTANTIATE
&& shipMovementType != EnumShipMovementType.RESTORE ) {
for (MovingEntity movingEntity : ship.entitiesOnShip) {
Entity entity = movingEntity.entity;
final Entity entity = movingEntity.getEntity();
if (entity == null) {
continue;
}
if (WarpDriveConfig.LOGGING_JUMP) {
WarpDrive.logger.info("Entity restoring position at (" + movingEntity.oldX + " " + movingEntity.oldY + " " + movingEntity.oldZ + ")");
WarpDrive.logger.info(String.format("Entity restoring position at (%f %f %f)",
movingEntity.originalX, movingEntity.originalY, movingEntity.originalZ));
}
// Update position
if (entity instanceof EntityPlayerMP) {
EntityPlayerMP player = (EntityPlayerMP) entity;
final EntityPlayerMP player = (EntityPlayerMP) entity;
player.setPositionAndUpdate(movingEntity.oldX, movingEntity.oldY, movingEntity.oldZ);
player.setPositionAndUpdate(movingEntity.originalX, movingEntity.originalY, movingEntity.originalZ);
} else {
entity.setPosition(movingEntity.oldX, movingEntity.oldY, movingEntity.oldZ);
entity.setPosition(movingEntity.originalX, movingEntity.originalY, movingEntity.originalZ);
}
}
}
@ -1267,8 +1422,8 @@ public class JumpSequencer extends AbstractSequencer {
private class CheckMovementResult {
final ArrayList<Vector3> atSource;
final ArrayList<Vector3> atTarget;
boolean isCollision = false;
public String reason = "";
boolean isCollision;
public String reason;
CheckMovementResult() {
atSource = new ArrayList<>(1);
@ -1430,7 +1585,7 @@ public class JumpSequencer extends AbstractSequencer {
@Override
public String toString() {
return String.format("%s/%d \'%s\' @ \'%s\' (%d %d %d) #%d",
return String.format("%s/%d \'%s\' @ %s (%d %d %d) #%d",
getClass().getSimpleName(), hashCode(),
(ship == null || ship.shipCore == null) ? "~NULL~" : (ship.shipCore.uuid + ":" + ship.shipCore.shipName),
sourceWorld == null ? "~NULL~" : sourceWorld.getWorldInfo().getWorldName(),

View file

@ -20,6 +20,7 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.DamageSource;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.util.math.BlockPos;
@ -163,9 +164,26 @@ public class LivingHandler {
// are we actually in orbit?
if ( celestialObjectChild != null
&& !celestialObject.isHyperspace()
&& celestialObjectChild.getSquareDistanceInParent(entityLivingBase.worldObj.provider.getDimension(), x, z) <= 0.0D ) {
&& celestialObjectChild.isInOrbit(entityLivingBase.worldObj.provider.getDimension(), x, z) ) {
WorldServer worldTarget = DimensionManager.getWorld(celestialObjectChild.dimensionId);
if (worldTarget == null) {
try {
final MinecraftServer server = entityLivingBase.worldObj.getMinecraftServer();
worldTarget = server.worldServerForDimension(celestialObjectChild.dimensionId);
} catch (Exception exception) {
WarpDrive.logger.error(String.format("%s: Failed to initialize dimension %d for %s",
exception.getMessage(),
celestialObjectChild.dimensionId,
entityLivingBase));
if (WarpDrive.isDev) {
exception.printStackTrace();
}
worldTarget = null;
}
}
final WorldServer worldTarget = DimensionManager.getWorld(celestialObjectChild.dimensionId);
if (worldTarget != null) {
final VectorI vEntry = celestialObjectChild.getEntryOffset();
final int xTarget = x + vEntry.x;

View file

@ -3,7 +3,9 @@ package cr0s.warpdrive.item;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IItemBase;
import cr0s.warpdrive.client.ClientProxy;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.registry.GameRegistry;
@ -21,6 +23,10 @@ public class ItemAbstractBase extends Item implements IItemBase {
GameRegistry.register(this);
}
@Override
public void onEntityExpireEvent(final EntityItem entityItem, final ItemStack itemStack) {
}
@Override
@Nonnull
@SideOnly(Side.CLIENT)

View file

@ -6,16 +6,19 @@ import cr0s.warpdrive.api.IParticleContainerItem;
import cr0s.warpdrive.api.Particle;
import cr0s.warpdrive.api.ParticleRegistry;
import cr0s.warpdrive.api.ParticleStack;
import cr0s.warpdrive.data.Vector3;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraft.util.text.TextComponentTranslation;
public class ItemElectromagneticCell extends ItemAbstractBase implements IParticleContainerItem {
@ -129,7 +132,7 @@ public class ItemElectromagneticCell extends ItemAbstractBase implements IPartic
}
private static int getDamageLevel(ItemStack itemStack, final ParticleStack particleStack) {
if (!(itemStack.getItem() instanceof ItemElectromagneticCell)) {
if (!(itemStack.getItem() instanceof ItemElectromagneticCell)) {
WarpDrive.logger.error("Invalid ItemStack passed, expecting ItemElectromagneticCell: " + itemStack);
return itemStack.getItemDamage();
}
@ -178,7 +181,7 @@ public class ItemElectromagneticCell extends ItemAbstractBase implements IPartic
} else if (!particleStack.isParticleEqual(resource) || particleStack.getAmount() >= getCapacity(itemStack)) {
return 0;
}
int transfer = Math.min(resource.getAmount(), getCapacity(itemStack) - particleStack.getAmount());
final int transfer = Math.min(resource.getAmount(), getCapacity(itemStack) - particleStack.getAmount());
if (doFill) {
particleStack.fill(transfer);
@ -194,7 +197,7 @@ public class ItemElectromagneticCell extends ItemAbstractBase implements IPartic
@Override
public ParticleStack drain(ItemStack itemStack, final ParticleStack resource, final boolean doDrain) {
ParticleStack particleStack = getParticleStack(itemStack);
final ParticleStack particleStack = getParticleStack(itemStack);
if (particleStack == null || particleStack.getParticle() == null) {
return null;
}
@ -205,7 +208,7 @@ public class ItemElectromagneticCell extends ItemAbstractBase implements IPartic
if (doDrain) {
particleStack.fill(-transfer);
NBTTagCompound tagCompound = itemStack.hasTagCompound() ? itemStack.getTagCompound() : new NBTTagCompound();
final NBTTagCompound tagCompound = itemStack.hasTagCompound() ? itemStack.getTagCompound() : new NBTTagCompound();
tagCompound.setTag("particle", particleStack.writeToNBT(new NBTTagCompound()));
if (!itemStack.hasTagCompound()) {
itemStack.setTagCompound(tagCompound);
@ -215,6 +218,32 @@ public class ItemElectromagneticCell extends ItemAbstractBase implements IPartic
return resource.copy(transfer);
}
@Override
public int getEntityLifespan(final ItemStack itemStack, final World world) {
final ParticleStack particleStack = getParticleStack(itemStack);
if ( particleStack == null
|| particleStack.isEmpty() ) {
return super.getEntityLifespan(itemStack, world);
}
final int lifespan = particleStack.getEntityLifespan();
if (lifespan < 0) {
return super.getEntityLifespan(itemStack, world);
}
// less content means more stable, so we scale lifespan with emptiness, up to doubling it
return (2 - particleStack.getAmount() / getCapacity(itemStack)) * lifespan;
}
@Override
public void onEntityExpireEvent(final EntityItem entityItem, final ItemStack itemStack) {
final ParticleStack particleStack = getParticleStack(itemStack);
if ( particleStack == null
|| particleStack.isEmpty() ) {
super.onEntityExpireEvent(entityItem, itemStack);
return;
}
particleStack.onWorldEffect(entityItem.worldObj, new Vector3(entityItem));
}
@Override
public void addInformation(ItemStack itemStack, EntityPlayer entityPlayer, List<String> list, boolean advancedItemTooltips) {
super.addInformation(itemStack, entityPlayer, list, advancedItemTooltips);

View file

@ -15,110 +15,131 @@ import net.minecraftforge.fml.common.Optional;
})
public class ItemIC2reactorLaserFocus extends ItemAbstractBase implements IReactorComponent {
private static final int MAX_HEAT = 3000;
private static final int[] xOffset = { -1, 0, 0, 1 };
private static final int[] yOffset = { 0, -1, 1, 0 };
public ItemIC2reactorLaserFocus(final String registryName) {
super(registryName);
setMaxDamage(MAX_HEAT);
setMaxDamage(WarpDriveConfig.IC2_REACTOR_MAX_HEAT_STORED);
setUnlocalizedName("warpdrive.energy.IC2reactorLaserFocus");
}
private static void damageComponent(ItemStack self, int damage) {
int currDamage = self.getItemDamage();
int nextDamage = Math.min(MAX_HEAT, Math.max(0, currDamage + damage));
self.setItemDamage(nextDamage);
public static int getCurrentHeat(final ItemStack itemStackFocus) {
return itemStackFocus.getItemDamage();
}
private static void balanceComponent(ItemStack self, ItemStack other) {
final int selfBalance = 4;
int otherDamage = other.getItemDamage();
int myDamage = self.getItemDamage();
int newOne = (otherDamage + (selfBalance - 1) * myDamage) / selfBalance;
int newTwo = otherDamage - (newOne - myDamage);
self.setItemDamage(newTwo);
other.setItemDamage(newOne);
public static int addHeat(final ItemStack itemStackFocus, final int heat) {
if (WarpDriveConfig.LOGGING_ENERGY) {
WarpDrive.logger.info(String.format("%s addHeat(heat %d)",
itemStackFocus, heat));
}
final int heatCurrent = getCurrentHeat(itemStackFocus);
final int heatToTransfer = Math.min(heat, WarpDriveConfig.IC2_REACTOR_MAX_HEAT_STORED - heatCurrent);
setHeat(itemStackFocus, heatCurrent + heatToTransfer);
return heat - heatToTransfer;
}
@Optional.Method(modid = "IC2")
private static void coolComponent(ItemStack self, IReactorComponent comp, IReactor reactor, ItemStack stack, int x, int y) {
int maxTransfer = MAX_HEAT - self.getItemDamage();
int compHeat = comp.getCurrentHeat(stack, reactor, x, y);
int transferHeat = -Math.min(compHeat, maxTransfer);
int retained = comp.alterHeat(stack, reactor, x, y, transferHeat);
damageComponent(self, retained - transferHeat);
private static void setHeat(final ItemStack itemStackFocus, final int heat) {
itemStackFocus.setItemDamage(heat);
}
@Optional.Method(modid = "IC2")
private static void coolReactor(IReactor reactor, ItemStack stack) {
int reactorHeat = reactor.getHeat();
int myHeat = stack.getItemDamage();
int transfer = Math.min(MAX_HEAT - myHeat, reactorHeat);
reactor.addHeat(-transfer);
damageComponent(stack, transfer);
}
@Override
@Optional.Method(modid = "IC2")
public void processChamber(ItemStack yourStack, IReactor reactor, int x, int y, boolean heatrun) {
if (heatrun) {
int[] xDif = { -1, 0, 0, 1 };
int[] yDif = { 0, -1, 1, 0 };
for (int i = 0; i < xDif.length; i++) {
int iX = x + xDif[i];
int iY = y + yDif[i];
ItemStack stack = reactor.getItemAt(iX, iY);
if (stack != null) {
Item item = stack.getItem();
if (item instanceof ItemIC2reactorLaserFocus) {
balanceComponent(yourStack, stack);
} else if (item instanceof IReactorComponent) {
coolComponent(yourStack, (IReactorComponent) item, reactor, stack, iX, iY);
}
}
}
coolReactor(reactor, yourStack);
private static void balanceComponent(final ItemStack itemStackFocus1, final ItemStack itemStackFocus2) {
final int heatOld1 = getCurrentHeat(itemStackFocus1);
final int heatOld2 = getCurrentHeat(itemStackFocus2);
// force unidirectional transfer so we only transfer once per simulation tick
if (heatOld1 < heatOld2) {
final int heatToTransfer = Math.min((heatOld2 - heatOld1) / 2, WarpDriveConfig.IC2_REACTOR_FOCUS_HEAT_TRANSFER_PER_TICK);
final int heatNew1 = Math.min(WarpDriveConfig.IC2_REACTOR_MAX_HEAT_STORED, heatOld1 + heatToTransfer);
final int heatNew2 = heatOld2 - (heatNew1 - heatOld1);
setHeat(itemStackFocus1, heatNew1);
setHeat(itemStackFocus2, heatNew2);
}
}
@Optional.Method(modid = "IC2")
private static void coolComponent(final ItemStack itemStackFocus, final IReactorComponent reactorComponent,
final IReactor reactor, final ItemStack itemStackComponent, final int x, final int y) {
final int heatMaxRate = Math.min(WarpDriveConfig.IC2_REACTOR_COMPONENT_HEAT_TRANSFER_PER_TICK,
WarpDriveConfig.IC2_REACTOR_MAX_HEAT_STORED - itemStackFocus.getItemDamage());
final int heatComponent = reactorComponent.getCurrentHeat(itemStackComponent, reactor, x, y);
final int heatToTransfer = -Math.min(heatComponent, heatMaxRate);
final int heatRetained = reactorComponent.alterHeat(itemStackComponent, reactor, x, y, heatToTransfer);
addHeat(itemStackFocus, heatRetained - heatToTransfer);
}
@Optional.Method(modid = "IC2")
private static void coolReactor(final IReactor reactor, final ItemStack self) {
final int heatMaxRate = Math.min(WarpDriveConfig.IC2_REACTOR_REACTOR_HEAT_TRANSFER_PER_TICK,
WarpDriveConfig.IC2_REACTOR_MAX_HEAT_STORED - self.getItemDamage());
final int heatReactor = reactor.getHeat();
final int heatToTransfer = Math.min(heatMaxRate, heatReactor);
reactor.addHeat(-heatToTransfer);
addHeat(self, heatToTransfer);
}
// IReactorComponent overrides
@Override
@Optional.Method(modid = "IC2")
public boolean acceptUraniumPulse(ItemStack yourStack, IReactor reactor, ItemStack pulsingStack, int youX, int youY, int pulseX, int pulseY, boolean heatrun) {
public void processChamber(final ItemStack itemStackFocus, final IReactor reactor, final int x, final int y, final boolean isRunning) {
if (!isRunning) {
return;
}
for (int index = 0; index < xOffset.length; index++) {
final int xComponent = x + xOffset[index];
final int yComponent = y + yOffset[index];
ItemStack stack = reactor.getItemAt(xComponent, yComponent);
if (stack != null) {
final Item item = stack.getItem();
if (item instanceof ItemIC2reactorLaserFocus) {
balanceComponent(itemStackFocus, stack);
} else if (item instanceof IReactorComponent) {
coolComponent(itemStackFocus, (IReactorComponent) item, reactor, stack, xComponent, yComponent);
}
}
}
coolReactor(reactor, itemStackFocus);
}
@Override
@Optional.Method(modid = "IC2")
public boolean acceptUraniumPulse(final ItemStack itemStackFocus, final IReactor reactor, final ItemStack pulsingStack,
final int xFocus, final int yFocus, final int xPulsing, final int yPulsing, final boolean isRunning) {
return false;
}
@Override
@Optional.Method(modid = "IC2")
public boolean canStoreHeat(ItemStack yourStack, IReactor reactor, int x, int y) {
public boolean canStoreHeat(final ItemStack itemStackFocus, final IReactor reactor, final int x, final int y) {
return true;
}
@Override
@Optional.Method(modid = "IC2")
public int getMaxHeat(ItemStack yourStack, IReactor reactor, int x, int y) {
return MAX_HEAT;
public int getMaxHeat(final ItemStack itemStackFocus, final IReactor reactor, final int x, final int y) {
return WarpDriveConfig.IC2_REACTOR_MAX_HEAT_STORED;
}
@Override
@Optional.Method(modid = "IC2")
public int getCurrentHeat(ItemStack yourStack, IReactor reactor, int x, int y) {
return yourStack.getItemDamage();
public int getCurrentHeat(final ItemStack itemStackFocus, final IReactor reactor, final int x, final int y) {
return getCurrentHeat(itemStackFocus);
}
@Override
@Optional.Method(modid = "IC2")
public int alterHeat(ItemStack yourStack, IReactor reactor, int x, int y, int heat) {
public int alterHeat(final ItemStack itemStackFocus, final IReactor reactor, final int x, final int y, final int heat) {
if (WarpDriveConfig.LOGGING_ENERGY) {
WarpDrive.logger.info(this + " alterHeat " + heat);
WarpDrive.logger.info(String.format("%s alterHeat(reactor %s, x %d, y %d, heat %d)",
itemStackFocus, reactor, x, y, heat));
}
int transferred = Math.min(heat, MAX_HEAT - yourStack.getItemDamage());
damageComponent(yourStack, transferred);
return heat - transferred;
return addHeat(itemStackFocus, heat);
}
@Override
@Optional.Method(modid = "IC2")
public float influenceExplosion(ItemStack yourStack, IReactor reactor) {
public float influenceExplosion(final ItemStack itemStack, final IReactor reactor) {
return 0;
}

View file

@ -1,5 +1,6 @@
package cr0s.warpdrive.network;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
@ -8,8 +9,10 @@ import io.netty.buffer.ByteBuf;
import java.nio.charset.StandardCharsets;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFirework;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraft.client.particle.*;
import net.minecraft.entity.Entity;
import net.minecraft.util.EnumParticleTypes;
@ -118,7 +121,7 @@ public class MessageSpawnParticle implements IMessage, IMessageHandler<MessageSp
Particle particle;
double noiseLevel = direction.getMagnitude() * 0.35D;
for (int i = 0; i < quantity; i++) {
for (int index = 0; index < quantity; index++) {
Vector3 directionRandomized = new Vector3(
direction.x + noiseLevel * (world.rand.nextFloat() - world.rand.nextFloat()),
direction.y + noiseLevel * (world.rand.nextFloat() - world.rand.nextFloat()),
@ -163,6 +166,27 @@ public class MessageSpawnParticle implements IMessage, IMessageHandler<MessageSp
particle = mc.effectRenderer.spawnEffectParticle(EnumParticleTypes.CLOUD.getParticleID(),
origin.x, origin.y, origin.z, directionRandomized.x, directionRandomized.y, directionRandomized.z);
break;
case "jammed":// jammed machine particle reusing vanilla angryVillager particle
// as of MC1.7.10, direction vector is ignored by upstream
final EnumFacing directionFacing = Commons.getHorizontalDirectionFromEntity(Minecraft.getMinecraft().thePlayer);
if (directionFacing.getFrontOffsetX() != 0) {
particle = mc.effectRenderer.spawnEffectParticle(EnumParticleTypes.VILLAGER_ANGRY.getParticleID(),
origin.x + 0.51D * directionFacing.getFrontOffsetX(),
origin.y - 0.50D + world.rand.nextDouble(),
origin.z - 0.50D + world.rand.nextDouble(),
directionRandomized.x, directionRandomized.y, directionRandomized.z);
} else {
particle = mc.effectRenderer.spawnEffectParticle(EnumParticleTypes.VILLAGER_ANGRY.getParticleID(),
origin.x - 0.50D + world.rand.nextDouble(),
origin.y - 0.50D + world.rand.nextDouble(),
origin.z + 0.51D * directionFacing.getFrontOffsetZ(),
directionRandomized.x, directionRandomized.y, directionRandomized.z);
}
assert(particle != null);
particle.multipleParticleScaleBy(0.5F + world.rand.nextFloat() * 1.5F);
particle.setParticleTextureIndex(81);
break;
}
if (particle == null) {

View file

@ -225,78 +225,4 @@ public class RenderCommons {
// close rendering
GL11.glPopMatrix();
}
/* @TODO camouflage rendering
public static boolean renderWorldBlockCamouflaged(final int x, final int y, final int z, final Block blockDefault, final RenderBlocks renderer, final int renderType, final Block blockCamouflage) {
return false;
if (renderType >= 0) {
try {
blockCamouflage.setBlockBoundsBasedOnState(renderer.blockAccess, x, y, z);
renderer.setRenderBoundsFromBlock(blockCamouflage);
switch (renderType) {
case 0 : renderer.renderStandardBlock(blockCamouflage, x, y, z); break;
case 1 : renderer.renderCrossedSquares(blockCamouflage, x, y, z); break;
case 2 : renderer.renderBlockTorch(blockCamouflage, x, y, z); break;
case 3 : renderer.renderBlockFire((BlockFire)blockCamouflage, x, y, z); break;
// case 4 : renderer.renderBlockLiquid(blockCamouflage, x, y, z); break; // not working due to material check of neighbours during computation
case 5 : renderer.renderBlockRedstoneWire(blockCamouflage, x, y, z); break;
case 6 : renderer.renderBlockCrops(blockCamouflage, x, y, z); break;
// case 7 : renderer.renderBlockDoor(blockCamouflage, x, y, z); break; // not working and doesn't make sense
case 9 : renderer.renderBlockMinecartTrack((BlockRailBase)blockCamouflage, x, y, z); break;
case 10 : renderer.renderBlockStairs((BlockStairs)blockCamouflage, x, y, z); break;
case 11 : renderer.renderBlockFence((BlockFence)blockCamouflage, x, y, z); break;
case 12 : renderer.renderBlockLever(blockCamouflage, x, y, z); break;
case 13 : renderer.renderBlockCactus(blockCamouflage, x, y, z); break;
case 14 : renderer.renderBlockBed(blockCamouflage, x, y, z); break;
case 15 : renderer.renderBlockRepeater((BlockRedstoneRepeater)blockCamouflage, x, y, z); break;
case 16 : renderer.renderPistonBase(blockCamouflage, x, y, z, false); break;
case 17 : renderer.renderPistonExtension(blockCamouflage, x, y, z, true); break;
case 18 : renderer.renderBlockPane((BlockPane)blockCamouflage, x, y, z); break;
// 19 is stem
case 20 : renderer.renderBlockVine(blockCamouflage, x, y, z); break;
case 21 : renderer.renderBlockFenceGate((BlockFenceGate)blockCamouflage, x, y, z); break;
// 22 is chest
case 23 : renderer.renderBlockLilyPad(blockCamouflage, x, y, z); break;
case 24 : renderer.renderBlockCauldron((BlockCauldron)blockCamouflage, x, y, z); break;
case 25 : renderer.renderBlockBrewingStand((BlockBrewingStand)blockCamouflage, x, y, z); break;
case 26 : renderer.renderBlockEndPortalFrame((BlockEndPortalFrame)blockCamouflage, x, y, z); break;
case 27 : renderer.renderBlockDragonEgg((BlockDragonEgg)blockCamouflage, x, y, z); break;
case 28 : renderer.renderBlockCocoa((BlockCocoa)blockCamouflage, x, y, z); break;
case 29 : renderer.renderBlockTripWireSource(blockCamouflage, x, y, z); break;
case 30 : renderer.renderBlockTripWire(blockCamouflage, x, y, z); break;
case 31 : renderer.renderBlockLog(blockCamouflage, x, y, z); break;
case 32 : renderer.renderBlockWall((BlockWall)blockCamouflage, x, y, z); break;
case 33 : renderer.renderBlockFlowerpot((BlockFlowerPot)blockCamouflage, x, y, z); break; // won't render content due to tileEntity access
case 34 : renderer.renderBlockBeacon((BlockBeacon)blockCamouflage, x, y, z); break;
case 35 : renderer.renderBlockAnvil((BlockAnvil)blockCamouflage, x, y, z); break;
case 36 : renderer.renderBlockRedstoneDiode((BlockRedstoneDiode)blockCamouflage, x, y, z); break;
case 37 : renderer.renderBlockRedstoneComparator((BlockRedstoneComparator)blockCamouflage, x, y, z); break;
case 38 : renderer.renderBlockHopper((BlockHopper)blockCamouflage, x, y, z); break;
case 39 : renderer.renderBlockQuartz(blockCamouflage, x, y, z); break;
// 40 is double plant
case 41 : renderer.renderBlockStainedGlassPane(blockCamouflage, x, y, z); break;
default:
// blacklist the faulty block
WarpDrive.logger.error("Disabling camouflage with block " + Block.blockRegistry.getNameForObject(blockCamouflage) + " due to invalid renderType " + renderType);
Dictionary.BLOCKS_NOCAMOUFLAGE.add(blockCamouflage);
return false;
}
} catch(Exception exception) {
exception.printStackTrace();
// blacklist the faulty block
WarpDrive.logger.error("Disabling camouflage block " + Block.blockRegistry.getNameForObject(blockCamouflage) + " due to previous exception");
Dictionary.BLOCKS_NOCAMOUFLAGE.add(blockCamouflage);
// render normal default block
renderer.renderStandardBlock(blockDefault, x, y, z);
// renderer.renderBlockAsItem(blockCamouflage, metaCamouflage, 1);
}
return true;
}
return renderer.renderStandardBlock(blockDefault, x, y, z);
}
/**/
}

View file

@ -0,0 +1,160 @@
package cr0s.warpdrive.world;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.data.CelestialObject;
import cr0s.warpdrive.data.CelestialObjectManager;
import cr0s.warpdrive.render.RenderBlank;
import cr0s.warpdrive.render.RenderSpaceSky;
import javax.annotation.Nonnull;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.WorldProvider;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public abstract class AbstractWorldProvider extends WorldProvider {
protected CelestialObject celestialObjectDimension = null;
protected boolean isRemote;
protected void updateCelestialObject() throws RuntimeException {
if (getDimension() == 0) {
throw new RuntimeException("Critical error: you can't use a WorldProvider before settings its dimension id!");
}
if (celestialObjectDimension == null) {
isRemote = FMLCommonHandler.instance().getEffectiveSide().isClient();
celestialObjectDimension = CelestialObjectManager.get(isRemote, getDimension(), 0, 0);
}
}
@Nonnull
@Override
public String getSaveFolder() {
updateCelestialObject();
if (celestialObjectDimension == null) {
throw new RuntimeException(String.format("Critical error: there's no celestial object defining %s dimension DIM%d, unable to proceed further",
isRemote ? "client" : "server", getDimension()));
}
return celestialObjectDimension.id;
}
/* @TODO MC1.10 dimension name
@Override
public String getDimensionName() {
updateCelestialObject();
if (celestialObjectDimension == null) {
if (isRemote) {
return String.format("DIM%d", getDimension());
} else {
throw new RuntimeException(String.format("Critical error: there's no celestial object defining %s dimension id %d, unable to proceed further",
"server", getDimension()));
}
}
return celestialObjectDimension.id;
}
/**/
@Override
public boolean canCoordinateBeSpawn(int x, int z) {
final BlockPos blockPos = worldObj.getTopSolidOrLiquidBlock(new BlockPos(x, 0, z));
return blockPos.getY() != 0;
}
/*
@Override
public BlockPos getEntrancePortalLocation() {
return null;
}
@Nonnull
@Override
public BlockPos getRandomizedSpawnPoint() {
BlockPos blockPos = new BlockPos(worldObj.getSpawnPoint());
// boolean isAdventure = worldObj.getWorldInfo().getGameType() == EnumGameType.ADVENTURE;
int spawnFuzz = 100;
int spawnFuzzHalf = spawnFuzz / 2;
{
blockPos = new BlockPos(
blockPos.getX() + worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf,
200,
blockPos.getZ() + worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf);
}
if (worldObj.isAirBlock(blockPos)) {
worldObj.setBlockState(blockPos, Blocks.STONE.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 1, 1, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 1, 2, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add(-1, 1, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add(-1, 2, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 1, 1), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 2, 1), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 1, -1), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 2, -1), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 3, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 0, 0), WarpDrive.blockAir.getStateFromMeta(15), 2);
worldObj.setBlockState(blockPos.add( 0, 1, 0), WarpDrive.blockAir.getStateFromMeta(15), 2);
}
return blockPos;
}
/**/
// shared for getFogColor(), getStarBrightness()
// @SideOnly(Side.CLIENT)
protected static CelestialObject celestialObject = null;
@SideOnly(Side.CLIENT)
@Nonnull
@Override
public Vec3d getSkyColor(@Nonnull Entity cameraEntity, float partialTicks) {
if (getCloudRenderer() == null) {
setCloudRenderer(RenderBlank.getInstance());
}
if (getSkyRenderer() == null) {
setSkyRenderer(RenderSpaceSky.getInstance());
}
celestialObject = cameraEntity.worldObj == null ? null : CelestialObjectManager.get(
cameraEntity.worldObj,
MathHelper.floor_double(cameraEntity.posX), MathHelper.floor_double(cameraEntity.posZ));
if (celestialObject == null) {
return new Vec3d(1.0D, 0.0D, 0.0D);
} else {
return new Vec3d(celestialObject.backgroundColor.red, celestialObject.backgroundColor.green, celestialObject.backgroundColor.blue);
}
}
@SideOnly(Side.CLIENT)
@Nonnull
@Override
public Vec3d getFogColor(float celestialAngle, float par2) {
final float factor = Commons.clamp(0.0F, 1.0F, MathHelper.cos(celestialAngle * (float) Math.PI * 2.0F) * 2.0F + 0.5F);
float red = celestialObject == null ? 0.0F : celestialObject.colorFog.red;
float green = celestialObject == null ? 0.0F : celestialObject.colorFog.green;
float blue = celestialObject == null ? 0.0F : celestialObject.colorFog.blue;
float factorRed = celestialObject == null ? 0.0F : celestialObject.factorFog.red;
float factorGreen = celestialObject == null ? 0.0F : celestialObject.factorFog.green;
float factorBlue = celestialObject == null ? 0.0F : celestialObject.factorFog.blue;
red *= factor * factorRed + (1.0F - factorRed );
green *= factor * factorGreen + (1.0F - factorGreen);
blue *= factor * factorBlue + (1.0F - factorBlue );
return new Vec3d(red, green, blue);
}
@SideOnly(Side.CLIENT)
@Override
public float getStarBrightness(float partialTicks) {
if (celestialObject == null) {
return 0.0F;
}
final float starBrightnessVanilla = super.getStarBrightness(partialTicks);
return celestialObject.baseStarBrightness + celestialObject.vanillaStarBrightness * starBrightnessVanilla;
}
}

View file

@ -1,22 +1,11 @@
package cr0s.warpdrive.world;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.client.ClientProxy;
import cr0s.warpdrive.data.CelestialObjectManager;
import cr0s.warpdrive.data.CelestialObject;
import cr0s.warpdrive.data.StarMapRegistry;
import cr0s.warpdrive.render.RenderBlank;
import cr0s.warpdrive.render.RenderSpaceSky;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.DimensionType;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeProviderSingle;
import net.minecraft.world.chunk.Chunk;
@ -26,33 +15,19 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
public class HyperSpaceWorldProvider extends WorldProvider {
private CelestialObject celestialObjectDimension = null;
public class HyperSpaceWorldProvider extends AbstractWorldProvider {
public HyperSpaceWorldProvider() {
biomeProvider = new BiomeProviderSingle(WarpDrive.spaceBiome);
hasNoSky = true;
}
@Override
public void setDimension(final int dimensionId) {
super.setDimension(dimensionId);
celestialObjectDimension = CelestialObjectManager.get(WarpDrive.proxy instanceof ClientProxy, dimensionId, 0, 0);
}
@Nonnull
@Override
public DimensionType getDimensionType() {
return WarpDrive.dimensionTypeHyperSpace;
}
// @Nonnull
@Override
public String getSaveFolder() {
return celestialObjectDimension == null ? "WarpDriveHyperSpace" + getDimension() : celestialObjectDimension.id;
}
@Override
public boolean canRespawnHere() {
return true;
@ -104,64 +79,6 @@ public class HyperSpaceWorldProvider extends WorldProvider {
}
}
// shared for getFogColor(), getStarBrightness()
// @SideOnly(Side.CLIENT)
private static CelestialObject celestialObject = null;
@Override
public boolean canCoordinateBeSpawn(int x, int z) {
final BlockPos blockPos = worldObj.getTopSolidOrLiquidBlock(new BlockPos(x, 0, z));
return blockPos.getY() != 0;
}
@Nonnull
@Override
public Vec3d getSkyColor(@Nonnull Entity cameraEntity, float partialTicks) {
if (getCloudRenderer() == null) {
setCloudRenderer(RenderBlank.getInstance());
}
if (getSkyRenderer() == null) {
setSkyRenderer(RenderSpaceSky.getInstance());
}
celestialObject = cameraEntity.worldObj == null ? null : CelestialObjectManager.get(
cameraEntity.worldObj,
MathHelper.floor_double(cameraEntity.posX), MathHelper.floor_double(cameraEntity.posZ));
if (celestialObject == null) {
return new Vec3d(1.0D, 0.0D, 0.0D);
} else {
return new Vec3d(celestialObject.backgroundColor.red, celestialObject.backgroundColor.green, celestialObject.backgroundColor.blue);
}
}
@Nonnull
@SideOnly(Side.CLIENT)
@Override
public Vec3d getFogColor(float celestialAngle, float par2) {
final float factor = Commons.clamp(0.0F, 1.0F, MathHelper.cos(celestialAngle * (float) Math.PI * 2.0F) * 2.0F + 0.5F);
float red = celestialObject == null ? 0.0F : celestialObject.colorFog.red;
float green = celestialObject == null ? 0.0F : celestialObject.colorFog.green;
float blue = celestialObject == null ? 0.0F : celestialObject.colorFog.blue;
float factorRed = celestialObject == null ? 0.0F : celestialObject.factorFog.red;
float factorGreen = celestialObject == null ? 0.0F : celestialObject.factorFog.green;
float factorBlue = celestialObject == null ? 0.0F : celestialObject.factorFog.blue;
red *= factor * factorRed + (1.0F - factorRed );
green *= factor * factorGreen + (1.0F - factorGreen);
blue *= factor * factorBlue + (1.0F - factorBlue );
return new Vec3d(red, green, blue);
}
@SideOnly(Side.CLIENT)
@Override
public float getStarBrightness(float partialTicks) {
if (celestialObject == null) {
return 0.0F;
}
final float starBrightnessVanilla = super.getStarBrightness(partialTicks);
return celestialObject.baseStarBrightness + celestialObject.vanillaStarBrightness * starBrightnessVanilla;
}
@SideOnly(Side.CLIENT)
@Override
public boolean isSkyColored() {
@ -188,38 +105,6 @@ public class HyperSpaceWorldProvider extends WorldProvider {
return false;
}
@Nonnull
@Override
public BlockPos getRandomizedSpawnPoint() {
BlockPos blockPos = new BlockPos(worldObj.getSpawnPoint());
// boolean isAdventure = worldObj.getWorldInfo().getGameType() == EnumGameType.ADVENTURE;
int spawnFuzz = 100;
int spawnFuzzHalf = spawnFuzz / 2;
{
blockPos = new BlockPos(
blockPos.getX() + worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf,
200,
blockPos.getZ() + worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf);
}
if (worldObj.isAirBlock(blockPos)) {
worldObj.setBlockState(blockPos, Blocks.STONE.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 1, 1, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 1, 2, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add(-1, 1, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add(-1, 2, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 1, 1), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 2, 1), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 1, -1), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 2, -1), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 3, 0), Blocks.GLASS.getDefaultState(), 2);
worldObj.setBlockState(blockPos.add( 0, 0, 0), WarpDrive.blockAir.getStateFromMeta(15), 2);
worldObj.setBlockState(blockPos.add( 0, 1, 0), WarpDrive.blockAir.getStateFromMeta(15), 2);
}
return blockPos;
}
@Override
public boolean isDaytime() {
return false;

View file

@ -1,23 +1,13 @@
package cr0s.warpdrive.world;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.client.ClientProxy;
import cr0s.warpdrive.data.CelestialObjectManager;
import cr0s.warpdrive.data.CelestialObject;
import cr0s.warpdrive.data.StarMapRegistry;
import cr0s.warpdrive.render.RenderBlank;
import cr0s.warpdrive.render.RenderSpaceSky;
import javax.annotation.Nonnull;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.DimensionType;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeProviderSingle;
import net.minecraft.world.chunk.Chunk;
@ -25,33 +15,19 @@ import net.minecraft.world.chunk.IChunkGenerator;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class SpaceWorldProvider extends WorldProvider {
private CelestialObject celestialObjectDimension = null;
public class SpaceWorldProvider extends AbstractWorldProvider {
public SpaceWorldProvider() {
biomeProvider = new BiomeProviderSingle(WarpDrive.spaceBiome);
hasNoSky = false;
}
@Override
public void setDimension(final int dimensionId) {
super.setDimension(dimensionId);
celestialObjectDimension = CelestialObjectManager.get(WarpDrive.proxy instanceof ClientProxy, dimensionId, 0, 0);
}
@Nonnull
@Override
public DimensionType getDimensionType() {
return WarpDrive.dimensionTypeSpace;
}
@Nonnull
@Override
public String getSaveFolder() {
return celestialObjectDimension == null ? "WarpDriveSpace" + getDimension() : celestialObjectDimension.id;
}
@Override
public boolean canRespawnHere() {
return true;
@ -95,7 +71,7 @@ public class SpaceWorldProvider extends WorldProvider {
@Override
protected void generateLightBrightnessTable() {
float f = 0.0F; // 0.1F
float f = 0.0F;
for (int i = 0; i <= 15; ++i) {
float f1 = 1.0F - i / 15.0F;
@ -103,65 +79,6 @@ public class SpaceWorldProvider extends WorldProvider {
}
}
@Override
public boolean canCoordinateBeSpawn(int x, int z) {
final BlockPos blockPos = worldObj.getTopSolidOrLiquidBlock(new BlockPos(x, 0, z));
return blockPos.getY() != 0;
}
// shared for getFogColor(), getStarBrightness()
// @SideOnly(Side.CLIENT)
private static CelestialObject celestialObject = null;
@SideOnly(Side.CLIENT)
@Nonnull
@Override
public Vec3d getSkyColor(@Nonnull Entity cameraEntity, float partialTicks) {
if (getCloudRenderer() == null) {
setCloudRenderer(RenderBlank.getInstance());
}
if (getSkyRenderer() == null) {
setSkyRenderer(RenderSpaceSky.getInstance());
}
celestialObject = cameraEntity.worldObj == null ? null : CelestialObjectManager.get(
cameraEntity.worldObj,
MathHelper.floor_double(cameraEntity.posX), MathHelper.floor_double(cameraEntity.posZ));
if (celestialObject == null) {
return new Vec3d(0.0D, 0.0D, 0.0D);
} else {
return new Vec3d(celestialObject.backgroundColor.red, celestialObject.backgroundColor.green, celestialObject.backgroundColor.blue);
}
}
@Nonnull
@SideOnly(Side.CLIENT)
@Override
public Vec3d getFogColor(float celestialAngle, float par2) {
final float factor = Commons.clamp(0.0F, 1.0F, MathHelper.cos(celestialAngle * (float) Math.PI * 2.0F) * 2.0F + 0.5F);
float red = celestialObject == null ? 0.0F : celestialObject.colorFog.red;
float green = celestialObject == null ? 0.0F : celestialObject.colorFog.green;
float blue = celestialObject == null ? 0.0F : celestialObject.colorFog.blue;
float factorRed = celestialObject == null ? 0.0F : celestialObject.factorFog.red;
float factorGreen = celestialObject == null ? 0.0F : celestialObject.factorFog.green;
float factorBlue = celestialObject == null ? 0.0F : celestialObject.factorFog.blue;
red *= factor * factorRed + (1.0F - factorRed );
green *= factor * factorGreen + (1.0F - factorGreen);
blue *= factor * factorBlue + (1.0F - factorBlue );
return new Vec3d(red, green, blue);
}
@SideOnly(Side.CLIENT)
@Override
public float getStarBrightness(float partialTicks) {
if (celestialObject == null) {
return 0.0F;
}
final float starBrightnessVanilla = super.getStarBrightness(partialTicks);
return celestialObject.baseStarBrightness + celestialObject.vanillaStarBrightness * starBrightnessVanilla;
}
@SideOnly(Side.CLIENT)
@Override
public boolean isSkyColored() {
@ -187,43 +104,7 @@ public class SpaceWorldProvider extends WorldProvider {
public boolean canBlockFreeze(@Nonnull BlockPos blockPos, boolean byWater) {
return false;
}
/*
@Override
public BlockPos getRandomizedSpawnPoint() {
BlockPos var5 = new BlockPos(worldObj.getSpawnPoint());
//boolean isAdventure = worldObj.getWorldInfo().getGameType() == EnumGameType.ADVENTURE;
int spawnFuzz = 1000;
int spawnFuzzHalf = spawnFuzz / 2;
{
var5.posX += worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf;
var5.posZ += worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf;
var5.posY = 200;
}
if (worldObj.isAirBlock(var5.posX, var5.posY, var5.posZ)) {
worldObj.setBlock(var5.posX, var5.posY, var5.posZ, Blocks.stone, 0, 2);
worldObj.setBlock(var5.posX + 1, var5.posY + 1, var5.posZ, Blocks.glass, 0, 2);
worldObj.setBlock(var5.posX + 1, var5.posY + 2, var5.posZ, Blocks.glass, 0, 2);
worldObj.setBlock(var5.posX - 1, var5.posY + 1, var5.posZ, Blocks.glass, 0, 2);
worldObj.setBlock(var5.posX - 1, var5.posY + 2, var5.posZ, Blocks.glass, 0, 2);
worldObj.setBlock(var5.posX, var5.posY + 1, var5.posZ + 1, Blocks.glass, 0, 2);
worldObj.setBlock(var5.posX, var5.posY + 2, var5.posZ + 1, Blocks.glass, 0, 2);
worldObj.setBlock(var5.posX, var5.posY + 1, var5.posZ - 1, Blocks.glass, 0, 2);
worldObj.setBlock(var5.posX, var5.posY + 3, var5.posZ - 1, Blocks.glass, 0, 2);
// worldObj.setBlockWithNotify(var5.posX, var5.posY + 3, var5.posZ, Block.glass.blockID);
}
return var5;
}
/**/
@Override
public boolean isDaytime() {
return true;

View file

@ -141,8 +141,10 @@ public class WorldGenStructure {
final GenericSet<Loot> lootSet = WarpDriveConfig.LootManager.getRandomSetFromGroup(rand, group);
if (lootSet == null) {
WarpDrive.logger.warn(String.format("No LootSet found with group %s for inventory @ DIM%d (%d %d %d): check your configuration",
group, worldObj.provider.getDimension(), x, y, z));
WarpDrive.logger.warn(String.format("No LootSet found with group %s for inventory @ %s (%d %d %d): check your configuration",
group,
worldObj.provider.getSaveFolder(),
x, y, z));
return;
}
@ -166,10 +168,11 @@ public class WorldGenStructure {
}
}
if (!isAdded) {
WarpDrive.logger.info(String.format("Unable to find a valid loot from LootSet %s for inventory %s in @ DIM%d (%d %d %d): check your configuration",
WarpDrive.logger.info(String.format("Unable to find a valid loot from LootSet %s for inventory %s in @ %s (%d %d %d): check your configuration",
lootSet.getFullName(),
inventory.hasCustomName() ? inventory.getName() : "-null name-",
worldObj.provider.getDimension(), x, y, z));
inventory.getName() == null ? "-null name-" : inventory.getName(),
worldObj.provider.getSaveFolder(),
x, y, z));
}
}
}

View file

@ -4,19 +4,19 @@ death.attack.warpdrive.asphyxia.player=%1$s因%2$s窒息
death.attack.warpdrive.cold=%1$s冻死了
death.attack.warpdrive.cold.player=%1$s被%2$s冻成了冰棍
death.attack.warpdrive.irradiation=%1$s受到过量辐照
death.attack.warpdrive.irradiation.player=%1$s被%2$s用辐照击杀
death.attack.warpdrive.irradiation.player=%2$s使用大剂量辐射照射了%1$s
death.attack.warpdrive.laser=激光击穿了%1$s
death.attack.warpdrive.laser.player=%2$s操纵激光焚化了%1$s
death.attack.warpdrive.shock=%1$s触电身亡
death.attack.warpdrive.shock.player=%1$s被%2$s电死
death.attack.warpdrive.teleportation=%1$s重组失败
death.attack.warpdrive.teleportation.player=%2$s利用传送整死了%1$s
death.attack.warpdrive.teleportation.player=%2$s传送%1$s时“失误”了
death.attack.warpdrive.warm=%1$s死于高温
death.attack.warpdrive.warm.player=%1$s被%2$s煮熟了
itemGroup.warpdrive=曲率驱动
item.warpdrive.crafting.Malformed.name=不良物
item.warpdrive.crafting.Malformed.name=畸变废
item.warpdrive.crafting.EmeraldCrystal.name=绿宝石调谐水晶
item.warpdrive.crafting.EnderCrystal.name=末影调谐水晶
item.warpdrive.crafting.DiamondCrystal.name=钻石调谐水晶
@ -50,14 +50,14 @@ item.warpdrive.atomic.electromagnetic_cell.tooltip.empty=使用粒子对撞机
item.warpdrive.atomic.electromagnetic_cell.tooltip.filled=存储%1$s ų总量%2$s
item.warpdrive.breathing.air_tank0.name=空气罐
item.warpdrive.breathing.air_tank1.name=Basic Air Tank
item.warpdrive.breathing.air_tank2.name=Advanced Air Tank
item.warpdrive.breathing.air_tank3.name=Superior Air Tank
item.warpdrive.breathing.air_tank1.name=基础空气罐
item.warpdrive.breathing.air_tank2.name=先进空气罐
item.warpdrive.breathing.air_tank3.name=卓越空气罐
item.warpdrive.energy.IC2reactorLaserFocus.name=IC2反应堆激光焦点
item.warpdrive.forcefield.shape.none.name=无形状
item.warpdrive.forcefield.shape.none.tooltip=§4无效的项目
item.warpdrive.forcefield.shape.none.tooltip=§4无效
item.warpdrive.forcefield.shape.sphere.name=球体
item.warpdrive.forcefield.shape.sphere.tooltip=
item.warpdrive.forcefield.shape.cylinder_h.name=圆柱体(水平)
@ -181,15 +181,14 @@ item.warpdrive.tool.tuning_fork.green.name=绿色音叉
item.warpdrive.tool.tuning_fork.red.name=红色音叉
item.warpdrive.tool.tuning_fork.black.name=黑色音叉
item.warpdrive.tool.tuning_fork.tooltip.usage=§b右击方块§7 to tune its crystals\n§bSneak§7 to tune alternate crystals
item.warpdrive.tool.tuning_fork.tooltip.usage-tbc=§b右键单击一个方块§7 来调整它的水晶\n§b潜行§7来选择替换的水晶
item.warpdrive.tool.tuning_fork.tooltip.usage=§b右击方块§7调节水晶频率\n§b潜行右击§7轮替水晶
tile.warpdrive.decoration.decorative.energized.name-tbc=能量方块
tile.warpdrive.decoration.decorative.network.name-tbc=网络方块
tile.warpdrive.decoration.decorative.plain.name-tbc=平坦方块
tile.warpdrive.decoration.decorative.energized.name=能量方块
tile.warpdrive.decoration.decorative.network.name=网络方块
tile.warpdrive.decoration.decorative.plain.name=平坦方块
tile.warpdrive.decoration.gas.name=气密方块
tile.warpdrive.decoration.bedrock_glass.name=Bedrock Glass
tile.warpdrive.decoration.bedrock_glass.name=基岩玻璃
tile.warpdrive.passive.IridiumBlock.name=铱块
tile.warpdrive.passive.HighlyAdvancedMachine.name=高新机械块
@ -199,43 +198,43 @@ tile.warpdrive.machines.ChunkLoader.name=区块加载器
tile.warpdrive.machines.Laser.name=激光
tile.warpdrive.machines.LaserMedium.name=激光介质(粒子助推器)
tile.warpdrive.atomic.accelerator_controller.name=Accelerator Controller
tile.warpdrive.atomic.accelerator_controller.tooltip=Controls one or more particle accelerators.\nShall be placed next to an electromagnet.
tile.warpdrive.atomic.accelerator_control_point.name=Accelerator control point
tile.warpdrive.atomic.accelerator_control_point.tooltip=Control accelerator nodes like collider, input and output.\nShall be placed exactly 1 block away from a void shell.\nStore results in any directly connected storage.
tile.warpdrive.atomic.chiller1.name=Basic Chiller
tile.warpdrive.atomic.chiller1.tooltip=Progressively cooldown electromagnets from a connected particle accelerator.\nShall be placed next to an electromagnet.
tile.warpdrive.atomic.chiller2.name=Advanced Chiller
tile.warpdrive.atomic.chiller2.tooltip=Progressively cooldown electromagnets from a connected particle accelerator.\nShall be placed next to an electromagnet.
tile.warpdrive.atomic.chiller3.name=Superior Chiller
tile.warpdrive.atomic.chiller3.tooltip=Progressively cooldown electromagnets from a connected particle accelerator.\nShall be placed next to an electromagnet.
tile.warpdrive.atomic.electromagnet1.plain.name=Basic Plain Electromagnet
tile.warpdrive.atomic.electromagnet1.plain.tooltip=Accelerate, focus and orient particles in the attached Void Shell.
tile.warpdrive.atomic.electromagnet1.glass.name=Basic Glass Electromagnet
tile.warpdrive.atomic.electromagnet1.glass.tooltip=Same a Plain Electromagnet, except you can see through it.
tile.warpdrive.atomic.electromagnet2.plain.name=Advanced Plain Electromagnet
tile.warpdrive.atomic.electromagnet2.plain.tooltip=Accelerate, focus and orient particles in the attached Void Shell.
tile.warpdrive.atomic.electromagnet2.glass.name=Advanced Glass Electromagnet
tile.warpdrive.atomic.electromagnet2.glass.tooltip=Same a Plain Electromagnet, except you can see through it.
tile.warpdrive.atomic.electromagnet3.plain.name=Superior Plain Electromagnet
tile.warpdrive.atomic.electromagnet3.plain.tooltip=Accelerate, focus and orient particles in the attached Void Shell.
tile.warpdrive.atomic.electromagnet3.glass.name=Superior Glass Electromagnet
tile.warpdrive.atomic.electromagnet3.glass.tooltip=Same a Plain Electromagnet, except you can see through it.
tile.warpdrive.atomic.particles_collider.name=Particles Collider
tile.warpdrive.atomic.particles_collider.tooltip=Deviates particles to collide against each others or a fixed target.\nRequires 12 blocks and an Accelerator control point to collect results.
tile.warpdrive.atomic.particles_injector.name=Particles Injector
tile.warpdrive.atomic.particles_injector.tooltip=Inject items or particles from a connected storage into a Basic Accelerator.
tile.warpdrive.atomic.void_shell_plain.name=Plain Void Shell
tile.warpdrive.atomic.void_shell_plain.tooltip=Provides 2 empty channels for particles to travel inside an accelerator setup.\nConnects only horizontally to other Void Shells.
tile.warpdrive.atomic.void_shell_glass.name=Glass Void Shell
tile.warpdrive.atomic.void_shell_glass.tooltip=Same as a Plain Void Shell, except you can see particles moving through it.
tile.warpdrive.atomic.accelerator_controller.name=加速器操纵仪
tile.warpdrive.atomic.accelerator_controller.tooltip=操纵一或多个粒子加速器.\n需要连接电磁体.
tile.warpdrive.atomic.accelerator_control_point.name=加速器控制点
tile.warpdrive.atomic.accelerator_control_point.tooltip=控制加速器上的对撞机、输入、输出等节点.\n需要贴真空腔放置.\n会将产物存入任何相连存储设施.
tile.warpdrive.atomic.chiller1.name=基础冷却器
tile.warpdrive.atomic.chiller1.tooltip=持续冷却相连的电磁体.\n需要放置于电磁体旁边.
tile.warpdrive.atomic.chiller2.name=先进冷却器
tile.warpdrive.atomic.chiller2.tooltip=持续冷却相连的电磁体.\n需要放置于电磁体旁边.
tile.warpdrive.atomic.chiller3.name=卓越冷却器
tile.warpdrive.atomic.chiller3.tooltip=持续冷却相连的电磁体.\n需要放置于电磁体旁边.
tile.warpdrive.atomic.electromagnet1.plain.name=基础朴素电磁体
tile.warpdrive.atomic.electromagnet1.plain.tooltip=加速、聚集、转向真空腔中的粒子.
tile.warpdrive.atomic.electromagnet1.glass.name=基础透明电磁体
tile.warpdrive.atomic.electromagnet1.glass.tooltip=与朴素电磁体相同,但你可以透过它看东西.
tile.warpdrive.atomic.electromagnet2.plain.name=先进朴素电磁体
tile.warpdrive.atomic.electromagnet2.plain.tooltip=加速、聚集、转向真空腔中的粒子.
tile.warpdrive.atomic.electromagnet2.glass.name=先进透明电磁体
tile.warpdrive.atomic.electromagnet2.glass.tooltip=与朴素电磁体相同,但你可以透过它看东西.
tile.warpdrive.atomic.electromagnet3.plain.name=卓越朴素电磁体
tile.warpdrive.atomic.electromagnet3.plain.tooltip=加速、聚集、转向真空腔中的粒子.
tile.warpdrive.atomic.electromagnet3.glass.name=卓越透明电磁体
tile.warpdrive.atomic.electromagnet3.glass.tooltip=与朴素电磁体相同,但你可以透过它看东西.
tile.warpdrive.atomic.particles_collider.name=+粒子对撞机
tile.warpdrive.atomic.particles_collider.tooltip=偏转粒子使之相撞或相融.\n需要12个方块,同时需要加速器控制点处理产物.
tile.warpdrive.atomic.particles_injector.name=粒子注入机
tile.warpdrive.atomic.particles_injector.tooltip=从相邻存储设备中提取物品或粒子注入粒子加速器.
tile.warpdrive.atomic.void_shell_plain.name=朴素真空腔
tile.warpdrive.atomic.void_shell_plain.tooltip=为加速器中的粒子提供运动空间.\n只能水平连接其他真空腔.
tile.warpdrive.atomic.void_shell_glass.name=透明真空腔
tile.warpdrive.atomic.void_shell_glass.tooltip=与朴素真空腔功能相同,但你可观察内部粒子运动.
tile.warpdrive.breathing.air.name-tbc=空气方块
tile.warpdrive.breathing.air_generator.name-tbc=空气发生器
tile.warpdrive.breathing.air_generator1.name=Basic Air Generator
tile.warpdrive.breathing.air_generator2.name=Advanced Air Generator
tile.warpdrive.breathing.air_generator3.name=Superior Air Generator
tile.warpdrive.breathing.air_shield.name=Energy Air Shield
tile.warpdrive.breathing.air.name=可呼吸空气
tile.warpdrive.breathing.air_generator.name=空气供给机
tile.warpdrive.breathing.air_generator1.name=基础空气供给机
tile.warpdrive.breathing.air_generator2.name=先进空气供给机
tile.warpdrive.breathing.air_generator3.name=卓越空气供给机
tile.warpdrive.breathing.air_shield.name=能量空气护罩
tile.warpdrive.building.ShipScanner.name=船体扫描仪
@ -251,13 +250,13 @@ tile.warpdrive.detection.WarpIsolation.name=曲率领域隔离方块
tile.warpdrive.detection.Siren.tooltip=红石触发
tile.warpdrive.detection.Siren0.name=工业警报器
tile.warpdrive.detection.Siren0.tooltip=工业警报器的声音范围是32米
tile.warpdrive.detection.Siren0.tooltip=探测半径32米
tile.warpdrive.detection.Siren4.name=基础空袭警报器
tile.warpdrive.detection.Siren4.tooltip=空袭警报器的声音范围是32米
tile.warpdrive.detection.Siren4.tooltip=探测半径32米
tile.warpdrive.detection.Siren5.name=高级空袭警报器
tile.warpdrive.detection.Siren5.tooltip=空袭警报器的声音范围是64米
tile.warpdrive.detection.Siren5.tooltip=探测半径64米
tile.warpdrive.detection.Siren6.name=卓越空袭警报器
tile.warpdrive.detection.Siren6.tooltip=空袭警报器的声音范围是128米
tile.warpdrive.detection.Siren6.tooltip=探测半径128米
tile.warpdrive.energy.EnanReactorCore.name=镜像体反应堆芯
tile.warpdrive.energy.EnanReactorLaser.name=镜像体反应堆稳定激光
@ -288,14 +287,14 @@ tile.warpdrive.forcefield.relay2.tooltip=支持一个力场升级在其网络内
tile.warpdrive.forcefield.relay3.name=卓越力场继电器
tile.warpdrive.forcefield.relay3.tooltip=支持一个力场升级在其网络内共享
tile.warpdrive.movement.Lift.name-tbc=电梯
tile.warpdrive.movement.ShipController.name-tbc=飞船控制器
tile.warpdrive.movement.ShipController.tooltip=Defines your ship front relative to the core. Attach a computer to open the user interface.\nShall be placed horizontally directly next to the Ship core.
tile.warpdrive.movement.ShipCore.name-tbc=飞船核心
tile.warpdrive.movement.ShipCore.tooltip=Defines your ship center relative to the controller. Connecting an energy source will charge the core.\nShall be placed horizontally directly next to the Ship controller.
tile.warpdrive.movement.ShipCore.bounding_box.disabled=Bounding box display have been disabled.
tile.warpdrive.movement.ShipCore.bounding_box.enabled=Bounding box display is now enabled. Only you can see it.\nSneak right-click the Ship core again to disable it.
tile.warpdrive.movement.Transporter.name-tbc=传送器
tile.warpdrive.movement.Lift.name=电梯
tile.warpdrive.movement.ShipController.name=飞船控制仪
tile.warpdrive.movement.ShipController.tooltip=放在核心前来控制和设定飞船, 在相连的电脑上打开交互界面.\n必须水平紧贴核心才能连接.
tile.warpdrive.movement.ShipCore.name=飞船核心
tile.warpdrive.movement.ShipCore.tooltip=相对于控制器以设定飞船中心.连接供能设备充能.\n必须水平紧贴控制器才能连接.
tile.warpdrive.movement.ShipCore.bounding_box.disabled=边界显示已禁用.
tile.warpdrive.movement.ShipCore.bounding_box.enabled=边界显示启用. 只有你可见.\n再次潜行右击核心可关闭.
tile.warpdrive.movement.Transporter.name=传送台
tile.warpdrive.weapon.LaserCamera.name=激光+相机
tile.warpdrive.weapon.WeaponController.name=武器控制器
@ -564,8 +563,8 @@ warpdrive.guide.prefix=%1$s:
warpdrive.error.badTileEntity=§c需要重放置以更新此方块.
warpdrive.monitor.viewingCamera=观景相机位于 %2$d, %3$d, %4$d 在视频频道%1$d
warpdrive.ship.attachedPlayers=所属的玩家: %1$s
warpdrive.ship.playerAttached=你现在位于飞船 %1$s.\n所属玩家是%2$s
warpdrive.ship.playerDetached=你已经脱离了飞船 %1$s.\n所属玩家是%2$s
warpdrive.ship.playerAttached=你在飞船 %1$s上.\n属于%2$s
warpdrive.ship.playerDetached=你已经脱离了飞船 %1$s.\n属于%2$s
warpdrive.ship.statusLine.cooling=%1$d s 冷却时间
warpdrive.ship.statusLine.isolation=%1$d有效的隔离方块提供%2$2.1f%%吸收.
@ -574,33 +573,31 @@ warpdrive.energy.side.changedToInput=%1$s侧面更改为能量输入模式
warpdrive.energy.side.changedToOutput=%1$s侧面更改为能量输出模式
warpdrive.energy.side.changedToDisabled=%1$s侧面更改为禁用模式
warpdrive.accelerator.guide.lowPower_noStorage=Energy storage is too low; we need at least %1$d to continue operation but can only store %2$d
warpdrive.accelerator.guide.lowPower_accelerating=We're running out of power chief, particles are on the loose, prepare for massive irradiation!
warpdrive.accelerator.guide.lowPower_noParticles=We need more power to start the accelerator!
warpdrive.accelerator.guide.noChiller=No chiller could be found for this accelerator!
warpdrive.accelerator.guide.lowPower_noStorage=能量不足;我们需要%1$d的能量储备维持运转 目前仅剩%2$d
warpdrive.accelerator.guide.lowPower_accelerating=我们的主能量储备耗尽, 粒子正在泄漏,准备承受巨量辐射!
warpdrive.accelerator.guide.lowPower_noParticles=需要更多能量以启动加速器!
warpdrive.accelerator.guide.noChiller=这台加速器没有冷却设备!
warpdrive.beam_frequency.tooltip=Beam frequency is set to %1$d
warpdrive.beam_frequency.tooltip-tbc=光线频率设置为%1$d
warpdrive.beam_frequency.get=Beam frequency %2$d has been retrieved from %1$s
warpdrive.beam_frequency.set=%1$s is now aligned with Beam frequency %2$d
warpdrive.beam_frequency.set-tbc=%1$s正在于光线通道 %2$d进行匹配
warpdrive.beam_frequency.statusLine.valid=光线频率%1$d是有效的
warpdrive.beam_frequency.statusLine.invalid=§c光线频率%1$d是无效的
warpdrive.beam_frequency.statusLine.undefined=§7未定义的光线频率.\n§b使用一个音叉§r 去设置它
warpdrive.beam_frequency.tooltip=设置光束频率为%1$d
warpdrive.beam_frequency.get=光束频率%2$d 已从 %1$s 断开
warpdrive.beam_frequency.set=光束%1$s 正与频率 %2$d进行匹配
warpdrive.beam_frequency.statusLine.valid=光束频率%1$d有效
warpdrive.beam_frequency.statusLine.invalid=§c光束频率%1$d无效
warpdrive.beam_frequency.statusLine.undefined=§7未定义的光束频率.\n§b使用一个音叉§r进行设置
warpdrive.breathing.alarm=Breathing alarm
warpdrive.breathing.invalid_setup=No breathing helmet\nor incomplete armor
warpdrive.breathing.low_reserve=Low air reserve!
warpdrive.breathing.no_air=No more air!
warpdrive.breathing.alarm=呼吸警报
warpdrive.breathing.invalid_setup=无呼吸头盔\未完成盔甲
warpdrive.breathing.low_reserve=空气储备不足!
warpdrive.breathing.no_air=空气耗尽!
warpdrive.control_channel.tooltip=Control channel is set to %1$d
warpdrive.control_channel.get=Control channel %2$d has been retrieved from %1$s
warpdrive.control_channel.set=%1$s is now tuned with Control channel %2$d
warpdrive.control_channel.statusLine.valid=Control channel %1$d is valid.
warpdrive.control_channel.statusLine.invalid=§cControl channel %1$d is invalid.
warpdrive.control_channel.statusLine.undefined=§7Undefined Control channel.\n§bUse a Tuning fork§r to set it.
warpdrive.control_channel.tooltip=控制连接设置为 %1$d
warpdrive.control_channel.get=控制连接 %2$d 已从 %1$s 断开
warpdrive.control_channel.set=%1$s 正与控制连接 %2$d 进行匹配
warpdrive.control_channel.statusLine.valid=控制连接 %1$d 有效.
warpdrive.control_channel.statusLine.invalid=§c控制连接 %1$d 无效.
warpdrive.control_channel.statusLine.undefined=§7未定义控制连接.\n§b使用音叉§r进行设置.
warpdrive.forcefield.guide.lowPower=我们已经耗尽了我们的能量,船长,减少我们的消耗或者找一个苏格兰工程师增加我们的能量!
warpdrive.forcefield.guide.lowPower=舰长,我们的能量已耗尽,请降低能耗或者找一个苏格兰工程师恢复能量!
warpdrive.forcefield.shape.statusLine.none=§c形状未定义.
warpdrive.forcefield.shape.statusLine.double=形状是完整的%1$s
@ -632,21 +629,21 @@ warpdrive.forcefield.upgrade.statusLine.stabilization=稳定
warpdrive.forcefield.upgrade.statusLine.thickness=厚度
warpdrive.forcefield.upgrade.statusLine.translation=转化
warpdrive.particle.ion.name=ion
warpdrive.particle.ion.tooltip=Produced by colliding a particle bunch in a basic accelerator
warpdrive.particle.proton.name=proton
warpdrive.particle.proton.tooltip=Produced by colliding a particle bunch in an advanced accelerator
warpdrive.particle.antimatter.name=antimatter
warpdrive.particle.antimatter.tooltip=Produced by colliding a particle bunch in a superior accelerator
warpdrive.particle.strange_matter.name=strange matter
warpdrive.particle.strange_matter.tooltip=Produced by colliding 2 particle bunches in a superior accelerator
warpdrive.particle.ion.name=离子
warpdrive.particle.ion.tooltip=产生于基础粒子加速器的束流对撞中.
warpdrive.particle.proton.name=质子
warpdrive.particle.proton.tooltip=产生于先进粒子加速器的束流对撞中.
warpdrive.particle.antimatter.name=反物质
warpdrive.particle.antimatter.tooltip=产生于卓越粒子加速器的束流对撞中.
warpdrive.particle.strange_matter.name=奇异物质
warpdrive.particle.strange_matter.tooltip=产生于卓越粒子加速器的二级束流对撞中.
warpdrive.upgrade.result.noUpgradeToDismount=§c没有可卸载的升级
warpdrive.upgrade.result.notEnoughUpgrades=§c你需要至少一个物品去升级这个方块
warpdrive.upgrade.result.invalidUpgrade=§c这不是一个能够升级升级方块的有效物品
warpdrive.upgrade.result.invalidProjectorUpgrade=§c这个升级对于一个投影仪来说过于巨大需要用一个继电器来替代它.
warpdrive.upgrade.result.invalidRelayUpgrade=§c这个升级只适用于投影仪.
warpdrive.upgrade.result.validUpgrades=这个方块所能加载的有效升级包括: %1$s. @TODO 仍未加载
warpdrive.upgrade.result.validUpgrades=这个方块所能加载的有效升级包括: %1$s. @TODO 仍未加载
warpdrive.upgrade.result.tooManyUpgrades=§c这个 %1$d升级已经安装.
warpdrive.upgrade.result.dismounted=升级 %1$s 已经被成功卸载.
warpdrive.upgrade.result.mounted=升级 %1$s已被成功安装.
@ -661,21 +658,19 @@ warpdrive.upgrade.result.shapeMounted=模型加载成功.
warpdrive.upgrade.statusLine.none=§7没有安装升级
warpdrive.upgrade.statusLine.valid=用升级%1$s.
warpdrive.video_channel.tooltip=Video channel is set to %1$d
warpdrive.video_channel.tooltip-tbc=视频通道设置为%1$d
warpdrive.video_channel.get=Video channel %2$d has been retrieved from %1$s
warpdrive.video_channel.set=%1$s is now tuned to Video channel %2$d
warpdrive.video_channel.set-tbc=%1$s正在调整到视频通道%2$d
warpdrive.video_channel.statusLine.valid=视频通道%1$d是有效的
warpdrive.video_channel.statusLine.validCamera=相机的视频通道 %1$d 是有效的,位置是 %2$d, %3$d, %4$d.
warpdrive.video_channel.tooltip-tbc=频道设置为%1$d
warpdrive.video_channel.get=视频频道 %2$d 已从频道 %1$s 断开
warpdrive.video_channel.set=%1$s正在切换至频道%2$d
warpdrive.video_channel.statusLine.valid=视频通道%1$d有效
warpdrive.video_channel.statusLine.validCamera=相机的视频通道 %1$d有效位于%2$d, %3$d, %4$d.
warpdrive.video_channel.statusLine.invalid=§c视频通道 %1$d 无效.
warpdrive.video_channel.statusLine.invalidOrNotLoaded=§c视频通道 %1$d 无效或者是相机的距离太远!
warpdrive.video_channel.statusLine.undefined=§7未定义的视频通道.\n§b使用一个音叉§r 去设置它.
warpdrive.cloakingCore.missingInnerAndOuter=§cIntegrity down to %1$d%%: missing channeling coil(s) towards %2$s and projecting coil(s) towards %3$s
warpdrive.cloakingCore.missingInner=§cIntegrity down to %1$d%%: missing channeling coil(s) towards %2$s
warpdrive.cloakingCore.missingOuter=§cIntegrity down to %1$d%%: missing projecting coil(s) towards %2$s
warpdrive.cloakingCore.valid=System is valid
warpdrive.cloakingCore.missingInnerAndOuter=§c完整度降低至 %1$d%%: %2$s 线圈失去联系且预计将失去 %3$s 线圈
warpdrive.cloakingCore.missingInner=§c完整度降低至 %1$d%%: %2$s 线圈失去联系
warpdrive.cloakingCore.missingOuter=§c完整度降低至 %1$d%%: 预计丢失 %2$s 线圈
warpdrive.cloakingCore.valid=系统认证
warpdrive.cloakingCore.disabled=伪装被禁用
warpdrive.cloakingCore.lowPower=§c伪装失效我们需要更多的能量.
warpdrive.cloakingCore.cloaking=一个层级 %1$d 伪装目前覆盖 %2$d方块!
@ -686,6 +681,5 @@ warpdrive.IC2reactorLaserMonitor.multipleReactors=%1$d反应堆已连接.
warpdrive.transporter.status=从%1$.0f %2$.0f %3$.0f到 %4$.0f %5$.0f %6$.0f
warpdrive.tooltip.itemTag.breathingHelmet=§b太空中呼吸§r消耗背包中的IC压缩空气
warpdrive.tooltip.itemTag.breathingHelmet-tbc=§b太空中呼吸§r 从你的背包消耗IC2的压缩空气
warpdrive.tooltip.itemTag.flyInSpace=§b太空喷气背包§r.
warpdrive.tooltip.itemTag.noFallDamage=§b减少摔落伤害§r.

View file

@ -193,8 +193,10 @@ local function writeCentered(y, text)
for key, monitor in pairs(monitors) do
if key ~= data.radar_monitorIndex then
local xSize, ySize = monitor.getSize()
monitor.setCursorPos((xSize - text:len()) / 2, y)
monitor.write(text)
if xSize ~= nil then
monitor.setCursorPos((xSize - text:len()) / 2, y)
monitor.write(text)
end
end
end
end
@ -424,7 +426,7 @@ end
local function input_readNumber(currentValue)
local inputAbort = false
local input = string.format(currentValue)
local input = w.format_string(currentValue)
if input == "0" then
input = ""
end
@ -448,19 +450,19 @@ local function input_readNumber(currentValue)
local keycode = params[2]
if keycode >= 2 and keycode <= 10 then -- 1 to 9
input = input .. string.format(keycode - 1)
input = input .. w.format_string(keycode - 1)
ignoreNextChar = true
elseif keycode == 11 or keycode == 82 then -- 0 & keypad 0
input = input .. "0"
ignoreNextChar = true
elseif keycode >= 79 and keycode <= 81 then -- keypad 1 to 3
input = input .. string.format(keycode - 78)
input = input .. w.format_string(keycode - 78)
ignoreNextChar = true
elseif keycode >= 75 and keycode <= 77 then -- keypad 4 to 6
input = input .. string.format(keycode - 71)
input = input .. w.format_string(keycode - 71)
ignoreNextChar = true
elseif keycode >= 71 and keycode <= 73 then -- keypad 7 to 9
input = input .. string.format(keycode - 64)
input = input .. w.format_string(keycode - 64)
ignoreNextChar = true
elseif keycode == 14 then -- Backspace
input = string.sub(input, 1, string.len(input) - 1)
@ -530,7 +532,7 @@ end
local function input_readText(currentValue)
local inputAbort = false
local input = string.format(currentValue)
local input = w.format_string(currentValue)
local ignoreNextChar = false
local x, y = w.getCursorPos()
@ -611,7 +613,7 @@ local function input_readConfirmation(message)
w.status_clear()
return true
end
elseif eventName == "char" then
local character = params[2]
w.status_clear()
@ -908,7 +910,7 @@ end
local function data_save()
for name, handlers in pairs(data_handlers) do
handlers.save(data)
handlers.save(data)
end
local file = fs.open("shipdata.txt", "w")

View file

@ -429,7 +429,9 @@ local success, message = pcall(w.run)
if not success then
print("failed with message")
print(message)
print("exiting")
w.sleep(3.0)
print("rebooting...")
w.reboot()
else
w.close()
end

View file

@ -200,7 +200,7 @@ local function writeCentered(y, text)
if term.isAvailable() then
local xSize, ySize = w.getResolution()
if xSize then
if xSize ~= nil then
component.gpu.set((xSize - text:len()) / 2, y, text)
end
w.setCursorPos(1, y + 1)
@ -432,7 +432,7 @@ end
local function input_readNumber(currentValue)
local inputAbort = false
local input = string.format(currentValue)
local input = w.format_string(currentValue)
if input == "0" then
input = ""
end
@ -459,19 +459,19 @@ local function input_readNumber(currentValue)
local keycode = params[4]
if keycode >= 2 and keycode <= 10 then -- 1 to 9
input = input .. string.format(keycode - 1)
input = input .. w.format_string(keycode - 1)
ignoreNextChar = true
elseif keycode == 11 or keycode == 82 then -- 0 & keypad 0
input = input .. "0"
ignoreNextChar = true
elseif keycode >= 79 and keycode <= 81 then -- keypad 1 to 3
input = input .. string.format(keycode - 78)
input = input .. w.format_string(keycode - 78)
ignoreNextChar = true
elseif keycode >= 75 and keycode <= 77 then -- keypad 4 to 6
input = input .. string.format(keycode - 71)
input = input .. w.format_string(keycode - 71)
ignoreNextChar = true
elseif keycode >= 71 and keycode <= 73 then -- keypad 7 to 9
input = input .. string.format(keycode - 64)
input = input .. w.format_string(keycode - 64)
ignoreNextChar = true
elseif keycode == 14 then -- Backspace
input = string.sub(input, 1, string.len(input) - 1)
@ -539,7 +539,7 @@ end
local function input_readText(currentValue)
local inputAbort = false
local input = string.format(currentValue)
local input = w.format_string(currentValue)
local ignoreNextChar = false
local x, y = w.getCursorPos()
@ -821,7 +821,6 @@ local function event_handler(eventName, param)
elseif eventName == "component_unavailable" then
-- not supported: task_complete, rednet_message, modem_message
elseif event_handlers[eventName] ~= nil then
w.status_showSuccess("param '" .. param .. "' of type " .. type(param))
needRedraw = event_handlers[eventName](eventName, param)
else
return false, needRedraw

View file

@ -422,7 +422,9 @@ local success, message = pcall(w.run)
if not success then
print("failed with message")
print(message)
print("exiting")
w.sleep(3.0)
print("rebooting...")
w.reboot()
else
w.close()
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -7,13 +7,17 @@
<!--
An astronomical object or celestial object is a naturally occurring physical entity, association, or structure in the observable universe.
They can be a planet, a more abstract construct like solar system (space dimension) or the all mighty hyperspace.
Hyperspace is defined by it's WarpDriveHyperspace dimension provider. It may a virtual parent celestial object (i.e. one with no dimension defined).
Hyperspace is defined by its WarpDriveHyperspace dimension provider.
Space is a dimension with Hyperspace as its parent.
In theory, multiple planets can exists in the same minecraft world (for example: The Twilight Forest exist on multiple planets in different star systems).
Multiple hyperspaces can be defined.
This default configuration is fairly simple.
In practice, you can have several hyperspaces containing multiple spaces containing numerous planets, etc..
When no dimension is defined, a celestial object is considered 'virtual'. An hyperspace can be virtual. A sun is (in most cases) virtual.
In theory, multiple planets can exists in the same Minecraft world (for example: The Twilight Forest exist on multiple planets in different star systems).
celestialObject.id should be unique for each Celestial object.
When provided by WarpDrive, this is the world folder name instead of DIMxxx or WarpDriveHyperspace and WarpDriveSpace.
When provided by WarpDrive, this is the world folder name instead of DIMxxx.
-->
@ -35,16 +39,16 @@
dimension.id: this is the id of the dimension. 0 is the Overworld, -1 is the Nether, 1 is the End.
dimension.isBreathable: this is a boolean flag defining if ambient atmosphere is breathable.
dimension.isHyperspace: this is a boolean flag defining if this an hyperspace dimension.
dimension.gravity: this is the gravity simulation type. Valid keywords are none (0.0), legacySpace, legacyHyperspace, normal (1.0).
dimension.gravity: this is the gravity simulation type. Valid keywords are 'none' (0.0), 'legacySpace', 'legacyHyperspace', 'normal' (1.0) or any value between 0 and 1.
dimension.center.x, dimension.center.z: those are the center coordinate of that dimension world border, measured in blocks. For convenience, it's usually 0, 0.
-->
<dimension id="-3" isBreathable="false" isHyperspace="true" gravity="legacyHyperspace">
<center x="0" z="0" />
<!--
provider defines how the world biomes are generated. If it's missing, the mod tries to self-assign space and hyperspace dimensions.
provider.type: this is the provider type. Valid keywords are "auto", "WarpDriveSpace", "WarpDriveHyperspace", "other".
Currently only Space and Hyperspace can be provided: use other mods to generate planet world.
-->
provider defines how the world biomes are generated. If it's missing, the mod tries to self-assign space and hyperspace dimensions.
provider.type: this is the provider type. Valid keywords are "auto", "WarpDriveSpace", "WarpDriveHyperspace", "other".
Currently only Space and Hyperspace can be provided: use other mods to generate planet world.
-->
<provider type="WarpDriveHyperspace" />
</dimension>
@ -54,7 +58,7 @@
skybox.backgroundColor is self explanatory. Vanilla enforces plain black at max render distance.
skybox.starBrightnessBase is the minimum brightness of stars in the sky.
skybox.starBrightnessVanilla is how much of the vanilla star brightness is used. Space and hyperspace have no Sun, hence it's a fixed value.
skybox.celestialObjectOpacity is used for that eery feeling. 0 will completly hide celestial objects.
skybox.celestialObjectOpacity is used for that eery feeling. 0 will completely hide celestial objects.
skybox.fogColor is the main color. Higher values increases the halo effect.
skybox.fogFactor is the fog opacity depending on local Sun position. Space and hyperspace have no Sun, hence it's a fixed value.
-->
@ -71,7 +75,7 @@
<celestialObject id="solarSystem">
<!--
parent defines the relation with a bigger enveloping celestial object.
parent.group, parent.name (optional): when using multiple files, you can attach to a parent by its group and name.
parent.id (optional): when using multiple files, you can attach to a parent by its id.
parent.center.x, parent.center.z: this is the center coordinates in the parent dimension, measured in blocks.
-->
<parent>
@ -85,8 +89,7 @@
<provider type="WarpDriveSpace" />
<!--
generate defines the chance of different structures to generate
generate.group, generate.name: identify the structure from the related XML files
Those only works in WarpDrive dimensions, they're ignored otherwise.
generate.group, generate.name: identify the structure from the related XML files (name is optional)
-->
<generate group="moon" ratio="0.00125" />
<generate group="asteroid" ratio="0.0067" />
@ -115,8 +118,8 @@
alpha: transparency factor from 0.00 (invisible) to 1.00 (opaque)
texture: optional texture to use, can come from resource pack, vanilla or the mod itself
periodU, periodV: optional texture rotation period over the planet, measured in seconds, defaults to 0 (disabled)
Texture coordinates are defined along U and V axis (you can see them as X and Y axs in the context of the texture pixels).
A periodU of 40 means the texture will do progressively shift along U axis, doing a full rotation in 40s.
Texture coordinates are defined along U and V axis (you can see them as X and Y axis in the context of the texture pixels).
A periodU of 40 means the texture will do progressively shift along U axis, doing a full rotation in 40 seconds.
A periodU of -80 means the texture will shift twice slower in the opposite direction.
additive: optional blending function, defaults to false (multiplicative)
Blending is the mathematical operation to mix existing pixel (previous layer or sky background) with the new one.
@ -136,9 +139,9 @@
<celestialObject id="earth">
<parent>
<!-- coordinates in the solar system, measured in blocks -->
<center x="-40000" z="20000" />
<center x="-40000" z="30000" />
</parent>
<size x="4000" z="4000" />
<size x="10000" z="10000" />
<dimension id="0" isBreathable="true" gravity="normal">
<center x="0" z="0" />
</dimension>
@ -155,7 +158,7 @@
<parent>
<center x="0" z="0" />
</parent>
<size x="1000" z="1000" />
<size x="2500" z="2500" />
<dimension id="-1" isBreathable="true" gravity="normal">
<center x="0" z="0" />
</dimension>