Initial work on Quantum Gate

This commit is contained in:
Calclavia 2014-02-24 22:54:52 +08:00
parent 39bda36b9b
commit cbbe4ecb5e
11 changed files with 540 additions and 71 deletions

View file

@ -29,8 +29,12 @@ import resonantinduction.electrical.tesla.TileTesla;
import resonantinduction.electrical.transformer.ItemTransformer;
import resonantinduction.electrical.wire.EnumWireMaterial;
import resonantinduction.electrical.wire.ItemWire;
import resonantinduction.quantum.gate.BlockGlyph;
import resonantinduction.quantum.gate.BlockQuantumGate;
import resonantinduction.quantum.gate.TileQuantumGate;
import calclavia.lib.content.ContentRegistry;
import calclavia.lib.network.PacketHandler;
import calclavia.lib.prefab.item.ItemBlockMetadata;
import calclavia.lib.recipe.UniversalRecipe;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Mod;
@ -89,6 +93,10 @@ public class Electrical
public static Block blockArmbot;
public static Item itemDisk;
// Quantum
public static Block blockGlyph;
public static Block blockQuantumGate;
@EventHandler
public void preInit(FMLPreInitializationEvent evt)
{
@ -115,6 +123,10 @@ public class Electrical
blockGenerator = contentRegistry.createTile(BlockGenerator.class, TileGenerator.class);
blockThermopile = contentRegistry.createTile(BlockThermopile.class, TileThermopile.class);
// Quantum
blockGlyph = contentRegistry.createBlock(BlockGlyph.class, ItemBlockMetadata.class);
blockQuantumGate = contentRegistry.createTile(BlockQuantumGate.class, TileQuantumGate.class);
Settings.save();
OreDictionary.registerOre("wire", itemWire);

View file

@ -9,6 +9,7 @@ import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;
import net.minecraft.entity.EntityLivingBase;
@ -24,6 +25,8 @@ import resonantinduction.core.Reference;
import resonantinduction.core.ResonantInduction;
import resonantinduction.core.Settings;
import resonantinduction.electrical.Electrical;
import resonantinduction.mechanical.fluid.transport.TileGrate;
import resonantinduction.mechanical.fluid.transport.TileGrate.ComparableVector;
import universalelectricity.api.energy.EnergyStorageHandler;
import universalelectricity.api.vector.Vector3;
import universalelectricity.api.vector.VectorWorld;
@ -144,36 +147,7 @@ public class TileTesla extends TileElectrical implements IMultiBlockStructure<Ti
/**
* Normal transportation
*/
List<ITesla> transferTeslaCoils = new ArrayList<ITesla>();
for (ITesla teslaReceiver : TeslaGrid.instance().get())
{
if (new Vector3((TileEntity) teslaReceiver).distance(new Vector3(this)) < this.getRange())
{
if (teslaReceiver instanceof TileTesla)
{
if (((TileTesla) teslaReceiver).getHeight() <= 1)
{
continue;
}
teslaReceiver = ((TileTesla) teslaReceiver).getMultiBlock().get();
}
/**
* Make sure Tesla is not part of this tower.
*/
if (!this.connectedTeslas.contains(teslaReceiver) && teslaReceiver.canTeslaTransfer(this))
{
transferTeslaCoils.add(teslaReceiver);
}
}
}
/**
* Sort by distance.
*/
Collections.sort(transferTeslaCoils, new Comparator()
PriorityQueue<ITesla> teslaToTransfer = new PriorityQueue<ITesla>(1024, new Comparator()
{
public int compare(ITesla o1, ITesla o2)
{
@ -199,55 +173,80 @@ public class TileTesla extends TileElectrical implements IMultiBlockStructure<Ti
}
});
if (transferTeslaCoils.size() > 0)
for (ITesla teslaReceiver : TeslaGrid.instance().get())
{
long transferEnergy = this.energy.getEnergy() / transferTeslaCoils.size();
int count = 0;
boolean sentPacket = false;
for (ITesla tesla : transferTeslaCoils)
if (new Vector3((TileEntity) teslaReceiver).distance(new Vector3(this)) < this.getRange() && teslaReceiver != this)
{
if (this.zapCounter % 5 == 0 && Settings.SOUND_FXS)
if (teslaReceiver instanceof TileTesla)
{
this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, Reference.PREFIX + "electricshock", (float) this.energy.getEnergy() / (float) TRANSFER_CAP, 1.3f - 0.5f * (this.dyeID / 16f));
}
Vector3 targetVector = new Vector3((TileEntity) tesla);
if (tesla instanceof TileTesla)
{
getMultiBlock().get().outputBlacklist.add(this);
targetVector = new Vector3(((TileTesla) tesla).getTopTelsa());
}
double distance = topTeslaVector.distance(targetVector);
Electrical.proxy.renderElectricShock(this.worldObj, new Vector3(topTesla).translate(new Vector3(0.5)), targetVector.translate(new Vector3(0.5)), EnumColor.DYES[this.dyeID].toColor());
this.transfer(tesla, Math.min(transferEnergy, TRANSFER_CAP));
if (!sentPacket && transferEnergy > 0)
{
this.sendPacket(3);
}
if (this.attackEntities && this.zapCounter % 5 == 0)
{
MovingObjectPosition mop = topTeslaVector.clone().translate(0.5).rayTraceEntities(this.worldObj, targetVector.clone().translate(0.5));
if (mop != null && mop.entityHit != null)
if (((TileTesla) teslaReceiver).getHeight() <= 1)
{
if (mop.entityHit instanceof EntityLivingBase)
continue;
}
teslaReceiver = ((TileTesla) teslaReceiver).getMultiBlock().get();
}
/**
* Make sure Tesla is not part of this tower.
*/
if (!this.connectedTeslas.contains(teslaReceiver) && teslaReceiver.canTeslaTransfer(this))
{
teslaToTransfer.add(teslaReceiver);
}
}
}
if (teslaToTransfer.size() > 0)
{
long transferEnergy = this.energy.getEnergy() / teslaToTransfer.size();
boolean sentPacket = false;
for (int count = 0; count < 10; count++)
{
if (!teslaToTransfer.isEmpty())
{
ITesla tesla = teslaToTransfer.poll();
if (this.zapCounter % 5 == 0 && Settings.SOUND_FXS)
{
this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, Reference.PREFIX + "electricshock", (float) this.energy.getEnergy() / (float) TRANSFER_CAP, 1.3f - 0.5f * (this.dyeID / 16f));
}
Vector3 targetVector = new Vector3((TileEntity) tesla);
if (tesla instanceof TileTesla)
{
getMultiBlock().get().outputBlacklist.add(this);
targetVector = new Vector3(((TileTesla) tesla).getTopTelsa());
}
double distance = topTeslaVector.distance(targetVector);
Electrical.proxy.renderElectricShock(this.worldObj, new Vector3(topTesla).translate(new Vector3(0.5)), targetVector.translate(new Vector3(0.5)), EnumColor.DYES[this.dyeID].toColor());
this.transfer(tesla, Math.min(transferEnergy, TRANSFER_CAP));
if (!sentPacket && transferEnergy > 0)
{
this.sendPacket(3);
}
if (this.attackEntities && this.zapCounter % 5 == 0)
{
MovingObjectPosition mop = topTeslaVector.clone().translate(0.5).rayTraceEntities(this.worldObj, targetVector.clone().translate(0.5));
if (mop != null && mop.entityHit != null)
{
mop.entityHit.attackEntityFrom(CustomDamageSource.electrocution, 4);
Electrical.proxy.renderElectricShock(this.worldObj, new Vector3(topTesla).clone().translate(0.5), new Vector3(mop.entityHit));
if (mop.entityHit instanceof EntityLivingBase)
{
mop.entityHit.attackEntityFrom(CustomDamageSource.electrocution, 4);
Electrical.proxy.renderElectricShock(this.worldObj, new Vector3(topTesla).clone().translate(0.5), new Vector3(mop.entityHit));
}
}
}
}
if (count++ > 1)
{
break;
}
}
}
}

