diff --git a/src/main/java/org/dimdev/ddutils/lsystem/LSystem.java b/src/main/java/org/dimdev/ddutils/lsystem/LSystem.java index d48d03b1..493614ff 100644 --- a/src/main/java/org/dimdev/ddutils/lsystem/LSystem.java +++ b/src/main/java/org/dimdev/ddutils/lsystem/LSystem.java @@ -6,28 +6,33 @@ import org.poly2tri.geometry.polygon.PolygonPoint; import org.poly2tri.triangulation.TriangulationPoint; import org.poly2tri.triangulation.delaunay.DelaunayTriangle; -import java.awt.Point; // TODO: wrong point class! -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; +import java.awt.*; // TODO: Wrong point class! +import java.util.*; +import java.util.List; -public final class LSystem { // TODO: Finish cleaning up this class - public static ArrayList curves = new ArrayList<>(); +public final class LSystem { // TODO: Rewrite this class + public static ArrayList curves = new ArrayList<>(); - /** - * An array containing the args to generate a curve. - * index 0 = rules - * index 1 = angle - * index 2 = start string - */ + // https://en.wikipedia.org/wiki/L-system + // + // System: {rules, angle, start_string} + // Rules: rule1:rule_2:...:rule_n + // Rule: from_substring>to_substring + // + // Each iteration, rules are applied to the string. After, string + // is interpreted as commands for a pencil on a sheet of paper: + // F - move forward by one step + // + - turn clockwise by angle + // - - turn counter-clockwise by angle + // [ - save state (push to stack) + // ] - restore state (pop from stack) public static final String[] TERDRAGON = {"F>+F----F++++F-", "60", "F"}; public static final String[] DRAGON = {"X>X+YF:Y>FX-Y", "90", "FX"}; public static final String[] TWINDRAGON = {"X>X+YF:Y>FX-Y", "90", "FX--FX"}; public static final String[] VORTEX = {"X>X+YF:Y>FX-Y", "90", "FX---FX"}; - static { // Used to be in mod init - // TODO + static { + // TODO: Move to separate class LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 4); LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 5); //LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 6); // degenerate @@ -83,73 +88,23 @@ public final class LSystem { // TODO: Finish cleaning up this class output = generate(args[2], steps, lSystemsRule); //get the boundary of the polygon - PolygonStorage polygon = getBoundary(convertToPoints(angle, output, steps)); + List polygon = getBoundary(convertToPoints(angle, output, steps)); //replace the boundary of the polygon with a series of points representing triangles for rendering - polygon.points = tesselate(polygon); - - curves.add(polygon); - } - - /** - * Naively returns all of the points comprising the fractal - */ - public static PolygonStorage getSpaceFillingCurve(ArrayList input) { - // store max x and y values to create bounding box - int maxY = Integer.MIN_VALUE; - int maxX = Integer.MIN_VALUE; - int minY = Integer.MAX_VALUE; - int minX = Integer.MAX_VALUE; - - // store confirmed duplicates here - HashSet duplicates = new HashSet<>(); - - // store possible singles here - HashSet singles = new HashSet<>(); - - // list to store confirmed singles and output in the correct order - ArrayList output = new ArrayList<>(); - - // sort into Hashmaps and hashsets to make contains operations possible, - // while testing for duplicates - for (double[] point : input) { - // convert doubles to ints and record min/max values - - int xCoord = (int) Math.round(point[0]); - int yCoord = (int) Math.round(point[1]); - - if (xCoord > maxX) { - maxX = xCoord; - } - if (xCoord < minX) { - minX = xCoord; - } - - if (yCoord > maxY) { - maxY = yCoord; - } - if (yCoord < minY) { - minY = yCoord; - } - output.add(new Point(xCoord, yCoord)); - } - return new PolygonStorage(output, maxX, maxY, minX, minY); + curves.add(new PolygonInfo(tesselate(polygon))); } /** * Takes an unordered list of points comprising a fractal curve and builds a * closed polygon around it */ - public static PolygonStorage getBoundary(ArrayList input) { + public static List getBoundary(ArrayList input) { // store max x and y values to create bounding box int maxY = Integer.MIN_VALUE; int maxX = Integer.MIN_VALUE; int minY = Integer.MAX_VALUE; int minX = Integer.MAX_VALUE; - // store confirmed duplicates here - HashSet duplicates = new HashSet<>(); - // store possible singles here HashSet singles = new HashSet<>(); @@ -159,24 +114,14 @@ public final class LSystem { // TODO: Finish cleaning up this class // sort into Hashmaps and hashsets to make contains operations possible, // while testing for duplicates for (double[] point : input) { - // convert doubles to ints and record min/max values - int xCoord = (int) Math.round(point[0]); int yCoord = (int) Math.round(point[1]); - if (xCoord > maxX) { - maxX = xCoord; - } - if (xCoord < minX) { - minX = xCoord; - } + if (xCoord > maxX) maxX = xCoord; + if (xCoord < minX) minX = xCoord; + if (yCoord > maxY) maxY = yCoord; + if (yCoord < minY) minY = yCoord; - if (yCoord > maxY) { - maxY = yCoord; - } - if (yCoord < minY) { - minY = yCoord; - } singles.add(new Point(xCoord, yCoord)); } @@ -235,7 +180,7 @@ public final class LSystem { // TODO: Finish cleaning up this class } while (!(output.get(output.size() - 1).equals(firstPoint) && output.size() > 1) && output.size() < singles.size()); - return new PolygonStorage(output, maxX, maxY, minX, minY); + return output; } /** @@ -341,30 +286,50 @@ public final class LSystem { // TODO: Finish cleaning up this class } // a data container class to transmit the important information about the polygon - public static class PolygonStorage { - public PolygonStorage(ArrayList points, int maxX, int maxY, int minX, int minY) { - this.points = points; - this.maxX = maxX; - this.maxY = maxY; - this.minX = minX; - this.minY = minY; - } - - public ArrayList points; + public static class PolygonInfo { + public final ArrayList points; public int maxX; - public int maxY; - public int minX; - public int minY; + public final int maxY; + public final int minX; + public final int minY; + + public PolygonInfo(ArrayList points) { + int minX, minY, maxX, maxY; + minX = minY = maxX = maxY = 0; + + // Find bounding box of the polygon + this.points = points; + if (points.size() > 0) { + Point firstPoint = points.get(0); + minX = firstPoint.x; + minY = firstPoint.y; + maxX = firstPoint.x; + maxY = firstPoint.y; + + for (Point point : points) { + if (point.x < minX) minX = point.x; + if (point.y < minY) minY = point.y; + if (point.x > maxX) maxX = point.x; + if (point.y > maxY) maxY = point.y; + } + } + + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } } - public static ArrayList tesselate(PolygonStorage polygon) { + // TODO: Use the GLU tesselator (GPU) instead of poly2tri (CPU): http://wiki.lwjgl.org/wiki/Using_GLU_Tesselator.html + public static ArrayList tesselate(List polygon) { ArrayList points = new ArrayList<>(); ArrayList polyPoints = new ArrayList<>(); - for (int i = 0; i < polygon.points.size(); i++) { - polyPoints.add(new PolygonPoint(polygon.points.get(i).x, polygon.points.get(i).y)); + for (Point p : polygon) { + polyPoints.add(new PolygonPoint(p.x, p.y)); } Polygon poly = new Polygon(polyPoints); @@ -379,88 +344,4 @@ public final class LSystem { // TODO: Finish cleaning up this class } return points; } - - // TODO: Figure out what this was meant to be - /* - public static ArrayList tesselate(Polygon polygon) { - ArrayList points = new ArrayList<>(); - - Tessellator tess = new Tessellator(); - double[] verticesC1 = new double[polygon.points.size() * 3]; - for (int i = 0; i < verticesC1.length; i += 3) { - Point point = polygon.points.get(i / 3); - verticesC1[i] = point.x; - verticesC1[i + 1] = point.y; - verticesC1[i + 2] = 0; - } - - tess.glBeginPolygon(); - - for (int i = 0; i < polygon.points.size(); i++) { - tess.gluTessVertex(verticesC1, i * 3, i); - } - - tess.gluEndPolygon(); - - - //Prints out the result of the tessellation. - for (int i = 0; i < tess.primitives.size(); i++) { - System.out.println(tess.primitives.get(i).toString()); - } - //To draw the shape it is now a simple matter to put the vertex data you passed in initially into a VBO, and the indices returned - //into an IBO (Index VBO). You have the types of the primitives and the number of indices for each one. Drawing the result should - //be a walk in the park, as long as you have read the appropriate tutorials here or elsewhere. - - - for (int i = 0; i < tess.primitives.size(); i++) { - - Primitives.Primitive prim = tess.primitives.get(i); - ArrayList vIndex = prim.vertices; - - if (prim.type == GL11.GL_TRIANGLE_STRIP) { - for (int ii = 0; ii < vIndex.size() - 1; ii++) { - points.add(new Point((int) verticesC1[vIndex.get(ii) * 3], (int) verticesC1[vIndex.get(ii) * 3 + 1])); - points.add(new Point((int) verticesC1[vIndex.get(ii + 1) * 3], (int) verticesC1[vIndex.get(ii + 1) * 3 + 1])); - } - } - - if (prim.type == GL11.GL_TRIANGLES) { - for (int ii = 0; ii < vIndex.size(); ii++) { - points.add(new Point((int) verticesC1[vIndex.get(ii) * 3], (int) verticesC1[vIndex.get(ii) * 3 + 1])); - } - } - - if (prim.type == GL11.GL_TRIANGLE_FAN) { - Integer firstIndex = vIndex.get(0); - // points.add(new Point((int)verticesC1[vIndex.get(firstIndex)],(int) verticesC1[vIndex.get(firstIndex)+1])); - - Integer[] vertexList = new Integer[vIndex.size() * 3]; - for (Integer ii = 0; ii < vIndex.size() - 2; ii++) { - vertexList[ii * 3] = vIndex.get(0); - vertexList[ii * 3 + 1] = vIndex.get(ii + 1); - vertexList[ii * 3 + 2] = vIndex.get(ii + 2); - } - - for (Integer vertex : vertexList) { - if (vertex != null) { - points.add(new Point((int) verticesC1[vertex * 3], (int) verticesC1[vertex * 3 + 1])); - } else { - break; - } - } - System.out.println(vertexList); - } - - // points.add(new Point((int)verticesC1[vIndex.get(firstIndex)],(int) verticesC1[vIndex.get(firstIndex)+1])); - // points.add(new Point((int)verticesC1[vIndex.get(ii)*3],(int) verticesC1[vIndex.get(ii)+1])); - // points.add(new Point((int)verticesC1[vIndex.get(ii+1)*3],(int) verticesC1[vIndex.get(ii+1)*3+1])); - - // points.add(new Point((int)verticesC1[index],(int)verticesC1[index+1])); - // System.out.println(verticesC1[index]+","+verticesC1[index+1]+","+verticesC1[index+2]); - - - //System.out.println(tess.primitives.get(i).toString()); - } - return points; - }*/ } diff --git a/src/main/java/org/dimdev/dimdoors/DimDoors.java b/src/main/java/org/dimdev/dimdoors/DimDoors.java index 38a22c73..5980986d 100644 --- a/src/main/java/org/dimdev/dimdoors/DimDoors.java +++ b/src/main/java/org/dimdev/dimdoors/DimDoors.java @@ -1,5 +1,6 @@ package org.dimdev.dimdoors; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.text.TextComponentTranslation; import org.dimdev.dimdoors.shared.ModConfig; @@ -85,8 +86,9 @@ public class DimDoors { } public static void sendTranslatedMessage(Entity entity, String text, Object... translationArgs) { - if (entity instanceof EntityPlayerMP) { - EntityPlayerMP player = (EntityPlayerMP) entity; + // TODO: check if too long and split into several messages? + if (entity instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) entity; player.sendStatusMessage(new TextComponentTranslation(text, translationArgs), ModConfig.general.useStatusBar); } } diff --git a/src/main/java/org/dimdev/dimdoors/client/ParticleRiftEffect.java b/src/main/java/org/dimdev/dimdoors/client/ParticleRiftEffect.java index a2fd7550..340b30c0 100644 --- a/src/main/java/org/dimdev/dimdoors/client/ParticleRiftEffect.java +++ b/src/main/java/org/dimdev/dimdoors/client/ParticleRiftEffect.java @@ -1,12 +1,12 @@ package org.dimdev.dimdoors.client; -import org.dimdev.dimdoors.shared.world.ModDimensions; import net.minecraft.client.particle.ParticleSimpleAnimated; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.entity.Entity; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import org.dimdev.dimdoors.shared.world.ModDimensions; // This has exactly the same appearence as the 1.6.4 mod. @SideOnly(Side.CLIENT) @@ -14,35 +14,33 @@ public class ParticleRiftEffect extends ParticleSimpleAnimated { // TODO: colors private float colorMultiplier; - public ParticleRiftEffect(World world, double x, double y, double z, double motionX, double motionY, double motionZ, float nonPocketColorMultiplier, float pocketColorMultiplier, float scale, int size, int spread) { + public ParticleRiftEffect(World world, double x, double y, double z, double motionX, double motionY, double motionZ, float nonPocketColorMultiplier, float pocketColorMultiplier, float scale, int averageAge, int ageSpread) { super(world, x, y, z, 160, 8, 0); this.motionX = motionX; this.motionY = motionY; this.motionZ = motionZ; particleScale *= scale; - particleMaxAge = size - spread / 2 + rand.nextInt(spread); + particleMaxAge = averageAge - ageSpread / 2 + rand.nextInt(ageSpread); colorMultiplier = ModDimensions.isDimDoorsPocketDimension(world) ? pocketColorMultiplier : nonPocketColorMultiplier; } @Override public void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { - if (particleAge < particleMaxAge / 3 || (particleAge + particleMaxAge) / 3 % 2 == 0) { - float oldRed = particleRed; - float oldGreen = particleGreen; - float oldBlue = particleBlue; - float oldAlpha = particleAlpha; - setRBGColorF(colorMultiplier * particleRed, colorMultiplier * particleGreen, colorMultiplier * particleBlue); - setAlphaF(0.7f); - super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); - setRBGColorF(oldRed, oldGreen, oldBlue); - setAlphaF(oldAlpha); - } + float oldRed = particleRed; + float oldGreen = particleGreen; + float oldBlue = particleBlue; + float oldAlpha = particleAlpha; + setRBGColorF(colorMultiplier * particleRed, colorMultiplier * particleGreen, colorMultiplier * particleBlue); + setAlphaF(1 - (float) particleAge / particleMaxAge); + super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); + setRBGColorF(oldRed, oldGreen, oldBlue); + setAlphaF(oldAlpha); } public static class Rift extends ParticleRiftEffect { public Rift(World world, double x, double y, double z, double motionX, double motionY, double motionZ) { - super(world, x, y, z, motionX, motionY, motionZ, 0.0f, 0.7f, 0.55f, 3800, 1600); + super(world, x, y, z, motionX, motionY, motionZ, 0.0f, 0.7f, 0.55f, 2000, 2000); } } diff --git a/src/main/java/org/dimdev/dimdoors/client/RiftCrackRenderer.java b/src/main/java/org/dimdev/dimdoors/client/RiftCrackRenderer.java index 5e75e704..e0bf9e11 100644 --- a/src/main/java/org/dimdev/dimdoors/client/RiftCrackRenderer.java +++ b/src/main/java/org/dimdev/dimdoors/client/RiftCrackRenderer.java @@ -11,7 +11,7 @@ import static org.lwjgl.opengl.GL11.*; public final class RiftCrackRenderer { - public static void drawCrack(int riftRotation, LSystem.PolygonStorage poly, double size, double xWorld, double yWorld, double zWorld) { + public static void drawCrack(float riftRotation, LSystem.PolygonInfo poly, double size, double xWorld, double yWorld, double zWorld) { // Calculate the proper size for the rift render double scale = size / (poly.maxX - poly.minX); @@ -39,11 +39,11 @@ public final class RiftCrackRenderer { double[] jitters = new double[jCount]; - double aggroScaling = size * size * size / 700f; + double jitterScale = size * size * size / 1300f; // We use random constants here on purpose just to get different wave forms - double xJitter = aggroScaling * Math.sin(1.1f * time*size) * Math.sin(0.8f * time); - double yJitter = aggroScaling * Math.sin(1.2f * time*size) * Math.sin(0.9f * time); - double zJitter = aggroScaling * Math.sin(1.3f * time*size) * Math.sin(0.7f * time); + double xJitter = jitterScale * Math.sin(1.1f * time*size) * Math.sin(0.8f * time); + double yJitter = jitterScale * Math.sin(1.2f * time*size) * Math.sin(0.9f * time); + double zJitter = jitterScale * Math.sin(1.3f * time*size) * Math.sin(0.7f * time); // generate a series of waveforms for (int i = 0; i < jCount; i += 1) { diff --git a/src/main/java/org/dimdev/dimdoors/client/TileEntityFloatingRiftRenderer.java b/src/main/java/org/dimdev/dimdoors/client/TileEntityFloatingRiftRenderer.java index 397cb68d..d0904e46 100644 --- a/src/main/java/org/dimdev/dimdoors/client/TileEntityFloatingRiftRenderer.java +++ b/src/main/java/org/dimdev/dimdoors/client/TileEntityFloatingRiftRenderer.java @@ -18,17 +18,22 @@ public class TileEntityFloatingRiftRenderer extends TileEntitySpecialRenderer= 0/*3000 || timeLeft >= 0 && timeLeft / 500 % 2 == 0*/) { + renderTesseract(rift, x, y, z, partialTicks); + } } + renderCrack(rift, x, y, z); } - private void renderCrack(TileEntityFloatingRift rift, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { + private void renderCrack(TileEntityFloatingRift rift, double x, double y, double z) { GL11.glPushMatrix(); // TODO: Make the sky get dark when a player approaches a rift? @@ -37,11 +42,8 @@ public class TileEntityFloatingRiftRenderer extends TileEntitySpecialRenderer> ItemDimensionalDoor(T block) { super(block); @@ -29,18 +32,33 @@ public abstract class ItemDimensionalDoor extends ItemDoor { // TODO: Biomes O' @Override public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + BlockPos originalPos = pos; // super.onItemUse needs the actual position + if (!world.getBlockState(pos).getBlock().isReplaceable(world, pos)) pos = pos.offset(facing); + boolean placedOnRift = world.getBlockState(pos).getBlock().equals(ModBlocks.RIFT); + + if (!placedOnRift && isRiftNear(world, pos)) { + if (world.isRemote) { + DimDoors.chat(player, "rifts.entrances.rift_too_close"); // TODO: Linebreaks don't work in status message. + TileEntityFloatingRiftRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.graphics.highlightRiftCoreFor; + } + return EnumActionResult.FAIL; + } + if (world.isRemote) return EnumActionResult.FAIL; - boolean replaceable = world.getBlockState(pos).getBlock().isReplaceable(world, pos); + // Store the rift entity if there's a rift block there that may be broken TileEntityFloatingRift rift = null; - if (world.getBlockState(replaceable ? pos : pos.offset(facing)).getBlock().equals(ModBlocks.RIFT)) { - rift = (TileEntityFloatingRift) world.getTileEntity(replaceable ? pos : pos.offset(facing)); - rift.setUnregisterDisabled(true); + if (placedOnRift) { + if (canBePlacedOnRift()) { + rift = (TileEntityFloatingRift) world.getTileEntity(pos); + rift.setUnregisterDisabled(true); + } else { + DimDoors.sendTranslatedMessage(player, "rifts.entrances.cannot_be_placed_on_rift"); + } } - EnumActionResult result = super.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); - if (!replaceable) pos = pos.offset(facing); + EnumActionResult result = super.onItemUse(player, world, originalPos, hand, facing, hitX, hitY, hitZ); if (result == EnumActionResult.SUCCESS) { IBlockState state = world.getBlockState(pos); if (rift == null) { @@ -66,6 +84,22 @@ public abstract class ItemDimensionalDoor extends ItemDoor { // TODO: Biomes O' return result; } + public static boolean isRiftNear(World world, BlockPos pos) { + // TODO: This is called every right click server-side! Is this efficient enough? Maybe use rift registry? + for (int x = pos.getX() - 5; x < pos.getX() + 5; x++) { + for (int y = pos.getY() - 5; y < pos.getY() + 5; y++) { + for (int z = pos.getZ() - 5; z < pos.getZ() + 5; z++) { + BlockPos searchPos = new BlockPos(x, y, z); + if (world.getBlockState(searchPos).getBlock() == ModBlocks.RIFT) { + TileEntityFloatingRift rift = (TileEntityFloatingRift) world.getTileEntity(searchPos); + if (Math.sqrt(pos.distanceSq(searchPos)) < rift.size / 250) return true; + } + } + } + } + return false; + } + @Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, World world, List tooltip, ITooltipFlag flag) { diff --git a/src/main/java/org/dimdev/dimdoors/shared/items/ItemRiftSignature.java b/src/main/java/org/dimdev/dimdoors/shared/items/ItemRiftSignature.java index 9be94e03..0fc9d42c 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/items/ItemRiftSignature.java +++ b/src/main/java/org/dimdev/dimdoors/shared/items/ItemRiftSignature.java @@ -18,7 +18,6 @@ import net.minecraft.world.World; import org.dimdev.ddutils.RotatedLocation; import org.dimdev.dimdoors.shared.blocks.ModBlocks; import org.dimdev.dimdoors.shared.rifts.DestinationMaker; -import org.dimdev.dimdoors.shared.rifts.destinations.GlobalDestination; import org.dimdev.dimdoors.shared.sound.ModSounds; import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift; diff --git a/src/main/java/org/dimdev/dimdoors/shared/items/ItemStabilizedRiftSignature.java b/src/main/java/org/dimdev/dimdoors/shared/items/ItemStabilizedRiftSignature.java index 6faa80e3..ac24eb63 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/items/ItemStabilizedRiftSignature.java +++ b/src/main/java/org/dimdev/dimdoors/shared/items/ItemStabilizedRiftSignature.java @@ -18,7 +18,6 @@ import org.dimdev.dimdoors.DimDoors; import org.dimdev.ddutils.RotatedLocation; import org.dimdev.dimdoors.shared.blocks.ModBlocks; import org.dimdev.dimdoors.shared.rifts.DestinationMaker; -import org.dimdev.dimdoors.shared.rifts.destinations.GlobalDestination; import org.dimdev.dimdoors.shared.sound.ModSounds; import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift; diff --git a/src/main/java/org/dimdev/dimdoors/shared/tileentities/TileEntityFloatingRift.java b/src/main/java/org/dimdev/dimdoors/shared/tileentities/TileEntityFloatingRift.java index a464c5d6..c846926c 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/tileentities/TileEntityFloatingRift.java +++ b/src/main/java/org/dimdev/dimdoors/shared/tileentities/TileEntityFloatingRift.java @@ -37,20 +37,20 @@ import java.util.Random; // TODO: Some of these properties will need to persist when converting to door and then back to rift! //Need to be saved: - @Saved /*package-private*/ int updateTimer; @Saved public boolean closing = false; // TODO: maybe we could have a closingSpeed instead? @Saved public int spawnedEndermenID = 0; - @Saved public float growth = 0; - @Saved protected float teleportTargetYaw; - @Saved protected float teleportTargetPitch; + @Saved public float size = 0; // TODO: store size in blocks + @Saved public float riftYaw = random.nextInt(360); + @Saved protected float teleportTargetPitch; // TODO: also render rift rotated on pitch axis? @Saved public int curveId = random.nextInt(LSystem.curves.size()); - @Saved public int riftRotation = random.nextInt(360); + // Don't need to be saved @Setter private boolean unregisterDisabled = false; + int updateTimer; @SideOnly(Side.CLIENT) public double renderAngle; // This is @SideOnly(Side.CLIENT), don't initialize the field ( = 0), or class initialization won't work on the server! @SideOnly(Side.CLIENT) private int cachedCurveId; - @SideOnly(Side.CLIENT) private LSystem.PolygonStorage curve; // Cache the curve for efficiency + @SideOnly(Side.CLIENT) private LSystem.PolygonInfo curve; // Cache the curve for efficiency public TileEntityFloatingRift() { updateTimer = random.nextInt(UPDATE_PERIOD); @@ -67,8 +67,8 @@ import java.util.Random; // Check if this rift should render white closing particles and // spread the closing effect to other rifts nearby. if (closing) { - if (growth > 0) { - growth -= ModConfig.general.riftCloseSpeed; + if (size > 0) { + size -= ModConfig.general.riftCloseSpeed; } else { world.setBlockToAir(pos); } @@ -86,7 +86,7 @@ import java.util.Random; // Logarithmic growth for (int n = 0; n < 10; n++) { // TODO: growthSpeed and growthSize config options - growth += 1F / (growth + 1); + size += 1F / (size + 1); } } @@ -164,7 +164,7 @@ import java.util.Random; } public void setTeleportTargetRotation(float yaw, float pitch) { - teleportTargetYaw = yaw; + riftYaw = yaw; teleportTargetPitch = pitch; markDirty(); } @@ -180,7 +180,7 @@ import java.util.Random; } @Override public float getDestinationYaw(float entityYaw) { - return teleportTargetYaw; + return riftYaw; } @Override public float getDestinationPitch(float entityPitch) { @@ -188,7 +188,7 @@ import java.util.Random; } @SideOnly(Side.CLIENT) - public LSystem.PolygonStorage getCurve() { + public LSystem.PolygonInfo getCurve() { if (curve != null && curveId == cachedCurveId) { return curve; } diff --git a/src/main/resources/assets/dimdoors/lang/en_US.lang b/src/main/resources/assets/dimdoors/lang/en_US.lang index d3e2d9f9..c46404c9 100644 --- a/src/main/resources/assets/dimdoors/lang/en_US.lang +++ b/src/main/resources/assets/dimdoors/lang/en_US.lang @@ -118,6 +118,8 @@ rifts.destinations.escape.did_not_use_rift=You didn't use a rift to enter the po rifts.destinations.escape.rift_has_closed=The rift you used to enter the pocket dimension has closed and you ended up in Limbo! rifts.destinations.private_pocket_exit.did_not_use_rift=You didn't use a rift to enter the pocket dimension and you ended up in Limbo! rifts.destinations.private_pocket_exit.rift_has_closed=The rift you used to enter the pocket dimension has closed and you ended up in Limbo! +rifts.entrances.rift_too_close=Placing a door this close to a tear in the world would be dangerous. Either place it on the rift's core (tesseract) or further away. Or use a rift signature to make a rift anyway, at your own risk! +rifts.entrances.cannot_be_placed_on_rift=This type of door can't be placed on a rift. dimdoors.general=General Options dimdoors.general.tooltip=General configuration options for the mod