Collisions without BlockMapping

This commit is contained in:
Camotoy 2024-05-17 17:52:19 -04:00
parent 1cd0aad79f
commit 06dc0d1ca8
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
14 changed files with 100 additions and 126 deletions

View file

@ -69,7 +69,6 @@ import org.geysermc.geyser.event.GeyserEventBus;
import org.geysermc.geyser.extension.GeyserExtensionManager; import org.geysermc.geyser.extension.GeyserExtensionManager;
import org.geysermc.geyser.impl.MinecraftVersionImpl; import org.geysermc.geyser.impl.MinecraftVersionImpl;
import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.level.WorldManager;
import org.geysermc.geyser.level.block.Blocks;
import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.network.netty.GeyserServer; import org.geysermc.geyser.network.netty.GeyserServer;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
@ -258,7 +257,6 @@ public class GeyserImpl implements GeyserApi {
VersionCheckUtils.checkForOutdatedJava(logger); VersionCheckUtils.checkForOutdatedJava(logger);
Blocks.VAULT.javaId();
for (int i = 0; i < BlockRegistries.JAVA_BLOCKS.get().length; i++) { for (int i = 0; i < BlockRegistries.JAVA_BLOCKS.get().length; i++) {
String cleanIdentifier = BlockRegistries.JAVA_BLOCKS.get(i).getCleanJavaIdentifier(); String cleanIdentifier = BlockRegistries.JAVA_BLOCKS.get(i).getCleanJavaIdentifier();
String newIdentifier = BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier(); String newIdentifier = BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier();

View file

@ -69,9 +69,6 @@ public final class BlockStateValues {
private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap(); private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap();
private static final IntSet UPPER_DOORS = new IntOpenHashSet(); private static final IntSet UPPER_DOORS = new IntOpenHashSet();
public static final int JAVA_AIR_ID = 0;
public static int JAVA_COBWEB_ID;
public static int JAVA_FURNACE_ID; public static int JAVA_FURNACE_ID;
public static int JAVA_FURNACE_LIT_ID; public static int JAVA_FURNACE_LIT_ID;
public static int JAVA_HONEY_BLOCK_ID; public static int JAVA_HONEY_BLOCK_ID;

View file

@ -34,6 +34,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockData;
import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.CustomBlockState;
import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState;
import org.geysermc.geyser.level.block.Blocks;
import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.Block;
import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.registry.loader.CollisionRegistryLoader; import org.geysermc.geyser.registry.loader.CollisionRegistryLoader;
@ -82,19 +83,13 @@ public class BlockRegistries {
/** /**
* A mapped registry containing which holds block IDs to its {@link BlockCollision}. * A mapped registry containing which holds block IDs to its {@link BlockCollision}.
*/ */
public static final IntMappedRegistry<BlockCollision> COLLISIONS; public static final ListRegistry<BlockCollision> COLLISIONS;
/** /**
* A mapped registry containing the Java identifiers to IDs. * A mapped registry containing the Java identifiers to IDs.
*/ */
public static final MappedRegistry<String, Integer, Object2IntMap<String>> JAVA_IDENTIFIER_TO_ID = MappedRegistry.create(RegistryLoaders.empty(Object2IntOpenHashMap::new)); public static final MappedRegistry<String, Integer, Object2IntMap<String>> JAVA_IDENTIFIER_TO_ID = MappedRegistry.create(RegistryLoaders.empty(Object2IntOpenHashMap::new));
/**
* A registry which stores unique Java IDs to its clean identifier
* This is used in the statistics form.
*/
public static final ArrayRegistry<String> CLEAN_JAVA_IDENTIFIERS = ArrayRegistry.create(RegistryLoaders.uninitialized());
/** /**
* A registry containing all the waterlogged blockstates. * A registry containing all the waterlogged blockstates.
*/ */
@ -141,12 +136,13 @@ public class BlockRegistries {
public static final SimpleMappedRegistry<String, CustomSkull> CUSTOM_SKULLS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); public static final SimpleMappedRegistry<String, CustomSkull> CUSTOM_SKULLS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
static { static {
Blocks.VAULT.javaId(); // FIXME
CustomSkullRegistryPopulator.populate(); CustomSkullRegistryPopulator.populate();
BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.PRE_INIT); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.PRE_INIT);
CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.DEFINITION); CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.DEFINITION);
CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.NON_VANILLA_REGISTRATION); CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.NON_VANILLA_REGISTRATION);
BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_JAVA); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_JAVA);
COLLISIONS = IntMappedRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collision.json"), CollisionRegistryLoader::new); COLLISIONS = ListRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collisions.nbt"), CollisionRegistryLoader::new);
CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.VANILLA_REGISTRATION); CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.VANILLA_REGISTRATION);
CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.CUSTOM_REGISTRATION); CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.CUSTOM_REGISTRATION);
BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_BEDROCK); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_BEDROCK);