View file

@ -0,0 +1,55 @@
package resonantinduction.quantum.gate;
import java.util.List;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import resonantinduction.core.Reference;
import calclavia.lib.prefab.block.BlockAdvanced;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockGlyph extends BlockAdvanced
{
public static final int MAX_GLYPH = 4;
public static final Icon[] icons = new Icon[MAX_GLYPH];
public BlockGlyph(int id)
{
super(id, Material.iron);
setHardness(32F);
setResistance(1000F);
}
@Override
@SideOnly(Side.CLIENT)
public Icon getIcon(int side, int meta)
{
return icons[meta];
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister register)
{
for (int i = 0; i < icons.length; i++)
{
icons[i] = register.registerIcon(Reference.PREFIX + "glyph_" + i);
}
this.blockIcon = icons[0];
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List)
{
for (int i = 0; i < icons.length; i++)
{
par3List.add(new ItemStack(par1, 1, i));
}
}
}

View file

@ -0,0 +1,125 @@
package resonantinduction.quantum.gate;
import java.util.Random;
import resonantinduction.core.ResonantInduction;
import resonantinduction.electrical.Electrical;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import calclavia.lib.prefab.block.BlockTile;
import calclavia.lib.utility.LanguageUtility;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockQuantumGate extends BlockTile
{
public Icon iconTop, iconSide, iconBot;
public BlockQuantumGate(int id)
{
super(id, Material.iron);
this.setHardness(32F);
this.setResistance(1000F);
}
/** A randomly called display update to be able to add particles or other items for display */
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World world, int x, int y, int z, Random par5Random)
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileQuantumGate)
{
int frequency = ((TileQuantumGate) tile).getFrequency();
if (frequency != -1)
{
/**
* Spawn particles all around the pillar
*/
for (int height = 0; height < 4; height++)
{
for (int i = 2; i < 6; i++)
{
ForgeDirection dir = ForgeDirection.getOrientation(i);
double spawnX = x + 0.5f + dir.offsetX;
double spawnY = y + 0.255f + par5Random.nextFloat() * 0.25f - height;
double spawnZ = z + 0.5f + dir.offsetZ;
double xRand = par5Random.nextFloat() * 0.6F - 0.3F;
double zRand = par5Random.nextFloat() * 0.6F - 0.3F;
world.spawnParticle("enchantmenttable", spawnX + xRand, spawnY, spawnZ + zRand, Math.random() * 0.5, 0.1, Math.random() * 0.5);
world.spawnParticle("enchantmenttable", spawnX - xRand, spawnY, spawnZ + zRand, Math.random() * 0.5, 0.1, Math.random() * 0.5);
world.spawnParticle("enchantmenttable", spawnX + xRand, spawnY, spawnZ - zRand, Math.random() * 0.5, 0.1, Math.random() * 0.5);
world.spawnParticle("enchantmenttable", spawnX - xRand, spawnY, spawnZ - zRand, Math.random() * 0.5, 0.1, Math.random() * 0.5);
if (((TileQuantumGate) tile).canFunction())
{
world.spawnParticle("portal", spawnX + xRand, spawnY, spawnZ + zRand, Math.random() * 0.5, 0.1, Math.random() * 0.5);
world.spawnParticle("portal", spawnX - xRand, spawnY, spawnZ + zRand, Math.random() * 0.5, 0.1, Math.random() * 0.5);
world.spawnParticle("portal", spawnX + xRand, spawnY, spawnZ - zRand, Math.random() * 0.5, 0.1, Math.random() * 0.5);
world.spawnParticle("portal", spawnX - xRand, spawnY, spawnZ - zRand, Math.random() * 0.5, 0.1, Math.random() * 0.5);
}
}
}
}
}
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int i, float f1, float f2, float f3)
{
if (player != null && player.getHeldItem() == null || player.getHeldItem().itemID != (Electrical.blockGlyph.blockID))
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileQuantumGate)
{
int frequency = ((TileQuantumGate) tile).getFrequency();
if (frequency == -1)
{
if (!world.isRemote)
player.addChatMessage("Quantum Gate not set up.");
}
else
{
if (!world.isRemote)
{
player.addChatMessage("Quantum Gate frequency: " + " " + frequency);
}
}
}
return true;
}
return false;
}
@Override
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity par5Entity)
{
}
@Override
public TileEntity createNewTileEntity(World world)
{
return new TileQuantumGate();
}
@Override
public boolean isOpaqueCube()
{
return false;
}
}

