forked from GrimAnticheat/Grim
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
All HitBox and CollisionBox Changes made for LineOfSightPlace
- Loading branch information
Showing
10 changed files
with
805 additions
and
278 deletions.
There are no files selected for viewing
201 changes: 45 additions & 156 deletions
201
src/main/java/ac/grim/grimac/utils/collisions/CollisionData.java
Large diffs are not rendered by default.
Oops, something went wrong.
537 changes: 417 additions & 120 deletions
537
src/main/java/ac/grim/grimac/utils/collisions/HitboxData.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicHitboxPane.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package ac.grim.grimac.utils.collisions.blocks.connecting; | ||
|
||
import ac.grim.grimac.player.GrimPlayer; | ||
import ac.grim.grimac.utils.collisions.CollisionData; | ||
import ac.grim.grimac.utils.collisions.datatypes.*; | ||
import com.github.retrooper.packetevents.PacketEvents; | ||
import com.github.retrooper.packetevents.manager.server.ServerVersion; | ||
import com.github.retrooper.packetevents.protocol.player.ClientVersion; | ||
import com.github.retrooper.packetevents.protocol.world.BlockFace; | ||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; | ||
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags; | ||
import com.github.retrooper.packetevents.protocol.world.states.enums.*; | ||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType; | ||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes; | ||
|
||
public class DynamicHitboxPane extends DynamicConnecting implements HitBoxFactory { | ||
|
||
private static final CollisionBox[] COLLISION_BOXES = makeShapes(1.0F, 1.0F, 16.0F, 0.0F, 16.0F, true); | ||
|
||
@Override | ||
public CollisionBox fetch(GrimPlayer player, StateType item, ClientVersion version, WrappedBlockState block, int x, int y, int z) { | ||
boolean east, north, south, west; | ||
|
||
// 1.13+ servers on 1.13+ clients send the full fence data | ||
if (isModernVersion(version)) { | ||
east = block.getEast() != East.FALSE; | ||
north = block.getNorth() != North.FALSE; | ||
south = block.getSouth() != South.FALSE; | ||
west = block.getWest() != West.FALSE; | ||
} else { | ||
east = connectsTo(player, version, x, y, z, BlockFace.EAST); | ||
north = connectsTo(player, version, x, y, z, BlockFace.NORTH); | ||
south = connectsTo(player, version, x, y, z, BlockFace.SOUTH); | ||
west = connectsTo(player, version, x, y, z, BlockFace.WEST); | ||
} | ||
|
||
// On 1.7 and 1.8 clients, and 1.13+ clients on 1.7 and 1.8 servers, the glass pane is + instead of | | ||
if (shouldUseOldPaneShape(version, north, south, east, west)) { | ||
north = south = east = west = true; | ||
} | ||
|
||
return version.isNewerThanOrEquals(ClientVersion.V_1_9) | ||
? getModernCollisionBox(north, east, south, west) | ||
: getLegacyCollisionBox(north, east, south, west); | ||
} | ||
|
||
private boolean isModernVersion(ClientVersion version) { | ||
return PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_13) | ||
&& version.isNewerThanOrEquals(ClientVersion.V_1_13); | ||
} | ||
|
||
private boolean shouldUseOldPaneShape(ClientVersion version, boolean north, boolean south, boolean east, boolean west) { | ||
return (!north && !south && !east && !west) && | ||
(version.isOlderThanOrEquals(ClientVersion.V_1_8) || | ||
(PacketEvents.getAPI().getServerManager().getVersion().isOlderThanOrEquals(ServerVersion.V_1_8_8) && | ||
version.isNewerThanOrEquals(ClientVersion.V_1_13))); | ||
} | ||
|
||
private CollisionBox getModernCollisionBox(boolean north, boolean east, boolean south, boolean west) { | ||
return COLLISION_BOXES[getAABBIndex(north, east, south, west)].copy(); | ||
} | ||
|
||
private CollisionBox getLegacyCollisionBox(boolean north, boolean east, boolean south, boolean west) { | ||
float minX = 0.4375F; | ||
float maxX = 0.5625F; | ||
float minZ = 0.4375F; | ||
float maxZ = 0.5625F; | ||
|
||
if ((!west || !east) && (west || east || north || south)) { | ||
if (west) { | ||
minX = 0.0F; | ||
} else if (east) { | ||
maxX = 1.0F; | ||
} | ||
} else { | ||
minX = 0.0F; | ||
maxX = 1.0F; | ||
} | ||
|
||
if ((!north || !south) && (west || east || north || south)) { | ||
if (north) { | ||
minZ = 0.0F; | ||
} else if (south) { | ||
maxZ = 1.0F; | ||
} | ||
} else { | ||
minZ = 0.0F; | ||
maxZ = 1.0F; | ||
} | ||
|
||
return new SimpleCollisionBox(minX, 0.0F, minZ, maxX, 1.0F, maxZ); | ||
} | ||
|
||
@Override | ||
public boolean canConnectToGlassBlock() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two, BlockFace direction) { | ||
if (BlockTags.GLASS_PANES.contains(one) || one == StateTypes.IRON_BARS) { | ||
return true; | ||
} else { | ||
return CollisionData.getData(one) | ||
.getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0) | ||
.isSideFullBlock(direction); | ||
} | ||
} | ||
} |
111 changes: 111 additions & 0 deletions
111
src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicHitboxWall.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package ac.grim.grimac.utils.collisions.blocks.connecting; | ||
|
||
import ac.grim.grimac.player.GrimPlayer; | ||
import ac.grim.grimac.utils.collisions.CollisionData; | ||
import ac.grim.grimac.utils.collisions.datatypes.*; | ||
import com.github.retrooper.packetevents.PacketEvents; | ||
import com.github.retrooper.packetevents.manager.server.ServerVersion; | ||
import com.github.retrooper.packetevents.protocol.player.ClientVersion; | ||
import com.github.retrooper.packetevents.protocol.world.BlockFace; | ||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; | ||
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags; | ||
import com.github.retrooper.packetevents.protocol.world.states.enums.*; | ||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType; | ||
|
||
public class DynamicHitboxWall extends DynamicConnecting implements HitBoxFactory { | ||
private static final CollisionBox[] HIT_BOXES = makeShapes(4.0F, 3.0F, 16.0F, 0.0F, 16.0F, false); | ||
|
||
@Override | ||
public CollisionBox fetch(GrimPlayer player, StateType heldItem, ClientVersion version, WrappedBlockState state, int x, int y, int z) { | ||
int[] connections = getConnections(player, version, state, x, y, z); | ||
int north = connections[0], south = connections[1], west = connections[2], east = connections[3], up = connections[4]; | ||
|
||
if (version.isNewerThanOrEquals(ClientVersion.V_1_13)) { | ||
return getModernHitBox(north, south, west, east, up); | ||
} else { | ||
return getLegacyHitBox(north, south, west, east); | ||
} | ||
} | ||
|
||
private int[] getConnections(GrimPlayer player, ClientVersion version, WrappedBlockState state, int x, int y, int z) { | ||
int north = 0, south = 0, west = 0, east = 0, up = 0; | ||
|
||
if (isModernServer()) { | ||
boolean sixteen = PacketEvents.getAPI().getServerManager().getVersion().isNewerThan(ServerVersion.V_1_16); | ||
north = getConnectionValue(state.getNorth(), sixteen); | ||
east = getConnectionValue(state.getEast(), sixteen); | ||
south = getConnectionValue(state.getSouth(), sixteen); | ||
west = getConnectionValue(state.getWest(), sixteen); | ||
up = state.isUp() ? 1 : 0; | ||
} else { | ||
north = connectsTo(player, version, x, y, z, BlockFace.NORTH) ? 1 : 0; | ||
south = connectsTo(player, version, x, y, z, BlockFace.SOUTH) ? 1 : 0; | ||
west = connectsTo(player, version, x, y, z, BlockFace.WEST) ? 1 : 0; | ||
east = connectsTo(player, version, x, y, z, BlockFace.EAST) ? 1 : 0; | ||
up = 1; | ||
} | ||
|
||
return new int[]{north, south, west, east, up}; | ||
} | ||
|
||
private boolean isModernServer() { | ||
return PacketEvents.getAPI().getServerManager().getVersion().isNewerThan(ServerVersion.V_1_12_2); | ||
} | ||
|
||
private int getConnectionValue(Enum<?> direction, boolean sixteen) { | ||
if (direction == North.NONE || direction == East.NONE || direction == South.NONE || direction == West.NONE) { | ||
return 0; | ||
} | ||
return (direction == North.LOW || direction == East.LOW || direction == South.LOW || direction == West.LOW || sixteen) ? 1 : 2; | ||
} | ||
|
||
private CollisionBox getModernHitBox(int north, int south, int west, int east, int up) { | ||
ComplexCollisionBox box = new ComplexCollisionBox(); | ||
if (up == 1) { | ||
box.add(new HexCollisionBox(4, 0, 4, 12, 16, 12)); | ||
} | ||
|
||
addDirectionalBox(box, north, 5, 0, 0.0D, 11, 14, 11); | ||
addDirectionalBox(box, south, 5, 0, 5, 11, 14, 16); | ||
addDirectionalBox(box, west, 0, 0, 5, 11, 14, 11); | ||
addDirectionalBox(box, east, 5, 0, 5, 16, 14, 11); | ||
|
||
return box; | ||
} | ||
|
||
private void addDirectionalBox(ComplexCollisionBox box, int direction, double x1, double y1, double z1, double x2, double y2, double z2) { | ||
if (direction == 1) { | ||
box.add(new HexCollisionBox(x1, y1, z1, x2, y2, z2)); | ||
} else if (direction == 2) { | ||
box.add(new HexCollisionBox(x1, y1, z1, x2, 16, z2)); | ||
} | ||
} | ||
|
||
private CollisionBox getLegacyHitBox(int north, int south, int west, int east) { | ||
float minX = 0.25F, maxX = 0.75F, minZ = 0.25F, maxZ = 0.75F; | ||
float maxY = 1.0F; | ||
|
||
if (north == 1) minZ = 0.0F; | ||
if (south == 1) maxZ = 1.0F; | ||
if (west == 1) minX = 0.0F; | ||
if (east == 1) maxX = 1.0F; | ||
|
||
if (north == 1 && south == 1 && west == 0 && east == 0) { | ||
maxY = 0.8125F; | ||
minX = 0.3125F; | ||
maxX = 0.6875F; | ||
} else if (west == 1 && east == 1 && north == 0 && south == 0) { | ||
maxY = 0.8125F; | ||
minZ = 0.3125F; | ||
maxZ = 0.6875F; | ||
} | ||
|
||
return new SimpleCollisionBox(minX, 0.0F, minZ, maxX, maxY, maxZ); | ||
} | ||
|
||
@Override | ||
public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two, BlockFace direction) { | ||
return BlockTags.WALLS.contains(one) || | ||
CollisionData.getData(one).getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0).isSideFullBlock(direction); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/main/java/ac/grim/grimac/utils/collisions/datatypes/HexOffsetCollisionBox.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package ac.grim.grimac.utils.collisions.datatypes; | ||
|
||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType; | ||
|
||
// Exists for the same reason as HexCollisionBox but for offset blocks; read comments there if unsure | ||
public class HexOffsetCollisionBox extends OffsetCollisionBox { | ||
public HexOffsetCollisionBox(StateType block, double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { | ||
super(block, minX / 16d, minY / 16d, minZ / 16d, maxX / 16d, maxY / 16d, maxZ / 16d); | ||
} | ||
} |
105 changes: 105 additions & 0 deletions
105
src/main/java/ac/grim/grimac/utils/collisions/datatypes/OffsetCollisionBox.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package ac.grim.grimac.utils.collisions.datatypes; | ||
|
||
import ac.grim.grimac.utils.math.GrimMath; | ||
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags; | ||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType; | ||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes; | ||
|
||
import java.util.HashSet; | ||
|
||
public class OffsetCollisionBox extends SimpleCollisionBox { | ||
|
||
public static enum OffsetType { | ||
NONE, | ||
XZ, | ||
XYZ, | ||
} | ||
|
||
float maxHorizontalModelOffset = 0.25F; | ||
float maxVerticalModelOffset = 0.2F; | ||
double offsetX = 0; | ||
double offsetY = 0; | ||
double offsetZ = 0; | ||
|
||
OffsetType offsetType; | ||
|
||
private static final HashSet<StateType> XZ_OFFSET_BLOCKSTATES = new HashSet<>(); | ||
private static final HashSet<StateType> XYZ_OFFSET_BLOCKSTATES = new HashSet<>(); | ||
|
||
static { | ||
// Can we add a hasOffSet to StateType() ? | ||
// Or a new BlockTag for XZ and XYZ Offset ? | ||
XZ_OFFSET_BLOCKSTATES.add(StateTypes.MANGROVE_PROPAGULE); | ||
|
||
XZ_OFFSET_BLOCKSTATES.addAll(BlockTags.SMALL_FLOWERS.getStates()); | ||
XZ_OFFSET_BLOCKSTATES.add(StateTypes.BAMBOO_SAPLING); | ||
XZ_OFFSET_BLOCKSTATES.add(StateTypes.BAMBOO); | ||
XZ_OFFSET_BLOCKSTATES.add(StateTypes.POINTED_DRIPSTONE); | ||
// Only offsets rendering HitBox on XZ // we should document this somewhere for future reference | ||
// XZ_OFFSET_BLOCKSTATES.addAll(BlockTags.TALL_FLOWERS.getStates()); | ||
// XZ_OFFSET_BLOCKSTATES.add(StateTypes.TALL_SEAGRASS); | ||
// XZ_OFFSET_BLOCKSTATES.add(StateTypes.TALL_GRASS); | ||
// XZ_OFFSET_BLOCKSTATES.add(StateTypes.LARGE_FERN); | ||
// XZ_OFFSET_BLOCKSTATES.add(StateTypes.WARPED_ROOTS); | ||
// XZ_OFFSET_BLOCKSTATES.add(StateTypes.NETHER_SPROUTS); | ||
// XZ_OFFSET_BLOCKSTATES.add(StateTypes.CRIMSON_ROOTS); | ||
// XZ_OFFSET_BLOCKSTATES.add(StateTypes.HANGING_ROOTS); | ||
|
||
// Only offsets rendering on XYZ, not HitBox | ||
// XYZ_OFFSET_BLOCKSTATES.add(StateTypes.SHORT_GRASS); | ||
// XYZ_OFFSET_BLOCKSTATES.add(StateTypes.FERN); | ||
// XYZ_OFFSET_BLOCKSTATES.add(StateTypes.SMALL_DRIPLEAF); | ||
} | ||
|
||
public OffsetCollisionBox(StateType block, double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { | ||
super(minX, minY, minZ, maxX, maxY, maxZ); | ||
if (block.equals(StateTypes.POINTED_DRIPSTONE)) { | ||
maxHorizontalModelOffset = 0.125F; | ||
} | ||
// else if (block.equals(StateTypes.SMALL_DRIPLEAF)) { | ||
// maxVerticalModelOffset = 0.1F; | ||
// } | ||
|
||
if (XZ_OFFSET_BLOCKSTATES.contains(block)) { | ||
offsetType = OffsetType.XZ; | ||
return; | ||
} else if (XYZ_OFFSET_BLOCKSTATES.contains(block)) { | ||
offsetType = OffsetType.XYZ; | ||
return; | ||
} | ||
throw new RuntimeException("Invalid State Type for OffSetCollisionBox: " + block); | ||
} | ||
|
||
@Override | ||
public SimpleCollisionBox offset(double x, double y, double z) { | ||
// In case you want to call .offset() again or get the box values without offset. | ||
resetBlockStateOffSet(); | ||
long l; | ||
switch (offsetType) { | ||
case NONE: | ||
return super.offset(x, y, z); | ||
case XZ: | ||
l = GrimMath.hashCode(x, 0, z); | ||
offsetX = GrimMath.clamp(((double)((float)(l & 15L) / 15.0F) - 0.5) * 0.5, (double)(-maxHorizontalModelOffset), (double)maxHorizontalModelOffset); | ||
offsetZ = GrimMath.clamp(((double)((float)(l >> 8 & 15L) / 15.0F) - 0.5) * 0.5, (double)(-maxHorizontalModelOffset), (double)maxHorizontalModelOffset); | ||
return super.offset(x + offsetX, y, z + offsetZ); | ||
case XYZ: | ||
l = GrimMath.hashCode(x, 0, z); | ||
offsetY = ((double)((float)(l >> 4 & 15L) / 15.0F) - 1.0) * (double) maxVerticalModelOffset; | ||
offsetX = GrimMath.clamp(((double)((float)(l & 15L) / 15.0F) - 0.5) * 0.5, (double)(-maxHorizontalModelOffset), (double)maxHorizontalModelOffset); | ||
offsetZ = GrimMath.clamp(((double)((float)(l >> 8 & 15L) / 15.0F) - 0.5) * 0.5, (double)(-maxHorizontalModelOffset), (double)maxHorizontalModelOffset); | ||
return super.offset(x + offsetX, offsetY, z + offsetZ); | ||
} | ||
// You *really* shouldn't be using this class if offsetType = null | ||
return null; | ||
} | ||
|
||
public void resetBlockStateOffSet() { | ||
this.minX += offsetX; | ||
this.minY += offsetY; | ||
this.minZ += offsetZ; | ||
this.maxX += offsetX; | ||
this.maxY += offsetY; | ||
this.maxZ += offsetZ; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters