3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-19 22:40:18 +01:00

Address @davchoo's review

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
Dieser Commit ist enthalten in:
Joshua Castle 2023-01-29 13:44:05 -08:00
Ursprung d71d9c142b
Commit 57c90da15b
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: F674F38216C35D5D
9 geänderte Dateien mit 91 neuen und 96 gelöschten Zeilen

Datei anzeigen

@ -26,8 +26,8 @@
package org.geysermc.geyser.api.block.custom.component; package org.geysermc.geyser.api.block.custom.component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.api.block.custom.component.placementfilter.PlacementFilter;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -78,11 +78,11 @@ public interface CustomBlockComponents {
/** /**
* Gets the placement filter component * Gets the placement filter component
* Equivalent to "minecraft:material_instances" * Equivalent to "minecraft:placement_filter"
* *
* @return The placement filter. * @return The placement filter.
*/ */
PlacementFilter placementFilter(); List<PlacementConditions> placementFilter();
/** /**
* Gets the destructible by mining component * Gets the destructible by mining component
@ -159,7 +159,7 @@ public interface CustomBlockComponents {
Builder materialInstance(@NonNull String name, @NonNull MaterialInstance materialInstance); Builder materialInstance(@NonNull String name, @NonNull MaterialInstance materialInstance);
Builder placementFilter(PlacementFilter placementFilter); Builder placementFilter(List<PlacementConditions> placementConditions);
Builder destructibleByMining(Float destructibleByMining); Builder destructibleByMining(Float destructibleByMining);

Datei anzeigen

@ -23,7 +23,7 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.api.block.custom.component.placementfilter; package org.geysermc.geyser.api.block.custom.component;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Set; import java.util.Set;
@ -33,7 +33,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
/* /*
* This class is used to store conditions for a placement filter for a custom block. * This class is used to store conditions for a placement filter for a custom block.
*/ */
public record Conditions(@NonNull Set<Face> allowedFaces, @NonNull LinkedHashMap<String, BlockFilterType> blockFilters) { public record PlacementConditions(@NonNull Set<Face> allowedFaces, @NonNull LinkedHashMap<String, BlockFilterType> blockFilters) {
public enum Face { public enum Face {
DOWN(1), DOWN(1),
UP(2), UP(2),
@ -42,14 +42,8 @@ public record Conditions(@NonNull Set<Face> allowedFaces, @NonNull LinkedHashMap
WEST(16), WEST(16),
EAST(32); EAST(32);
private final byte value;
Face(int value) { Face(int value) {
this.value = (byte) value; value = (byte) value;
}
public byte getValue() {
return value;
} }
} }
public enum BlockFilterType { public enum BlockFilterType {

Datei anzeigen

@ -1,36 +0,0 @@
/*
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.api.block.custom.component.placementfilter;
import java.util.List;
import org.checkerframework.checker.nullness.qual.NonNull;
/*
* This class is used to store a placement filter for a custom block.
*/
public record PlacementFilter(@NonNull List<Conditions> conditions) {
}

Datei anzeigen

@ -35,7 +35,7 @@ public class PropertyType {
private final Class<?> typeClass; private final Class<?> typeClass;
public Class<?> getTypeClass() { public Class<?> typeClass() {
return typeClass; return typeClass;
} }

Datei anzeigen

@ -1,6 +1,6 @@
package org.geysermc.geyser.api.event.lifecycle; package org.geysermc.geyser.api.event.lifecycle;
import lombok.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.event.Event; import org.geysermc.event.Event;
/** /**

Datei anzeigen

@ -43,7 +43,7 @@ public final class Constants {
public static final String GEYSER_NAMESPACE = "geyser_custom"; public static final String GEYSER_NAMESPACE = "geyser_custom";
public static final String MINECRAFT_SKIN_SERVER_URL = "http://textures.minecraft.net/texture/"; public static final String MINECRAFT_SKIN_SERVER_URL = "https://textures.minecraft.net/texture/";
static { static {
URI wsUri = null; URI wsUri = null;

Datei anzeigen

@ -34,11 +34,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.api.block.custom.component.BoxComponent; import org.geysermc.geyser.api.block.custom.component.BoxComponent;
import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents;
import org.geysermc.geyser.api.block.custom.component.MaterialInstance; import org.geysermc.geyser.api.block.custom.component.MaterialInstance;
import org.geysermc.geyser.api.block.custom.component.PlacementConditions;
import org.geysermc.geyser.api.block.custom.component.RotationComponent; import org.geysermc.geyser.api.block.custom.component.RotationComponent;
import org.geysermc.geyser.api.block.custom.component.placementfilter.PlacementFilter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -49,7 +50,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
String displayName; String displayName;
String geometry; String geometry;
Map<String, MaterialInstance> materialInstances; Map<String, MaterialInstance> materialInstances;
PlacementFilter placementFilter; List<PlacementConditions> placementFilter;
Float destructibleByMining; Float destructibleByMining;
Float friction; Float friction;
Integer lightEmission; Integer lightEmission;
@ -110,7 +111,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
} }
@Override @Override
public PlacementFilter placementFilter() { public List<PlacementConditions> placementFilter() {
return placementFilter; return placementFilter;
} }
@ -160,7 +161,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
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<>();
protected PlacementFilter placementFilter; protected List<PlacementConditions> placementFilter;
protected Float destructibleByMining; protected Float destructibleByMining;
protected Float friction; protected Float friction;
protected Integer lightEmission; protected Integer lightEmission;
@ -221,7 +222,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
} }
@Override @Override
public Builder placementFilter(PlacementFilter placementFilter) { public Builder placementFilter(List<PlacementConditions> placementFilter) {
this.placementFilter = placementFilter; this.placementFilter = placementFilter;
return this; return this;
} }

Datei anzeigen

@ -35,13 +35,12 @@ import org.geysermc.geyser.api.block.custom.CustomBlockData;
import org.geysermc.geyser.api.block.custom.CustomBlockPermutation; import org.geysermc.geyser.api.block.custom.CustomBlockPermutation;
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.api.block.custom.component.BoxComponent;
import org.geysermc.geyser.api.block.custom.component.PlacementConditions;
import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents;
import org.geysermc.geyser.api.block.custom.component.MaterialInstance; import org.geysermc.geyser.api.block.custom.component.MaterialInstance;
import org.geysermc.geyser.api.block.custom.component.RotationComponent; import org.geysermc.geyser.api.block.custom.component.RotationComponent;
import org.geysermc.geyser.api.block.custom.component.placementfilter.Conditions; import org.geysermc.geyser.api.block.custom.component.PlacementConditions.BlockFilterType;
import org.geysermc.geyser.api.block.custom.component.placementfilter.PlacementFilter; import org.geysermc.geyser.api.block.custom.component.PlacementConditions.Face;
import org.geysermc.geyser.api.block.custom.component.placementfilter.Conditions.BlockFilterType;
import org.geysermc.geyser.api.block.custom.component.placementfilter.Conditions.Face;
import org.geysermc.geyser.api.item.custom.CustomItemData; import org.geysermc.geyser.api.item.custom.CustomItemData;
import org.geysermc.geyser.api.item.custom.CustomItemOptions; import org.geysermc.geyser.api.item.custom.CustomItemOptions;
import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException; import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException;
@ -53,7 +52,9 @@ import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.mappings.util.BlockPropertyTypeMaps; import org.geysermc.geyser.registry.mappings.util.BlockPropertyTypeMaps;
import org.geysermc.geyser.registry.mappings.util.CustomBlockMapping; import org.geysermc.geyser.registry.mappings.util.CustomBlockMapping;
import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.BlockMapping;
import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.BlockUtils;
import org.geysermc.geyser.util.MathUtils;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
@ -419,10 +420,50 @@ 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);
CustomBlockComponentsBuilder builder = new CustomBlockComponentsBuilder(); CustomBlockComponentsBuilder builder = new CustomBlockComponentsBuilder();
BoxComponent boxComponent = createBoxComponent(id); BoxComponent boxComponent = createBoxComponent(id);
builder.selectionBox(boxComponent).collisionBox(boxComponent);
BoxComponent selectionBox = boxComponent;
if (node.has("selection_box")) {
JsonNode selectionBoxNode = node.get("selection_box");
if (selectionBoxNode.isObject()) {
if (selectionBoxNode.has("origin") && selectionBoxNode.has("size")) {
JsonNode origin = selectionBoxNode.get("origin");
int originX = origin.get(0).intValue();
int originY = origin.get(1).intValue();
int originZ = origin.get(2).intValue();
JsonNode size = selectionBoxNode.get("size");
int sizeX = size.get(0).intValue();
int sizeY = size.get(1).intValue();
int sizeZ = size.get(2).intValue();
selectionBox = new BoxComponent(originX, originY, originZ, sizeX, sizeY, sizeZ);
}
}
}
builder.selectionBox(selectionBox);
BoxComponent collisionBox = boxComponent;
if (node.has("collision_box")) {
JsonNode collisionBoxNode = node.get("collision_box");
if (collisionBoxNode.isObject()) {
if (collisionBoxNode.has("origin") && collisionBoxNode.has("size")) {
JsonNode origin = collisionBoxNode.get("origin");
int originX = origin.get(0).intValue();
int originY = origin.get(1).intValue();
int originZ = origin.get(2).intValue();
JsonNode size = collisionBoxNode.get("size");
int sizeX = size.get(0).intValue();
int sizeY = size.get(1).intValue();
int sizeZ = size.get(2).intValue();
collisionBox = new BoxComponent(originX, originY, originZ, sizeX, sizeY, sizeZ);
}
}
}
builder.collisionBox(collisionBox);
// Ideally we would just be able to calculate the right value for this, but it seems that hardness value on bedrock does not follow Java // Ideally we would just be able to calculate the right value for this, but it seems that hardness value on bedrock does not follow Java
// As such this might as well just be configured for now if people so choose // As such this might as well just be configured for now if people so choose
@ -492,7 +533,7 @@ public class MappingsReader_v1 extends MappingsReader {
if (placementFilter.has("conditions")) { if (placementFilter.has("conditions")) {
JsonNode conditions = placementFilter.get("conditions"); JsonNode conditions = placementFilter.get("conditions");
if (conditions.isArray()) { if (conditions.isArray()) {
PlacementFilter filter = createPlacementFilterComponent(conditions); List<PlacementConditions> filter = createPlacementFilterComponent(conditions);
builder.placementFilter(filter); builder.placementFilter(filter);
} }
} }
@ -525,7 +566,13 @@ public class MappingsReader_v1 extends MappingsReader {
* @return the {@link BoxComponent} * @return the {@link BoxComponent}
*/ */
private BoxComponent createBoxComponent(int id) { private BoxComponent createBoxComponent(int id) {
BoundingBox boundingBox = BlockUtils.getCollision(id).getBoundingBoxes()[0]; // Some blocks (e.g. plants) have no collision box
BlockCollision blockCollision = BlockUtils.getCollision(id);
if (blockCollision == null) {
return new BoxComponent(0, 0, 0, 0, 0, 0);
}
BoundingBox boundingBox = blockCollision.getBoundingBoxes()[0];
float offsetX = (float) boundingBox.getSizeX() * 8; float offsetX = (float) boundingBox.getSizeX() * 8;
float offsetY = (float) boundingBox.getSizeY() * 8; float offsetY = (float) boundingBox.getSizeY() * 8;
@ -536,13 +583,13 @@ public class MappingsReader_v1 extends MappingsReader {
// One possible solution would be to create invisible blocks that we use only for collision box // One possible solution would be to create invisible blocks that we use only for collision box
// 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 = clamp((float) boundingBox.getMiddleX() * 16 - 8 - offsetX, -8, 8); float cornerX = MathUtils.clamp((float) boundingBox.getMiddleX() * 16 - 8 - offsetX, -8, 8);
float cornerY = clamp((float) boundingBox.getMiddleY() * 16 - offsetY, 0, 16); float cornerY = MathUtils.clamp((float) boundingBox.getMiddleY() * 16 - offsetY, 0, 16);
float cornerZ = clamp((float) boundingBox.getMiddleZ() * 16 - 8 - offsetZ, -8, 8); float cornerZ = MathUtils.clamp((float) boundingBox.getMiddleZ() * 16 - 8 - offsetZ, -8, 8);
float sizeX = clamp((float) boundingBox.getSizeX() * 16, 0, 16); float sizeX = MathUtils.clamp((float) boundingBox.getSizeX() * 16, 0, 16);
float sizeY = clamp((float) boundingBox.getSizeY() * 16, 0, 16); float sizeY = MathUtils.clamp((float) boundingBox.getSizeY() * 16, 0, 16);
float sizeZ = clamp((float) boundingBox.getSizeZ() * 16, 0, 16); float sizeZ = MathUtils.clamp((float) boundingBox.getSizeZ() * 16, 0, 16);
BoxComponent boxComponent = new BoxComponent(cornerX, cornerY, cornerZ, sizeX, sizeY, sizeZ); BoxComponent boxComponent = new BoxComponent(cornerX, cornerY, cornerZ, sizeX, sizeY, sizeZ);
@ -563,17 +610,17 @@ public class MappingsReader_v1 extends MappingsReader {
texture = node.get("texture").asText(); texture = node.get("texture").asText();
} }
String renderMethod = "alpha_test"; String renderMethod = "opaque";
if (node.has("render_method")) { if (node.has("render_method")) {
renderMethod = node.get("render_method").asText(); renderMethod = node.get("render_method").asText();
} }
boolean faceDimming = false; boolean faceDimming = true;
if (node.has("face_dimming")) { if (node.has("face_dimming")) {
faceDimming = node.get("face_dimming").asBoolean(); faceDimming = node.get("face_dimming").asBoolean();
} }
boolean ambientOcclusion = false; boolean ambientOcclusion = true;
if (node.has("ambient_occlusion")) { if (node.has("ambient_occlusion")) {
ambientOcclusion = node.get("ambient_occlusion").asBoolean(); ambientOcclusion = node.get("ambient_occlusion").asBoolean();
} }
@ -582,12 +629,12 @@ public class MappingsReader_v1 extends MappingsReader {
} }
/** /**
* Creates the {@link PlacementFilter} for the passed conditions node * Creates the list of {@link PlacementConditions} for the passed conditions node
* @param node the conditions node * @param node the conditions node
* @return the {@link PlacementFilter} * @return the list of {@link PlacementConditions}
*/ */
private PlacementFilter createPlacementFilterComponent(JsonNode node) { private List<PlacementConditions> createPlacementFilterComponent(JsonNode node) {
List<Conditions> conditions = new ArrayList<>(); List<PlacementConditions> conditions = new ArrayList<>();
// The structure of the placement filter component is the most complex of the current components // The structure of the placement filter component is the most complex of the current components
// Each condition effectively seperated into an two arrays: one of allowed faces, and one of blocks/block molang queries // Each condition effectively seperated into an two arrays: one of allowed faces, and one of blocks/block molang queries
@ -619,10 +666,10 @@ public class MappingsReader_v1 extends MappingsReader {
} }
} }
conditions.add(new Conditions(faces, blockFilters)); conditions.add(new PlacementConditions(faces, blockFilters));
}); });
return new PlacementFilter(conditions); return conditions;
} }
/** /**
@ -672,15 +719,4 @@ public class MappingsReader_v1 extends MappingsReader {
return pairs; return pairs;
} }
/**
* Clamps the given value between the given min and max
* @param value the value to clamp
* @param min the minimum value
* @param max the maximum value
* @return the clamped value
*/
private float clamp(float value, float min, float max) {
return Math.max(min, Math.min(max, value));
}
} }

