Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4848efc8a | ||
|
|
0ddf0b5d22 | ||
|
|
fde6e03b98 | ||
|
|
55c084216d | ||
|
|
f3074e3934 |
No files matched your search
@@ -63,7 +63,7 @@ public class MultiPlace extends BlockPlaceCheck {
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
if (player.getClientVersion().isNewerThan(ClientVersion.V_1_8) && !player.skippedTickInActualMovement) {
|
||||
if (player.getClientVersion().isNewerThan(ClientVersion.V_1_8) && !player.skippedTickInActualMovement && predictionComplete.isChecked()) {
|
||||
for (String verbose : flags) {
|
||||
flagAndAlert(verbose);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,12 @@ package ac.grim.grimac.utils.collisions;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.predictionengine.movementtick.MovementTickerStrider;
|
||||
import ac.grim.grimac.utils.collisions.blocks.*;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicCollisionFence;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicCollisionPane;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicCollisionWall;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicFence;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicPane;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicWall;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.*;
|
||||
import ac.grim.grimac.utils.data.packetentity.PacketEntityStrider;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.nmsutil.Materials;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
@@ -24,7 +25,6 @@ import com.viaversion.viaversion.api.Via;
|
||||
import io.github.retrooper.packetevents.util.viaversion.ViaVersionUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
// Warning for major game updates!
|
||||
// Do not use an enum for stuff like Axis and other data types not in 1.7
|
||||
@@ -71,7 +71,9 @@ public enum CollisionData {
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}, StateTypes.LAVA),
|
||||
|
||||
BREWING_STAND((player, version, block, x, y, z) -> {
|
||||
WATER(NoCollisionBox.INSTANCE, StateTypes.WATER),
|
||||
|
||||
BREWINGSTAND((player, version, block, x, y, z) -> {
|
||||
int base = 0;
|
||||
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_13))
|
||||
@@ -84,13 +86,27 @@ public enum CollisionData {
|
||||
}, StateTypes.BREWING_STAND),
|
||||
|
||||
BAMBOO((player, version, block, x, y, z) -> {
|
||||
// ViaVersion replacement, sugarcane
|
||||
if (version.isOlderThan(ClientVersion.V_1_14)) {
|
||||
// ViaVersion replacement block - sugarcane
|
||||
if (version.isOlderThan(ClientVersion.V_1_13_2))
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}
|
||||
return new HexOffsetCollisionBox(block.getType(), 6.5D, 0.0D, 6.5D, 9.5D, 16.0D, 9.5D);
|
||||
|
||||
// Offset taken from NMS
|
||||
long i = (x * 3129871L) ^ (long) z * 116129781L ^ (long) 0;
|
||||
i = i * i * 42317861L + i * 11L;
|
||||
i = i >> 16;
|
||||
|
||||
return new HexCollisionBox(6.5D, 0.0D, 6.5D, 9.5D, 16.0D, 9.5D).offset((((i & 15L) / 15.0F) - 0.5D) * 0.5D, 0, (((i >> 8 & 15L) / 15.0F) - 0.5D) * 0.5D);
|
||||
}, StateTypes.BAMBOO),
|
||||
|
||||
|
||||
BAMBOO_SAPLING((player, version, block, x, y, z) -> {
|
||||
long i = (x * 3129871L) ^ (long) z * 116129781L ^ (long) 0;
|
||||
i = i * i * 42317861L + i * 11L;
|
||||
i = i >> 16;
|
||||
|
||||
return new HexCollisionBox(4.0D, 0.0D, 4.0D, 12.0D, 12.0D, 12.0D).offset((((i & 15L) / 15.0F) - 0.5D) * 0.5D, 0, (((i >> 8 & 15L) / 15.0F) - 0.5D) * 0.5D);
|
||||
}, StateTypes.BAMBOO_SAPLING),
|
||||
|
||||
COMPOSTER((player, version, block, x, y, z) -> {
|
||||
double height = 0.125;
|
||||
|
||||
@@ -143,7 +159,7 @@ public enum CollisionData {
|
||||
}
|
||||
}, BlockTags.ANVIL.getStates().toArray(new StateType[0])),
|
||||
|
||||
WALL(new DynamicCollisionWall(), BlockTags.WALLS.getStates().toArray(new StateType[0])),
|
||||
WALL(new DynamicWall(), BlockTags.WALLS.getStates().toArray(new StateType[0])),
|
||||
|
||||
SLAB((player, version, data, x, y, z) -> {
|
||||
Type slabType = data.getTypeData();
|
||||
@@ -161,7 +177,7 @@ public enum CollisionData {
|
||||
SKULL(new SimpleCollisionBox(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F, false),
|
||||
StateTypes.CREEPER_HEAD, StateTypes.ZOMBIE_HEAD, StateTypes.DRAGON_HEAD, StateTypes.PLAYER_HEAD,
|
||||
StateTypes.SKELETON_SKULL, StateTypes.WITHER_SKELETON_SKULL, StateTypes.HEAVY_CORE),
|
||||
|
||||
|
||||
PIGLIN_HEAD(new HexCollisionBox(3.0D, 0.0D, 3.0D, 13.0D, 8.0D, 13.0D), StateTypes.PIGLIN_HEAD),
|
||||
|
||||
// Overwrite previous SKULL enum for legacy, where head and wall skull isn't separate
|
||||
@@ -194,6 +210,13 @@ public enum CollisionData {
|
||||
}
|
||||
}, StateTypes.PIGLIN_WALL_HEAD),
|
||||
|
||||
BANNER(new HexCollisionBox(4.0D, 0.0D, 4.0D, 12.0D, 16.0D, 12.0D),
|
||||
BlockTags.BANNERS.getStates().toArray(new StateType[0])),
|
||||
|
||||
CORAL_FAN((player, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 4.0D, 14.0D);
|
||||
}, BlockTags.CORALS.getStates().toArray(new StateType[0])),
|
||||
|
||||
DOOR(new DoorHandler(), BlockTags.DOORS.getStates().toArray(new StateType[0])),
|
||||
|
||||
HOPPER((player, version, data, x, y, z) -> {
|
||||
@@ -258,31 +281,43 @@ public enum CollisionData {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D);
|
||||
}, StateTypes.STONECUTTER),
|
||||
|
||||
CORAL_FAN(NoCollisionBox.INSTANCE, BlockTags.CORALS.getStates().toArray(new StateType[0])),
|
||||
SWEET_BERRY((player, version, data, x, y, z) -> {
|
||||
if (data.getAge() == 0) {
|
||||
return new HexCollisionBox(3.0D, 0.0D, 3.0D, 13.0D, 8.0D, 13.0D);
|
||||
} else if (data.getAge() < 3) {
|
||||
return new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D);
|
||||
}
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}, StateTypes.SWEET_BERRY_BUSH),
|
||||
|
||||
RAILS(NoCollisionBox.INSTANCE, BlockTags.RAILS.getStates().toArray(new StateType[0])),
|
||||
SAPLING(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D),
|
||||
BlockTags.SAPLINGS.getStates().toArray(new StateType[0])),
|
||||
|
||||
BANNER(NoCollisionBox.INSTANCE, BlockTags.BANNERS.getStates().toArray(new StateType[0])),
|
||||
ROOTS(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D),
|
||||
StateTypes.WARPED_ROOTS, StateTypes.CRIMSON_ROOTS),
|
||||
|
||||
SMALL_FLOWER(NoCollisionBox.INSTANCE, BlockTags.SMALL_FLOWERS.getStates().toArray(new StateType[0])),
|
||||
FLOWER(new HexCollisionBox(5.0D, 0.0D, 5.0D, 11.0D, 10.0D, 11.0D),
|
||||
BlockTags.SMALL_FLOWERS.getStates().toArray(new StateType[0])),
|
||||
|
||||
TALL_FLOWER(NoCollisionBox.INSTANCE, BlockTags.TALL_FLOWERS.getStates().toArray(new StateType[0])),
|
||||
DEAD_BUSH(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D), StateTypes.DEAD_BUSH),
|
||||
|
||||
SAPLING(NoCollisionBox.INSTANCE, BlockTags.SAPLINGS.getStates().toArray(new StateType[0])),
|
||||
SUGARCANE(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 16.0D, 14.0D), StateTypes.SUGAR_CANE),
|
||||
|
||||
BUTTON(NoCollisionBox.INSTANCE, BlockTags.BUTTONS.getStates().toArray(new StateType[0])),
|
||||
NETHER_SPROUTS(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 3.0D, 14.0D), StateTypes.NETHER_SPROUTS),
|
||||
|
||||
// All states that unconditionally have no collision and are not in a group where every member also has no collision.
|
||||
NO_COLLISION(NoCollisionBox.INSTANCE, StateTypes.TWISTING_VINES_PLANT, StateTypes.WEEPING_VINES_PLANT,
|
||||
StateTypes.TWISTING_VINES, StateTypes.WEEPING_VINES, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT,
|
||||
StateTypes.TALL_SEAGRASS, StateTypes.SEAGRASS, StateTypes.SHORT_GRASS, StateTypes.FERN, StateTypes.NETHER_SPROUTS,
|
||||
StateTypes.DEAD_BUSH, StateTypes.SUGAR_CANE, StateTypes.SWEET_BERRY_BUSH, StateTypes.WARPED_ROOTS,
|
||||
StateTypes.CRIMSON_ROOTS, StateTypes.TORCHFLOWER_CROP, StateTypes.PINK_PETALS, StateTypes.TALL_GRASS,
|
||||
StateTypes.LARGE_FERN, StateTypes.BAMBOO_SAPLING, StateTypes.HANGING_ROOTS,
|
||||
StateTypes.SMALL_DRIPLEAF, StateTypes.END_PORTAL, StateTypes.LEVER, StateTypes.PUMPKIN_STEM, StateTypes.MELON_STEM,
|
||||
StateTypes.ATTACHED_MELON_STEM, StateTypes.ATTACHED_PUMPKIN_STEM, StateTypes.BEETROOTS, StateTypes.POTATOES,
|
||||
StateTypes.WHEAT, StateTypes.CARROTS, StateTypes.NETHER_WART, StateTypes.MOVING_PISTON, StateTypes.AIR, StateTypes.CAVE_AIR,
|
||||
StateTypes.VOID_AIR, StateTypes.LIGHT, StateTypes.WATER),
|
||||
GRASS_FERN(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D),
|
||||
StateTypes.GRASS, StateTypes.FERN),
|
||||
|
||||
TALL_GRASS(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.TALL_GRASS),
|
||||
|
||||
SEA_GRASS(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D),
|
||||
StateTypes.SEAGRASS),
|
||||
|
||||
CAVE_VINES(new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D), StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT),
|
||||
|
||||
TWISTING_VINES_BLOCK(new HexCollisionBox(4.0D, 0.0D, 4.0D, 12.0D, 15.0D, 12.0D), StateTypes.TWISTING_VINES, StateTypes.WEEPING_VINES),
|
||||
|
||||
TWISTING_VINES(new HexCollisionBox(4.0D, 0.0D, 4.0D, 12.0D, 16.0D, 12.0D), StateTypes.TWISTING_VINES_PLANT, StateTypes.WEEPING_VINES_PLANT),
|
||||
|
||||
KELP(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D), StateTypes.KELP),
|
||||
// Kelp block is a full block, so it by default is correct
|
||||
@@ -410,6 +445,33 @@ public enum CollisionData {
|
||||
return new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 15.0D, 15.0D); // post
|
||||
}, StateTypes.HONEY_BLOCK),
|
||||
|
||||
SPORE_BLOSSOM(new HexCollisionBox(2.0D, 13.0D, 2.0D, 14.0D, 16.0D, 14.0D), StateTypes.SPORE_BLOSSOM),
|
||||
|
||||
GLOW_LICHEN((player, version, data, x, y, z) -> {
|
||||
ComplexCollisionBox box = new ComplexCollisionBox();
|
||||
|
||||
if (data.isUp()) {
|
||||
box.add(new HexCollisionBox(0.0D, 15.0D, 0.0D, 16.0D, 16.0D, 16.0D));
|
||||
}
|
||||
if (data.isDown()) {
|
||||
box.add(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D));
|
||||
}
|
||||
if (data.getWest() == West.TRUE) {
|
||||
box.add(new HexCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 16.0D, 16.0D));
|
||||
}
|
||||
if (data.getEast() == East.TRUE) {
|
||||
box.add(new HexCollisionBox(15.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D));
|
||||
}
|
||||
if (data.getNorth() == North.TRUE) {
|
||||
box.add(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 1.0D));
|
||||
}
|
||||
if (data.getSouth() == South.TRUE) {
|
||||
box.add(new HexCollisionBox(0.0D, 0.0D, 15.0D, 16.0D, 16.0D, 16.0D));
|
||||
}
|
||||
|
||||
return box;
|
||||
}, StateTypes.GLOW_LICHEN),
|
||||
|
||||
DRAGON_EGG_BLOCK(new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D), StateTypes.DRAGON_EGG),
|
||||
|
||||
GRINDSTONE((player, version, data, x, y, z) -> {
|
||||
@@ -505,7 +567,7 @@ public enum CollisionData {
|
||||
|
||||
}, StateTypes.GRINDSTONE),
|
||||
|
||||
PANE(new DynamicCollisionPane(), Materials.getPanes().toArray(new StateType[0])),
|
||||
PANE(new DynamicPane(), Materials.getPanes().toArray(new StateType[0])),
|
||||
|
||||
CHAIN_BLOCK((player, version, data, x, y, z) -> {
|
||||
if (version.isOlderThan(ClientVersion.V_1_16)) {
|
||||
@@ -542,7 +604,7 @@ public enum CollisionData {
|
||||
|
||||
}, BlockTags.FENCE_GATES.getStates().toArray(new StateType[0])),
|
||||
|
||||
FENCE(new DynamicCollisionFence(), BlockTags.FENCES.getStates().toArray(new StateType[0])),
|
||||
FENCE(new DynamicFence(), BlockTags.FENCES.getStates().toArray(new StateType[0])),
|
||||
|
||||
SNOW((player, version, data, x, y, z) -> {
|
||||
if (data.getLayers() == 1 && version.isNewerThanOrEquals(ClientVersion.V_1_13)) {
|
||||
@@ -620,6 +682,8 @@ public enum CollisionData {
|
||||
|
||||
}, StateTypes.FARMLAND),
|
||||
|
||||
HANGING_ROOTS(new HexCollisionBox(2.0D, 10.0D, 2.0D, 14.0D, 16.0D, 14.0D), StateTypes.HANGING_ROOTS),
|
||||
|
||||
GRASS_PATH((player, version, data, x, y, z) -> {
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_9))
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 15.0D, 16.0D);
|
||||
@@ -682,36 +746,17 @@ public enum CollisionData {
|
||||
}, StateTypes.END_ROD, StateTypes.LIGHTNING_ROD),
|
||||
|
||||
CAULDRON((player, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.getById(467))) { // changed in 19w13a, 1.14 Snapshot
|
||||
return new ComplexCollisionBox(
|
||||
new SimpleCollisionBox(0.0, 0.0, 0.0, 0.125, 1.0, 0.25, false),
|
||||
new SimpleCollisionBox(0.0, 0.0, 0.75, 0.125, 1.0, 1.0, false),
|
||||
new SimpleCollisionBox(0.125, 0.0, 0.0, 0.25, 1.0, 0.125, false),
|
||||
new SimpleCollisionBox(0.125, 0.0, 0.875, 0.25, 1.0, 1.0, false),
|
||||
new SimpleCollisionBox(0.75, 0.0, 0.0, 1.0, 1.0, 0.125, false),
|
||||
new SimpleCollisionBox(0.75, 0.0, 0.875, 1.0, 1.0, 1.0, false),
|
||||
new SimpleCollisionBox(0.875, 0.0, 0.125, 1.0, 1.0, 0.25, false),
|
||||
new SimpleCollisionBox(0.875, 0.0, 0.75, 1.0, 1.0, 0.875, false),
|
||||
new SimpleCollisionBox(0.0, 0.1875, 0.25, 1.0, 0.25, 0.75, false),
|
||||
new SimpleCollisionBox(0.125, 0.1875, 0.125, 0.875, 0.25, 0.25, false),
|
||||
new SimpleCollisionBox(0.125, 0.1875, 0.75, 0.875, 0.25, 0.875, false),
|
||||
new SimpleCollisionBox(0.25, 0.1875, 0.0, 0.75, 1.0, 0.125, false),
|
||||
new SimpleCollisionBox(0.25, 0.1875, 0.875, 0.75, 1.0, 1.0, false),
|
||||
new SimpleCollisionBox(0.0, 0.25, 0.25, 0.125, 1.0, 0.75, false),
|
||||
new SimpleCollisionBox(0.875, 0.25, 0.25, 1.0, 1.0, 0.75, false)
|
||||
);
|
||||
} else {
|
||||
double height = 0.25;
|
||||
if (version.isOlderThan(ClientVersion.V_1_13))
|
||||
height = 0.3125;
|
||||
double height = 0.25;
|
||||
|
||||
return new ComplexCollisionBox(
|
||||
new SimpleCollisionBox(0, 0, 0, 1, height, 1, false),
|
||||
new SimpleCollisionBox(0, height, 0, 0.125, 1, 1, false),
|
||||
new SimpleCollisionBox(1 - 0.125, height, 0, 1, 1, 1, false),
|
||||
new SimpleCollisionBox(0, height, 0, 1, 1, 0.125, false),
|
||||
new SimpleCollisionBox(0, height, 1 - 0.125, 1, 1, 1, false));
|
||||
}
|
||||
if (version.isOlderThan(ClientVersion.V_1_13))
|
||||
height = 0.3125;
|
||||
|
||||
return new ComplexCollisionBox(
|
||||
new SimpleCollisionBox(0, 0, 0, 1, height, 1, false),
|
||||
new SimpleCollisionBox(0, height, 0, 0.125, 1, 1, false),
|
||||
new SimpleCollisionBox(1 - 0.125, height, 0, 1, 1, 1, false),
|
||||
new SimpleCollisionBox(0, height, 0, 1, 1, 0.125, false),
|
||||
new SimpleCollisionBox(0, height, 1 - 0.125, 1, 1, 1, false));
|
||||
}, BlockTags.CAULDRONS.getStates().toArray(new StateType[0])),
|
||||
|
||||
CACTUS(new SimpleCollisionBox(0.0625, 0, 0.0625,
|
||||
@@ -784,18 +829,71 @@ public enum CollisionData {
|
||||
|
||||
CORAL_PLANT((player, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 15.0D, 14.0D);
|
||||
}, Stream.concat(
|
||||
Arrays.stream(BlockTags.CORAL_PLANTS.getStates().toArray(new StateType[0])),
|
||||
Stream.of(StateTypes.DEAD_HORN_CORAL, StateTypes.DEAD_TUBE_CORAL, StateTypes.DEAD_BRAIN_CORAL,
|
||||
StateTypes.DEAD_BUBBLE_CORAL, StateTypes.DEAD_FIRE_CORAL)
|
||||
)
|
||||
.distinct() // This will remove duplicates
|
||||
.toArray(StateType[]::new)
|
||||
),
|
||||
}, BlockTags.CORAL_PLANTS.getStates().toArray(new StateType[0])),
|
||||
|
||||
SIGN(new SimpleCollisionBox(0.25, 0.0, 0.25, 0.75, 1.0, 0.75, false),
|
||||
BlockTags.STANDING_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
BEETROOT((player, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, (data.getAge() + 1) * 2, 1.0D);
|
||||
}, StateTypes.BEETROOTS),
|
||||
|
||||
WHEAT((player, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, (data.getAge() + 1) * 2, 1.0D);
|
||||
}, StateTypes.WHEAT),
|
||||
|
||||
CARROT_NETHERWART((player, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, data.getAge() + 2, 1.0D);
|
||||
}, StateTypes.CARROTS, StateTypes.NETHER_WART),
|
||||
|
||||
NETHER_WART((player, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 5 + (data.getAge() * 3), 1.0D);
|
||||
}, StateTypes.NETHER_WART),
|
||||
|
||||
BUTTON((player, version, data, x, y, z) -> {
|
||||
double f2 = (float) (data.isPowered() ? 1 : 2) / 16.0;
|
||||
|
||||
switch (data.getFacing()) {
|
||||
case WEST:
|
||||
return new SimpleCollisionBox(0.0, 0.375, 0.3125, f2, 0.625, 0.6875, false);
|
||||
case EAST:
|
||||
return new SimpleCollisionBox(1.0 - f2, 0.375, 0.3125, 1.0, 0.625, 0.6875, false);
|
||||
case NORTH:
|
||||
return new SimpleCollisionBox(0.3125, 0.375, 0.0, 0.6875, 0.625, f2, false);
|
||||
case SOUTH:
|
||||
return new SimpleCollisionBox(0.3125, 0.375, 1.0 - f2, 0.6875, 0.625, 1.0, false);
|
||||
case DOWN:
|
||||
return new SimpleCollisionBox(0.3125, 0.0, 0.375, 0.6875, 0.0 + f2, 0.625, false);
|
||||
case UP:
|
||||
return new SimpleCollisionBox(0.3125, 1.0 - f2, 0.375, 0.6875, 1.0, 0.625, false);
|
||||
}
|
||||
|
||||
return NoCollisionBox.INSTANCE;
|
||||
|
||||
}, BlockTags.BUTTONS.getStates().toArray(new StateType[0])),
|
||||
|
||||
LEVER((player, version, data, x, y, z) -> {
|
||||
double f = 0.1875;
|
||||
|
||||
switch (data.getFacing()) {
|
||||
case WEST:
|
||||
return new SimpleCollisionBox(1.0 - f * 2.0, 0.2, 0.5 - f, 1.0, 0.8, 0.5 + f, false);
|
||||
case EAST:
|
||||
return new SimpleCollisionBox(0.0, 0.2, 0.5 - f, f * 2.0, 0.8, 0.5 + f, false);
|
||||
case NORTH:
|
||||
return new SimpleCollisionBox(0.5 - f, 0.2, 1.0 - f * 2.0, 0.5 + f, 0.8, 1.0, false);
|
||||
case SOUTH:
|
||||
return new SimpleCollisionBox(0.5 - f, 0.2, 0.0, 0.5 + f, 0.8, f * 2.0, false);
|
||||
case DOWN:
|
||||
return new SimpleCollisionBox(0.25, 0.4, 0.25, 0.75, 1.0, 0.75, false);
|
||||
case UP:
|
||||
return new SimpleCollisionBox(0.25, 0.0, 0.25, 0.75, 0.6, 0.75, false);
|
||||
}
|
||||
|
||||
return NoCollisionBox.INSTANCE;
|
||||
|
||||
}, StateTypes.LEVER),
|
||||
|
||||
STONE_PRESSURE_PLATE((player, version, data, x, y, z) -> {
|
||||
if (data.isPowered()) { // Pressed
|
||||
return new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 0.5D, 15.0D);
|
||||
@@ -827,6 +925,27 @@ public enum CollisionData {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D);
|
||||
}, StateTypes.TRIPWIRE),
|
||||
|
||||
ATTACHED_PUMPKIN_STEM((player, version, data, x, y, z) -> {
|
||||
if (version.isOlderThan(ClientVersion.V_1_13))
|
||||
return new HexCollisionBox(7.0D, 0.0D, 7.0D, 9.0D, 16.0D, 9.0D);
|
||||
|
||||
switch (data.getFacing()) {
|
||||
case SOUTH:
|
||||
return new HexCollisionBox(6.0D, 0.0D, 6.0D, 10.0D, 10.0D, 16.0D);
|
||||
case WEST:
|
||||
return new HexCollisionBox(0.0D, 0.0D, 6.0D, 10.0D, 10.0D, 10.0D);
|
||||
case NORTH:
|
||||
return new HexCollisionBox(6.0D, 0.0D, 0.0D, 10.0D, 10.0D, 10.0D);
|
||||
case EAST:
|
||||
default:
|
||||
return new HexCollisionBox(6.0D, 0.0D, 6.0D, 16.0D, 10.0D, 10.0D);
|
||||
}
|
||||
}, StateTypes.ATTACHED_MELON_STEM, StateTypes.ATTACHED_PUMPKIN_STEM),
|
||||
|
||||
PUMPKIN_STEM((player, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(7, 0, 7, 9, 2 * (data.getAge() + 1), 9);
|
||||
}, StateTypes.PUMPKIN_STEM, StateTypes.MELON_STEM),
|
||||
|
||||
TRIPWIRE_HOOK((player, version, data, x, y, z) -> {
|
||||
switch (data.getFacing()) {
|
||||
case NORTH:
|
||||
@@ -861,6 +980,20 @@ public enum CollisionData {
|
||||
|
||||
}, StateTypes.WALL_TORCH, StateTypes.REDSTONE_WALL_TORCH),
|
||||
|
||||
RAILS((player, version, data, x, y, z) -> {
|
||||
Shape shape = data.getShape();
|
||||
if (shape == Shape.ASCENDING_EAST || shape == Shape.ASCENDING_WEST ||
|
||||
shape == Shape.ASCENDING_NORTH || shape == Shape.ASCENDING_SOUTH) {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D);
|
||||
}
|
||||
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D);
|
||||
|
||||
}, BlockTags.RAILS.getStates().toArray(new StateType[0])),
|
||||
|
||||
// Known as block 36 - has no collision box
|
||||
TECHNICAL_MOVING_PISTON(NoCollisionBox.INSTANCE, StateTypes.MOVING_PISTON),
|
||||
|
||||
// 1.17 blocks
|
||||
CANDLE((player, version, data, x, y, z) -> {
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_17)) {
|
||||
@@ -889,13 +1022,7 @@ public enum CollisionData {
|
||||
|
||||
SCULK_SENSOR(new HexCollisionBox(0.0, 0.0, 0.0, 16.0, 8.0, 16.0), StateTypes.SCULK_SENSOR, StateTypes.CALIBRATED_SCULK_SENSOR),
|
||||
|
||||
DECORATED_POT((player, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_19_3)) {
|
||||
return new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0);
|
||||
} else { // ViaVersion replacement is a Brick
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}
|
||||
}, StateTypes.DECORATED_POT),
|
||||
DECORATED_POT(new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0), StateTypes.DECORATED_POT),
|
||||
|
||||
BIG_DRIPLEAF((player, version, data, x, y, z) -> {
|
||||
if (version.isOlderThanOrEquals(ClientVersion.V_1_16_4))
|
||||
@@ -911,29 +1038,34 @@ public enum CollisionData {
|
||||
|
||||
}, StateTypes.BIG_DRIPLEAF),
|
||||
|
||||
POINTED_DRIPSTONE((player, version, data, x, y, z) -> {
|
||||
DRIPSTONE((player, version, data, x, y, z) -> {
|
||||
if (version.isOlderThan(ClientVersion.V_1_17))
|
||||
return getEndRod(version, BlockFace.UP);
|
||||
|
||||
SimpleCollisionBox box;
|
||||
HexCollisionBox box;
|
||||
|
||||
if (data.getThickness() == Thickness.TIP_MERGE) {
|
||||
box = new HexOffsetCollisionBox(data.getType(), 5.0, 0.0, 5.0, 11.0, 16.0, 11.0);
|
||||
box = new HexCollisionBox(5.0, 0.0, 5.0, 11.0, 16.0, 11.0);
|
||||
} else if (data.getThickness() == Thickness.TIP) {
|
||||
if (data.getVerticalDirection() == VerticalDirection.DOWN) {
|
||||
box = new HexOffsetCollisionBox(data.getType(), 5.0, 5.0, 5.0, 11.0, 16.0, 11.0);
|
||||
box = new HexCollisionBox(5.0, 5.0, 5.0, 11.0, 16.0, 11.0);
|
||||
} else {
|
||||
box = new HexOffsetCollisionBox(data.getType(), 5.0, 0.0, 5.0, 11.0, 11.0, 11.0);
|
||||
box = new HexCollisionBox(5.0, 0.0, 5.0, 11.0, 11.0, 11.0);
|
||||
}
|
||||
} else if (data.getThickness() == Thickness.FRUSTUM) {
|
||||
box = new HexOffsetCollisionBox(data.getType(), 4.0, 0.0, 4.0, 12.0, 16.0, 12.0);
|
||||
box = new HexCollisionBox(4.0, 0.0, 4.0, 12.0, 16.0, 12.0);
|
||||
} else if (data.getThickness() == Thickness.MIDDLE) {
|
||||
box = new HexOffsetCollisionBox(data.getType(), 3.0, 0.0, 3.0, 13.0, 16.0, 13.0);
|
||||
box = new HexCollisionBox(3.0, 0.0, 3.0, 13.0, 16.0, 13.0);
|
||||
} else {
|
||||
box = new HexOffsetCollisionBox(data.getType(), 2.0, 0.0, 2.0, 14.0, 16.0, 14.0);
|
||||
box = new HexCollisionBox(2.0, 0.0, 2.0, 14.0, 16.0, 14.0);
|
||||
}
|
||||
|
||||
return box;
|
||||
// Copied from NMS and it works! That's all you need to know.
|
||||
long i = (x * 3129871L) ^ (long) z * 116129781L ^ (long) 0;
|
||||
i = i * i * 42317861L + i * 11L;
|
||||
i = i >> 16;
|
||||
|
||||
return box.offset(GrimMath.clamp((((i & 15L) / 15.0F) - 0.5D) * 0.5D, -0.125f, 0.125f), 0, GrimMath.clamp((((i >> 8 & 15L) / 15.0F) - 0.5D) * 0.5D, -0.125f, 0.125f));
|
||||
}, StateTypes.POINTED_DRIPSTONE),
|
||||
|
||||
POWDER_SNOW((player, version, data, x, y, z) -> {
|
||||
@@ -960,6 +1092,8 @@ public enum CollisionData {
|
||||
return new HexCollisionBox(6.0D, 0.0D, 0.0D, 10.0D, 16.0D, 16.0D);
|
||||
}, StateTypes.NETHER_PORTAL),
|
||||
|
||||
END_PORTAL(new HexCollisionBox(0.0D, 6.0D, 0.0D, 16.0D, 12.0D, 16.0D), StateTypes.END_PORTAL),
|
||||
|
||||
AZALEA((player, version, data, x, y, z) -> {
|
||||
return new ComplexCollisionBox(new HexCollisionBox(0.0, 8.0, 0.0, 16.0, 16.0, 16.0),
|
||||
new HexCollisionBox(6.0, 0.0, 6.0, 10.0, 8.0, 10.0));
|
||||
@@ -1007,34 +1141,30 @@ public enum CollisionData {
|
||||
}
|
||||
}, StateTypes.MANGROVE_PROPAGULE),
|
||||
|
||||
SCULK_SHRIKER((player, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_18_2)) {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D);
|
||||
} else {
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}
|
||||
}, StateTypes.SCULK_SHRIEKER),
|
||||
SCULK_SHRIKER(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), StateTypes.SCULK_SHRIEKER),
|
||||
|
||||
SNIFFER_EGG((player, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_19_4)) {
|
||||
return new HexCollisionBox(1.0D, 0.0D, 2.0D, 15.0D, 16.0D, 14.0D);
|
||||
} else {
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
FROGSPAWN(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 1.5D, 16.0D), StateTypes.FROGSPAWN),
|
||||
|
||||
SNIFFER_EGG(new HexCollisionBox(1.0D, 0.0D, 2.0D, 15.0D, 16.0D, 14.0D), StateTypes.SNIFFER_EGG),
|
||||
|
||||
PINK_PETALS_BLOCK(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 3.0D, 16.0D), StateTypes.PINK_PETALS),
|
||||
|
||||
TORCHFLOWER_CROP((player, version, data, x, y, z) -> {
|
||||
if (data.getAge() == 0) {
|
||||
return new HexCollisionBox(5.0D, 0.0D, 5.0D, 11.0D, 6.0D, 11.0D);
|
||||
}
|
||||
}, StateTypes.SNIFFER_EGG),
|
||||
// age is 1
|
||||
return new HexCollisionBox(5.0D, 0.0D, 5.0D, 11.0D, 10.0D, 11.0D);
|
||||
}, StateTypes.TORCHFLOWER_CROP),
|
||||
|
||||
PITCHER_CROP((player, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_19_4)) {
|
||||
final SimpleCollisionBox COLLISION_SHAPE_BULB = new HexCollisionBox(5.0D, -1.0D, 5.0D, 11.0D, 3.0D, 11.0D);
|
||||
final SimpleCollisionBox COLLISION_SHAPE_CROP = new HexCollisionBox(3.0D, -1.0D, 3.0D, 13.0D, 5.0D, 13.0D);
|
||||
final SimpleCollisionBox COLLISION_SHAPE_BULB = new HexCollisionBox(5.0D, -1.0D, 5.0D, 11.0D, 3.0D, 11.0D);
|
||||
final SimpleCollisionBox COLLISION_SHAPE_CROP = new HexCollisionBox(3.0D, -1.0D, 3.0D, 13.0D, 5.0D, 13.0D);
|
||||
|
||||
if (data.getAge() == 0) {
|
||||
return COLLISION_SHAPE_BULB;
|
||||
} else {
|
||||
return data.getHalf() == Half.LOWER ? COLLISION_SHAPE_CROP : NoCollisionBox.INSTANCE;
|
||||
}
|
||||
if (data.getAge() == 0) {
|
||||
return COLLISION_SHAPE_BULB;
|
||||
} else {
|
||||
return NoCollisionBox.INSTANCE;
|
||||
return data.getHalf() == Half.LOWER ? COLLISION_SHAPE_CROP : NoCollisionBox.INSTANCE;
|
||||
}
|
||||
}, StateTypes.PITCHER_CROP),
|
||||
|
||||
@@ -1051,6 +1181,8 @@ public enum CollisionData {
|
||||
}
|
||||
}, BlockTags.WALL_HANGING_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
NONE(NoCollisionBox.INSTANCE, StateTypes.AIR, StateTypes.CAVE_AIR, StateTypes.VOID_AIR, StateTypes.LIGHT),
|
||||
|
||||
DEFAULT(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.STONE);
|
||||
|
||||
// This should be an array... but a hashmap will do for now...
|
||||
@@ -1122,7 +1254,7 @@ public enum CollisionData {
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}
|
||||
|
||||
public static CollisionBox getCocoa(ClientVersion version, int age, BlockFace direction) {
|
||||
private static CollisionBox getCocoa(ClientVersion version, int age, BlockFace direction) {
|
||||
// From 1.9 - 1.10, the large cocoa block is the same as the medium one
|
||||
// https://bugs.mojang.com/browse/MC-94274
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_9_1) && version.isOlderThan(ClientVersion.V_1_11))
|
||||
@@ -1191,7 +1323,7 @@ public enum CollisionData {
|
||||
// Would pre-computing all states be worth the memory cost? I doubt it
|
||||
public static CollisionData getData(StateType state) { // TODO: Find a better hack for lava and scaffolding
|
||||
// What the fuck mojang, why put noCollision() and then give PITCHER_CROP collision?
|
||||
return state.isSolid() || state == StateTypes.LAVA || state == StateTypes.SCAFFOLDING || state == StateTypes.PITCHER_CROP || state == StateTypes.HEAVY_CORE || BlockTags.WALL_HANGING_SIGNS.contains(state) ? rawLookupMap.getOrDefault(state, DEFAULT) : NO_COLLISION;
|
||||
return state.isSolid() || state == StateTypes.LAVA || state == StateTypes.SCAFFOLDING || state == StateTypes.PITCHER_CROP || state == StateTypes.HEAVY_CORE || BlockTags.WALL_HANGING_SIGNS.contains(state) ? rawLookupMap.getOrDefault(state, DEFAULT) : NONE;
|
||||
}
|
||||
|
||||
// TODO: This is wrong if a block doesn't have any hitbox and isn't specified, light block?
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package ac.grim.grimac.utils.collisions;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicHitboxFence;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicHitboxPane;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicHitboxWall;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicFence;
|
||||
import ac.grim.grimac.utils.collisions.blocks.connecting.DynamicWall;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.*;
|
||||
import ac.grim.grimac.utils.nmsutil.Materials;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
@@ -18,510 +17,9 @@ import java.util.*;
|
||||
|
||||
// Expansion to the CollisionData class, which is different than regular ray tracing hitboxes
|
||||
public enum HitboxData {
|
||||
|
||||
RAILS((player, item, version, data, x, y, z) -> {
|
||||
switch (data.getShape()) {
|
||||
case ASCENDING_NORTH:
|
||||
case ASCENDING_SOUTH:
|
||||
case ASCENDING_EAST:
|
||||
case ASCENDING_WEST:
|
||||
if (version.isOlderThan(ClientVersion.V_1_8)) {
|
||||
StateType railType = data.getType();
|
||||
// Activator rails always appear as flat detector rails in 1.7.10 because of ViaVersion
|
||||
// Ascending power rails in 1.7 have flat rail hitbox https://bugs.mojang.com/browse/MC-9134
|
||||
if (railType == StateTypes.ACTIVATOR_RAIL || (railType == StateTypes.POWERED_RAIL && data.isPowered())) {
|
||||
return new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F, false);
|
||||
}
|
||||
return new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F, false);
|
||||
} else if (version.isOlderThan(ClientVersion.V_1_9)) {
|
||||
return new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F, false);
|
||||
} else if (version.isNewerThanOrEquals(ClientVersion.V_1_9) && version.isOlderThan(ClientVersion.V_1_10)) {
|
||||
// https://bugs.mojang.com/browse/MC-89552 sloped rails in 1.9 - it is slightly taller than a regular rail
|
||||
return new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.1875F, 1.0F, false);
|
||||
} else if (version.isOlderThan(ClientVersion.V_1_11)) {
|
||||
// https://bugs.mojang.com/browse/MC-102638 All sloped rails are full blocks in 1.10
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D);
|
||||
default:
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D);
|
||||
}
|
||||
}, BlockTags.RAILS.getStates().toArray(new StateType[0])),
|
||||
|
||||
END_PORTAL((player, item, version, data, x, y, z) -> {
|
||||
if (version.isOlderThan(ClientVersion.V_1_9)) {
|
||||
return new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 0.0625D, 1.0D);
|
||||
} else if (version.isOlderThan(ClientVersion.V_1_17)) {
|
||||
return new SimpleCollisionBox(0.0, 0.0D, 0.0D, 1.0D, 0.75D, 1.0D);
|
||||
}
|
||||
return new HexCollisionBox(0.0D, 6.0D, 0.0D, 16.0D, 12.0D, 16.0D);
|
||||
}, StateTypes.END_PORTAL),
|
||||
|
||||
FENCE_GATE((player, item, version, data, x, y, z) -> {
|
||||
// This technically should be taken from the block data/made multi-version/run block updates... but that's too far even for me
|
||||
// This way is so much easier and works unless the magic stick wand is used
|
||||
boolean isInWall;
|
||||
boolean isXAxis = data.getFacing() == BlockFace.WEST || data.getFacing() == BlockFace.EAST;
|
||||
if (isXAxis) {
|
||||
boolean zPosWall = Materials.isWall(player.compensatedWorld.getStateTypeAt(x, y, z + 1));
|
||||
boolean zNegWall = Materials.isWall(player.compensatedWorld.getStateTypeAt(x, y, z - 1));
|
||||
isInWall = zPosWall || zNegWall;
|
||||
} else {
|
||||
boolean xPosWall = Materials.isWall(player.compensatedWorld.getStateTypeAt(x + 1, y, z));
|
||||
boolean xNegWall = Materials.isWall(player.compensatedWorld.getStateTypeAt(x - 1, y, z));
|
||||
isInWall = xPosWall || xNegWall;
|
||||
}
|
||||
|
||||
if (isInWall) {
|
||||
return isXAxis ? new HexCollisionBox(6.0D, 0.0D, 0.0D, 10.0D, 13.0D, 16.0D) : new HexCollisionBox(0.0D, 0.0D, 6.0D, 16.0D, 13.0D, 10.0D);
|
||||
}
|
||||
|
||||
return isXAxis ? new HexCollisionBox(6.0D, 0.0D, 0.0D, 10.0D, 16.0D, 16.0D) : new HexCollisionBox(0.0D, 0.0D, 6.0D, 16.0D, 16.0D, 10.0D);
|
||||
}, BlockTags.FENCE_GATES.getStates().toArray(new StateType[0])),
|
||||
|
||||
|
||||
FENCE(new DynamicHitboxFence(), BlockTags.FENCES.getStates().toArray(new StateType[0])),
|
||||
|
||||
PANE(new DynamicHitboxPane(), Materials.getPanes().toArray(new StateType[0])),
|
||||
|
||||
LEVER(((player, item, version, data, x, y, z) -> {
|
||||
Face face = data.getFace();
|
||||
BlockFace facing = data.getFacing();
|
||||
if (version.isOlderThan(ClientVersion.V_1_13)) {
|
||||
double f = 0.1875;
|
||||
|
||||
switch (face) {
|
||||
case WALL:
|
||||
switch (facing) {
|
||||
case WEST:
|
||||
return new SimpleCollisionBox(1.0 - f * 2.0, 0.2, 0.5 - f, 1.0, 0.8, 0.5 + f, false);
|
||||
case EAST:
|
||||
return new SimpleCollisionBox(0.0, 0.2, 0.5 - f, f * 2.0, 0.8, 0.5 + f, false);
|
||||
case NORTH:
|
||||
return new SimpleCollisionBox(0.5 - f, 0.2, 1.0 - f * 2.0, 0.5 + f, 0.8, 1.0, false);
|
||||
case SOUTH:
|
||||
return new SimpleCollisionBox(0.5 - f, 0.2, 0.0, 0.5 + f, 0.8, f * 2.0, false);
|
||||
}
|
||||
case CEILING:
|
||||
return new SimpleCollisionBox(0.25, 0.4, 0.25, 0.75, 1.0, 0.75, false);
|
||||
case FLOOR:
|
||||
return new SimpleCollisionBox(0.25, 0.0, 0.25, 0.75, 0.6, 0.75, false);
|
||||
}
|
||||
}
|
||||
|
||||
switch (face) {
|
||||
case FLOOR:
|
||||
// X-AXIS
|
||||
if (facing == BlockFace.EAST || facing == BlockFace.WEST) {
|
||||
return new SimpleCollisionBox(0.25, 0.0, 0.3125, 0.75, 0.375, 0.6875, false);
|
||||
}
|
||||
// Z-AXIS
|
||||
return new SimpleCollisionBox(0.3125, 0.0, 0.25, 0.6875, 0.375, 0.75, false);
|
||||
case WALL:
|
||||
switch (facing) {
|
||||
case EAST:
|
||||
return new SimpleCollisionBox(0.0, 0.25, 0.3125, 0.375, 0.75, 0.6875, false);
|
||||
case WEST:
|
||||
return new SimpleCollisionBox(0.625, 0.25, 0.3125, 1.0, 0.75, 0.6875, false);
|
||||
case SOUTH:
|
||||
return new SimpleCollisionBox(0.3125, 0.25, 0.0, 0.6875, 0.75, 0.375, false);
|
||||
case NORTH:
|
||||
default:
|
||||
return new SimpleCollisionBox(0.3125, 0.25, 0.625, 0.6875, 0.75, 1.0, false);
|
||||
}
|
||||
case CEILING:
|
||||
default:
|
||||
// X-AXIS
|
||||
if (facing == BlockFace.EAST || facing == BlockFace.WEST) {
|
||||
return new SimpleCollisionBox(0.25, 0.625, 0.3125, 0.75, 1.0, 0.6875, false);
|
||||
}
|
||||
// Z-Axis
|
||||
return new SimpleCollisionBox(0.3125, 0.625, 0.25, 0.6875, 1.0, 0.75, false);
|
||||
}
|
||||
}), StateTypes.LEVER),
|
||||
|
||||
BUTTON((player, item, version, data, x, y, z) -> {
|
||||
final Face face = data.getFace();
|
||||
final BlockFace facing = data.getFacing();
|
||||
final boolean powered = data.isPowered();
|
||||
|
||||
|
||||
if (version.isOlderThan(ClientVersion.V_1_13)) {
|
||||
double f2 = (float) (data.isPowered() ? 1 : 2) / 16.0;
|
||||
|
||||
switch (face) {
|
||||
case WALL:
|
||||
switch (facing) {
|
||||
case WEST:
|
||||
return new SimpleCollisionBox(0.0, 0.375, 0.3125, f2, 0.625, 0.6875, false);
|
||||
case EAST:
|
||||
return new SimpleCollisionBox(1.0 - f2, 0.375, 0.3125, 1.0, 0.625, 0.6875, false);
|
||||
case NORTH:
|
||||
return new SimpleCollisionBox(0.3125, 0.375, 0.0, 0.6875, 0.625, f2, false);
|
||||
case SOUTH:
|
||||
return new SimpleCollisionBox(0.3125, 0.375, 1.0 - f2, 0.6875, 0.625, 1.0, false);
|
||||
}
|
||||
case CEILING:
|
||||
return new SimpleCollisionBox(0.3125, 1.0 - f2, 0.375, 0.6875, 1.0, 0.625, false);
|
||||
case FLOOR:
|
||||
return new SimpleCollisionBox(0.3125, 0.0, 0.375, 0.6875, 0.0 + f2, 0.625, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (face) {
|
||||
case WALL:
|
||||
CollisionBox shape;
|
||||
switch (facing) {
|
||||
case EAST:
|
||||
shape = powered ? new HexCollisionBox(0.0, 6.0, 5.0, 1.0, 10.0, 11.0) : new HexCollisionBox(0.0, 6.0, 5.0, 2.0, 10.0, 11.0);
|
||||
break;
|
||||
case WEST:
|
||||
shape = powered ? new HexCollisionBox(15.0, 6.0, 5.0, 16.0, 10.0, 11.0) : new HexCollisionBox(14.0, 6.0, 5.0, 16.0, 10.0, 11.0);
|
||||
break;
|
||||
case SOUTH:
|
||||
shape = powered ? new HexCollisionBox(5.0, 6.0, 0.0, 11.0, 10.0, 1.0) : new HexCollisionBox(5.0, 6.0, 0.0, 11.0, 10.0, 2.0);
|
||||
break;
|
||||
case NORTH:
|
||||
case UP:
|
||||
case DOWN:
|
||||
shape = powered ? new HexCollisionBox(5.0, 6.0, 15.0, 11.0, 10.0, 16.0) : new HexCollisionBox(5.0, 6.0, 14.0, 11.0, 10.0, 16.0);
|
||||
break;
|
||||
default:
|
||||
shape = NoCollisionBox.INSTANCE;
|
||||
}
|
||||
|
||||
return shape;
|
||||
case CEILING:
|
||||
// ViaVersion shows lever
|
||||
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_8)) {
|
||||
return LEVER.dynamic.fetch(player, item, version, data, x, y, z);
|
||||
}
|
||||
// x axis
|
||||
if (facing == BlockFace.EAST || facing == BlockFace.WEST) {
|
||||
return powered ? new HexCollisionBox(6.0, 15.0, 5.0, 10.0, 16.0, 11.0) : new HexCollisionBox(6.0, 14.0, 5.0, 10.0, 16.0, 11.0);
|
||||
} else {
|
||||
return powered ? new HexCollisionBox(5.0, 15.0, 6.0, 11.0, 16.0, 10.0) : new HexCollisionBox(5.0, 14.0, 6.0, 11.0, 16.0, 10.0);
|
||||
}
|
||||
case FLOOR:
|
||||
// ViaVersion shows lever
|
||||
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_8)) {
|
||||
return LEVER.dynamic.fetch(player, item, version, data, x, y, z);
|
||||
}
|
||||
// x axis
|
||||
if (facing == BlockFace.EAST || facing == BlockFace.WEST) {
|
||||
return powered ? new HexCollisionBox(6.0, 0.0, 5.0, 10.0, 1.0, 11.0) : new HexCollisionBox(6.0, 0.0, 5.0, 10.0, 2.0, 11.0);
|
||||
}
|
||||
|
||||
return powered ? new HexCollisionBox(5.0, 0.0, 6.0, 11.0, 1.0, 10.0) : new HexCollisionBox(5.0, 0.0, 6.0, 11.0, 2.0, 10.0);
|
||||
default:
|
||||
throw new IllegalStateException("Impossible Hitbox State");
|
||||
}
|
||||
}, BlockTags.BUTTONS.getStates().toArray(new StateType[0])),
|
||||
|
||||
WALL(new DynamicHitboxWall(), BlockTags.WALLS.getStates().toArray(new StateType[0])),
|
||||
|
||||
WALL_SIGN((player, item, version, data, x, y, z) -> {
|
||||
switch (data.getFacing()) {
|
||||
case NORTH:
|
||||
return new HexCollisionBox(0.0, 4.5, 14.0, 16.0, 12.5, 16.0);
|
||||
case SOUTH:
|
||||
return new HexCollisionBox(0.0, 4.5, 0.0, 16.0, 12.5, 2.0);
|
||||
case EAST:
|
||||
return new HexCollisionBox(0.0, 4.5, 0.0, 2.0, 12.5, 16.0);
|
||||
case WEST:
|
||||
return new HexCollisionBox(14.0, 4.5, 0.0, 16.0, 12.5, 16.0);
|
||||
default:
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}
|
||||
}, BlockTags.WALL_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
WALL_HANGING_SIGN((player, item, version, data, x, y, z) -> {
|
||||
switch (data.getFacing()) {
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
return new ComplexCollisionBox(new HexCollisionBox(0.0D, 14.0D, 6.0D, 16.0D, 16.0D, 10.0D),
|
||||
new HexCollisionBox(1.0D, 0.0D, 7.0D, 15.0D, 10.0D, 9.0D));
|
||||
default:
|
||||
return new ComplexCollisionBox(new HexCollisionBox(6.0D, 14.0D, 0.0D, 10.0D, 16.0D, 16.0D),
|
||||
new HexCollisionBox(7.0D, 0.0D, 1.0D, 9.0D, 10.0D, 15.0D));
|
||||
}
|
||||
}, BlockTags.WALL_HANGING_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
STANDING_SIGN((player, item, version, data, x, y, z) ->
|
||||
new HexCollisionBox(4.0, 0.0, 4.0, 12.0, 16.0, 12.0),
|
||||
BlockTags.STANDING_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
SAPLING(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D),
|
||||
BlockTags.SAPLINGS.getStates().toArray(new StateType[0])),
|
||||
|
||||
ROOTS(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D),
|
||||
StateTypes.WARPED_ROOTS, StateTypes.CRIMSON_ROOTS),
|
||||
|
||||
BANNER(new HexCollisionBox(4.0D, 0.0D, 4.0D, 12.0D, 16.0D, 12.0D),
|
||||
StateTypes.WHITE_BANNER, StateTypes.ORANGE_BANNER, StateTypes.MAGENTA_BANNER, StateTypes.LIGHT_BLUE_BANNER,
|
||||
StateTypes.YELLOW_BANNER, StateTypes.LIME_BANNER, StateTypes.PINK_BANNER, StateTypes.GRAY_BANNER,
|
||||
StateTypes.LIGHT_GRAY_BANNER, StateTypes.CYAN_BANNER, StateTypes.PURPLE_BANNER, StateTypes.BLUE_BANNER,
|
||||
StateTypes.BROWN_BANNER, StateTypes.GREEN_BANNER, StateTypes.RED_BANNER, StateTypes.BLACK_BANNER),
|
||||
|
||||
WALL_BANNER((player, item, version, data, x, y, z) -> {
|
||||
// ViaVersion replacement block
|
||||
if (version.isOlderThan(ClientVersion.V_1_8)) {
|
||||
return WALL_SIGN.dynamic.fetch(player, item, version, data, x, y, z);
|
||||
}
|
||||
|
||||
switch (data.getFacing()) {
|
||||
case NORTH:
|
||||
return new HexCollisionBox(0.0, 0.0, 14.0, 16.0, 12.5, 16.0);
|
||||
case EAST:
|
||||
return new HexCollisionBox(0.0, 0.0, 0.0, 2.0, 12.5, 16.0);
|
||||
case WEST:
|
||||
return new HexCollisionBox(14.0, 0.0, 0.0, 16.0, 12.5, 16.0);
|
||||
case SOUTH:
|
||||
return new HexCollisionBox(0.0, 0.0, 0.0, 16.0, 12.5, 2.0);
|
||||
default:
|
||||
throw new IllegalStateException("Impossible Banner Facing State; Something very wrong is going on");
|
||||
}
|
||||
}, StateTypes.WHITE_WALL_BANNER, StateTypes.ORANGE_WALL_BANNER, StateTypes.MAGENTA_WALL_BANNER,
|
||||
StateTypes.LIGHT_BLUE_WALL_BANNER, StateTypes.YELLOW_WALL_BANNER, StateTypes.LIME_WALL_BANNER,
|
||||
StateTypes.PINK_WALL_BANNER, StateTypes.GRAY_WALL_BANNER, StateTypes.LIGHT_GRAY_WALL_BANNER,
|
||||
StateTypes.CYAN_WALL_BANNER, StateTypes.PURPLE_WALL_BANNER, StateTypes.BLUE_WALL_BANNER,
|
||||
StateTypes.BROWN_WALL_BANNER, StateTypes.GREEN_WALL_BANNER, StateTypes.RED_WALL_BANNER, StateTypes.BLACK_WALL_BANNER),
|
||||
|
||||
BREWING_STAND((player, item, version, block, x, y, z) -> {
|
||||
// BEWARE OF https://bugs.mojang.com/browse/MC-85109 FOR 1.8 PLAYERS
|
||||
if (version.isOlderThan(ClientVersion.V_1_13)) {
|
||||
return new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
|
||||
} else {
|
||||
return new ComplexCollisionBox(
|
||||
new HexCollisionBox(1.0, 0.0, 1.0, 15.0, 2.0, 15.0),
|
||||
new SimpleCollisionBox(0.4375, 0.0, 0.4375, 0.5625, 0.875, 0.5625, false));
|
||||
}
|
||||
}, StateTypes.BREWING_STAND),
|
||||
|
||||
SMALL_FLOWER((player, item, version, data, x, y, z) -> player.getClientVersion().isOlderThan(ClientVersion.V_1_13)
|
||||
? new SimpleCollisionBox(0.3125D, 0.0D, 0.3125D, 0.6875D, 0.625D, 0.6875D)
|
||||
: new OffsetCollisionBox(data.getType(), 0.3125D, 0.0D, 0.3125D, 0.6875D, 0.625D, 0.6875D),
|
||||
BlockTags.SMALL_FLOWERS.getStates().toArray(new StateType[0])),
|
||||
|
||||
TALL_FLOWERS(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), BlockTags.TALL_FLOWERS.getStates().toArray(new StateType[0])),
|
||||
|
||||
FIRE((player, item, version, data, x, y, z) -> {
|
||||
// Since 1.16 fire has a small hitbox
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_16)) {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D);
|
||||
}
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}, BlockTags.FIRE.getStates().toArray(new StateType[0])),
|
||||
|
||||
HONEY_BLOCK(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.HONEY_BLOCK),
|
||||
|
||||
POWDER_SNOW(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.POWDER_SNOW),
|
||||
|
||||
SOUL_SAND(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.SOUL_SAND),
|
||||
|
||||
CACTUS((player, item, version, data, x, y, z) -> {
|
||||
if (version.isOlderThan(ClientVersion.V_1_13)) {
|
||||
// https://bugs.mojang.com/browse/MC-59610
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}
|
||||
return new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D);
|
||||
}, StateTypes.CACTUS),
|
||||
|
||||
SNOW((player, item, version, data, x, y, z) -> {
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, data.getLayers() * 0.125, 1);
|
||||
}, StateTypes.SNOW),
|
||||
|
||||
LECTERN_BLOCK((player, item, version, data, x, y, z) -> {
|
||||
ComplexCollisionBox common = new ComplexCollisionBox(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D),
|
||||
new HexCollisionBox(4.0D, 2.0D, 4.0D, 12.0D, 14.0D, 12.0D));
|
||||
|
||||
if (data.getFacing() == BlockFace.WEST) {
|
||||
common.add(new HexCollisionBox(1.0D, 10.0D, 0.0D, 5.333333D, 14.0D, 16.0D));
|
||||
common.add(new HexCollisionBox(5.333333D, 12.0D, 0.0D, 9.666667D, 16.0D, 16.0D));
|
||||
common.add(new HexCollisionBox(9.666667D, 14.0D, 0.0D, 14.0D, 18.0D, 16.0D));
|
||||
} else if (data.getFacing() == BlockFace.NORTH) {
|
||||
common.add(new HexCollisionBox(0.0D, 10.0D, 1.0D, 16.0D, 14.0D, 5.333333D));
|
||||
common.add(new HexCollisionBox(0.0D, 12.0D, 5.333333D, 16.0D, 16.0D, 9.666667D));
|
||||
common.add(new HexCollisionBox(0.0D, 14.0D, 9.666667D, 16.0D, 18.0D, 14.0D));
|
||||
} else if (data.getFacing() == BlockFace.EAST) {
|
||||
common.add(new HexCollisionBox(10.666667D, 10.0D, 0.0D, 15.0D, 14.0D, 16.0D));
|
||||
common.add(new HexCollisionBox(6.333333D, 12.0D, 0.0D, 10.666667D, 16.0D, 16.0D));
|
||||
common.add(new HexCollisionBox(2.0D, 14.0D, 0.0D, 6.333333D, 18.0D, 16.0D));
|
||||
} else { // SOUTH
|
||||
common.add(new HexCollisionBox(0.0D, 10.0D, 10.666667D, 16.0D, 14.0D, 15.0D));
|
||||
common.add(new HexCollisionBox(0.0D, 12.0D, 6.333333D, 16.0D, 16.0D, 10.666667D));
|
||||
common.add(new HexCollisionBox(0.0D, 14.0D, 2.0D, 16.0D, 18.0D, 6.333333D));
|
||||
}
|
||||
|
||||
return common;
|
||||
}, StateTypes.LECTERN),
|
||||
|
||||
GLOW_LICHEN_SCULK_VEIN((player, item, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_16_4)) {
|
||||
ComplexCollisionBox box = new ComplexCollisionBox();
|
||||
|
||||
if (data.isUp()) {
|
||||
box.add(new HexCollisionBox(0.0D, 15.0D, 0.0D, 16.0D, 16.0D, 16.0D));
|
||||
}
|
||||
if (data.isDown()) {
|
||||
box.add(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D));
|
||||
}
|
||||
if (data.getWest() == West.TRUE) {
|
||||
box.add(new HexCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 16.0D, 16.0D));
|
||||
}
|
||||
if (data.getEast() == East.TRUE) {
|
||||
box.add(new HexCollisionBox(15.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D));
|
||||
}
|
||||
if (data.getNorth() == North.TRUE) {
|
||||
box.add(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 1.0D));
|
||||
}
|
||||
if (data.getSouth() == South.TRUE) {
|
||||
box.add(new HexCollisionBox(0.0D, 0.0D, 15.0D, 16.0D, 16.0D, 16.0D));
|
||||
}
|
||||
|
||||
return box;
|
||||
} else { // ViaVersion just replaces this with... nothing
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}
|
||||
}, StateTypes.GLOW_LICHEN, StateTypes.SCULK_CATALYST),
|
||||
|
||||
SPORE_BLOSSOM((player, item, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_16_4)) {
|
||||
return new HexCollisionBox(2.0D, 13.0D, 2.0D, 14.0D, 16.0D, 14.0D);
|
||||
} else { // ViaVersion replacement is a Peony
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}
|
||||
}, StateTypes.SPORE_BLOSSOM),
|
||||
|
||||
PITCHER_CROP((player, item, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_19_4)) {
|
||||
final SimpleCollisionBox FULL_UPPER_SHAPE = new HexCollisionBox(3.0D, 0.0D, 3.0D, 13.0D, 15.0D, 13.0D);
|
||||
final SimpleCollisionBox FULL_LOWER_SHAPE = new HexCollisionBox(3.0D, -1.0D, 3.0D, 13.0D, 16.0D, 13.0D);
|
||||
final SimpleCollisionBox COLLISION_SHAPE_BULB = new HexCollisionBox(5.0D, -1.0D, 5.0D, 11.0D, 3.0D, 11.0D);
|
||||
final SimpleCollisionBox COLLISION_SHAPE_CROP = new HexCollisionBox(3.0D, -1.0D, 3.0D, 13.0D, 5.0D, 13.0D);
|
||||
final SimpleCollisionBox[] UPPER_SHAPE_BY_AGE = new SimpleCollisionBox[]{new HexCollisionBox(3.0D, 0.0D, 3.0D, 13.0D, 11.0D, 13.0D), FULL_UPPER_SHAPE};
|
||||
final SimpleCollisionBox[] LOWER_SHAPE_BY_AGE = new SimpleCollisionBox[]{COLLISION_SHAPE_BULB, new HexCollisionBox(3.0D, -1.0D, 3.0D, 13.0D, 14.0D, 13.0D), FULL_LOWER_SHAPE, FULL_LOWER_SHAPE, FULL_LOWER_SHAPE};
|
||||
|
||||
return data.getHalf() == Half.UPPER ? UPPER_SHAPE_BY_AGE[Math.min(Math.abs(4 - (data.getAge() + 1)), UPPER_SHAPE_BY_AGE.length - 1)] : LOWER_SHAPE_BY_AGE[data.getAge()];
|
||||
} else {
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}
|
||||
}, StateTypes.PITCHER_CROP),
|
||||
|
||||
WHEAT_BEETROOTS((player, item, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, (data.getAge() + 1) * 2, 16.0D);
|
||||
}, StateTypes.WHEAT, StateTypes.BEETROOTS),
|
||||
|
||||
CARROT_POTATOES((player, item, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, data.getAge() + 2, 16.0D);
|
||||
}, StateTypes.CARROTS, StateTypes.POTATOES),
|
||||
|
||||
NETHER_WART((player, item, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0, 5 + (data.getAge() * 3), 16.0D);
|
||||
}, StateTypes.NETHER_WART),
|
||||
|
||||
ATTACHED_PUMPKIN_STEM((player, item, version, data, x, y, z) -> {
|
||||
if (version.isOlderThan(ClientVersion.V_1_13))
|
||||
return new HexCollisionBox(7.0D, 0.0D, 7.0D, 9.0D, 16.0D, 9.0D);
|
||||
|
||||
switch (data.getFacing()) {
|
||||
case SOUTH:
|
||||
return new HexCollisionBox(6.0D, 0.0D, 6.0D, 10.0D, 10.0D, 16.0D);
|
||||
case WEST:
|
||||
return new HexCollisionBox(0.0D, 0.0D, 6.0D, 10.0D, 10.0D, 10.0D);
|
||||
case NORTH:
|
||||
return new HexCollisionBox(6.0D, 0.0D, 0.0D, 10.0D, 10.0D, 10.0D);
|
||||
case EAST:
|
||||
default:
|
||||
return new HexCollisionBox(6.0D, 0.0D, 6.0D, 16.0D, 10.0D, 10.0D);
|
||||
}
|
||||
}, StateTypes.ATTACHED_MELON_STEM, StateTypes.ATTACHED_PUMPKIN_STEM),
|
||||
|
||||
PUMPKIN_STEM((player, item, version, data, x, y, z) -> {
|
||||
return new HexCollisionBox(7, 0, 7, 9, 2 * (data.getAge() + 1), 9);
|
||||
}, StateTypes.PUMPKIN_STEM, StateTypes.MELON_STEM),
|
||||
|
||||
// Hitbox/Outline is Same as Collision
|
||||
COCOA_BEANS((player, item, version, data, x, y, z) -> {
|
||||
return CollisionData.getCocoa(version, data.getAge(), data.getFacing());
|
||||
}, StateTypes.COCOA),
|
||||
|
||||
|
||||
// Easier to just use no collision box
|
||||
// Redstone wire is very complex with its collision shapes and has many de-syncs
|
||||
REDSTONE_WIRE(NoCollisionBox.INSTANCE, StateTypes.REDSTONE_WIRE),
|
||||
|
||||
SWEET_BERRY((player, item, version, data, x, y, z) -> {
|
||||
if (data.getAge() == 0) {
|
||||
return new HexCollisionBox(3.0D, 0.0D, 3.0D, 13.0D, 8.0D, 13.0D);
|
||||
} else if (data.getAge() < 3) {
|
||||
return new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D);
|
||||
}
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}, StateTypes.SWEET_BERRY_BUSH),
|
||||
|
||||
CORAL_FAN(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 4.0D, 14.0D), BlockTags.CORALS.getStates().toArray(new StateType[0])),
|
||||
|
||||
TORCHFLOWER_CROP((player, item, version, data, x, y, z) -> {
|
||||
if (data.getAge() == 0) {
|
||||
return new HexCollisionBox(5.0D, 0.0D, 5.0D, 11.0D, 6.0D, 11.0D);
|
||||
}
|
||||
// age is 1
|
||||
return new HexCollisionBox(5.0D, 0.0D, 5.0D, 11.0D, 10.0D, 11.0D);
|
||||
}, StateTypes.TORCHFLOWER_CROP),
|
||||
|
||||
DEAD_BUSH(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D), StateTypes.DEAD_BUSH),
|
||||
|
||||
SUGARCANE(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 16.0D, 14.0D), StateTypes.SUGAR_CANE),
|
||||
|
||||
NETHER_SPROUTS(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 3.0D, 14.0D), StateTypes.NETHER_SPROUTS),
|
||||
|
||||
HANGING_ROOTS(new HexCollisionBox(2.0D, 10.0D, 2.0D, 14.0D, 16.0D, 14.0D), StateTypes.HANGING_ROOTS),
|
||||
|
||||
GRASS_FERN((player, item, version, data, x ,y, z) -> {
|
||||
if (version.isOlderThan(ClientVersion.V_1_13)) {
|
||||
return new SimpleCollisionBox(0.1F, 0.0F, 0.1F, 0.9F, 0.8F, 0.9F);
|
||||
}
|
||||
return new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D);
|
||||
}, StateTypes.SHORT_GRASS, StateTypes.FERN),
|
||||
|
||||
SEA_GRASS(new HexCollisionBox(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D),
|
||||
StateTypes.SEAGRASS),
|
||||
|
||||
TALL_SEAGRASS(new HexCollisionBox(2.0, 0.0, 2.0, 14.0, 16.0, 14.0),
|
||||
StateTypes.TALL_SEAGRASS),
|
||||
|
||||
SMALL_DRIPLEAF(new HexCollisionBox(2.0, 0.0, 2.0, 14.0, 13.0, 14.0), StateTypes.SMALL_DRIPLEAF),
|
||||
|
||||
CAVE_VINES(new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D), StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT),
|
||||
|
||||
// Then your enum entries become:
|
||||
TWISTING_VINES_BLOCK((player, item, version, data, x, y, z) ->
|
||||
getVineCollisionBox(version, false, true), StateTypes.TWISTING_VINES),
|
||||
|
||||
WEEPING_VINES_BLOCK((player, item, version, data, x, y, z) ->
|
||||
getVineCollisionBox(version, true, true), StateTypes.WEEPING_VINES),
|
||||
|
||||
TWISTING_VINES((player, item, version, data, x, y, z) ->
|
||||
getVineCollisionBox(version, false, false), StateTypes.TWISTING_VINES_PLANT),
|
||||
|
||||
WEEPING_VINES((player, item, version, data, x, y, z) ->
|
||||
getVineCollisionBox(version, true, false), StateTypes.WEEPING_VINES_PLANT),
|
||||
|
||||
TALL_PLANT(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.TALL_GRASS, StateTypes.LARGE_FERN),
|
||||
|
||||
BAMBOO((player, item, version, data, x, y, z) -> data.getLeaves() == Leaves.LARGE
|
||||
? new HexOffsetCollisionBox(data.getType(), 3.0, 0.0, 3.0, 13.0, 16.0, 13.0)
|
||||
: new HexOffsetCollisionBox(data.getType(), 5.0, 0.0, 5.0, 11.0, 16.0, 11.0), StateTypes.BAMBOO),
|
||||
|
||||
BAMBOO_SAPLING((player, item, version, data, x, y, z) -> {
|
||||
return new HexOffsetCollisionBox(data.getType(), 4.0D, 0.0D, 4.0D, 12.0D, 12.0D, 12.0D);
|
||||
}, StateTypes.BAMBOO_SAPLING),
|
||||
|
||||
SCAFFOLDING((player, item, version, data, x, y, z) -> {
|
||||
// If is holding scaffolding or Via replacement - hay bale
|
||||
if (item == StateTypes.SCAFFOLDING || version.isOlderThan(ClientVersion.V_1_14)) {
|
||||
// If is holding scaffolding
|
||||
if (item == StateTypes.SCAFFOLDING) {
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true);
|
||||
}
|
||||
|
||||
@@ -569,54 +67,222 @@ public enum HitboxData {
|
||||
|
||||
}, StateTypes.BIG_DRIPLEAF),
|
||||
|
||||
PINK_PETALS_BLOCK((player, item, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_20_2)) {
|
||||
int flowerAmount = data.getFlowerAmount();
|
||||
int horizontalIndex = getHorizontalID(data.getFacing());
|
||||
FENCE_GATE((player, item, version, data, x, y, z) -> {
|
||||
// This technically should be taken from the block data/made multi-version/run block updates... but that's too far even for me
|
||||
// This way is so much easier and works unless the magic stick wand is used
|
||||
boolean isInWall;
|
||||
boolean isXAxis = data.getFacing() == BlockFace.WEST || data.getFacing() == BlockFace.EAST;
|
||||
if (isXAxis) {
|
||||
boolean zPosWall = Materials.isWall(player.compensatedWorld.getStateTypeAt(x, y, z + 1));
|
||||
boolean zNegWall = Materials.isWall(player.compensatedWorld.getStateTypeAt(x, y, z - 1));
|
||||
isInWall = zPosWall || zNegWall;
|
||||
} else {
|
||||
boolean xPosWall = Materials.isWall(player.compensatedWorld.getStateTypeAt(x + 1, y, z));
|
||||
boolean xNegWall = Materials.isWall(player.compensatedWorld.getStateTypeAt(x - 1, y, z));
|
||||
isInWall = xPosWall || xNegWall;
|
||||
}
|
||||
|
||||
CollisionBox result = NoCollisionBox.INSTANCE;
|
||||
if (isInWall) {
|
||||
return isXAxis ? new HexCollisionBox(6.0D, 0.0D, 0.0D, 10.0D, 13.0D, 16.0D) : new HexCollisionBox(0.0D, 0.0D, 6.0D, 16.0D, 13.0D, 10.0D);
|
||||
}
|
||||
|
||||
// Pre-defined collision boxes for each quadrant
|
||||
HexCollisionBox[] boxes = new HexCollisionBox[] {
|
||||
new HexCollisionBox(8, 0, 8, 16, 3, 16), // SE
|
||||
new HexCollisionBox(8, 0, 0, 16, 3, 8), // NE
|
||||
new HexCollisionBox(0, 0, 0, 8, 3, 8), // NW
|
||||
new HexCollisionBox(0, 0, 8, 8, 3, 16) // SW
|
||||
};
|
||||
return isXAxis ? new HexCollisionBox(6.0D, 0.0D, 0.0D, 10.0D, 16.0D, 16.0D) : new HexCollisionBox(0.0D, 0.0D, 6.0D, 16.0D, 16.0D, 10.0D);
|
||||
}, BlockTags.FENCE_GATES.getStates().toArray(new StateType[0])),
|
||||
|
||||
// Add boxes based on flower amount and facing
|
||||
for (int i = 0; i < flowerAmount; i++) {
|
||||
int index = Math.floorMod(i - horizontalIndex, 4);
|
||||
result = result.union(boxes[index]);
|
||||
|
||||
FENCE((player, item, version, data, x, y, z) -> {
|
||||
WrappedBlockState state = player.compensatedWorld.getWrappedBlockStateAt(x, y, z);
|
||||
|
||||
if (version.isOlderThanOrEquals(ClientVersion.V_1_12_2)) {
|
||||
int i = 0;
|
||||
if (data.getSouth() == South.TRUE) {
|
||||
i |= 0b1;
|
||||
}
|
||||
if (data.getWest() == West.TRUE) {
|
||||
i |= 0b10;
|
||||
}
|
||||
if (data.getNorth() == North.TRUE) {
|
||||
i |= 0b100;
|
||||
}
|
||||
if (data.getEast() == East.TRUE) {
|
||||
i |= 0b1000;
|
||||
}
|
||||
|
||||
return result;
|
||||
} else if (version.isNewerThan(ClientVersion.V_1_19_3)) {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 3.0D, 16.0D);
|
||||
} else if (version.isNewerThan(ClientVersion.V_1_12_2)) {
|
||||
return CORAL_FAN.dynamic.fetch(player, item, version, data, x, y, z);
|
||||
return DynamicFence.LEGACY_BOUNDING_BOXES[i].copy();
|
||||
}
|
||||
return GRASS_FERN.dynamic.fetch(player, item, version, data, x, y, z);
|
||||
}, StateTypes.PINK_PETALS),
|
||||
|
||||
MANGROVE_PROPAGULE(((player, item, version, data, x, y, z) -> {
|
||||
if (data.isHanging()) {
|
||||
return new HexOffsetCollisionBox(data.getType(), 7.0, 0.0, 7.0, 9.0, 16.0, 9.0);
|
||||
} else {
|
||||
return new HexOffsetCollisionBox(data.getType(), 7.0, getPropaguleMinHeight(data.getAge()), 7.0, 9.0, 16.0, 9.0);
|
||||
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
||||
CollisionData.getData(state.getType()).getMovementCollisionBox(player, version, state).downCast(boxes);
|
||||
|
||||
for (SimpleCollisionBox box : boxes) {
|
||||
box.maxY = 1;
|
||||
}
|
||||
}), StateTypes.MANGROVE_PROPAGULE),
|
||||
|
||||
FROGSPAWN((player, item, version, data, x, y, z) -> {
|
||||
if (version.isNewerThan(ClientVersion.V_1_18_2)) {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 1.5D, 16.0D);
|
||||
} else { // ViaVersion just replaces this with... nothing
|
||||
return NoCollisionBox.INSTANCE;
|
||||
return new ComplexCollisionBox(boxes.toArray(new SimpleCollisionBox[0]));
|
||||
}, BlockTags.FENCES.getStates().toArray(new StateType[0])),
|
||||
|
||||
WALL((player, item, version, data, x, y, z) -> {
|
||||
WrappedBlockState state = player.compensatedWorld.getWrappedBlockStateAt(x, y, z);
|
||||
return new DynamicWall().fetchRegularBox(player, state, version, x, y, z);
|
||||
}, BlockTags.WALLS.getStates().toArray(new StateType[0])),
|
||||
|
||||
HONEY_BLOCK(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.HONEY_BLOCK),
|
||||
|
||||
POWDER_SNOW(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.POWDER_SNOW),
|
||||
|
||||
SOUL_SAND(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.SOUL_SAND),
|
||||
|
||||
CACTUS(new HexCollisionBox(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D), StateTypes.CACTUS),
|
||||
|
||||
SNOW((player, item, version, data, x, y, z) -> {
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, data.getLayers() * 0.125, 1);
|
||||
}, StateTypes.SNOW),
|
||||
|
||||
LECTERN_BLOCK((player, item, version, data, x, y, z) -> {
|
||||
ComplexCollisionBox common = new ComplexCollisionBox(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D),
|
||||
new HexCollisionBox(4.0D, 2.0D, 4.0D, 12.0D, 14.0D, 12.0D));
|
||||
|
||||
if (data.getFacing() == BlockFace.WEST) {
|
||||
common.add(new HexCollisionBox(1.0D, 10.0D, 0.0D, 5.333333D, 14.0D, 16.0D));
|
||||
common.add(new HexCollisionBox(5.333333D, 12.0D, 0.0D, 9.666667D, 16.0D, 16.0D));
|
||||
common.add(new HexCollisionBox(9.666667D, 14.0D, 0.0D, 14.0D, 18.0D, 16.0D));
|
||||
} else if (data.getFacing() == BlockFace.NORTH) {
|
||||
common.add(new HexCollisionBox(0.0D, 10.0D, 1.0D, 16.0D, 14.0D, 5.333333D));
|
||||
common.add(new HexCollisionBox(0.0D, 12.0D, 5.333333D, 16.0D, 16.0D, 9.666667D));
|
||||
common.add(new HexCollisionBox(0.0D, 14.0D, 9.666667D, 16.0D, 18.0D, 14.0D));
|
||||
} else if (data.getFacing() == BlockFace.EAST) {
|
||||
common.add(new HexCollisionBox(10.666667D, 10.0D, 0.0D, 15.0D, 14.0D, 16.0D));
|
||||
common.add(new HexCollisionBox(6.333333D, 12.0D, 0.0D, 10.666667D, 16.0D, 16.0D));
|
||||
common.add(new HexCollisionBox(2.0D, 14.0D, 0.0D, 6.333333D, 18.0D, 16.0D));
|
||||
} else { // SOUTH
|
||||
common.add(new HexCollisionBox(0.0D, 10.0D, 10.666667D, 16.0D, 14.0D, 15.0D));
|
||||
common.add(new HexCollisionBox(0.0D, 12.0D, 6.333333D, 16.0D, 16.0D, 10.666667D));
|
||||
common.add(new HexCollisionBox(0.0D, 14.0D, 2.0D, 16.0D, 18.0D, 6.333333D));
|
||||
}
|
||||
}, StateTypes.FROGSPAWN),
|
||||
|
||||
// always a fullblock hitbox. Via replacement is obsidian
|
||||
SCULK_SHRIKER(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true), StateTypes.SCULK_SHRIEKER);
|
||||
return common;
|
||||
}, StateTypes.LECTERN),
|
||||
|
||||
WALL_HANGING_SIGNS((player, item, version, data, x, y, z) -> {
|
||||
switch (data.getFacing()) {
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
return new ComplexCollisionBox(new HexCollisionBox(0.0D, 14.0D, 6.0D, 16.0D, 16.0D, 10.0D),
|
||||
new HexCollisionBox(1.0D, 0.0D, 7.0D, 15.0D, 10.0D, 9.0D));
|
||||
case WEST:
|
||||
case EAST:
|
||||
return new ComplexCollisionBox(new HexCollisionBox(6.0D, 14.0D, 0.0D, 10.0D, 16.0D, 16.0D),
|
||||
new HexCollisionBox(7.0D, 0.0D, 1.0D, 9.0D, 10.0D, 15.0D));
|
||||
default:
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}
|
||||
}, BlockTags.WALL_HANGING_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
PITCHER_CROP((player, item, version, data, x, y, z) -> {
|
||||
final SimpleCollisionBox FULL_UPPER_SHAPE = new HexCollisionBox(3.0D, 0.0D, 3.0D, 13.0D, 15.0D, 13.0D);
|
||||
final SimpleCollisionBox FULL_LOWER_SHAPE = new HexCollisionBox(3.0D, -1.0D, 3.0D, 13.0D, 16.0D, 13.0D);
|
||||
final SimpleCollisionBox COLLISION_SHAPE_BULB = new HexCollisionBox(5.0D, -1.0D, 5.0D, 11.0D, 3.0D, 11.0D);
|
||||
final SimpleCollisionBox COLLISION_SHAPE_CROP = new HexCollisionBox(3.0D, -1.0D, 3.0D, 13.0D, 5.0D, 13.0D);
|
||||
final SimpleCollisionBox[] UPPER_SHAPE_BY_AGE = new SimpleCollisionBox[]{new HexCollisionBox(3.0D, 0.0D, 3.0D, 13.0D, 11.0D, 13.0D), FULL_UPPER_SHAPE};
|
||||
final SimpleCollisionBox[] LOWER_SHAPE_BY_AGE = new SimpleCollisionBox[]{COLLISION_SHAPE_BULB, new HexCollisionBox(3.0D, -1.0D, 3.0D, 13.0D, 14.0D, 13.0D), FULL_LOWER_SHAPE, FULL_LOWER_SHAPE, FULL_LOWER_SHAPE};
|
||||
|
||||
return data.getHalf() == Half.UPPER ? UPPER_SHAPE_BY_AGE[Math.min(Math.abs(4 - (data.getAge() + 1)), UPPER_SHAPE_BY_AGE.length - 1)] : LOWER_SHAPE_BY_AGE[data.getAge()];
|
||||
}, StateTypes.PITCHER_CROP),
|
||||
|
||||
BUTTON((player, item, version, data, x, y, z) -> {
|
||||
final BlockFace facing = data.getFacing();
|
||||
final boolean powered = data.isPowered();
|
||||
switch (data.getFace()) {
|
||||
case FLOOR:
|
||||
// x axis
|
||||
if (facing == BlockFace.EAST || facing == BlockFace.WEST) {
|
||||
return powered ? new HexCollisionBox(6.0, 0.0, 5.0, 10.0, 1.0, 11.0) : new HexCollisionBox(6.0, 0.0, 5.0, 10.0, 2.0, 11.0);
|
||||
}
|
||||
|
||||
return powered ? new HexCollisionBox(5.0, 0.0, 6.0, 11.0, 1.0, 10.0) : new HexCollisionBox(5.0, 0.0, 6.0, 11.0, 2.0, 10.0);
|
||||
case WALL:
|
||||
CollisionBox shape;
|
||||
switch (facing) {
|
||||
case EAST:
|
||||
shape = powered ? new HexCollisionBox(0.0, 6.0, 5.0, 1.0, 10.0, 11.0) : new HexCollisionBox(0.0, 6.0, 5.0, 2.0, 10.0, 11.0);
|
||||
break;
|
||||
case WEST:
|
||||
shape = powered ? new HexCollisionBox(15.0, 6.0, 5.0, 16.0, 10.0, 11.0) : new HexCollisionBox(14.0, 6.0, 5.0, 16.0, 10.0, 11.0);
|
||||
break;
|
||||
case SOUTH:
|
||||
shape = powered ? new HexCollisionBox(5.0, 6.0, 0.0, 11.0, 10.0, 1.0) : new HexCollisionBox(5.0, 6.0, 0.0, 11.0, 10.0, 2.0);
|
||||
break;
|
||||
case NORTH:
|
||||
case UP:
|
||||
case DOWN:
|
||||
shape = powered ? new HexCollisionBox(5.0, 6.0, 15.0, 11.0, 10.0, 16.0) : new HexCollisionBox(5.0, 6.0, 14.0, 11.0, 10.0, 16.0);
|
||||
break;
|
||||
default:
|
||||
shape = NoCollisionBox.INSTANCE;
|
||||
}
|
||||
|
||||
return shape;
|
||||
case CEILING:
|
||||
default:
|
||||
// x axis
|
||||
if (facing == BlockFace.EAST || facing == BlockFace.WEST) {
|
||||
return powered ? new HexCollisionBox(6.0, 15.0, 5.0, 10.0, 16.0, 11.0) : new HexCollisionBox(6.0, 14.0, 5.0, 10.0, 16.0, 11.0);
|
||||
} else {
|
||||
return powered ? new HexCollisionBox(5.0, 15.0, 6.0, 11.0, 16.0, 10.0) : new HexCollisionBox(5.0, 14.0, 6.0, 11.0, 16.0, 10.0);
|
||||
}
|
||||
}
|
||||
}, BlockTags.BUTTONS.getStates().toArray(new StateType[0])),
|
||||
|
||||
WALL_SIGN((player, item, version, data, x, y, z) -> {
|
||||
switch (data.getFacing()) {
|
||||
case NORTH:
|
||||
return new HexCollisionBox(0.0, 4.5, 14.0, 16.0, 12.5, 16.0);
|
||||
case SOUTH:
|
||||
return new HexCollisionBox(0.0, 4.5, 0.0, 16.0, 12.5, 2.0);
|
||||
case EAST:
|
||||
return new HexCollisionBox(0.0, 4.5, 0.0, 2.0, 12.5, 16.0);
|
||||
case WEST:
|
||||
return new HexCollisionBox(14.0, 4.5, 0.0, 16.0, 12.5, 16.0);
|
||||
default:
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}
|
||||
}, BlockTags.WALL_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
WALL_HANGING_SIGN((player, item, version, data, x, y, z) -> {
|
||||
switch (data.getFacing()) {
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
return new ComplexCollisionBox(new HexCollisionBox(0.0D, 14.0D, 6.0D, 16.0D, 16.0D, 10.0D),
|
||||
new HexCollisionBox(1.0D, 0.0D, 7.0D, 15.0D, 10.0D, 9.0D));
|
||||
default:
|
||||
return new ComplexCollisionBox(new HexCollisionBox(6.0D, 14.0D, 0.0D, 10.0D, 16.0D, 16.0D),
|
||||
new HexCollisionBox(7.0D, 0.0D, 1.0D, 9.0D, 10.0D, 15.0D));
|
||||
}
|
||||
}, BlockTags.WALL_HANGING_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
STANDING_SIGN((player, item, version, data, x, y, z) ->
|
||||
new HexCollisionBox(4.0, 0.0, 4.0, 12.0, 16.0, 12.0),
|
||||
BlockTags.STANDING_SIGNS.getStates().toArray(new StateType[0])),
|
||||
|
||||
REDSTONE_WIRE((player, item, version, data, x, y, z) ->
|
||||
// Easier to just use no collision box
|
||||
// Redstone wire is very complex with its collision shapes and has many de-syncs
|
||||
NoCollisionBox.INSTANCE,
|
||||
StateTypes.REDSTONE_WIRE),
|
||||
|
||||
FIRE((player, item, version, data, x, y, z) -> {
|
||||
// Since 1.16 fire has a small hitbox
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_16)) {
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D);
|
||||
}
|
||||
|
||||
return NoCollisionBox.INSTANCE;
|
||||
}, BlockTags.FIRE.getStates().toArray(new StateType[0])),
|
||||
|
||||
BANNER(((player, item, version, data, x, y, z) ->
|
||||
new SimpleCollisionBox(4.0, 0.0, 4.0, 12.0, 16.0, 12.0)),
|
||||
BlockTags.BANNERS.getStates().toArray(new StateType[0]));
|
||||
|
||||
|
||||
private static final Map<StateType, HitboxData> lookup = new HashMap<>();
|
||||
|
||||
@@ -663,59 +329,6 @@ public enum HitboxData {
|
||||
return data.box.copy().offset(x, y, z);
|
||||
|
||||
// Allow this class to override collision boxes when they aren't the same as regular boxes
|
||||
HitBoxFactory hitBoxFactory = data.dynamic;
|
||||
CollisionBox collisionBox = hitBoxFactory.fetch(player, heldItem, version, block, x, y, z);
|
||||
collisionBox.offset(x, y, z);
|
||||
return collisionBox;
|
||||
}
|
||||
|
||||
private static int getPropaguleMinHeight(int age) {
|
||||
switch (age) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
return 13 - age * 3;
|
||||
case 3:
|
||||
case 4:
|
||||
return (4 - age) * 3;
|
||||
}
|
||||
throw new IllegalStateException("Impossible Propagule Height");
|
||||
}
|
||||
|
||||
private static CollisionBox getVineCollisionBox(ClientVersion version, boolean isWeeping, boolean isBlock) {
|
||||
if (version.isNewerThan(ClientVersion.V_1_15_2)) {
|
||||
if (isWeeping) {
|
||||
return isBlock
|
||||
? new HexCollisionBox(4.0, 9.0, 4.0, 12.0, 16.0, 12.0)
|
||||
: new HexCollisionBox(1.0, 0.0, 1.0, 15.0, 16.0, 15.0);
|
||||
} else {
|
||||
return new HexCollisionBox(4.0D, 0.0D, 4.0D, 12.0D, isBlock ? 15.0D : 16.0D, 12.0D);
|
||||
}
|
||||
} else {
|
||||
// Via replacement - 4 sided vine
|
||||
return new ComplexCollisionBox(
|
||||
new HexCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 16.0D, 16.0D),
|
||||
new HexCollisionBox(15.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D),
|
||||
new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 1.0D),
|
||||
new HexCollisionBox(0.0D, 0.0D, 15.0D, 16.0D, 16.0D, 16.0D)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getHorizontalID(BlockFace facing) {
|
||||
switch (facing) {
|
||||
case DOWN:
|
||||
case UP:
|
||||
return -1;
|
||||
case NORTH:
|
||||
return 2;
|
||||
case SOUTH:
|
||||
return 0;
|
||||
case WEST:
|
||||
return 1;
|
||||
case EAST:
|
||||
return 3;
|
||||
}
|
||||
throw new IllegalStateException("Impossible blockface for getHorizontalID");
|
||||
return HitboxData.getData(block.getType()).dynamic.fetch(player, heldItem, version, block, x, y, z).offset(x, y, z);
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -18,9 +18,11 @@ import com.github.retrooper.packetevents.protocol.world.states.enums.West;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
|
||||
public class DynamicCollisionFence extends DynamicConnecting implements CollisionFactory {
|
||||
public class DynamicFence extends DynamicConnecting implements CollisionFactory {
|
||||
private static final CollisionBox[] COLLISION_BOXES = makeShapes(2.0F, 2.0F, 24.0F, 0.0F, 24.0F, true);
|
||||
|
||||
public static SimpleCollisionBox[] LEGACY_BOUNDING_BOXES = new SimpleCollisionBox[] {new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D)};
|
||||
|
||||
@Override
|
||||
public CollisionBox fetch(GrimPlayer player, ClientVersion version, WrappedBlockState block, int x, int y, int z) {
|
||||
boolean east;
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
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.CollisionBox;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.ComplexCollisionBox;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.HitBoxFactory;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DynamicHitboxFence extends DynamicConnecting implements HitBoxFactory {
|
||||
private static final CollisionBox[] MODERN_HITBOXES = makeShapes(2.0F, 2.0F, 24.0F, 0.0F, 24.0F, true);
|
||||
|
||||
public static SimpleCollisionBox[] LEGACY_HITBOXES = new SimpleCollisionBox[] {new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D)};
|
||||
|
||||
static {
|
||||
for (int i = 0; i < MODERN_HITBOXES.length; i++) {
|
||||
CollisionBox collisionBox = MODERN_HITBOXES[i];
|
||||
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
||||
collisionBox.downCast(boxes);
|
||||
|
||||
for (SimpleCollisionBox box : boxes) {
|
||||
if (box.maxY > 1) {
|
||||
box.maxY = 1;
|
||||
}
|
||||
}
|
||||
|
||||
MODERN_HITBOXES[i] = new ComplexCollisionBox(boxes.toArray(new SimpleCollisionBox[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollisionBox fetch(GrimPlayer player, StateType heldItem, ClientVersion version, WrappedBlockState block, int x, int y, int z) {
|
||||
boolean east;
|
||||
boolean north;
|
||||
boolean south;
|
||||
boolean west;
|
||||
|
||||
// 1.13+ servers on 1.13+ clients send the full fence data
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_13)
|
||||
&& version.isNewerThanOrEquals(ClientVersion.V_1_13)) {
|
||||
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);
|
||||
}
|
||||
|
||||
return version.isNewerThanOrEquals(ClientVersion.V_1_12_2)
|
||||
? getModernCollisionBox(north, east, south, west)
|
||||
: getLegacyCollisionBox(north, east, south, west);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private CollisionBox getLegacyCollisionBox(boolean north, boolean east, boolean south, boolean west) {
|
||||
return LEGACY_HITBOXES[getAABBIndex(north, east, south, west)].copy();
|
||||
}
|
||||
|
||||
private CollisionBox getModernCollisionBox(boolean north, boolean east, boolean south, boolean west) {
|
||||
return MODERN_HITBOXES[getAABBIndex(north, east, south, west)].copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two, BlockFace direction) {
|
||||
if (BlockTags.FENCES.contains(one))
|
||||
return !(one == StateTypes.NETHER_BRICK_FENCE) && !(two == StateTypes.NETHER_BRICK_FENCE);
|
||||
else
|
||||
return BlockTags.FENCES.contains(one) || CollisionData.getData(one).getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0).isSideFullBlock(direction);
|
||||
}
|
||||
}
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
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
@@ -1,111 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -19,7 +19,7 @@ import com.github.retrooper.packetevents.protocol.world.states.enums.West;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
|
||||
public class DynamicCollisionPane extends DynamicConnecting implements CollisionFactory {
|
||||
public class DynamicPane extends DynamicConnecting implements CollisionFactory {
|
||||
|
||||
private static final CollisionBox[] COLLISION_BOXES = makeShapes(1.0F, 1.0F, 16.0F, 0.0F, 16.0F, true);
|
||||
|
||||
+1
-5
@@ -15,16 +15,12 @@ import com.github.retrooper.packetevents.protocol.world.states.enums.South;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.enums.West;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
|
||||
public class DynamicCollisionWall extends DynamicConnecting implements CollisionFactory {
|
||||
public class DynamicWall extends DynamicConnecting implements CollisionFactory {
|
||||
public static final CollisionBox[] BOXES = makeShapes(4.0F, 3.0F, 16.0F, 0.0F, 16.0F, false);
|
||||
// https://bugs.mojang.com/browse/MC-9565
|
||||
// https://bugs.mojang.com/browse/MC-94016
|
||||
private static final CollisionBox[] COLLISION_BOXES = makeShapes(4.0F, 3.0F, 24.0F, 0.0F, 24.0F, false);
|
||||
|
||||
/**
|
||||
* @deprecated use DynamicHitboxWall
|
||||
*/
|
||||
@Deprecated
|
||||
public CollisionBox fetchRegularBox(GrimPlayer player, WrappedBlockState state, ClientVersion version, int x, int y, int z) {
|
||||
int north, south, west, east, up;
|
||||
north = south = west = east = up = 0;
|
||||
@@ -5,8 +5,6 @@ import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import java.util.List;
|
||||
|
||||
public interface CollisionBox {
|
||||
CollisionBox union(SimpleCollisionBox other);
|
||||
|
||||
boolean isCollided(SimpleCollisionBox other);
|
||||
|
||||
boolean isIntersected(SimpleCollisionBox other);
|
||||
|
||||
@@ -16,12 +16,6 @@ public class ComplexCollisionBox implements CollisionBox {
|
||||
return boxes.add(collisionBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollisionBox union(SimpleCollisionBox other) {
|
||||
add(other);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollided(SimpleCollisionBox other) {
|
||||
for (CollisionBox box : boxes) {
|
||||
|
||||
@@ -21,14 +21,6 @@ public class DynamicCollisionBox implements CollisionBox {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
// Untested but currently unused
|
||||
// *should* work because every single one of these eventually becomes a Complex, Simple, or NoCollision Box
|
||||
@Override
|
||||
public CollisionBox union(SimpleCollisionBox other) {
|
||||
CollisionBox dynamicBox = box.fetch(player, version, block, x, y, z).offset(x, y, z);
|
||||
return dynamicBox.union(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollided(SimpleCollisionBox other) {
|
||||
return box.fetch(player, version, block, x, y, z).offset(x, y, z).isCollided(other);
|
||||
|
||||
@@ -2,18 +2,6 @@ package ac.grim.grimac.utils.collisions.datatypes;
|
||||
|
||||
public class HexCollisionBox extends SimpleCollisionBox {
|
||||
|
||||
/**
|
||||
* Creates a box defined by two points in 3d space; used to represent hitboxes and collision boxes.
|
||||
* Mojang's block hitbox values are all based on chunks, so they're stored in game as 16 * the actual size
|
||||
* When copying block hitbox values, it may be easier to simple copy the multiplied values and use this class
|
||||
* If your min/max values are < 1 you should probably check out {@link SimpleCollisionBox}
|
||||
* @param minX 16 * x position of first corner
|
||||
* @param minY 16 * y position of first corner
|
||||
* @param minZ 16 * z position of first corner
|
||||
* @param maxX 16 * x position of second corner
|
||||
* @param maxY 16 * y position of second corner
|
||||
* @param maxZ 16 * z position of second corner
|
||||
*/
|
||||
public HexCollisionBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
|
||||
this.minX = minX / 16d;
|
||||
this.minY = minY / 16d;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,6 @@ public class NoCollisionBox implements CollisionBox {
|
||||
private NoCollisionBox() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollisionBox union(SimpleCollisionBox other) {
|
||||
return other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollided(SimpleCollisionBox other) {
|
||||
return false;
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -24,17 +24,6 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
this(0, 0, 0, 0, 0, 0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a box defined by two points in 3d space; used to represent hitboxes and collision boxes.
|
||||
* If your min/max values are > 1 you should probably check out {@link HexCollisionBox}
|
||||
* @param minX x position of first corner
|
||||
* @param minY y position of first corner
|
||||
* @param minZ z position of first corner
|
||||
* @param maxX x position of second corner
|
||||
* @param maxY y position of second corner
|
||||
* @param maxZ z position of second corner
|
||||
* @param fullBlock - whether on not the box is a perfect 1x1x1 sized block
|
||||
*/
|
||||
public SimpleCollisionBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ, boolean fullBlock) {
|
||||
this.minX = minX;
|
||||
this.maxX = maxX;
|
||||
@@ -58,17 +47,7 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
this(minX, minY, minZ, minX + 1, minY + 1, minZ + 1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a box defined by two points in 3d space; used to represent hitboxes and collision boxes.
|
||||
* If your min/max values are > 1 you should probably check out {@link HexCollisionBox}
|
||||
* Use only if you don't know the fullBlock status, which is rare
|
||||
* @param minX x position of first corner
|
||||
* @param minY y position of first corner
|
||||
* @param minZ z position of first corner
|
||||
* @param maxX x position of second corner
|
||||
* @param maxY y position of second corner
|
||||
* @param maxZ z position of second corner
|
||||
*/
|
||||
// Use only if you don't know the fullBlock status, which is rare
|
||||
public SimpleCollisionBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
|
||||
this.minX = minX;
|
||||
this.maxX = maxX;
|
||||
@@ -163,8 +142,7 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
return vectors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollisionBox union(SimpleCollisionBox other) {
|
||||
public SimpleCollisionBox union(SimpleCollisionBox other) {
|
||||
this.minX = Math.min(this.minX, other.minX);
|
||||
this.minY = Math.min(this.minY, other.minY);
|
||||
this.minZ = Math.min(this.minZ, other.minZ);
|
||||
|
||||
@@ -101,29 +101,29 @@ public final class ValuedAttribute {
|
||||
}
|
||||
|
||||
public double with(WrapperPlayServerUpdateAttributes.Property property) {
|
||||
double d0 = property.getValue();
|
||||
double baseValue = property.getValue();
|
||||
double additionSum = 0;
|
||||
double multiplyBaseSum = 0;
|
||||
double multiplyTotalProduct = 1.0;
|
||||
|
||||
List<WrapperPlayServerUpdateAttributes.PropertyModifier> modifiers = property.getModifiers();
|
||||
modifiers.removeIf(modifier -> modifier.getUUID().equals(SPRINTING_MODIFIER_UUID) || modifier.getName().getKey().equals("sprinting"));
|
||||
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier attributemodifier : modifiers) {
|
||||
if (attributemodifier.getOperation() == WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.ADDITION)
|
||||
d0 += attributemodifier.getAmount();
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier modifier : modifiers) {
|
||||
switch (modifier.getOperation()) {
|
||||
case ADDITION:
|
||||
additionSum += modifier.getAmount();
|
||||
break;
|
||||
case MULTIPLY_BASE:
|
||||
multiplyBaseSum += modifier.getAmount();
|
||||
break;
|
||||
case MULTIPLY_TOTAL:
|
||||
multiplyTotalProduct *= (1.0 + modifier.getAmount());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double d1 = d0;
|
||||
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier attributemodifier : modifiers) {
|
||||
if (attributemodifier.getOperation() == WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.MULTIPLY_BASE)
|
||||
d1 += d0 * attributemodifier.getAmount();
|
||||
}
|
||||
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier attributemodifier : modifiers) {
|
||||
if (attributemodifier.getOperation() == WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.MULTIPLY_TOTAL)
|
||||
d1 *= 1.0D + attributemodifier.getAmount();
|
||||
}
|
||||
|
||||
double newValue = GrimMath.clampFloat((float) d1, (float) min, (float) max);
|
||||
double newValue = GrimMath.clamp((baseValue + additionSum) * (1 + multiplyBaseSum) * multiplyTotalProduct, min, max);
|
||||
if (setRewriter != null) {
|
||||
newValue = setRewriter.apply(this.value, newValue);
|
||||
}
|
||||
|
||||
@@ -105,10 +105,4 @@ public class GrimMath {
|
||||
public static boolean isNearlySame(double a, double b, double epoch) {
|
||||
return Math.abs(a-b) < epoch;
|
||||
}
|
||||
|
||||
public static long hashCode(double x, int y, double z) {
|
||||
long l = (long)(x * 3129871) ^ (long)z * 116129781L ^ (long)y;
|
||||
l = l * l * 42317861L + l * 11L;
|
||||
return l >> 16;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user