From f5282bd767efdc895bc276deb63debe782f3ef49 Mon Sep 17 00:00:00 2001 From: AEon - Tobias Date: Sat, 18 Aug 2018 03:14:41 +0200 Subject: [PATCH] Phantom bridge (#1397) * Rework. Desyncs for no apparent reason. Apart from that, it works. Desyncing started after I implemented the "diagTemplate" methods. Can definitely be optimised, some advice for that would be good (lots of duplicated code for the "templates"). * Code cleanup. Reverted stuff that I didn't want to commit. * Some fine tuning for speed. playerVel is not very accurate still but this should work out for most stuff. Might need a lot of testing. Might still not work properly on servers. Diagonal templates are inconsistent, need variables switched. Will deal with that later (maybe). In any case, this works just fine unless you're speeding diagonally. * The occasional stuff that should not be pushed. Meaningless whitespaces or code reformatting. * The occasional stuff that should not be pushed. Meaningless whitespaces or code reformatting. Take 2. * MERGE ME I'M AWESOME * removed unused import * Refactoring, adding braces, renaming constants etc etc. done. * take 2 * take 2 * Removed one-liners they grew organically because I initially created every "bridge" with a unique for loop before I removed duplicate code by passing variables/ranges they were helpful until I found good names for the variables, now they've outlived their usefulness * tiny bit of fine tuning * various fluff / small fixes more fine tuning, code reformatting, meaningful variables, for loop fix (variable mismatch), shrinking a redundant method to a call to an advanced method --- .../bloodmagic/block/BlockPhantom.java | 2 +- .../item/sigil/ItemSigilPhantomBridge.java | 166 ++++++++++++++++-- .../bloodmagic/tile/TilePhantomBlock.java | 15 +- 3 files changed, 160 insertions(+), 23 deletions(-) diff --git a/src/main/java/WayofTime/bloodmagic/block/BlockPhantom.java b/src/main/java/WayofTime/bloodmagic/block/BlockPhantom.java index bb6ad64a5..084e6486a 100644 --- a/src/main/java/WayofTime/bloodmagic/block/BlockPhantom.java +++ b/src/main/java/WayofTime/bloodmagic/block/BlockPhantom.java @@ -77,6 +77,6 @@ public boolean hasTileEntity(IBlockState state) { @Nullable @Override public TileEntity createTileEntity(World world, IBlockState state) { - return new TilePhantomBlock(100); + return new TilePhantomBlock(20); } } diff --git a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilPhantomBridge.java b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilPhantomBridge.java index eb2d14313..856a971eb 100644 --- a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilPhantomBridge.java +++ b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilPhantomBridge.java @@ -1,7 +1,11 @@ package WayofTime.bloodmagic.item.sigil; -import WayofTime.bloodmagic.util.helper.PlayerHelper; import WayofTime.bloodmagic.core.RegistrarBloodMagicBlocks; +import WayofTime.bloodmagic.util.Constants; +import WayofTime.bloodmagic.util.helper.NBTHelper; +import WayofTime.bloodmagic.util.helper.PlayerHelper; +import com.google.common.base.Predicate; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; @@ -9,11 +13,44 @@ import org.apache.commons.lang3.tuple.Pair; import java.util.HashMap; +import java.util.List; import java.util.Map; public class ItemSigilPhantomBridge extends ItemSigilToggleableBase { - private static final double EXPANSION_FACTOR = 2; - private static final int RANGE = 3; + public static final Predicate IS_PHANTOM_ACTIVE = (Entity entity) -> entity instanceof EntityPlayer && isPhantomActive((EntityPlayer) entity); + + public static final String[] CIRCLE7X7 = new String[]{ + " XXX ", + " XXXXX ", + "XXXXXXX", + "XXXXXXX", + "XXXXXXX", + " XXXXX ", + " XXX " + }; + + public static final String[] CIRCLE9X9 = new String[]{ + " XXXXX ", + " XXXXXXX ", + "XXXXXXXXX", + "XXXXXXXXX", + "XXXXXXXXX", + "XXXXXXXXX", + "XXXXXXXXX", + " XXXXXXX ", + " XXXXX " + }; + + //imagine you're looking into positive Z + public static final String[] DIAG = new String[]{ + "XXX ", // ----------------- + "XXXX ", // Template Guide + "XXXXX ", // ----------------- + " XXXXX",// ^ // You stand in the bottom right corner, 1 block right, 1 block below the bottom right X + " XXXX",// | // inverted: flips it so you are in top left corner + " XXX" // Z // XnZ: mirrors the template on the X axis + // <--X + }; private Map> prevPositionMap = new HashMap<>(); @@ -46,6 +83,7 @@ public void onSigilUpdate(ItemStack stack, World world, EntityPlayer player, int double playerVelZ = player.posZ - prevPosition.getRight(); double totalVel = Math.sqrt(playerVelX * playerVelX + playerVelZ * playerVelZ); + //Moves more than totalVel^2 blocks in any direction within a tick if (totalVel > 2) { //I am SURE you are teleporting! playerVelX = 0; @@ -58,32 +96,122 @@ public void onSigilUpdate(ItemStack stack, World world, EntityPlayer player, int int posY = playerPos.getY(); int posZ = playerPos.getZ(); - double offsetPosX = posX + EXPANSION_FACTOR * playerVelX; - double offsetPosZ = posZ + EXPANSION_FACTOR * playerVelZ; - double avgX = (posX + offsetPosX) / 2; - double avgZ = (posZ + offsetPosZ) / 2; + //Standing still, sneaking or walking with framerate drops + if (totalVel >= 0 && totalVel < 0.3) { + circleTemplate7x7(posX, posY, posZ, verticalOffset, world); + //anything between the first case and being slightly faster than walking + //walking fairly quickly on X-axis + } else if (playerVelZ > -0.2 && playerVelZ < 0.2) { + if (playerVelX > 0.4) { + if (playerVelX > 1) { + rectangleBridge(posX, posY, posZ, verticalOffset, world, -1, 1, 7, 9); // long bridge + } + rectangleBridge(posX, posY, posZ, verticalOffset, world, -2, 2, 1, 6); // short bridge + } + if (playerVelX < -0.4) { + if (playerVelX < -1) { + rectangleBridge(posX, posY, posZ, verticalOffset, world, 7, 9, -1, 1); + } + rectangleBridge(posX, posY, posZ, verticalOffset, world, -2, 2, -6, -1); + } + //walking fairly quickly on Z-axis + } else if (playerVelX > -0.2 && playerVelX < 0.2) { + if (playerVelZ > 0.4) { + if (playerVelZ > 1) { + rectangleBridge(posX, posY, posZ, verticalOffset, world, 2, 6, -2, 2); + } + rectangleBridge(posX, posY, posZ, verticalOffset, world, 1, 6, -2, 2); + } + if (playerVelZ < -0.4) { + if (playerVelZ < -1) { + rectangleBridge(posX, posY, posZ, verticalOffset, world, -9, -7, -1, 1); + } + rectangleBridge(posX, posY, posZ, verticalOffset, world, -6, -1, -2, 2); + } + } else if (playerVelX > 0.2) { // diagonal movement + if (playerVelZ > 0.2) { + templateReaderCustom(posX, posY, posZ, verticalOffset, world, 1, 1, DIAG, false, false); + } else if (playerVelZ < -0.2) { + templateReaderCustom(posX, posY, posZ, verticalOffset, world, 1, -1, DIAG, false, true); + } + } else if (playerVelX < -0.2) { + if (playerVelZ > 0.2) { + templateReaderCustom(posX, posY, posZ, verticalOffset, world, -1, 1, DIAG, true, true); + } else if (playerVelZ < -0.2) { + templateReaderCustom(posX, posY, posZ, verticalOffset, world, -1, -1, DIAG, true, false); + } + } else { + circleTemplate9x9(posX, posY, posZ, verticalOffset, world); + } + + prevPositionMap.put(player, Pair.of(player.posX, player.posZ)); + } - double C = 2 * (RANGE + EXPANSION_FACTOR * totalVel) + 1; - int truncC = (int) C; + private static void circleTemplate9x9(int posX, int posY, int posZ, int verticalOffset, World world) { + int x = -5; + int z = -5; + templateReader(posX, posY, posZ, verticalOffset, world, z, x, CIRCLE9X9); + } - //TODO: Make this for-loop better. - for (int ix = -truncC; ix <= truncC; ix++) { - for (int iz = -truncC; iz <= truncC; iz++) { - if (computeEllipse(ix + avgX, iz + avgZ, posX, posZ, offsetPosX, offsetPosZ) > C) { - continue; - } + private static void circleTemplate7x7(int posX, int posY, int posZ, int verticalOffset, World world) { + int x = -4; + int z = -4; + templateReader(posX, posY, posZ, verticalOffset, world, z, x, CIRCLE7X7); + } - BlockPos blockPos = new BlockPos(ix + posX, posY + verticalOffset, iz + posZ); + private static void rectangleBridge(int posX, int posY, int posZ, int verticalOffset, World world, int startZ, int endZ, int startX, int endX) { + for (int z = startZ; z <= endZ; z++) { + for (int x = startX; x <= endX; x++) { + BlockPos blockPos = new BlockPos(posX + x, posY + verticalOffset, posZ + z); if (world.isAirBlock(blockPos)) world.setBlockState(blockPos, RegistrarBloodMagicBlocks.PHANTOM.getDefaultState()); } } + } - prevPositionMap.put(player, Pair.of(player.posX, player.posZ)); + private static void templateReader(int posX, int posY, int posZ, int verticalOffset, World world, int offsetZ, int offsetX, String[] template) { + templateReaderCustom(posX, posY, posZ, verticalOffset, world, offsetZ, offsetX, template, false, false); } - public static double computeEllipse(double x, double z, double focusX1, double focusZ1, double focusX2, double focusZ2) { - return Math.sqrt((x - focusX1) * (x - focusX1) + (z - focusZ1) * (z - focusZ1)) + Math.sqrt((x - focusX2) * (x - focusX2) + (z - focusZ2) * (z - focusZ2)); + private static void templateReaderCustom(int posX, int posY, int posZ, int verticalOffset, World world, int offsetZ, int offsetX, String[] template, boolean inverted, boolean XnZ) { + int x = 0; + for (String row : template) { + if (inverted) + x--; + else + x++; + int z = 0; + for (char block : row.toCharArray()) { + if (inverted && !XnZ || XnZ && !inverted) + z--; + else + z++; + if (block == 'X') { + BlockPos blockPos = new BlockPos(posX + offsetX + x, posY + verticalOffset, posZ + offsetZ + z); + + if (world.isAirBlock(blockPos)) + world.setBlockState(blockPos, RegistrarBloodMagicBlocks.PHANTOM.getDefaultState()); + } + } + } + } + + public static boolean isPhantomActive(EntityPlayer entity) { + for (int i = 0; i < entity.inventory.getSizeInventory(); i++) { + ItemStack stack = entity.inventory.getStackInSlot(i); + if (stack.getItem() instanceof ItemSigilPhantomBridge) + return NBTHelper.checkNBT(stack).getTagCompound().getBoolean(Constants.NBT.ACTIVATED); + if (stack.getItem() instanceof ItemSigilHolding) { + List inv = ItemSigilHolding.getInternalInventory(stack); + for (int j = 0; j < ItemSigilHolding.inventorySize; j++) { + ItemStack invStack = inv.get(j); + if (invStack.getItem() instanceof ItemSigilPhantomBridge) + return NBTHelper.checkNBT(invStack).getTagCompound().getBoolean(Constants.NBT.ACTIVATED); + } + } + + } + return false; } } diff --git a/src/main/java/WayofTime/bloodmagic/tile/TilePhantomBlock.java b/src/main/java/WayofTime/bloodmagic/tile/TilePhantomBlock.java index cdda27d8e..c1d2007fb 100644 --- a/src/main/java/WayofTime/bloodmagic/tile/TilePhantomBlock.java +++ b/src/main/java/WayofTime/bloodmagic/tile/TilePhantomBlock.java @@ -1,7 +1,9 @@ package WayofTime.bloodmagic.tile; +import WayofTime.bloodmagic.item.sigil.ItemSigilPhantomBridge; import WayofTime.bloodmagic.util.Constants; import WayofTime.bloodmagic.tile.base.TileTicking; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; public class TilePhantomBlock extends TileTicking { @@ -27,11 +29,18 @@ public NBTTagCompound serialize(NBTTagCompound tagCompound) { @Override public void onUpdate() { - ticksRemaining--; + if(!world.isRemote) { + EntityPlayer player = world.getClosestPlayer(getPos().getX(), getPos().getY(), getPos().getZ(), 10.0D, ItemSigilPhantomBridge.IS_PHANTOM_ACTIVE); + if (player != null && !player.isSneaking()) + return; + ticksRemaining--; + } + if (ticksRemaining <= 0) { - getWorld().setBlockToAir(getPos()); - getWorld().removeTileEntity(getPos()); + world.setBlockToAir(getPos()); + world.removeTileEntity(getPos()); } + } }