Improve documentation of (predicate) new API

This commit is contained in:
Eclipse 2024-12-16 16:35:49 +00:00
parent b5cef996fb
commit 66e288f302
No known key found for this signature in database
GPG key ID: 95E6998F82EC938A
6 changed files with 85 additions and 14 deletions

View file

@ -34,7 +34,7 @@ import org.geysermc.geyser.api.util.CreativeCategory;
import java.util.Set;
/**
* This is used to store options for a custom item that can't be described using item components.
* This is used to store options for a custom item defintion that can't be described using item components.
*/
public interface CustomItemBedrockOptions {

View file

@ -34,14 +34,28 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen
import java.util.List;
/**
* This is used to define a custom item and its properties.
* This is used to define a custom item and its properties for a specific Java item and item model definition combination.
*
* <p>A custom item definition will be used for all item stacks that match the Java item and item model this item is for.
* Additionally, predicates can be added that allow fine-grained control as to when to use this custom item. These predicates are similar
* to the predicates available in Java item model definitions.</p>
*
* <p>In Geyser, all registered custom item definitions for a Java item model will be checked in a specific order:
*
* <ol>
* <li>First by checking their priority values, higher priority values going first.</li>
* <li>Then by checking if they both have a similar range dispatch predicate, the one with the highest threshold going first.</li>
* <li>Lastly by the amount of predicates, from most to least.</li>
* </ol>
*
* This ensures predicates will be checked in a correct order, and that in most cases specifying a priority value isn't necessary, and in the few cases
* where Geyser doesn't properly sort definitions, specifying a priority value will.
* </p>
*/
// TODO note that definitions will be sorted by predicates
public interface CustomItemDefinition {
/**
* The Bedrock identifier for this custom item. This can't be in the {@code minecraft} namespace. If the {@code minecraft} namespace is given in the builder, the default
* namespace of the implementation is used. For Geyser, the default namespace is the {@code geyser_custom} namespace.
* The Bedrock identifier for this custom item. This can't be in the {@code minecraft} namespace.
*/
@NonNull Identifier bedrockIdentifier();
@ -51,7 +65,7 @@ public interface CustomItemDefinition {
@NonNull String displayName();
/**
* The item model this definition is for. If the model is in the {@code minecraft} namespace, then the definition is required to have a predicate.
* The item model this definition is for. If the model is in the {@code minecraft} namespace, then the definition must have at least one predicate.
*
* <p>If multiple item definitions for a model are registered, then only one can have no predicate.</p>
*/
@ -61,7 +75,10 @@ public interface CustomItemDefinition {
* The icon used for this item.
*
* <p>If none is set in the item's Bedrock options, then the item's Bedrock identifier is used,
* the namespace separator replaced with {@code .} and the path separators ({@code /}) replaced with {@code _}.</p>
* the namespace separator ({@code :}) replaced with {@code .} and the path separators ({@code /}) replaced with {@code _}. For example:</p>
*
* <p>{@code my_datapack:my_custom_item} => {@code my_datapack.my_custom_item}</p>
* <p>{@code my_datapack:cool_items/cool_item_1} => {@code my_datapack.cool_items_cool_item_1}</p>
*/
default @NonNull String icon() {
return bedrockOptions().icon() == null ? bedrockIdentifier().toString().replaceAll(":", ".").replaceAll("/", "_") : bedrockOptions().icon();
@ -69,9 +86,6 @@ public interface CustomItemDefinition {
/**
* The predicates that have to match for this item to be used. These predicates are similar to the Java item model predicates.
*
* <p>If all predicates match for multiple definitions, then the first registered item with all matching predicates is used. If no predicates match, then the item definition without any predicates
* is used, if any.</p>
*/
@NonNull List<CustomItemPredicate> predicates();
@ -118,7 +132,7 @@ public interface CustomItemDefinition {
Builder priority(int priority);
// TODO do we want another format for this?
// TODO do we want a component(Type, Value) method instead?
Builder components(@NonNull DataComponents components);
CustomItemDefinition build();

View file

@ -25,6 +25,13 @@
package org.geysermc.geyser.api.item.custom.v2.predicate;
/**
* A predicate that checks for a certain boolean property of the item stack and returns true if it matches the expected value.
*
* @param property the property to check.
* @param expected whether the property should be true or false. Defaults to true.
* @param index only used for the {@code CUSTOM_MODEL_DATA} property, determines which flag of the item's custom model data to check. Defaults to 0.
*/
public record ConditionPredicate(ConditionProperty property, boolean expected, int index) implements CustomItemPredicate {
public ConditionPredicate(ConditionProperty property, boolean expected) {
@ -35,11 +42,22 @@ public record ConditionPredicate(ConditionProperty property, boolean expected, i
this(property, true);
}
// TODO maybe we can extend this
public enum ConditionProperty {
/**
* Checks if the item is broken (has 1 durability point left).
*/
BROKEN,
/**
* Checks if the item is damaged (has non-full durability).
*/
DAMAGED,
/**
* Checks if the item is unbreakable.
*/
UNBREAKABLE,
/**
* Returns one of the item's custom model data flags, defaults to false.
*/
CUSTOM_MODEL_DATA
}
}

View file

@ -27,5 +27,11 @@ package org.geysermc.geyser.api.item.custom.v2.predicate;
import org.geysermc.geyser.api.item.custom.v2.predicate.match.MatchPredicateProperty;
/**
* A predicate that matches a property of the item stack and returns true if it matches the expected value.
*
* @param property the property to check for.
* @param data the value expected.
*/
public record MatchPredicate<T>(MatchPredicateProperty<T> property, T data) implements CustomItemPredicate {
}

View file

@ -25,6 +25,15 @@
package org.geysermc.geyser.api.item.custom.v2.predicate;
/**
* A predicate that checks for a certain numeric property of the item stack and returns true if it is above the specified threshold.
*
* @param property the property to check.
* @param threshold the threshold the property should be above.
* @param scale factor to multiply the property value with before checking it with the threshold. Defaults to 1.0.
* @param normalizeIfPossible if the property value should be normalised to a value between 0.0 and 1.0. Defaults to false. Only works for certain properties.
* @param index only used for the {@code CUSTOM_MODEL_DATA} property, determines which float of the item's custom model data to check. Defaults to 0.
*/
public record RangeDispatchPredicate(RangeDispatchProperty property, double threshold, double scale, boolean normalizeIfPossible, int index) implements CustomItemPredicate {
public RangeDispatchPredicate(RangeDispatchProperty property, double threshold, double scale, boolean normalizeIfPossible) {
@ -39,11 +48,24 @@ public record RangeDispatchPredicate(RangeDispatchProperty property, double thre
this(property, threshold, 1.0);
}
// TODO check if we can change items while bedrock is using them, and if bedrock will continue to use them
public enum RangeDispatchProperty {
/**
* Checks the item's bundle fullness. Returns the total stack count of all the items in a bundle.
*
* <p>Usually used with bundles, but works for any item with the {@code minecraft:bundle_contents} component.</p>
*/
BUNDLE_FULLNESS,
/**
* Checks the item's damage value. Can be normalised.
*/
DAMAGE,
/**
* Checks the item's stack count. Can be normalised.
*/
COUNT,
/**
* Checks one of the item's custom model data floats, defaults to 0.0.
*/
CUSTOM_MODEL_DATA
}
}

View file

@ -27,12 +27,23 @@ package org.geysermc.geyser.api.item.custom.v2.predicate.match;
import org.geysermc.geyser.api.util.Identifier;
// TODO can we do more?
public class MatchPredicateProperty<T> {
/**
* Matches for the item's charged projectile. Usually used with crossbows, but checks any item with the {@code minecraft:charged_projectiles} component.
*/
public static final MatchPredicateProperty<ChargeType> CHARGE_TYPE = create();
/**
* Matches the item's trim material identifier. Works for any item with the {@code minecraft:trim} component.
*/
public static final MatchPredicateProperty<Identifier> TRIM_MATERIAL = create();
/**
* Matches the dimension identifier the Bedrock session player is currently in.
*/
public static final MatchPredicateProperty<Identifier> CONTEXT_DIMENSION = create();
/**
* Matches a string of the item's custom model data strings.
*/
public static final MatchPredicateProperty<CustomModelDataString> CUSTOM_MODEL_DATA = create();
private MatchPredicateProperty() {}