diff options
Diffstat (limited to 'src/Java/gtPlusPlus/api/objects/minecraft')
4 files changed, 487 insertions, 0 deletions
diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java b/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java new file mode 100644 index 0000000000..d258d1fe73 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java @@ -0,0 +1,85 @@ +package gtPlusPlus.api.objects.minecraft; + +import java.io.Serializable; + +public class BlockPos implements Serializable{ + + private static final long serialVersionUID = -7271947491316682006L; + public final int xPos; + public final int yPos; + public final int zPos; + public final int dim; + + public BlockPos(int x, int y, int z){ + this(x, y, z, 0); + } + + public BlockPos(int x, int y, int z, int dim){ + this.xPos = x; + this.yPos = y; + this.zPos = z; + this.dim = dim; + } + + public String getLocationString() { + return "[X: "+this.xPos+"][Y: "+this.yPos+"][Z: "+this.zPos+"][Dim: "+this.dim+"]"; + } + + @Override + public int hashCode() { + int hash = 5; + hash += (13 * this.xPos); + hash += (19 * this.yPos); + hash += (31 * this.zPos); + hash += (17 * this.dim); + return hash; + } + + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (other == this) { + return true; + } + if(!(other instanceof BlockPos)) { + return false; + } + BlockPos otherPoint = (BlockPos)other; + return this.xPos == otherPoint.xPos && this.yPos == otherPoint.yPos && this.zPos == otherPoint.zPos && this.dim == otherPoint.dim; + } + + public int distanceFrom(BlockPos target) { + if (target.dim != this.dim) { + return Short.MIN_VALUE; + } + return distanceFrom(target.xPos, target.yPos, target.zPos); + } + + /** + * + * @param x X coordinate of target. + * @param y Y coordinate of target. + * @param z Z coordinate of target. + * @return square of distance + */ + public int distanceFrom(int x, int y, int z) { + int distanceX = this.xPos - x; + int distanceY = this.yPos - y; + int distanceZ = this.zPos - z; + return distanceX * distanceX + distanceY * distanceY + distanceZ * distanceZ; + } + + public boolean isWithinRange(BlockPos target, int range) { + if (target.dim != this.dim) { + return false; + } + return isWithinRange(target.xPos, target.yPos, target.zPos, range); + } + + public boolean isWithinRange(int x, int y, int z, int range) { + return distanceFrom(x, y, z) <= (range * range); + } + +} diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java b/src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java new file mode 100644 index 0000000000..b411e8875a --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java @@ -0,0 +1,309 @@ +/* + * Copyright (c) CovertJaguar, 2014 http://railcraft.info + * + * This code is the property of CovertJaguar + * and may only be used with explicit written + * permission unless otherwise specified on the + * license page at http://railcraft.info/wiki/info:license. + */ +package gtPlusPlus.api.objects.minecraft; + +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.ListMultimap; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import gtPlusPlus.GTplusplus; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.Triplet; +import gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.GregtechMetaTileEntityChunkLoader; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.entity.Entity; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.ForgeChunkManager; +import net.minecraftforge.common.ForgeChunkManager.LoadingCallback; +import net.minecraftforge.common.ForgeChunkManager.OrderedLoadingCallback; +import net.minecraftforge.common.ForgeChunkManager.Ticket; +import net.minecraftforge.common.ForgeChunkManager.Type; +import net.minecraftforge.event.entity.EntityEvent; + +/** + * @author CovertJaguar <http://www.railcraft.info> + */ +public class ChunkManager implements LoadingCallback, OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback { + + private static ChunkManager instance; + + public static ConcurrentHashMap<BlockPos, Triplet<Integer, GregtechMetaTileEntityChunkLoader, DimChunkPos>> mChunkLoaderManagerMap = new ConcurrentHashMap<BlockPos, Triplet<Integer, GregtechMetaTileEntityChunkLoader, DimChunkPos>>(); + + + public static ChunkManager getInstance() { + if (instance == null) { + instance = new ChunkManager(); + } + return instance; + } + + @SubscribeEvent + public void entityEnteredChunk(EntityEvent.EnteringChunk event) { + + } + + /** + * Returns a Set of ChunkCoordIntPair containing the chunks between the + * start and end chunks. + * <p/> + * One of the pairs of start/end coords need to be equal. + * <p/> + * Coordinates are in chunk coordinates, not world coordinates. + * + * @param xChunkA Start Chunk x-Coord + * @param zChunkA Start Chunk z-Coord + * @param xChunkB End Chunk x-Coord + * @param zChunkB End Chunk z-Coord + * @param max Max number of chunks to return + * @return A set of chunks. + */ + public Set<ChunkCoordIntPair> getChunksBetween(int xChunkA, int zChunkA, int xChunkB, int zChunkB, int max) { + Set<ChunkCoordIntPair> chunkList = new HashSet<ChunkCoordIntPair>(); + + if (xChunkA != xChunkB && zChunkA != zChunkB) { + return chunkList; + } + + int xStart = Math.min(xChunkA, xChunkB); + int xEnd = Math.max(xChunkA, xChunkB); + + int zStart = Math.min(zChunkA, zChunkB); + int zEnd = Math.max(zChunkA, zChunkB); + + for (int xx = xStart; xx <= xEnd; xx++) { + for (int zz = zStart; zz <= zEnd; zz++) { + chunkList.add(new ChunkCoordIntPair(xx, zz)); + if (chunkList.size() >= max) { + return chunkList; + } + } + } + return chunkList; + } + + /** + * Returns a Set of ChunkCoordIntPair containing the chunks around point [x, + * z]. Coordinates are in chunk coordinates, not world coordinates. + * + * @param xChunk Chunk x-Coord + * @param zChunk Chunk z-Coord + * @param radius Distance from [x, z] to include, in number of chunks. + * @return A set of chunks. + */ + public Set<ChunkCoordIntPair> getChunksAround(int xChunk, int zChunk, int radius) { + Set<ChunkCoordIntPair> chunkList = new HashSet<ChunkCoordIntPair>(); + for (int xx = xChunk - radius; xx <= xChunk + radius; xx++) { + for (int zz = zChunk - radius; zz <= zChunk + radius; zz++) { + chunkList.add(new ChunkCoordIntPair(xx, zz)); + } + } + return chunkList; + } + + /** + * Returns a Set of ChunkCoordIntPair containing the chunks around point [x, + * z]. Coordinates are in world coordinates, not chunk coordinates. + * + * @param xWorld World x-Coord + * @param zWorld World z-Coord + * @param radius Distance from [x, z] to include, in blocks. + * @return A set of chunks. + */ + public Set<ChunkCoordIntPair> getBufferAround(int xWorld, int zWorld, int radius) { + int minX = (xWorld - radius) >> 4; + int maxX = (xWorld + radius) >> 4; + int minZ = (zWorld - radius) >> 4; + int maxZ = (zWorld + radius) >> 4; + + Set<ChunkCoordIntPair> chunkList = new HashSet<ChunkCoordIntPair>(); + for (int xx = minX; xx <= maxX; xx++) { + for (int zz = minZ; zz <= maxZ; zz++) { + chunkList.add(new ChunkCoordIntPair(xx, zz)); + } + } + return chunkList; + } + + private void printAnchor(String type, int x, int y, int z) { + Logger.INFO("[Chunk Loader] "+type+" @ [x: "+x+"][y: "+y+"][z: "+z+"]"); + } + + @Override + public void ticketsLoaded(List<Ticket> tickets, World world) { + + if (world.isRemote) return; + + // System.out.println("Callback 2"); + for (Ticket ticket : tickets) { + if (ticket.isPlayerTicket()) + continue; + Entity entity = ticket.getEntity(); + if (entity == null) { + int x = ticket.getModData().getInteger("xCoord"); + int y = ticket.getModData().getInteger("yCoord"); + int z = ticket.getModData().getInteger("zCoord"); + + if (y >= 0) { + BlockPos tile = new BlockPos(x, y, z); + + Ticket H = tryForceLoadChunk(new DimChunkPos(world, tile).getChunk()); + + int jhg = 0; + while (jhg < 50) { + jhg++; + } + + if (!mChunkLoaderManagerMap.isEmpty()) { + GregtechMetaTileEntityChunkLoader f = mChunkLoaderManagerMap.get(tile).getValue_2(); + int timeout = 0; + while (f == null) { + if (timeout > 5000) { + Logger.INFO("[Chunk Loader] Timed out"); + break; + } + else { + GregtechMetaTileEntityChunkLoader g; + if (!mChunkLoaderManagerMap.isEmpty()) { + g = mChunkLoaderManagerMap.get(tile).getValue_2(); + if (g == null) { + timeout++; + } + else { + Logger.INFO("[Chunk Loader]Tile became Valid"); + f = g; + break; + } + } + } + } + try { + if (f != null) { + + + if (H != null) { + ForgeChunkManager.releaseTicket(H); + } + + f.forceChunkLoading(ticket); + printAnchor("Force Chunk Loading. Chunk Loader has ID of "+f.getLoaderID()+". ",x,y,z); + } + else { + Logger.INFO("Tile Entity is null."); + } + } + catch (Throwable t) { + t.printStackTrace(); + Logger.INFO("Mild problem with chunk loading, nothing to worry about."); + } + + + if (H != null) { + ForgeChunkManager.releaseTicket(H); + } + + } + + /*if (tile instanceof IGregTechTileEntity) { + final IGregTechTileEntity tGregTechTileEntity = (IGregTechTileEntity) tile; + IGregTechTileEntity anchor = (IGregTechTileEntity) tile; + GregtechMetaTileEntityChunkLoader jun = (GregtechMetaTileEntityChunkLoader) anchor; + jun.forceChunkLoading(ticket); + //printAnchor(anchor.getName(), x, y, z); + }*/ + } + } + } + } + + @Override + public List<Ticket> ticketsLoaded(List<Ticket> tickets, World world, int maxTicketCount) { + // System.out.println("Callback 1"); + Set<Ticket> adminTickets = new HashSet<Ticket>(); + Set<Ticket> worldTickets = new HashSet<Ticket>(); + Set<Ticket> cartTickets = new HashSet<Ticket>(); + for (Ticket ticket : tickets) { + Entity entity = ticket.getEntity(); + if (entity == null) { + int x = ticket.getModData().getInteger("xCoord"); + int y = ticket.getModData().getInteger("yCoord"); + int z = ticket.getModData().getInteger("zCoord"); + if (y >= 0) { + worldTickets.add(ticket); + } + } + } + + List<Ticket> claimedTickets = new LinkedList<Ticket>(); + claimedTickets.addAll(cartTickets); + claimedTickets.addAll(adminTickets); + claimedTickets.addAll(worldTickets); + return claimedTickets; + } + + @Override + public ListMultimap<String, Ticket> playerTicketsLoaded(ListMultimap<String, Ticket> tickets, World world) { + return LinkedListMultimap.create(); + } + + + public static Timer createChunkQueue() { + return ChunkTimerLoader(); + } + + public static Ticket tryForceLoadChunk(Chunk c) { + Ticket T = getTicketFromForge(c.worldObj); + ForgeChunkManager.forceChunk(T, c.getChunkCoordIntPair()); + Logger.INFO("[Chunk Loader] Trying to force load a chunk that holds a chunkloader."); + return T; + } + + public static Ticket getTicketFromForge(World world) { + return ForgeChunkManager.requestTicket(GTplusplus.instance, world, Type.NORMAL); + } + + static Timer ChunkTimerLoader() { + Timer timer; + timer = new Timer(); + timer.schedule(new ChunkCache(), 10 * 1000); + return timer; + } + + //Timer Task for notifying the player. + static class ChunkCache extends TimerTask { + public ChunkCache() { + + } + + @Override + public void run() { + if (mChunkLoaderManagerMap.size() > 0) { + for (Triplet<Integer, GregtechMetaTileEntityChunkLoader, DimChunkPos> j : mChunkLoaderManagerMap.values()) { + Ticket T; + Chunk C; + T = j.getValue_2().getTicketFromForge(); + C = j.getValue_3().getChunk(); + ForgeChunkManager.forceChunk(T, C.getChunkCoordIntPair()); + Logger.INFO("[Chunk Loader] Trying to force load a chunk that holds a chunkloader."); + } + } + else { + Logger.INFO("[Chunk Loader] No chunks to try to force load chunks that hold chunkloaders."); + } + } + } +}
\ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java b/src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java new file mode 100644 index 0000000000..010e522a14 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java @@ -0,0 +1,52 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraft.client.Minecraft; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; + +public class DimChunkPos { + + public final int dimension; + public final int xPos; + public final int zPos; + public final Chunk mainChunk; + + + public DimChunkPos(World world, BlockPos block){ + this.dimension = world.provider.dimensionId; + this.mainChunk = world.getChunkFromBlockCoords(block.xPos, block.zPos); + this.xPos = this.mainChunk.xPosition; + this.zPos = this.mainChunk.zPosition; + } + + + public DimChunkPos(TileEntity tile){ + this.dimension = tile.getWorldObj().provider.dimensionId; + this.mainChunk = tile.getWorldObj().getChunkFromBlockCoords(tile.xCoord, tile.zCoord); + this.xPos = this.mainChunk.xPosition; + this.zPos = this.mainChunk.zPosition; + } + + public DimChunkPos(int dim, int x, int z){ + this.dimension = dim; + this.xPos = x; + this.zPos = z; + Chunk h = Minecraft.getMinecraft().getIntegratedServer().worldServerForDimension(dim).getChunkFromChunkCoords(xPos, zPos); + if (h == null) { + this.mainChunk = null; + } + else { + this.mainChunk = h; + } + } + + public Chunk getChunk() { + if (this.mainChunk != null) { + return this.mainChunk; + } + Chunk h = Minecraft.getMinecraft().getIntegratedServer().worldServerForDimension(this.dimension).getChunkFromChunkCoords(xPos, zPos); + return h; + } + +} diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java b/src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java new file mode 100644 index 0000000000..f5db1d9e3a --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java @@ -0,0 +1,41 @@ +package gtPlusPlus.api.objects.minecraft; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +public class GenericStack { + + private ItemStack mItemStack; + private FluidStack mFluidStack; + + public GenericStack(ItemStack s){ + this.mItemStack = s; + this.mFluidStack = null; + } + + public GenericStack(FluidStack f){ + this.mItemStack = null; + this.mFluidStack = f; + } + + public GenericStack() { + this.mItemStack = null; + this.mFluidStack = null; + } + + public synchronized final FluidStack getFluidStack() { + return mFluidStack; + } + + public synchronized final ItemStack getItemStack() { + return mItemStack; + } + + public synchronized final void setItemStack(ItemStack mItemStack) { + this.mItemStack = mItemStack; + } + + public synchronized final void setFluidStack(FluidStack mFluidStack) { + this.mFluidStack = mFluidStack; + } +} |