View file

@ -0,0 +1,108 @@
package resonantinduction.quantum.gate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.World;
import universalelectricity.api.vector.Vector3;
import universalelectricity.api.vector.VectorWorld;
public class QuantumGateManager
{
private static HashMap<Integer, QuantumGateManager> managerList = new HashMap<Integer, QuantumGateManager>();
private HashSet<TileQuantumGate> teleporters = new HashSet<TileQuantumGate>();
private static HashMap<String, Long> coolDown = new HashMap<String, Long>();
public static QuantumGateManager getManagerForDim(int dim)
{
if (managerList.get(dim) == null)
{
managerList.put(dim, new QuantumGateManager());
}
return managerList.get(dim);
}
/** Adds a teleport anchor to this list or anchors */
public static void addAnchor(TileQuantumGate anch)
{
if (anch != null)
{
QuantumGateManager manager = getManagerForDim(anch.worldObj.provider.dimensionId);
if (!manager.teleporters.contains(anch))
{
manager.teleporters.add(anch);
}
}
}
/** Removes a teleport anchor to this list or anchors */
public static void remAnchor(TileQuantumGate anch)
{
if (anch != null)
{
QuantumGateManager manager = getManagerForDim(anch.worldObj.provider.dimensionId);
manager.teleporters.remove(anch);
}
}
public static HashSet<TileQuantumGate> getConnectedAnchors(World world)
{
return getManagerForDim(world.provider.dimensionId).teleporters;
}
public boolean contains(TileQuantumGate anch)
{
return teleporters.contains(anch);
}
public static TileQuantumGate getClosestWithFrequency(VectorWorld vec, int frequency, TileQuantumGate... anchors)
{
TileQuantumGate tele = null;
List<TileQuantumGate> ignore = new ArrayList<TileQuantumGate>();
if (anchors != null)
{
ignore.addAll(Arrays.asList(anchors));
}
Iterator<TileQuantumGate> it = new ArrayList(QuantumGateManager.getConnectedAnchors(vec.world)).iterator();
while (it.hasNext())
{
TileQuantumGate teleporter = it.next();
if (!ignore.contains(teleporter) && teleporter.getFrequency() == frequency)
{
if (tele == null || new Vector3(tele).distance(vec) > new Vector3(teleporter).distance(vec))
{
tele = teleporter;
}
}
}
return tele;
}
protected static void moveEntity(Entity entity, VectorWorld location)
{
if (entity != null && location != null)
{
location.world.markBlockForUpdate((int) location.x, (int) location.y, (int) location.z);
if (entity instanceof EntityPlayerMP)
{
if (coolDown.get(((EntityPlayerMP) entity).username) == null || (System.currentTimeMillis() - coolDown.get(((EntityPlayerMP) entity).username) > 30))
{
((EntityPlayerMP) entity).playerNetServerHandler.setPlayerLocation(location.x, location.y, location.z, 0, 0);
coolDown.put(((EntityPlayerMP) entity).username, System.currentTimeMillis());
}
}
else
{
entity.setPosition(location.x, location.y, location.z);
}
}
}
}

