Skip to content

Commit

Permalink
Phantom bridge (#1397)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
AEon - Tobias authored and TehNut committed Aug 18, 2018
1 parent 3d3ce53 commit f5282bd
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/main/java/WayofTime/bloodmagic/block/BlockPhantom.java
Expand Up @@ -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);
}
}
@@ -1,19 +1,56 @@
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;
import net.minecraft.world.World;
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<Entity> 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<EntityPlayer, Pair<Double, Double>> prevPositionMap = new HashMap<>();

Expand Down Expand Up @@ -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;
Expand All @@ -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<ItemStack> 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;
}
}
15 changes: 12 additions & 3 deletions 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 {
Expand All @@ -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());
}

}
}

0 comments on commit f5282bd

Please sign in to comment.