Datei anzeigen

@ -15,8 +15,8 @@ import org.geysermc.geyser.api.block.custom.CustomBlockState;
import org.geysermc.geyser.api.block.custom.component.BoxComponent; import org.geysermc.geyser.api.block.custom.component.BoxComponent;
import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents;
import org.geysermc.geyser.api.block.custom.component.MaterialInstance; import org.geysermc.geyser.api.block.custom.component.MaterialInstance;
import org.geysermc.geyser.api.block.custom.component.placementfilter.Conditions.Face; import org.geysermc.geyser.api.block.custom.component.PlacementConditions;
import org.geysermc.geyser.api.block.custom.component.placementfilter.PlacementFilter; import org.geysermc.geyser.api.block.custom.component.PlacementConditions.Face;
import org.geysermc.geyser.api.block.custom.property.CustomBlockProperty; import org.geysermc.geyser.api.block.custom.property.CustomBlockProperty;
import org.geysermc.geyser.api.block.custom.property.PropertyType; import org.geysermc.geyser.api.block.custom.property.PropertyType;
import org.geysermc.geyser.api.event.lifecycle.GeyserDefineCustomBlocksEvent; import org.geysermc.geyser.api.event.lifecycle.GeyserDefineCustomBlocksEvent;
@ -304,15 +304,15 @@ public class CustomBlockRegistryPopulator {
* @param placementFilter the placement filter to convert * @param placementFilter the placement filter to convert
* @return the NBT representation of the provided placement filter * @return the NBT representation of the provided placement filter
*/ */
private static List<NbtMap> convertPlacementFilter(PlacementFilter placementFilter) { private static List<NbtMap> convertPlacementFilter(List<PlacementConditions> placementFilter) {
List<NbtMap> conditions = new ArrayList<>(); List<NbtMap> conditions = new ArrayList<>();
placementFilter.conditions().forEach((condition) -> { placementFilter.forEach((condition) -> {
NbtMapBuilder conditionBuilder = NbtMap.builder(); NbtMapBuilder conditionBuilder = NbtMap.builder();
// allowed_faces on the network is represented by 6 bits for the 6 possible faces // allowed_faces on the network is represented by 6 bits for the 6 possible faces
// the enum has the proper values for that face only, so we just bitwise OR them together // the enum has the proper values for that face only, so we just bitwise OR them together
byte allowedFaces = 0; byte allowedFaces = 0;
for (Face face : condition.allowedFaces()) { allowedFaces |= face.getValue(); } for (Face face : condition.allowedFaces()) { allowedFaces |= (1 << face.ordinal()); }
conditionBuilder.putByte("allowed_faces", allowedFaces); conditionBuilder.putByte("allowed_faces", allowedFaces);
// block_filters is a list of either blocks or queries for block tags // block_filters is a list of either blocks or queries for block tags