Refactored build modes for easier expansion.
Allowed buildmodes to intersect with existing blocks 1 block deep.
This commit is contained in:
@@ -192,4 +192,31 @@ public class BuildModes {
|
||||
Dictionary<EntityPlayer, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer;
|
||||
return currentlyBreaking.get(player) != null;
|
||||
}
|
||||
|
||||
//Find coordinates on a line bound by a plane
|
||||
protected static Vec3d findXBound(double x, Vec3d start, Vec3d look) {
|
||||
//then y and z are
|
||||
double y = (x - start.x) / look.x * look.y + start.y;
|
||||
double z = (x - start.x) / look.x * look.z + start.z;
|
||||
|
||||
return new Vec3d(x, y, z);
|
||||
}
|
||||
|
||||
protected static Vec3d findYBound(double y, Vec3d start, Vec3d look) {
|
||||
//then x and z are
|
||||
double x = (y - start.y) / look.y * look.x + start.x;
|
||||
double z = (y - start.y) / look.y * look.z + start.z;
|
||||
|
||||
return new Vec3d(x, y, z);
|
||||
}
|
||||
|
||||
protected static Vec3d findZBound(double z, Vec3d start, Vec3d look) {
|
||||
//then x and y are
|
||||
double x = (z - start.z) / look.z * look.x + start.x;
|
||||
double y = (z - start.z) / look.z * look.y + start.y;
|
||||
|
||||
return new Vec3d(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||
import nl.requios.effortlessbuilding.helper.ReachHelper;
|
||||
|
||||
import java.util.*;
|
||||
@@ -18,6 +19,33 @@ public class Floor implements IBuildMode {
|
||||
Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
|
||||
Dictionary<UUID, Vec3d> hitVecTable = new Hashtable<>();
|
||||
|
||||
class Criteria {
|
||||
Vec3d planeBound;
|
||||
double distToPlayerSq;
|
||||
|
||||
Criteria(Vec3d planeBound, Vec3d start) {
|
||||
this.planeBound = planeBound;
|
||||
this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared();
|
||||
}
|
||||
|
||||
//check if its not behind the player and its not too close and not too far
|
||||
//also check if raytrace from player to block does not intersect blocks
|
||||
public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) {
|
||||
|
||||
boolean intersects = false;
|
||||
if (!skipRaytrace) {
|
||||
//collision within a 1 block radius to selected is fine
|
||||
RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, planeBound, false, true, false);
|
||||
intersects = rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK &&
|
||||
planeBound.subtract(rayTraceResult.hitVec).lengthSquared() > 4;
|
||||
}
|
||||
|
||||
return planeBound.subtract(start).dotProduct(look) > 0 &&
|
||||
distToPlayerSq > 4 && distToPlayerSq < reach * reach &&
|
||||
!intersects;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(EntityPlayer player) {
|
||||
rightClickClientTable.put(player.getUniqueID(), 0);
|
||||
@@ -69,47 +97,10 @@ public class Floor implements IBuildMode {
|
||||
if (blockPos != null)
|
||||
list.add(blockPos);
|
||||
} else {
|
||||
Vec3d look = player.getLookVec();
|
||||
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
BlockPos secondPos = findFloor(player, firstPos, skipRaytrace);
|
||||
if (secondPos == null) return list;
|
||||
|
||||
//try on z axis
|
||||
double y = firstPos.getY();
|
||||
|
||||
//then x and z are
|
||||
double x = (y - start.y) / look.y * look.x + start.x;
|
||||
double z = (y - start.y) / look.y * look.z + start.z;
|
||||
|
||||
Vec3d yBound = new Vec3d(x, y, z);
|
||||
|
||||
//distance to player
|
||||
double yDistSquared = yBound.subtract(start).lengthSquared();
|
||||
|
||||
|
||||
int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach
|
||||
|
||||
//check if its not behind the player and its not too close and not too far
|
||||
boolean yValid = yBound.subtract(start).dotProduct(look) > 0 &&
|
||||
yDistSquared > 4 && yDistSquared < reach * reach;
|
||||
|
||||
//select the one that is closest to the player and is valid
|
||||
Vec3d selected = null;
|
||||
if (yValid) selected = yBound;
|
||||
|
||||
if (selected == null) return list;
|
||||
|
||||
//check if it doesnt go through blocks
|
||||
//TODO collision within a 1 block radius to selected is fine
|
||||
if (!skipRaytrace) {
|
||||
RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false);
|
||||
if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
//return empty list
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
BlockPos secondPos = new BlockPos(selected);
|
||||
|
||||
//Add whole wall
|
||||
//Add whole floor
|
||||
//Limit amount of blocks you can place per row
|
||||
int limit = ReachHelper.getMaxBlocksPlacedAtOnce(player);
|
||||
|
||||
@@ -135,6 +126,29 @@ public class Floor implements IBuildMode {
|
||||
return list;
|
||||
}
|
||||
|
||||
public BlockPos findFloor(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) {
|
||||
Vec3d look = player.getLookVec();
|
||||
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
|
||||
List<Criteria> criteriaList = new ArrayList<>(3);
|
||||
|
||||
//Y
|
||||
Vec3d yBound = BuildModes.findYBound(firstPos.getY(), start, look);
|
||||
criteriaList.add(new Criteria(yBound, start));
|
||||
|
||||
//Remove invalid criteria
|
||||
int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach
|
||||
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
|
||||
|
||||
//If none are valid, return empty list of blocks
|
||||
if (criteriaList.isEmpty()) return null;
|
||||
|
||||
//Then only 1 can be valid, return that one
|
||||
Criteria selected = criteriaList.get(0);
|
||||
|
||||
return new BlockPos(selected.planeBound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumFacing getSideHit(EntityPlayer player) {
|
||||
return sideHitTable.get(player.getUniqueID());
|
||||
|
||||
@@ -18,6 +18,57 @@ public class Line implements IBuildMode {
|
||||
Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
|
||||
Dictionary<UUID, Vec3d> hitVecTable = new Hashtable<>();
|
||||
|
||||
class Criteria {
|
||||
Vec3d planeBound;
|
||||
Vec3d lineBound;
|
||||
double distToLineSq;
|
||||
double distToPlayerSq;
|
||||
|
||||
Criteria(Vec3d planeBound, BlockPos firstPos, Vec3d start) {
|
||||
this.planeBound = planeBound;
|
||||
this.lineBound = toLongestLine(this.planeBound, firstPos);
|
||||
this.distToLineSq = this.lineBound.subtract(this.planeBound).lengthSquared();
|
||||
this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared();
|
||||
}
|
||||
|
||||
//Make it from a plane into a line
|
||||
//Select the axis that is longest
|
||||
private Vec3d toLongestLine(Vec3d boundVec, BlockPos firstPos) {
|
||||
BlockPos bound = new BlockPos(boundVec);
|
||||
|
||||
BlockPos firstToSecond = bound.subtract(firstPos);
|
||||
firstToSecond = new BlockPos(Math.abs(firstToSecond.getX()), Math.abs(firstToSecond.getY()), Math.abs(firstToSecond.getZ()));
|
||||
int longest = Math.max(firstToSecond.getX(), Math.max(firstToSecond.getY(), firstToSecond.getZ()));
|
||||
if (longest == firstToSecond.getX()) {
|
||||
return new Vec3d(bound.getX(), firstPos.getY(), firstPos.getZ());
|
||||
}
|
||||
if (longest == firstToSecond.getY()) {
|
||||
return new Vec3d(firstPos.getX(), bound.getY(), firstPos.getZ());
|
||||
}
|
||||
if (longest == firstToSecond.getZ()) {
|
||||
return new Vec3d(firstPos.getX(), firstPos.getY(), bound.getZ());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//check if its not behind the player and its not too close and not too far
|
||||
//also check if raytrace from player to block does not intersect blocks
|
||||
public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) {
|
||||
|
||||
boolean intersects = false;
|
||||
if (!skipRaytrace) {
|
||||
//collision within a 1 block radius to selected is fine
|
||||
RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, lineBound, false, true, false);
|
||||
intersects = rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK &&
|
||||
planeBound.subtract(rayTraceResult.hitVec).lengthSquared() > 4;
|
||||
}
|
||||
|
||||
return planeBound.subtract(start).dotProduct(look) > 0 &&
|
||||
distToPlayerSq > 4 && distToPlayerSq < reach * reach &&
|
||||
!intersects;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(EntityPlayer player) {
|
||||
rightClickClientTable.put(player.getUniqueID(), 0);
|
||||
@@ -69,107 +120,13 @@ public class Line implements IBuildMode {
|
||||
if (blockPos != null)
|
||||
list.add(blockPos);
|
||||
} else {
|
||||
Vec3d look = player.getLookVec();
|
||||
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
|
||||
|
||||
|
||||
//try on x axis
|
||||
double x = firstPos.getX();
|
||||
|
||||
//then y and z are
|
||||
double y = (x - start.x) / look.x * look.y + start.y;
|
||||
double z = (x - start.x) / look.x * look.z + start.z;
|
||||
|
||||
Vec3d xBound = new Vec3d(x, y, z);
|
||||
Vec3d xBoundLine = toLongestLine(xBound, firstPos);
|
||||
double xDistToLine = xBoundLine.subtract(xBound).lengthSquared();
|
||||
|
||||
//distance to player
|
||||
double xDistSquared = xBound.subtract(start).lengthSquared();
|
||||
|
||||
|
||||
|
||||
//try on y axis
|
||||
y = firstPos.getY();
|
||||
|
||||
//then x and z are
|
||||
x = (y - start.y) / look.y * look.x + start.x;
|
||||
z = (y - start.y) / look.y * look.z + start.z;
|
||||
|
||||
Vec3d yBound = new Vec3d(x, y, z);
|
||||
Vec3d yBoundLine = toLongestLine(yBound, firstPos);
|
||||
double yDistToLine = yBoundLine.subtract(yBound).lengthSquared();
|
||||
|
||||
//distance to player
|
||||
double yDistSquared = yBound.subtract(start).lengthSquared();
|
||||
|
||||
|
||||
|
||||
//try on z axis
|
||||
z = firstPos.getZ();
|
||||
|
||||
//then x and y are
|
||||
x = (z - start.z) / look.z * look.x + start.x;
|
||||
y = (z - start.z) / look.z * look.y + start.y;
|
||||
|
||||
Vec3d zBound = new Vec3d(x, y, z);
|
||||
Vec3d zBoundLine = toLongestLine(zBound, firstPos);
|
||||
double zDistToLine = zBoundLine.subtract(zBound).lengthSquared();
|
||||
|
||||
//distance to player
|
||||
double zDistSquared = zBound.subtract(start).lengthSquared();
|
||||
|
||||
|
||||
|
||||
int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach
|
||||
|
||||
//check if its not behind the player and its not too close and not too far
|
||||
boolean xValid = xBound.subtract(start).dotProduct(look) > 0 &&
|
||||
xDistSquared > 4 && xDistSquared < reach * reach;
|
||||
|
||||
boolean yValid = yBound.subtract(start).dotProduct(look) > 0 &&
|
||||
yDistSquared > 4 && yDistSquared < reach * reach;
|
||||
|
||||
boolean zValid = zBound.subtract(start).dotProduct(look) > 0 &&
|
||||
zDistSquared > 4 && zDistSquared < reach * reach;
|
||||
|
||||
//select the one that is closest (from wall position to its line counterpart) and is valid
|
||||
//TODO: if multiple are very close, choose closest to player
|
||||
Vec3d selected = null;
|
||||
double selectedDistToLine = 0;
|
||||
|
||||
if (xValid) {
|
||||
selected = xBoundLine;
|
||||
selectedDistToLine = xDistToLine;
|
||||
} else if (yValid) {
|
||||
selected = yBoundLine;
|
||||
selectedDistToLine = yDistToLine;
|
||||
} else if (zValid) {
|
||||
selected = zBoundLine;
|
||||
selectedDistToLine = yDistToLine;
|
||||
}
|
||||
|
||||
if (yValid && yDistToLine < selectedDistToLine) selected = yBoundLine;
|
||||
if (zValid && zDistToLine < selectedDistToLine) selected = zBoundLine;
|
||||
|
||||
if (selected == null) return list;
|
||||
|
||||
//check if it doesnt go through blocks
|
||||
if (!skipRaytrace) {
|
||||
RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false);
|
||||
if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
//return empty list
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
BlockPos secondPos = new BlockPos(selected);
|
||||
BlockPos secondPos = findLine(player, firstPos, skipRaytrace);
|
||||
if (secondPos == null) return list;
|
||||
|
||||
//Limit amount of blocks we can place
|
||||
int axisLimit = ReachHelper.getMaxBlocksPerAxis(player);
|
||||
|
||||
//Add whole line
|
||||
|
||||
int x1 = firstPos.getX(), x2 = secondPos.getX();
|
||||
int y1 = firstPos.getY(), y2 = secondPos.getY();
|
||||
int z1 = firstPos.getZ(), z2 = secondPos.getZ();
|
||||
@@ -190,26 +147,51 @@ public class Line implements IBuildMode {
|
||||
return list;
|
||||
}
|
||||
|
||||
//Make it into a line
|
||||
//Select the axis that is longest
|
||||
private Vec3d toLongestLine(Vec3d boundVec, BlockPos firstPos) {
|
||||
BlockPos bound = new BlockPos(boundVec);
|
||||
public BlockPos findLine(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) {
|
||||
Vec3d look = player.getLookVec();
|
||||
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
|
||||
List<Criteria> criteriaList = new ArrayList<>(3);
|
||||
|
||||
//X
|
||||
Vec3d xBound = BuildModes.findXBound(firstPos.getX(), start, look);
|
||||
criteriaList.add(new Criteria(xBound, firstPos, start));
|
||||
|
||||
//Y
|
||||
Vec3d yBound = BuildModes.findYBound(firstPos.getY(), start, look);
|
||||
criteriaList.add(new Criteria(yBound, firstPos, start));
|
||||
|
||||
//Z
|
||||
Vec3d zBound = BuildModes.findZBound(firstPos.getZ(), start, look);
|
||||
criteriaList.add(new Criteria(zBound, firstPos, start));
|
||||
|
||||
//Remove invalid criteria
|
||||
int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach
|
||||
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
|
||||
|
||||
//If none are valid, return empty list of blocks
|
||||
if (criteriaList.isEmpty()) return null;
|
||||
|
||||
//If only 1 is valid, choose that one
|
||||
Criteria selected = criteriaList.get(0);
|
||||
|
||||
//If multiple are valid, choose based on criteria
|
||||
if (criteriaList.size() > 1) {
|
||||
//Select the one that is closest (from wall position to its line counterpart)
|
||||
for (int i = 1; i < criteriaList.size(); i++) {
|
||||
Criteria criteria = criteriaList.get(i);
|
||||
if (criteria.distToLineSq < selected.distToLineSq)
|
||||
selected = criteria;
|
||||
}
|
||||
|
||||
//TODO: if multiple are very close, choose closest to player
|
||||
|
||||
BlockPos firstToSecond = bound.subtract(firstPos);
|
||||
firstToSecond = new BlockPos(Math.abs(firstToSecond.getX()), Math.abs(firstToSecond.getY()), Math.abs(firstToSecond.getZ()));
|
||||
int longest = Math.max(firstToSecond.getX(), Math.max(firstToSecond.getY(), firstToSecond.getZ()));
|
||||
if (longest == firstToSecond.getX()) {
|
||||
return new Vec3d(bound.getX(), firstPos.getY(), firstPos.getZ());
|
||||
}
|
||||
if (longest == firstToSecond.getY()) {
|
||||
return new Vec3d(firstPos.getX(), bound.getY(), firstPos.getZ());
|
||||
}
|
||||
if (longest == firstToSecond.getZ()) {
|
||||
return new Vec3d(firstPos.getX(), firstPos.getY(), bound.getZ());
|
||||
}
|
||||
return null;
|
||||
|
||||
return new BlockPos(selected.lineBound);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EnumFacing getSideHit(EntityPlayer player) {
|
||||
return sideHitTable.get(player.getUniqueID());
|
||||
|
||||
@@ -18,6 +18,35 @@ public class Wall implements IBuildMode {
|
||||
Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
|
||||
Dictionary<UUID, Vec3d> hitVecTable = new Hashtable<>();
|
||||
|
||||
class Criteria {
|
||||
Vec3d planeBound;
|
||||
double distToPlayerSq;
|
||||
double angle;
|
||||
|
||||
Criteria(Vec3d planeBound, BlockPos firstPos, Vec3d start, Vec3d look) {
|
||||
this.planeBound = planeBound;
|
||||
this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared();
|
||||
this.angle = this.planeBound.subtract(new Vec3d(firstPos)).normalize().dotProduct(look);
|
||||
}
|
||||
|
||||
//check if its not behind the player and its not too close and not too far
|
||||
//also check if raytrace from player to block does not intersect blocks
|
||||
public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) {
|
||||
|
||||
boolean intersects = false;
|
||||
if (!skipRaytrace) {
|
||||
//collision within a 1 block radius to selected is fine
|
||||
RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, planeBound, false, true, false);
|
||||
intersects = rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK &&
|
||||
planeBound.subtract(rayTraceResult.hitVec).lengthSquared() > 4;
|
||||
}
|
||||
|
||||
return planeBound.subtract(start).dotProduct(look) > 0 &&
|
||||
distToPlayerSq > 4 && distToPlayerSq < reach * reach &&
|
||||
!intersects;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(EntityPlayer player) {
|
||||
rightClickClientTable.put(player.getUniqueID(), 0);
|
||||
@@ -69,72 +98,11 @@ public class Wall implements IBuildMode {
|
||||
if (blockPos != null)
|
||||
list.add(blockPos);
|
||||
} else {
|
||||
Vec3d look = player.getLookVec();
|
||||
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
|
||||
//try on x axis
|
||||
double x = firstPos.getX();
|
||||
|
||||
//then y and z are
|
||||
double y = (x - start.x) / look.x * look.y + start.y;
|
||||
double z = (x - start.x) / look.x * look.z + start.z;
|
||||
|
||||
Vec3d xBound = new Vec3d(x, y, z);
|
||||
|
||||
//distance to player
|
||||
double xDistSquared = xBound.subtract(start).lengthSquared();
|
||||
|
||||
//angle to look
|
||||
//double xAngle = xBound.subtract(new Vec3d(firstPos)).normalize().dotProduct(look);
|
||||
|
||||
//try on z axis
|
||||
z = firstPos.getZ();
|
||||
|
||||
//then x and y are
|
||||
x = (z - start.z) / look.z * look.x + start.x;
|
||||
y = (z - start.z) / look.z * look.y + start.y;
|
||||
|
||||
Vec3d zBound = new Vec3d(x, y, z);
|
||||
|
||||
//distance to player
|
||||
double zDistSquared = zBound.subtract(start).lengthSquared();
|
||||
|
||||
//angle to look
|
||||
//double zAngle = zBound.subtract(new Vec3d(firstPos)).normalize().dotProduct(look);
|
||||
|
||||
int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach
|
||||
|
||||
//check if its not behind the player and its not too close and not too far
|
||||
boolean xValid = xBound.subtract(start).dotProduct(look) > 0 &&
|
||||
xDistSquared > 4 && xDistSquared < reach * reach;
|
||||
|
||||
boolean zValid = zBound.subtract(start).dotProduct(look) > 0 &&
|
||||
zDistSquared > 4 && zDistSquared < reach * reach;
|
||||
|
||||
//select the one that is closest and is valid
|
||||
Vec3d selected = null;
|
||||
if (xValid)
|
||||
selected = xBound;
|
||||
else if (zValid)
|
||||
selected = zBound;
|
||||
if (zValid && zDistSquared < xDistSquared/*Math.abs(zAngle) < Math.abs(xAngle)*/) selected = zBound;
|
||||
|
||||
if (selected == null) return list;
|
||||
|
||||
//check if it doesnt go through blocks
|
||||
//TODO collision within a 1 block radius to selected is fine
|
||||
if (!skipRaytrace) {
|
||||
RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false);
|
||||
if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
//return empty list
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
BlockPos secondPos = new BlockPos(selected);
|
||||
BlockPos secondPos = findWall(player, firstPos, skipRaytrace);
|
||||
if (secondPos == null) return list;
|
||||
|
||||
//Add whole wall
|
||||
//Limit amount of blocks you can place per row
|
||||
//Limit amount of blocks we can place per row
|
||||
int limit = ReachHelper.getMaxBlocksPlacedAtOnce(player);
|
||||
int axisLimit = ReachHelper.getMaxBlocksPerAxis(player);
|
||||
|
||||
@@ -168,6 +136,46 @@ public class Wall implements IBuildMode {
|
||||
return list;
|
||||
}
|
||||
|
||||
public BlockPos findWall(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) {
|
||||
Vec3d look = player.getLookVec();
|
||||
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
|
||||
List<Criteria> criteriaList = new ArrayList<>(3);
|
||||
|
||||
//X
|
||||
Vec3d xBound = BuildModes.findXBound(firstPos.getX(), start, look);
|
||||
criteriaList.add(new Criteria(xBound, firstPos, start, look));
|
||||
|
||||
//Z
|
||||
Vec3d zBound = BuildModes.findZBound(firstPos.getZ(), start, look);
|
||||
criteriaList.add(new Criteria(zBound, firstPos, start, look));
|
||||
|
||||
//Remove invalid criteria
|
||||
int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach
|
||||
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
|
||||
|
||||
//If none are valid, return empty list of blocks
|
||||
if (criteriaList.isEmpty()) return null;
|
||||
|
||||
//If only 1 is valid, choose that one
|
||||
Criteria selected = criteriaList.get(0);
|
||||
|
||||
//If multiple are valid, choose based on criteria
|
||||
if (criteriaList.size() > 1) {
|
||||
//Select the one that is closest
|
||||
for (int i = 1; i < criteriaList.size(); i++) {
|
||||
Criteria criteria = criteriaList.get(i);
|
||||
if (criteria.distToPlayerSq < selected.distToPlayerSq)
|
||||
selected = criteria;
|
||||
}
|
||||
|
||||
//TODO: limit angle
|
||||
//Math.abs(zAngle) < Math.abs(xAngle)
|
||||
}
|
||||
|
||||
return new BlockPos(selected.planeBound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumFacing getSideHit(EntityPlayer player) {
|
||||
return sideHitTable.get(player.getUniqueID());
|
||||
|
||||
@@ -300,7 +300,7 @@ public class BlockPreviewRenderer {
|
||||
|
||||
//Check if can place
|
||||
//If check is turned off, check if blockstate is the same (for dissolve effect)
|
||||
if ((!checkCanPlace /*&& player.world.getBlockState(blockPos) == blockState*/) || //TODO enable
|
||||
if ((!checkCanPlace /*&& player.world.getBlockState(blockPos) == blockState*/) || //TODO enable (breaks breaking shader)
|
||||
SurvivalHelper.canPlace(player.world, player, blockPos, blockState, itemstack, modifierSettings.doQuickReplace(), EnumFacing.UP)) {
|
||||
|
||||
ShaderHandler.useShader(ShaderHandler.dissolve, generateShaderCallback(dissolve,
|
||||
|
||||
Reference in New Issue
Block a user