View file

@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.registry.loader.RegistryLoader; import org.geysermc.geyser.registry.loader.RegistryLoader;
import java.util.List; import java.util.List;
import java.util.function.Supplier;
public class ListRegistry<M> extends Registry<List<M>> { public class ListRegistry<M> extends Registry<List<M>> {
/** /**
@ -98,6 +99,18 @@ public class ListRegistry<M> extends Registry<List<M>> {
* @return a new registry with the given RegistryLoader supplier * @return a new registry with the given RegistryLoader supplier
*/ */
public static <I, M> ListRegistry<M> create(RegistryLoader<I, List<M>> registryLoader) { public static <I, M> ListRegistry<M> create(RegistryLoader<I, List<M>> registryLoader) {
return new ListRegistry<M>(null, registryLoader); return new ListRegistry<>(null, registryLoader);
}
/**
* Creates a new integer mapped registry with the given {@link RegistryLoader} and input.
*
* @param registryLoader the registry loader
* @param <I> the input
* @param <M> the type value
* @return a new registry with the given RegistryLoader supplier
*/
public static <I, M> ListRegistry<M> create(I input, Supplier<RegistryLoader<I, List<M>>> registryLoader) {
return new ListRegistry<>(input, registryLoader.get());
} }
} }

View file

@ -25,18 +25,19 @@
package org.geysermc.geyser.registry.loader; package org.geysermc.geyser.registry.loader;
import com.fasterxml.jackson.databind.node.ArrayNode;
import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtList;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.nbt.NbtUtils;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.BlockMapping;
import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.geyser.translator.collision.CollisionRemapper; import org.geysermc.geyser.translator.collision.CollisionRemapper;
import org.geysermc.geyser.translator.collision.OtherCollision; import org.geysermc.geyser.translator.collision.OtherCollision;
@ -51,41 +52,43 @@ import java.util.regex.Pattern;
/** /**
* Loads collision data from the given resource path. * Loads collision data from the given resource path.
*/ */
public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String, Int2ObjectMap<BlockCollision>> { public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String, List<BlockCollision>> {
@Override @Override
public Int2ObjectMap<BlockCollision> load(Pair<String, String> input) { public List<BlockCollision> load(Pair<String, String> input) {
Int2ObjectMap<BlockCollision> collisions = new Int2ObjectOpenHashMap<>();
Map<Class<?>, CollisionInfo> annotationMap = new IdentityHashMap<>(); Map<Class<?>, CollisionInfo> annotationMap = new IdentityHashMap<>();
for (Class<?> clazz : FileUtils.getGeneratedClassesForAnnotation(CollisionRemapper.class.getName())) { for (Class<?> clazz : FileUtils.getGeneratedClassesForAnnotation(CollisionRemapper.class.getName())) {
GeyserImpl.getInstance().getLogger().debug("Found annotated collision translator: " + clazz.getCanonicalName()); GeyserImpl.getInstance().getLogger().debug("Found annotated collision translator: " + clazz.getCanonicalName());
CollisionRemapper collisionRemapper = clazz.getAnnotation(CollisionRemapper.class); CollisionRemapper collisionRemapper = clazz.getAnnotation(CollisionRemapper.class);
annotationMap.put(clazz, new CollisionInfo(collisionRemapper, Pattern.compile(collisionRemapper.regex()), Pattern.compile(collisionRemapper.paramRegex()))); annotationMap.put(clazz, new CollisionInfo(collisionRemapper, Pattern.compile(collisionRemapper.regex())));
} }
// Load collision mappings file // Load collision mappings file
int[] indices;
List<BoundingBox[]> collisionList; List<BoundingBox[]> collisionList;
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow(input.value())) { try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow(input.value())) {
ArrayNode collisionNode = (ArrayNode) GeyserImpl.JSON_MAPPER.readTree(stream); NbtMap collisionData = (NbtMap) NbtUtils.createGZIPReader(stream).readTag();
collisionList = loadBoundingBoxes(collisionNode); indices = collisionData.getIntArray("indices");
//SuppressWarnings unchecked
collisionList = loadBoundingBoxes(collisionData.getList("collisions", NbtType.LIST));
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load collision data", e); throw new AssertionError("Unable to load collision data", e);
} }
BlockMapping[] blockMappings = BlockRegistries.JAVA_BLOCKS.get(); List<BlockState> blockStates = BlockRegistries.BLOCK_STATES.get();
List<BlockCollision> collisions = new ObjectArrayList<>(blockStates.size());
// Map of unique collisions to its instance // Map of unique collisions to its instance
Map<BlockCollision, BlockCollision> collisionInstances = new Object2ObjectOpenHashMap<>(); Map<BlockCollision, BlockCollision> collisionInstances = new Object2ObjectOpenHashMap<>();
for (int i = 0; i < blockMappings.length; i++) { for (int i = 0; i < blockStates.size(); i++) {
BlockMapping blockMapping = blockMappings[i]; BlockState state = blockStates.get(i);
if (blockMapping == null) { if (state == null) {
GeyserImpl.getInstance().getLogger().warning("Missing block mapping for Java block " + i); GeyserImpl.getInstance().getLogger().warning("Missing block state for Java block " + i);
continue; continue;
} }
BlockCollision newCollision = instantiateCollision(blockMapping, annotationMap, collisionList); BlockCollision newCollision = instantiateCollision(state, annotationMap, indices[i], collisionList);
if (newCollision != null) { if (newCollision != null) {
// If there's an existing instance equal to this one, use that instead // If there's an existing instance equal to this one, use that instead
@ -97,33 +100,27 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String,
} }
} }
collisions.put(i, newCollision); collisions.add(newCollision);
} }
return collisions; return collisions;
} }
private @Nullable BlockCollision instantiateCollision(BlockMapping mapping, Map<Class<?>, CollisionInfo> annotationMap, List<BoundingBox[]> collisionList) { private @Nullable BlockCollision instantiateCollision(BlockState state, Map<Class<?>, CollisionInfo> annotationMap, int collisionIndex, List<BoundingBox[]> collisionList) {
String[] blockIdParts = mapping.getJavaIdentifier().split("\\["); String blockName = state.block().javaIdentifier().substring("minecraft:".length());
String blockName = blockIdParts[0].replace("minecraft:", "");
String params = "";
if (blockIdParts.length == 2) {
params = "[" + blockIdParts[1];
}
int collisionIndex = mapping.getCollisionIndex();
for (Map.Entry<Class<?>, CollisionInfo> collisionRemappers : annotationMap.entrySet()) { for (Map.Entry<Class<?>, CollisionInfo> collisionRemappers : annotationMap.entrySet()) {
Class<?> type = collisionRemappers.getKey(); Class<?> type = collisionRemappers.getKey();
CollisionInfo collisionInfo = collisionRemappers.getValue(); CollisionInfo collisionInfo = collisionRemappers.getValue();
CollisionRemapper annotation = collisionInfo.collisionRemapper; CollisionRemapper annotation = collisionInfo.collisionRemapper;
if (collisionInfo.pattern.matcher(blockName).find() && collisionInfo.paramsPattern.matcher(params).find()) { if (collisionInfo.pattern.matcher(blockName).find()) {
try { try {
if (annotation.passDefaultBoxes()) { if (annotation.passDefaultBoxes()) {
// Create an OtherCollision instance and get the bounding boxes // Create an OtherCollision instance and get the bounding boxes
BoundingBox[] defaultBoxes = collisionList.get(collisionIndex); BoundingBox[] defaultBoxes = collisionList.get(collisionIndex);
return (BlockCollision) type.getDeclaredConstructor(String.class, BoundingBox[].class).newInstance(params, defaultBoxes); return (BlockCollision) type.getDeclaredConstructor(BlockState.class, BoundingBox[].class).newInstance(state, defaultBoxes);
} else { } else {
return (BlockCollision) type.getDeclaredConstructor(String.class).newInstance(params); return (BlockCollision) type.getDeclaredConstructor(BlockState.class).newInstance(state);
} }
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -138,25 +135,25 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String,
// Unless some of the low IDs are changed, which is unlikely, the second item should always be full collision // Unless some of the low IDs are changed, which is unlikely, the second item should always be full collision
if (collisionIndex == 1) { if (collisionIndex == 1) {
return new SolidCollision(params); return new SolidCollision(state);
} }
return new OtherCollision(collisionList.get(collisionIndex)); return new OtherCollision(collisionList.get(collisionIndex));
} }
private List<BoundingBox[]> loadBoundingBoxes(ArrayNode collisionNode) { private List<BoundingBox[]> loadBoundingBoxes(List<NbtList> collisionNode) {
List<BoundingBox[]> collisions = new ObjectArrayList<>(); List<BoundingBox[]> collisions = new ObjectArrayList<>();
for (int collisionIndex = 0; collisionIndex < collisionNode.size(); collisionIndex++) { for (int collisionIndex = 0; collisionIndex < collisionNode.size(); collisionIndex++) {
ArrayNode boundingBoxArray = (ArrayNode) collisionNode.get(collisionIndex); @SuppressWarnings("unchecked") NbtList<NbtList<Double>> boundingBoxArray = (NbtList<NbtList<Double>>) collisionNode.get(collisionIndex);
BoundingBox[] boundingBoxes = new BoundingBox[boundingBoxArray.size()]; BoundingBox[] boundingBoxes = new BoundingBox[boundingBoxArray.size()];
for (int i = 0; i < boundingBoxArray.size(); i++) { for (int i = 0; i < boundingBoxArray.size(); i++) {
ArrayNode boxProperties = (ArrayNode) boundingBoxArray.get(i); NbtList<Double> boxProperties = boundingBoxArray.get(i);
boundingBoxes[i] = new BoundingBox(boxProperties.get(0).asDouble(), boundingBoxes[i] = new BoundingBox(boxProperties.get(0),
boxProperties.get(1).asDouble(), boxProperties.get(1),
boxProperties.get(2).asDouble(), boxProperties.get(2),
boxProperties.get(3).asDouble(), boxProperties.get(3),
boxProperties.get(4).asDouble(), boxProperties.get(4),
boxProperties.get(5).asDouble()); boxProperties.get(5));
} }
// Sorting by lowest Y first fixes some bugs // Sorting by lowest Y first fixes some bugs
@ -173,6 +170,5 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String,
public static class CollisionInfo { public static class CollisionInfo {
private final CollisionRemapper collisionRemapper; private final CollisionRemapper collisionRemapper;
private final Pattern pattern; private final Pattern pattern;
private final Pattern paramsPattern;
} }
} }

View file

@ -409,7 +409,6 @@ public final class BlockRegistryPopulator {
Deque<String> cleanIdentifiers = new ArrayDeque<>(); Deque<String> cleanIdentifiers = new ArrayDeque<>();
int javaRuntimeId = -1; int javaRuntimeId = -1;
int cobwebBlockId = -1;
int furnaceRuntimeId = -1; int furnaceRuntimeId = -1;
int furnaceLitRuntimeId = -1; int furnaceLitRuntimeId = -1;
int honeyBlockRuntimeId = -1; int honeyBlockRuntimeId = -1;
@ -485,10 +484,7 @@ public final class BlockRegistryPopulator {
// It's possible to only have this store differences in names, but the key set of all Java names is used in sending command suggestions // It's possible to only have this store differences in names, but the key set of all Java names is used in sending command suggestions
BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.register(cleanJavaIdentifier.intern(), bedrockIdentifier.intern()); BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.register(cleanJavaIdentifier.intern(), bedrockIdentifier.intern());
if (javaId.contains("cobweb")) { if (javaId.startsWith("minecraft:furnace[facing=north")) {
cobwebBlockId = uniqueJavaId;
} else if (javaId.startsWith("minecraft:furnace[facing=north")) {
if (javaId.contains("lit=true")) { if (javaId.contains("lit=true")) {
furnaceLitRuntimeId = javaRuntimeId; furnaceLitRuntimeId = javaRuntimeId;
} else { } else {
@ -507,11 +503,6 @@ public final class BlockRegistryPopulator {
} }
} }
if (cobwebBlockId == -1) {
throw new AssertionError("Unable to find cobwebs in palette");
}
BlockStateValues.JAVA_COBWEB_ID = cobwebBlockId;
if (furnaceRuntimeId == -1) { if (furnaceRuntimeId == -1) {
throw new AssertionError("Unable to find furnace in palette"); throw new AssertionError("Unable to find furnace in palette");
} }

View file

@ -37,12 +37,6 @@ public @interface CollisionRemapper {
*/ */
String regex(); String regex();
/**
* Regex of block state parameters to apply this collision to
* Defaults to matching any value
*/
String paramRegex() default ".*";
/** /**
* Signals if a new instance needs to created for every block state * Signals if a new instance needs to created for every block state
*/ */

View file

@ -26,13 +26,14 @@
package org.geysermc.geyser.translator.collision; package org.geysermc.geyser.translator.collision;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.level.physics.CollisionManager; import org.geysermc.geyser.level.physics.CollisionManager;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@CollisionRemapper(regex = "^dirt_path$", passDefaultBoxes = true) @CollisionRemapper(regex = "^dirt_path$", passDefaultBoxes = true)
public class DirtPathCollision extends BlockCollision { public class DirtPathCollision extends BlockCollision {
public DirtPathCollision(String params, BoundingBox[] defaultBoxes) { public DirtPathCollision(BlockState state, BoundingBox[] defaultBoxes) {
super(defaultBoxes); super(defaultBoxes);
} }

View file

@ -26,6 +26,8 @@
package org.geysermc.geyser.translator.collision; package org.geysermc.geyser.translator.collision;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.geysermc.geyser.level.block.property.Properties;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -40,20 +42,18 @@ public class DoorCollision extends BlockCollision {
*/ */
private int facing; private int facing;
public DoorCollision(String params, BoundingBox[] defaultBoxes) { public DoorCollision(BlockState state, BoundingBox[] defaultBoxes) {
super(defaultBoxes); super(defaultBoxes);
if (params.contains("facing=north")) { facing = switch (state.getValue(Properties.HORIZONTAL_FACING)) {
facing = 1; case NORTH -> 1;
} else if (params.contains("facing=east")) { case EAST -> 2;
facing = 2; case SOUTH -> 3;
} else if (params.contains("facing=south")) { case WEST -> 4;
facing = 3; default -> throw new IllegalStateException();
} else if (params.contains("facing=west")) { };
facing = 4;
}
// If the door is open it changes direction // If the door is open it changes direction
if (params.contains("open=true")) { if (state.getValue(Properties.OPEN)) {
facing = facing % 2 + 1; facing = facing % 2 + 1;
} }
} }

View file

@ -26,6 +26,8 @@
package org.geysermc.geyser.translator.collision; package org.geysermc.geyser.translator.collision;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.geysermc.geyser.level.block.property.Properties;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -44,24 +46,23 @@ public class GlassPaneAndIronBarsCollision extends BlockCollision {
*/ */
private int facing; private int facing;
public GlassPaneAndIronBarsCollision(String params, BoundingBox[] defaultBoxes) { public GlassPaneAndIronBarsCollision(BlockState state, BoundingBox[] defaultBoxes) {
super(defaultBoxes); super(defaultBoxes);
//east=true,north=true,south=true,west=true if (state.getValue(Properties.NORTH) && state.getValue(Properties.EAST)) {
if (params.contains("north=true") && params.contains("east=true")) {
facing = 5; facing = 5;
} else if (params.contains("east=true") && params.contains("south=true")) { } else if (state.getValue(Properties.EAST) && state.getValue(Properties.SOUTH)) {
facing = 6; facing = 6;
} else if (params.contains("south=true") && params.contains("west=true")) { } else if (state.getValue(Properties.SOUTH) && state.getValue(Properties.WEST)) {
facing = 7; facing = 7;
} else if (params.contains("west=true") && params.contains("north=true")) { } else if (state.getValue(Properties.WEST) && state.getValue(Properties.NORTH)) {
facing = 8; facing = 8;
} else if (params.contains("north=true")) { } else if (state.getValue(Properties.NORTH)) {
facing = 1; facing = 1;
} else if (params.contains("east=true")) { } else if (state.getValue(Properties.EAST)) {
facing = 2; facing = 2;
} else if (params.contains("south=true")) { } else if (state.getValue(Properties.SOUTH)) {
facing = 3; facing = 3;
} else if (params.contains("west=true")) { } else if (state.getValue(Properties.WEST)) {
facing = 4; facing = 4;
} }
} }

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.translator.collision; package org.geysermc.geyser.translator.collision;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -35,7 +36,7 @@ import org.geysermc.geyser.session.GeyserSession;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@CollisionRemapper(regex = "^scaffolding$", usesParams = true, passDefaultBoxes = true) @CollisionRemapper(regex = "^scaffolding$", usesParams = true, passDefaultBoxes = true)
public class ScaffoldingCollision extends BlockCollision { public class ScaffoldingCollision extends BlockCollision {
public ScaffoldingCollision(String params, BoundingBox[] defaultBoxes) { public ScaffoldingCollision(BlockState state, BoundingBox[] defaultBoxes) {
super(defaultBoxes); super(defaultBoxes);
} }

View file

@ -26,12 +26,13 @@
package org.geysermc.geyser.translator.collision; package org.geysermc.geyser.translator.collision;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.BoundingBox;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@CollisionRemapper(regex = "shulker_box$") // These have no collision in the mappings as it depends on the NBT data @CollisionRemapper(regex = "shulker_box$") // These have no collision in the mappings as it depends on the NBT data
public class SolidCollision extends BlockCollision { public class SolidCollision extends BlockCollision {
public SolidCollision(String params) { public SolidCollision(BlockState state) {
super(new BoundingBox[] { super(new BoundingBox[] {
new BoundingBox(0.5, 0.5, 0.5, 1, 1, 1) new BoundingBox(0.5, 0.5, 0.5, 1, 1, 1)
}); });

View file

@ -26,42 +26,27 @@
package org.geysermc.geyser.translator.collision; package org.geysermc.geyser.translator.collision;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.geysermc.geyser.level.block.property.Properties;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.level.physics.CollisionManager; import org.geysermc.geyser.level.physics.CollisionManager;
import org.geysermc.geyser.level.physics.Direction;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@CollisionRemapper(regex = "_trapdoor$", usesParams = true, passDefaultBoxes = true) @CollisionRemapper(regex = "_trapdoor$", usesParams = true, passDefaultBoxes = true)
public class TrapdoorCollision extends BlockCollision { public class TrapdoorCollision extends BlockCollision {
/** private final Direction facing;
* 1 = north
* 2 = east
* 3 = south
* 4 = west
* 5 = up
* 6 = down
*/
private int facing;
public TrapdoorCollision(String params, BoundingBox[] defaultBoxes) { public TrapdoorCollision(BlockState state, BoundingBox[] defaultBoxes) {
super(defaultBoxes); super(defaultBoxes);
if (params.contains("open=true")) { if (state.getValue(Properties.OPEN)) {
if (params.contains("facing=north")) { facing = state.getValue(Properties.HORIZONTAL_FACING);
facing = 1;
} else if (params.contains("facing=east")) {
facing = 2;
} else if (params.contains("facing=south")) {
facing = 3;
} else if (params.contains("facing=west")) {
facing = 4;
}
} else { } else {
if (params.contains("half=bottom")) { if (state.getValue(Properties.HALF).equals("bottom")) {
// Up facing = Direction.UP;
facing = 5;
} else { } else {
// Down facing = Direction.DOWN;
facing = 6;
} }
} }
} }
@ -72,22 +57,22 @@ public class TrapdoorCollision extends BlockCollision {
// Check for door bug (doors are 0.1875 blocks thick on Java but 0.1825 blocks thick on Bedrock) // Check for door bug (doors are 0.1875 blocks thick on Java but 0.1825 blocks thick on Bedrock)
if (this.checkIntersection(x, y, z, playerCollision)) { if (this.checkIntersection(x, y, z, playerCollision)) {
switch (facing) { switch (facing) {
case 1: // North case NORTH:
playerCollision.setMiddleZ(z + 0.5125); playerCollision.setMiddleZ(z + 0.5125);
break; break;
case 2: // East case EAST:
playerCollision.setMiddleX(x + 0.5125); playerCollision.setMiddleX(x + 0.5125);
break; break;
case 3: // South case SOUTH:
playerCollision.setMiddleZ(z + 0.4875); playerCollision.setMiddleZ(z + 0.4875);
break; break;
case 4: // West case WEST:
playerCollision.setMiddleX(x + 0.4875); playerCollision.setMiddleX(x + 0.4875);
break; break;
case 5: case UP:
// Up-facing trapdoors are handled by the step-up check // Up-facing trapdoors are handled by the step-up check
break; break;
case 6: // Down case DOWN:
// (top y of trap door) - (trap door thickness) = top y of player // (top y of trap door) - (trap door thickness) = top y of player
playerCollision.setMiddleY(y + 1 - (3.0 / 16.0) - playerCollision.getSizeY() / 2.0 - CollisionManager.COLLISION_TOLERANCE); playerCollision.setMiddleY(y + 1 - (3.0 / 16.0) - playerCollision.getSizeY() / 2.0 - CollisionManager.COLLISION_TOLERANCE);
break; break;

@ -1 +1 @@
Subproject commit 7c01501ed6a0ee8848a66d729000539f2661f785 Subproject commit 6b661f0d517d895aebc1f55a25d2c86f033beb1d