View file

@ -0,0 +1,163 @@
package resonantinduction.quantum.gate;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import resonantinduction.electrical.tesla.ITesla;
import resonantinduction.electrical.tesla.TeslaGrid;
import universalelectricity.api.energy.EnergyStorageHandler;
import universalelectricity.api.vector.Vector3;
import universalelectricity.api.vector.VectorWorld;
import calclavia.lib.prefab.tile.TileElectrical;
/**
* @author Calclavia, Archadia
*/
public class TileQuantumGate extends TileElectrical implements ITesla
{
private long lastFrequencyCheck = 0;
private int frequency = 0;
public TileQuantumGate()
{
energy = new EnergyStorageHandler(100000);
ioMap = 0;
}
@Override
public void initiate()
{
super.initiate();
TeslaGrid.instance().register(this);
if (!worldObj.isRemote)
{
QuantumGateManager.addAnchor(this);
}
}
@Override
public void updateEntity()
{
super.updateEntity();
if (canFunction() && ticks % 60 == 0)
{
AxisAlignedBB bounds = AxisAlignedBB.getAABBPool().getAABB(xCoord - 1, yCoord - 4, zCoord - 1, xCoord + 2, yCoord + 2, zCoord + 2);
List<Entity> entities = worldObj.getEntitiesWithinAABB(Entity.class, bounds);
for (Entity entity : entities)
{
if (entity instanceof EntityPlayer)
if (entity.isSneaking())
continue;
doTeleport(entity);
}
}
}
public boolean canFunction()
{
return energy.isFull();
}
@Override
public void validate()
{
super.validate();
}
@Override
public void invalidate()
{
if (!worldObj.isRemote)
{
QuantumGateManager.remAnchor(this);
}
TeslaGrid.instance().unregister(this);
super.invalidate();
}
public void doTeleport(Entity entity)
{
VectorWorld teleportSpot = null;
if (getFrequency() != -1)
{
TileQuantumGate teleporter = QuantumGateManager.getClosestWithFrequency(new VectorWorld(this), getFrequency(), this);
if (teleporter != null)
{
teleportSpot = new VectorWorld(teleporter).translate(0.5, 2, 0.5);
}
}
if (teleportSpot != null)
{
QuantumGateManager.moveEntity(entity, teleportSpot);
}
}
/** @return -1 if the teleporter is unable to teleport. */
public int getFrequency()
{
if (System.currentTimeMillis() - this.lastFrequencyCheck > 10)
{
this.lastFrequencyCheck = System.currentTimeMillis();
this.frequency = 0;
for (int i = 4; i > 0; i--)
{
Vector3 position = new Vector3(xCoord, yCoord - i, this.zCoord);
Block block = Block.blocksList[this.worldObj.getBlockId((int) position.x, (int) position.y, (int) position.z)];
if (block instanceof BlockGlyph)
{
int metadata = this.worldObj.getBlockMetadata((int) position.x, (int) position.y, (int) position.z);
this.frequency += Math.pow(BlockGlyph.MAX_GLYPH, i - 2) * metadata;
}
else
{
return -1;
}
}
}
return frequency;
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
}
@Override
public long teslaTransfer(long transferEnergy, boolean doTransfer)
{
return energy.receiveEnergy(transferEnergy, doTransfer);
}
@Override
public boolean canTeslaTransfer(TileEntity transferTile)
{
return true;
}
}

View file

@ -139,6 +139,13 @@ item.resonantinduction\:wire.superconductor.name=Superconductor Wire
item.resonantinduction\:transformer.name=Transformer
item.resonantinduction\:multimeter.name=Multimeter
### Quantum Tier
tile.resonantinduction\:quantumGate.name=Quantum Gate
tile.resonantinduction\:glyph.0.name=Monogon Glyph
tile.resonantinduction\:glyph.1.name=Digon Glyph
tile.resonantinduction\:glyph.2.name=Trigon Glyph
tile.resonantinduction\:glyph.3.name=Tetragon Glyph
## Tool-tips
tooltip.transformer.stepUp=Step Up
tooltip.transformer.stepDown=Step Down

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB