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:
Ursprung
d71d9c142b
Commit
57c90da15b
@ -26,8 +26,8 @@
|
||||
package org.geysermc.geyser.api.block.custom.component;
|
||||
|
||||
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.Set;
|
||||
|
||||
@ -78,11 +78,11 @@ public interface CustomBlockComponents {
|
||||
|
||||
/**
|
||||
* Gets the placement filter component
|
||||
* Equivalent to "minecraft:material_instances"
|
||||
* Equivalent to "minecraft:placement_filter"
|
||||
*
|
||||
* @return The placement filter.
|
||||
*/
|
||||
PlacementFilter placementFilter();
|
||||
List<PlacementConditions> placementFilter();
|
||||
|
||||
/**
|
||||
* Gets the destructible by mining component
|
||||
@ -159,7 +159,7 @@ public interface CustomBlockComponents {
|
||||
|
||||
Builder materialInstance(@NonNull String name, @NonNull MaterialInstance materialInstance);
|
||||
|
||||
Builder placementFilter(PlacementFilter placementFilter);
|
||||
Builder placementFilter(List<PlacementConditions> placementConditions);
|
||||
|
||||
Builder destructibleByMining(Float destructibleByMining);
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
* @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.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.
|
||||
*/
|
||||
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 {
|
||||
DOWN(1),
|
||||
UP(2),
|
||||
@ -42,14 +42,8 @@ public record Conditions(@NonNull Set<Face> allowedFaces, @NonNull LinkedHashMap
|
||||
WEST(16),
|
||||
EAST(32);
|
||||
|
||||
private final byte value;
|
||||
|
||||
Face(int value) {
|
||||
this.value = (byte) value;
|
||||
}
|
||||
|
||||
public byte getValue() {
|
||||
return value;
|
||||
value = (byte) value;
|
||||
}
|
||||
}
|
||||
public enum BlockFilterType {
|
@ -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) {
|
||||
}
|
@ -35,7 +35,7 @@ public class PropertyType {
|
||||
|
||||
private final Class<?> typeClass;
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
public Class<?> typeClass() {
|
||||
return typeClass;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.geysermc.geyser.api.event.lifecycle;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.event.Event;
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,7 @@ public final class Constants {
|
||||
|
||||
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 {
|
||||
URI wsUri = null;
|
||||
|
@ -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.CustomBlockComponents;
|
||||
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.placementfilter.PlacementFilter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@ -49,7 +50,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
||||
String displayName;
|
||||
String geometry;
|
||||
Map<String, MaterialInstance> materialInstances;
|
||||
PlacementFilter placementFilter;
|
||||
List<PlacementConditions> placementFilter;
|
||||
Float destructibleByMining;
|
||||
Float friction;
|
||||
Integer lightEmission;
|
||||
@ -110,7 +111,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementFilter placementFilter() {
|
||||
public List<PlacementConditions> placementFilter() {
|
||||
return placementFilter;
|
||||
}
|
||||
|
||||
@ -160,7 +161,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
||||
protected String displayName;
|
||||
protected String geometry;
|
||||
protected final Object2ObjectMap<String, MaterialInstance> materialInstances = new Object2ObjectOpenHashMap<>();
|
||||
protected PlacementFilter placementFilter;
|
||||
protected List<PlacementConditions> placementFilter;
|
||||
protected Float destructibleByMining;
|
||||
protected Float friction;
|
||||
protected Integer lightEmission;
|
||||
@ -221,7 +222,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder placementFilter(PlacementFilter placementFilter) {
|
||||
public Builder placementFilter(List<PlacementConditions> placementFilter) {
|
||||
this.placementFilter = placementFilter;
|
||||
return this;
|
||||
}
|
||||
|
@ -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.CustomBlockState;
|
||||
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.MaterialInstance;
|
||||
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.placementfilter.PlacementFilter;
|
||||
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.block.custom.component.PlacementConditions.BlockFilterType;
|
||||
import org.geysermc.geyser.api.block.custom.component.PlacementConditions.Face;
|
||||
import org.geysermc.geyser.api.item.custom.CustomItemData;
|
||||
import org.geysermc.geyser.api.item.custom.CustomItemOptions;
|
||||
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.CustomBlockMapping;
|
||||
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.MathUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@ -419,10 +420,50 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
private CustomBlockComponents createCustomBlockComponents(JsonNode node, String stateKey, String name) {
|
||||
// This is needed to find the correct selection box for the given block
|
||||
int id = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(stateKey, -1);
|
||||
|
||||
CustomBlockComponentsBuilder builder = new CustomBlockComponentsBuilder();
|
||||
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
|
||||
// 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")) {
|
||||
JsonNode conditions = placementFilter.get("conditions");
|
||||
if (conditions.isArray()) {
|
||||
PlacementFilter filter = createPlacementFilterComponent(conditions);
|
||||
List<PlacementConditions> filter = createPlacementFilterComponent(conditions);
|
||||
builder.placementFilter(filter);
|
||||
}
|
||||
}
|
||||
@ -525,7 +566,13 @@ public class MappingsReader_v1 extends MappingsReader {
|
||||
* @return the {@link BoxComponent}
|
||||
*/
|
||||
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 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
|
||||
// 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
|
||||
float cornerX = clamp((float) boundingBox.getMiddleX() * 16 - 8 - offsetX, -8, 8);
|
||||
float cornerY = clamp((float) boundingBox.getMiddleY() * 16 - offsetY, 0, 16);
|
||||
float cornerZ = clamp((float) boundingBox.getMiddleZ() * 16 - 8 - offsetZ, -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 cornerZ = MathUtils.clamp((float) boundingBox.getMiddleZ() * 16 - 8 - offsetZ, -8, 8);
|
||||
|
||||
float sizeX = clamp((float) boundingBox.getSizeX() * 16, 0, 16);
|
||||
float sizeY = clamp((float) boundingBox.getSizeY() * 16, 0, 16);
|
||||
float sizeZ = clamp((float) boundingBox.getSizeZ() * 16, 0, 16);
|
||||
float sizeX = MathUtils.clamp((float) boundingBox.getSizeX() * 16, 0, 16);
|
||||
float sizeY = MathUtils.clamp((float) boundingBox.getSizeY() * 16, 0, 16);
|
||||
float sizeZ = MathUtils.clamp((float) boundingBox.getSizeZ() * 16, 0, 16);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
String renderMethod = "alpha_test";
|
||||
String renderMethod = "opaque";
|
||||
if (node.has("render_method")) {
|
||||
renderMethod = node.get("render_method").asText();
|
||||
}
|
||||
|
||||
boolean faceDimming = false;
|
||||
boolean faceDimming = true;
|
||||
if (node.has("face_dimming")) {
|
||||
faceDimming = node.get("face_dimming").asBoolean();
|
||||
}
|
||||
|
||||
boolean ambientOcclusion = false;
|
||||
boolean ambientOcclusion = true;
|
||||
if (node.has("ambient_occlusion")) {
|
||||
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
|
||||
* @return the {@link PlacementFilter}
|
||||
* @return the list of {@link PlacementConditions}
|
||||
*/
|
||||
private PlacementFilter createPlacementFilterComponent(JsonNode node) {
|
||||
List<Conditions> conditions = new ArrayList<>();
|
||||
private List<PlacementConditions> createPlacementFilterComponent(JsonNode node) {
|
||||
List<PlacementConditions> conditions = new ArrayList<>();
|
||||
|
||||
// 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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.CustomBlockComponents;
|
||||
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.placementfilter.PlacementFilter;
|
||||
import org.geysermc.geyser.api.block.custom.component.PlacementConditions;
|
||||
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.PropertyType;
|
||||
import org.geysermc.geyser.api.event.lifecycle.GeyserDefineCustomBlocksEvent;
|
||||
@ -304,15 +304,15 @@ public class CustomBlockRegistryPopulator {
|
||||
* @param placementFilter the placement filter to convert
|
||||
* @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<>();
|
||||
placementFilter.conditions().forEach((condition) -> {
|
||||
placementFilter.forEach((condition) -> {
|
||||
NbtMapBuilder conditionBuilder = NbtMap.builder();
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
// block_filters is a list of either blocks or queries for block tags
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren