Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-10-02 08:00:07 +02:00
Initial framework for extended collision boxes
Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
Dieser Commit ist enthalten in:
Ursprung
f1bd04a71d
Commit
4002c1df8d
@ -51,6 +51,13 @@ public interface CustomBlockComponents {
|
|||||||
*/
|
*/
|
||||||
BoxComponent collisionBox();
|
BoxComponent collisionBox();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the extended collision box
|
||||||
|
* Places an invisible collision block above the block to prevent players from jumping on top of it, if defined
|
||||||
|
* @return The extended collision box.
|
||||||
|
*/
|
||||||
|
BoxComponent extendedCollisionBox();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the display name component
|
* Gets the display name component
|
||||||
* Equivalent to "minecraft:display_name"
|
* Equivalent to "minecraft:display_name"
|
||||||
@ -153,6 +160,8 @@ public interface CustomBlockComponents {
|
|||||||
|
|
||||||
Builder collisionBox(BoxComponent collisionBox);
|
Builder collisionBox(BoxComponent collisionBox);
|
||||||
|
|
||||||
|
Builder extendedCollisionBox(BoxComponent extendedCollisionBox);
|
||||||
|
|
||||||
Builder displayName(String displayName);
|
Builder displayName(String displayName);
|
||||||
|
|
||||||
Builder geometry(String geometry);
|
Builder geometry(String geometry);
|
||||||
|
@ -47,6 +47,7 @@ import java.util.Set;
|
|||||||
public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
||||||
BoxComponent selectionBox;
|
BoxComponent selectionBox;
|
||||||
BoxComponent collisionBox;
|
BoxComponent collisionBox;
|
||||||
|
BoxComponent extendedCollisionBox;
|
||||||
String displayName;
|
String displayName;
|
||||||
String geometry;
|
String geometry;
|
||||||
Map<String, MaterialInstance> materialInstances;
|
Map<String, MaterialInstance> materialInstances;
|
||||||
@ -63,6 +64,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
|||||||
private GeyserCustomBlockComponents(CustomBlockComponentsBuilder builder) {
|
private GeyserCustomBlockComponents(CustomBlockComponentsBuilder builder) {
|
||||||
this.selectionBox = builder.selectionBox;
|
this.selectionBox = builder.selectionBox;
|
||||||
this.collisionBox = builder.collisionBox;
|
this.collisionBox = builder.collisionBox;
|
||||||
|
this.extendedCollisionBox = builder.extendedCollisionBox;
|
||||||
this.displayName = builder.displayName;
|
this.displayName = builder.displayName;
|
||||||
this.geometry = builder.geometry;
|
this.geometry = builder.geometry;
|
||||||
if (builder.materialInstances.isEmpty()) {
|
if (builder.materialInstances.isEmpty()) {
|
||||||
@ -95,6 +97,11 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
|||||||
return collisionBox;
|
return collisionBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BoxComponent extendedCollisionBox() {
|
||||||
|
return extendedCollisionBox;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String displayName() {
|
public String displayName() {
|
||||||
return displayName;
|
return displayName;
|
||||||
@ -158,6 +165,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
|||||||
public static class CustomBlockComponentsBuilder implements Builder {
|
public static class CustomBlockComponentsBuilder implements Builder {
|
||||||
protected BoxComponent selectionBox;
|
protected BoxComponent selectionBox;
|
||||||
protected BoxComponent collisionBox;
|
protected BoxComponent collisionBox;
|
||||||
|
protected BoxComponent extendedCollisionBox;
|
||||||
protected String displayName;
|
protected String displayName;
|
||||||
protected String geometry;
|
protected String geometry;
|
||||||
protected final Object2ObjectMap<String, MaterialInstance> materialInstances = new Object2ObjectOpenHashMap<>();
|
protected final Object2ObjectMap<String, MaterialInstance> materialInstances = new Object2ObjectOpenHashMap<>();
|
||||||
@ -203,6 +211,13 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Builder extendedCollisionBox(BoxComponent extendedCollisionBox) {
|
||||||
|
validateBox(extendedCollisionBox);
|
||||||
|
this.extendedCollisionBox = extendedCollisionBox;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Builder displayName(String displayName) {
|
public Builder displayName(String displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
|
@ -33,6 +33,7 @@ import it.unimi.dsi.fastutil.ints.IntSet;
|
|||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
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.component.BoxComponent;
|
||||||
import org.geysermc.geyser.registry.loader.CollisionRegistryLoader;
|
import org.geysermc.geyser.registry.loader.CollisionRegistryLoader;
|
||||||
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
||||||
import org.geysermc.geyser.registry.populator.BlockRegistryPopulator;
|
import org.geysermc.geyser.registry.populator.BlockRegistryPopulator;
|
||||||
@ -111,6 +112,11 @@ public class BlockRegistries {
|
|||||||
*/
|
*/
|
||||||
public static final SimpleMappedRegistry<String, CustomBlockData> CUSTOM_BLOCK_ITEM_OVERRIDES = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
public static final SimpleMappedRegistry<String, CustomBlockData> CUSTOM_BLOCK_ITEM_OVERRIDES = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A registry which stores Java Ids and the extended collision box that should be placed above.
|
||||||
|
*/
|
||||||
|
public static final SimpleMappedRegistry<Integer, BoxComponent> CUSTOM_BLOCK_EXTENDED_COLLISION_BOXES = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A registry which stores skin texture hashes to custom skull blocks.
|
* A registry which stores skin texture hashes to custom skull blocks.
|
||||||
*/
|
*/
|
||||||
|
@ -294,10 +294,12 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
private CustomBlockComponents createCustomBlockComponents(JsonNode node, String stateKey, String name) {
|
private CustomBlockComponents createCustomBlockComponents(JsonNode node, String stateKey, String name) {
|
||||||
// This is needed to find the correct selection box for the given block
|
// This is needed to find the correct selection box for the given block
|
||||||
int id = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(stateKey, -1);
|
int id = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(stateKey, -1);
|
||||||
BoxComponent boxComponent = createBoxComponent(id);
|
BoxComponent boxComponent = createBoxComponent(id, 0, 16, 0);
|
||||||
|
BoxComponent extendedboxComponent = createBoxComponent(id, 16, 32, -16);
|
||||||
CustomBlockComponents.Builder builder = new CustomBlockComponentsBuilder()
|
CustomBlockComponents.Builder builder = new CustomBlockComponentsBuilder()
|
||||||
.collisionBox(boxComponent)
|
.collisionBox(boxComponent)
|
||||||
.selectionBox(boxComponent);
|
.selectionBox(boxComponent)
|
||||||
|
.extendedCollisionBox(extendedboxComponent);
|
||||||
|
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
// No other components were defined
|
// No other components were defined
|
||||||
@ -312,6 +314,11 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
if (collisionBox != null) {
|
if (collisionBox != null) {
|
||||||
builder.collisionBox(collisionBox);
|
builder.collisionBox(collisionBox);
|
||||||
}
|
}
|
||||||
|
BoxComponent extendedCollisionBox = createBoxComponent(node.get("extended_collision_box"));
|
||||||
|
if (extendedCollisionBox != null) {
|
||||||
|
builder.extendedCollisionBox(extendedCollisionBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// We set this to max value by default so that we may dictate the correct destroy time ourselves
|
// We set this to max value by default so that we may dictate the correct destroy time ourselves
|
||||||
float destructibleByMining = Float.MAX_VALUE;
|
float destructibleByMining = Float.MAX_VALUE;
|
||||||
@ -404,9 +411,12 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
/**
|
/**
|
||||||
* Creates a {@link BoxComponent} based on a Java block's collision
|
* Creates a {@link BoxComponent} based on a Java block's collision
|
||||||
* @param javaId the block's Java ID
|
* @param javaId the block's Java ID
|
||||||
|
* @param minHeight the minimum height of the box
|
||||||
|
* @param maxHeight the maximum height of the box
|
||||||
|
* @param heightTranslation the height translation of the box
|
||||||
* @return the {@link BoxComponent}
|
* @return the {@link BoxComponent}
|
||||||
*/
|
*/
|
||||||
private BoxComponent createBoxComponent(int javaId) {
|
private BoxComponent createBoxComponent(int javaId, float minHeight, float maxHeight, float heightTranslation) {
|
||||||
// Some blocks (e.g. plants) have no collision box
|
// Some blocks (e.g. plants) have no collision box
|
||||||
BlockCollision blockCollision = BlockUtils.getCollision(javaId);
|
BlockCollision blockCollision = BlockUtils.getCollision(javaId);
|
||||||
if (blockCollision == null) {
|
if (blockCollision == null) {
|
||||||
@ -425,11 +435,11 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||||||
// These could be placed above the block when a custom block exceeds this limit
|
// These could be placed above the block when a custom block exceeds this limit
|
||||||
// I am hopeful this will be extended slightly since the geometry of blocks can be 1.875^3
|
// I am hopeful this will be extended slightly since the geometry of blocks can be 1.875^3
|
||||||
float cornerX = MathUtils.clamp((float) boundingBox.getMiddleX() * 16 - 8 - offsetX, -8, 8);
|
float cornerX = MathUtils.clamp((float) boundingBox.getMiddleX() * 16 - 8 - offsetX, -8, 8);
|
||||||
float cornerY = MathUtils.clamp((float) boundingBox.getMiddleY() * 16 - offsetY, 0, 16);
|
float cornerY = MathUtils.clamp((float) boundingBox.getMiddleY() * 16 - offsetY + heightTranslation, minHeight, maxHeight);
|
||||||
float cornerZ = MathUtils.clamp((float) boundingBox.getMiddleZ() * 16 - 8 - offsetZ, -8, 8);
|
float cornerZ = MathUtils.clamp((float) boundingBox.getMiddleZ() * 16 - 8 - offsetZ, -8, 8);
|
||||||
|
|
||||||
float sizeX = MathUtils.clamp((float) boundingBox.getSizeX() * 16, 0, 16);
|
float sizeX = MathUtils.clamp((float) boundingBox.getSizeX() * 16, 0, 16);
|
||||||
float sizeY = MathUtils.clamp((float) boundingBox.getSizeY() * 16, 0, 16);
|
float sizeY = MathUtils.clamp((float) boundingBox.getSizeY() * 16 + heightTranslation, minHeight, maxHeight);
|
||||||
float sizeZ = MathUtils.clamp((float) boundingBox.getSizeZ() * 16, 0, 16);
|
float sizeZ = MathUtils.clamp((float) boundingBox.getSizeZ() * 16, 0, 16);
|
||||||
|
|
||||||
return new BoxComponent(cornerX, cornerY, cornerZ, sizeX, sizeY, sizeZ);
|
return new BoxComponent(cornerX, cornerY, cornerZ, sizeX, sizeY, sizeZ);
|
||||||
|
@ -44,6 +44,8 @@ public class CustomBlockRegistryPopulator {
|
|||||||
Set<CustomBlockData> customBlocks = new ObjectOpenHashSet<>();
|
Set<CustomBlockData> customBlocks = new ObjectOpenHashSet<>();
|
||||||
Int2ObjectMap<CustomBlockState> blockStateOverrides = new Int2ObjectOpenHashMap<>();
|
Int2ObjectMap<CustomBlockState> blockStateOverrides = new Int2ObjectOpenHashMap<>();
|
||||||
Map<String, CustomBlockData> customBlockItemOverrides = new HashMap<>();
|
Map<String, CustomBlockData> customBlockItemOverrides = new HashMap<>();
|
||||||
|
Map<Integer, BoxComponent> extendedCollisionBoxes = new HashMap<>();
|
||||||
|
|
||||||
GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() {
|
GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() {
|
||||||
@Override
|
@Override
|
||||||
public void registerCustomBlock(@NonNull CustomBlockData customBlockData) {
|
public void registerCustomBlock(@NonNull CustomBlockData customBlockData) {
|
||||||
@ -69,6 +71,10 @@ public class CustomBlockRegistryPopulator {
|
|||||||
throw new IllegalArgumentException("Custom block is unregistered. Name: " + customBlockState.name());
|
throw new IllegalArgumentException("Custom block is unregistered. Name: " + customBlockState.name());
|
||||||
}
|
}
|
||||||
CustomBlockState oldBlockState = blockStateOverrides.put(id, customBlockState);
|
CustomBlockState oldBlockState = blockStateOverrides.put(id, customBlockState);
|
||||||
|
BoxComponent extendedCollisionBox = customBlockState.block().components().extendedCollisionBox();
|
||||||
|
if (extendedCollisionBox != null) {
|
||||||
|
extendedCollisionBoxes.put(id, extendedCollisionBox);
|
||||||
|
}
|
||||||
if (oldBlockState != null) {
|
if (oldBlockState != null) {
|
||||||
GeyserImpl.getInstance().getLogger().debug("Duplicate block state override for Java Identifier: " +
|
GeyserImpl.getInstance().getLogger().debug("Duplicate block state override for Java Identifier: " +
|
||||||
javaIdentifier + " Old override: " + oldBlockState.name() + " New override: " + customBlockState.name());
|
javaIdentifier + " Old override: " + oldBlockState.name() + " New override: " + customBlockState.name());
|
||||||
@ -97,6 +103,10 @@ public class CustomBlockRegistryPopulator {
|
|||||||
block.states().forEach((javaIdentifier, customBlockState) -> {
|
block.states().forEach((javaIdentifier, customBlockState) -> {
|
||||||
int id = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(javaIdentifier, -1);
|
int id = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(javaIdentifier, -1);
|
||||||
blockStateOverrides.put(id, customBlockState);
|
blockStateOverrides.put(id, customBlockState);
|
||||||
|
BoxComponent extendedCollisionBox = customBlockState.block().components().extendedCollisionBox();
|
||||||
|
if (extendedCollisionBox != null) {
|
||||||
|
extendedCollisionBoxes.put(id, extendedCollisionBox);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -108,6 +118,9 @@ public class CustomBlockRegistryPopulator {
|
|||||||
|
|
||||||
BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.set(customBlockItemOverrides);
|
BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.set(customBlockItemOverrides);
|
||||||
GeyserImpl.getInstance().getLogger().info("Registered " + customBlockItemOverrides.size() + " custom block item overrides.");
|
GeyserImpl.getInstance().getLogger().info("Registered " + customBlockItemOverrides.size() + " custom block item overrides.");
|
||||||
|
|
||||||
|
BlockRegistries.CUSTOM_BLOCK_EXTENDED_COLLISION_BOXES.set(extendedCollisionBoxes);
|
||||||
|
GeyserImpl.getInstance().getLogger().info("Registered " + extendedCollisionBoxes.size() + " custom block extended collision boxes.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren