1
0
mirror of https://github.com/GeyserMC/Rainbow.git synced 2025-12-19 14:59:16 +00:00

Version bumps to 25w46a, ResourceLocation -> Identifier

This commit is contained in:
Eclipse
2025-11-12 13:55:58 +00:00
parent 27aecbfed6
commit d452de0bf1
25 changed files with 141 additions and 143 deletions

View File

@@ -22,7 +22,7 @@ public class RainbowClient implements ClientModInitializer {
ClientCommandRegistrationCallback.EVENT.register((dispatcher, buildContext) -> PackGeneratorCommand.register(dispatcher, packManager, packMapper));
ClientTickEvents.START_CLIENT_TICK.register(packMapper::tick);
ArgumentTypeRegistry.registerArgumentType(Rainbow.getModdedLocation("command_suggestions"),
ArgumentTypeRegistry.registerArgumentType(Rainbow.getModdedIdentifier("command_suggestions"),
CommandSuggestionsArgumentType.class, SingletonArgumentInfo.contextFree(CommandSuggestionsArgumentType::new));
RainbowIO.registerExceptionListener(new RainbowClientIOHandler());

View File

@@ -1,5 +1,5 @@
org.gradle.jvmargs=-Xmx1G
# Mod Properties
mod_version=0.2.0-1.21.10-SNAPSHOT
mod_version=0.2.0-1.21.11-SNAPSHOT
maven_group=org.geysermc.rainbow

View File

@@ -1,11 +1,11 @@
[versions]
minecraft = "1.21.10"
minecraft-supported = ">=1.21.9 <=1.21.10"
minecraft = "25w46a"
minecraft-supported = "*" # TODO
parchment = "2025.10.12"
fabric-loom = "1.11-SNAPSHOT"
fabric-loom = "1.13-SNAPSHOT"
fabric-loader = "0.17.3"
fabric-api = "0.135.0+1.21.10"
fabric-api = "0.138.4+1.21.11"
creative = "817fa982c4"
packconverter = "3.4.1-20251013.173215-13"
@@ -23,4 +23,3 @@ creative-serializer-minecraft = {group = "com.github.GeyserMC.unnamed-creative",
packconverter = {group = "org.geysermc.pack", name = "converter", version.ref = "packconverter"}
[plugins]
fabric-loom = {id = "fabric-loom", version.ref = "fabric-loom"}

View File

@@ -1,7 +1,7 @@
package org.geysermc.rainbow;
import com.mojang.logging.LogUtils;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import org.slf4j.Logger;
public class Rainbow {
@@ -10,19 +10,19 @@ public class Rainbow {
public static final String MOD_NAME = "Rainbow";
public static final Logger LOGGER = LogUtils.getLogger();
public static ResourceLocation getModdedLocation(String path) {
return ResourceLocation.fromNamespaceAndPath(MOD_ID, path);
public static Identifier getModdedIdentifier(String path) {
return Identifier.fromNamespaceAndPath(MOD_ID, path);
}
public static String safeResourceLocation(ResourceLocation location) {
return location.toString().replace(':', '.').replace('/', '_');
public static String bedrockSafeIdentifier(Identifier identifier) {
return identifier.toString().replace(':', '.').replace('/', '_');
}
public static ResourceLocation decorateResourceLocation(ResourceLocation location, String type, String extension) {
return location.withPath(path -> type + "/" + path + "." + extension);
public static Identifier decorateResourceLocation(Identifier identifier, String type, String extension) {
return identifier.withPath(path -> type + "/" + path + "." + extension);
}
public static ResourceLocation decorateTextureLocation(ResourceLocation location) {
return decorateResourceLocation(location, "textures", "png");
public static Identifier decorateTextureLocation(Identifier identifier) {
return decorateResourceLocation(identifier, "textures", "png");
}
}

View File

@@ -6,7 +6,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import org.geysermc.rainbow.Rainbow;
import org.geysermc.rainbow.definition.predicate.GeyserPredicate;
@@ -14,8 +14,8 @@ import java.util.List;
import java.util.Optional;
// TODO other keys, etc.
// TODO display name can be a component
public record GeyserBaseDefinition(ResourceLocation bedrockIdentifier, Optional<String> displayName,
// TODO display name can be a literal text component
public record GeyserBaseDefinition(Identifier bedrockIdentifier, Optional<String> displayName,
List<GeyserPredicate> predicates, BedrockOptions bedrockOptions, DataComponentPatch components) {
private static final List<DataComponentType<?>> SUPPORTED_COMPONENTS = List.of(DataComponents.CONSUMABLE, DataComponents.EQUIPPABLE, DataComponents.FOOD,
DataComponents.MAX_DAMAGE, DataComponents.MAX_STACK_SIZE, DataComponents.USE_COOLDOWN, DataComponents.ENCHANTABLE, DataComponents.ENCHANTMENT_GLINT_OVERRIDE);
@@ -38,7 +38,7 @@ public record GeyserBaseDefinition(ResourceLocation bedrockIdentifier, Optional<
public static final MapCodec<GeyserBaseDefinition> MAP_CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
ResourceLocation.CODEC.fieldOf("bedrock_identifier").forGetter(GeyserBaseDefinition::bedrockIdentifier),
Identifier.CODEC.fieldOf("bedrock_identifier").forGetter(GeyserBaseDefinition::bedrockIdentifier),
Codec.STRING.optionalFieldOf("display_name").forGetter(GeyserBaseDefinition::displayName),
GeyserPredicate.LIST_CODEC.optionalFieldOf("predicate", List.of()).forGetter(GeyserBaseDefinition::predicates),
BedrockOptions.CODEC.optionalFieldOf("bedrock_options", BedrockOptions.DEFAULT).forGetter(GeyserBaseDefinition::bedrockOptions),
@@ -61,17 +61,17 @@ public record GeyserBaseDefinition(ResourceLocation bedrockIdentifier, Optional<
}
public String textureName() {
return bedrockOptions.icon.orElse(Rainbow.safeResourceLocation(bedrockIdentifier));
return bedrockOptions.icon.orElse(Rainbow.bedrockSafeIdentifier(bedrockIdentifier));
}
public record BedrockOptions(Optional<String> icon, boolean allowOffhand, boolean displayHandheld, int protectionValue, List<ResourceLocation> tags) {
public record BedrockOptions(Optional<String> icon, boolean allowOffhand, boolean displayHandheld, int protectionValue, List<Identifier> tags) {
public static final Codec<BedrockOptions> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
Codec.STRING.optionalFieldOf("icon").forGetter(BedrockOptions::icon),
Codec.BOOL.optionalFieldOf("allow_offhand", true).forGetter(BedrockOptions::allowOffhand),
Codec.BOOL.optionalFieldOf("display_handheld", false).forGetter(BedrockOptions::displayHandheld),
Codec.INT.optionalFieldOf("protection_value", 0).forGetter(BedrockOptions::protectionValue),
ResourceLocation.CODEC.listOf().optionalFieldOf("tags", List.of()).forGetter(BedrockOptions::tags)
Identifier.CODEC.listOf().optionalFieldOf("tags", List.of()).forGetter(BedrockOptions::tags)
).apply(instance, BedrockOptions::new)
);
public static final BedrockOptions DEFAULT = new BedrockOptions(Optional.empty(), true, false, 0, List.of());

View File

@@ -2,7 +2,7 @@ package org.geysermc.rainbow.definition;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import org.jetbrains.annotations.NotNull;
import java.util.Comparator;
@@ -11,11 +11,11 @@ import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
public record GeyserGroupDefinition(Optional<ResourceLocation> model, List<GeyserMapping> definitions) implements GeyserMapping {
public record GeyserGroupDefinition(Optional<Identifier> model, List<GeyserMapping> definitions) implements GeyserMapping {
public static final MapCodec<GeyserGroupDefinition> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
ResourceLocation.CODEC.optionalFieldOf("model").forGetter(GeyserGroupDefinition::model),
Identifier.CODEC.optionalFieldOf("model").forGetter(GeyserGroupDefinition::model),
GeyserMapping.CODEC.listOf().fieldOf("definitions").forGetter(GeyserGroupDefinition::definitions)
).apply(instance, GeyserGroupDefinition::new)
);
@@ -26,12 +26,12 @@ public record GeyserGroupDefinition(Optional<ResourceLocation> model, List<Geyse
.toList());
}
public boolean isFor(Optional<ResourceLocation> model) {
public boolean isFor(Optional<Identifier> model) {
return this.model.isPresent() && model.isPresent() && this.model.get().equals(model.get());
}
public boolean conflictsWith(Optional<ResourceLocation> parentModel, GeyserItemDefinition other) {
Optional<ResourceLocation> thisModel = model.or(() -> parentModel);
public boolean conflictsWith(Optional<Identifier> parentModel, GeyserItemDefinition other) {
Optional<Identifier> thisModel = model.or(() -> parentModel);
for (GeyserMapping definition : definitions) {
if (definition instanceof GeyserGroupDefinition group && group.conflictsWith(thisModel, other)) {
return true;
@@ -61,7 +61,7 @@ public record GeyserGroupDefinition(Optional<ResourceLocation> model, List<Geyse
@Override
public int compareTo(@NotNull GeyserMapping other) {
if (other instanceof GeyserGroupDefinition(Optional<ResourceLocation> otherModel, List<GeyserMapping> otherDefinitions)) {
if (other instanceof GeyserGroupDefinition(Optional<Identifier> otherModel, List<GeyserMapping> otherDefinitions)) {
if (model.isPresent() && otherModel.isPresent()) {
return model.get().compareTo(otherModel.get());
} else if (model.isPresent()) {

View File

@@ -1,6 +1,6 @@
package org.geysermc.rainbow.definition;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
@@ -9,7 +9,7 @@ public interface GeyserItemDefinition extends GeyserMapping {
GeyserBaseDefinition base();
boolean conflictsWith(Optional<ResourceLocation> parentModel, GeyserItemDefinition other);
boolean conflictsWith(Optional<Identifier> parentModel, GeyserItemDefinition other);
@Override
default int compareTo(@NotNull GeyserMapping other) {

View File

@@ -3,7 +3,7 @@ package org.geysermc.rainbow.definition;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import java.util.Optional;
@@ -17,7 +17,7 @@ public record GeyserLegacyDefinition(GeyserBaseDefinition base, int customModelD
);
@Override
public boolean conflictsWith(Optional<ResourceLocation> parentModel, GeyserItemDefinition other) {
public boolean conflictsWith(Optional<Identifier> parentModel, GeyserItemDefinition other) {
if (other instanceof GeyserLegacyDefinition otherLegacy) {
return customModelData == otherLegacy.customModelData && base.conflictsWith(otherLegacy.base);
}

View File

@@ -5,7 +5,7 @@ import com.google.common.collect.MultimapBuilder;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.world.item.Item;
import org.geysermc.rainbow.CodecUtil;
@@ -41,7 +41,7 @@ public class GeyserMappings {
}
public void map(Holder<Item> item, GeyserItemDefinition mapping) {
Optional<ResourceLocation> model = mapping instanceof GeyserSingleDefinition single ? Optional.of(single.model().orElseThrow()) : Optional.empty();
Optional<Identifier> model = mapping instanceof GeyserSingleDefinition single ? Optional.of(single.model().orElseThrow()) : Optional.empty();
Optional<GeyserGroupDefinition> modelGroup = Optional.empty();
Collection<GeyserMapping> existingMappings = new ArrayList<>(mappings.get(item));

View File

@@ -2,23 +2,23 @@ package org.geysermc.rainbow.definition;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import java.util.Optional;
public record GeyserSingleDefinition(GeyserBaseDefinition base, Optional<ResourceLocation> model) implements GeyserItemDefinition {
public record GeyserSingleDefinition(GeyserBaseDefinition base, Optional<Identifier> model) implements GeyserItemDefinition {
public static final MapCodec<GeyserSingleDefinition> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
GeyserBaseDefinition.MAP_CODEC.forGetter(GeyserSingleDefinition::base),
ResourceLocation.CODEC.optionalFieldOf("model").forGetter(GeyserSingleDefinition::model)
Identifier.CODEC.optionalFieldOf("model").forGetter(GeyserSingleDefinition::model)
).apply(instance, GeyserSingleDefinition::new)
);
@Override
public boolean conflictsWith(Optional<ResourceLocation> parentModel, GeyserItemDefinition other) {
public boolean conflictsWith(Optional<Identifier> parentModel, GeyserItemDefinition other) {
if (other instanceof GeyserSingleDefinition otherSingle) {
ResourceLocation thisModel = model.or(() -> parentModel).orElseThrow();
ResourceLocation otherModel = otherSingle.model.or(() -> parentModel).orElseThrow();
Identifier thisModel = model.or(() -> parentModel).orElseThrow();
Identifier otherModel = otherSingle.model.or(() -> parentModel).orElseThrow();
return thisModel.equals(otherModel) && base.conflictsWith(other.base());
}
return false;

View File

@@ -3,8 +3,8 @@ package org.geysermc.rainbow.mapping;
import net.minecraft.client.renderer.item.ClientItem;
import net.minecraft.client.resources.model.EquipmentClientInfo;
import net.minecraft.client.resources.model.ResolvedModel;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.equipment.EquipmentAsset;
import org.geysermc.rainbow.mapping.texture.TextureResource;
@@ -12,11 +12,11 @@ import java.util.Optional;
public interface AssetResolver {
Optional<ResolvedModel> getResolvedModel(ResourceLocation location);
Optional<ResolvedModel> getResolvedModel(Identifier identifier);
Optional<ClientItem> getClientItem(ResourceLocation location);
Optional<ClientItem> getClientItem(Identifier identifier);
Optional<EquipmentClientInfo> getEquipmentInfo(ResourceKey<EquipmentAsset> key);
Optional<TextureResource> getTexture(ResourceLocation atlas, ResourceLocation location);
Optional<TextureResource> getTexture(Identifier atlas, Identifier identifier);
}

View File

@@ -25,8 +25,8 @@ import net.minecraft.client.renderer.item.properties.select.DisplayContext;
import net.minecraft.client.renderer.item.properties.select.SelectItemModelProperties;
import net.minecraft.client.renderer.item.properties.select.TrimMaterialProperty;
import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.ProblemReporter;
@@ -52,6 +52,7 @@ import org.geysermc.rainbow.definition.predicate.GeyserRangeDispatchPredicate;
import org.geysermc.rainbow.mixin.LateBoundIdMapperAccessor;
import org.geysermc.rainbow.mixin.RangeSelectItemModelAccessor;
import org.geysermc.rainbow.pack.BedrockItem;
import org.jspecify.annotations.NonNull;
import java.util.List;
import java.util.Optional;
@@ -59,24 +60,24 @@ import java.util.function.Function;
import java.util.stream.Stream;
public class BedrockItemMapper {
private static final List<ResourceLocation> TRIMMABLE_ARMOR_TAGS = Stream.of("is_armor", "trimmable_armors")
.map(ResourceLocation::withDefaultNamespace)
private static final List<Identifier> TRIMMABLE_ARMOR_TAGS = Stream.of("is_armor", "trimmable_armors")
.map(Identifier::withDefaultNamespace)
.toList();
private static <T> ResourceLocation getId(ExtraCodecs.LateBoundIdMapper<ResourceLocation, T> mapper,
private static <T> Identifier getId(ExtraCodecs.LateBoundIdMapper<@NonNull Identifier, @NonNull T> mapper,
T type) {
//noinspection unchecked
return ((LateBoundIdMapperAccessor<ResourceLocation, ?>) mapper).getIdToValue().inverse().get(type);
return ((LateBoundIdMapperAccessor<Identifier, ?>) mapper).getIdToValue().inverse().get(type);
}
public static void tryMapStack(ItemStack stack, ResourceLocation modelLocation, ProblemReporter reporter, PackContext context) {
context.assetResolver().getClientItem(modelLocation).map(ClientItem::model)
.ifPresentOrElse(model -> mapItem(model, stack, reporter.forChild(() -> "client item definition " + modelLocation + " "), base -> new GeyserSingleDefinition(base, Optional.of(modelLocation)), context),
() -> reporter.report(() -> "missing client item definition " + modelLocation));
public static void tryMapStack(ItemStack stack, Identifier modelIdentifier, ProblemReporter reporter, PackContext context) {
context.assetResolver().getClientItem(modelIdentifier).map(ClientItem::model)
.ifPresentOrElse(model -> mapItem(model, stack, reporter.forChild(() -> "client item definition " + modelIdentifier + " "), base -> new GeyserSingleDefinition(base, Optional.of(modelIdentifier)), context),
() -> reporter.report(() -> "missing client item definition " + modelIdentifier));
}
public static void tryMapStack(ItemStack stack, int customModelData, ProblemReporter reporter, PackContext context) {
ResourceLocation itemModel = stack.get(DataComponents.ITEM_MODEL);
Identifier itemModel = stack.get(DataComponents.ITEM_MODEL);
ItemModel.Unbaked vanillaModel = context.assetResolver().getClientItem(itemModel).map(ClientItem::model).orElseThrow();
ProblemReporter childReporter = reporter.forChild(() -> "item model " + itemModel + " with custom model data " + customModelData + " ");
if (vanillaModel instanceof RangeSelectItemModel.Unbaked(RangeSelectItemModelProperty property, float scale, List<RangeSelectItemModel.Entry> entries, Optional<ItemModel.Unbaked> fallback)) {
@@ -117,24 +118,24 @@ public class BedrockItemMapper {
}
private static void mapBlockModelWrapper(BlockModelWrapper.Unbaked model, MappingContext context) {
ResourceLocation itemModelLocation = model.model();
Identifier itemModelIdentifier = model.model();
context.packContext().assetResolver().getResolvedModel(itemModelLocation)
context.packContext().assetResolver().getResolvedModel(itemModelIdentifier)
.ifPresentOrElse(itemModel -> {
ResourceLocation bedrockIdentifier;
if (itemModelLocation.getNamespace().equals(ResourceLocation.DEFAULT_NAMESPACE)) {
bedrockIdentifier = ResourceLocation.fromNamespaceAndPath("geyser_mc", itemModelLocation.getPath());
Identifier bedrockIdentifier;
if (itemModelIdentifier.getNamespace().equals(Identifier.DEFAULT_NAMESPACE)) {
bedrockIdentifier = Identifier.fromNamespaceAndPath("geyser_mc", itemModelIdentifier.getPath());
} else {
bedrockIdentifier = itemModelLocation;
bedrockIdentifier = itemModelIdentifier;
}
BedrockGeometryContext geometry = BedrockGeometryContext.create(bedrockIdentifier, itemModel, context.stack, context.packContext);
if (context.packContext.reportSuccesses()) {
// Not a problem, but just report to get the model printed in the report file
context.report("creating mapping for block model " + itemModelLocation);
context.report("creating mapping for block model " + itemModelIdentifier);
}
context.create(bedrockIdentifier, geometry);
}, () -> context.report("missing block model " + itemModelLocation));
}, () -> context.report("missing block model " + itemModelIdentifier));
}
private static void mapConditionalModel(ConditionalItemModel.Unbaked model, MappingContext context) {
@@ -230,8 +231,8 @@ public class BedrockItemMapper {
return new MappingContext(predicateStack, stack, reporter.forChild(() -> childName), definitionCreator, packContext);
}
public void create(ResourceLocation bedrockIdentifier, BedrockGeometryContext geometry) {
List<ResourceLocation> tags = stack.is(ItemTags.TRIMMABLE_ARMOR) ? TRIMMABLE_ARMOR_TAGS : List.of();
public void create(Identifier bedrockIdentifier, BedrockGeometryContext geometry) {
List<Identifier> tags = stack.is(ItemTags.TRIMMABLE_ARMOR) ? TRIMMABLE_ARMOR_TAGS : List.of();
GeyserBaseDefinition base = new GeyserBaseDefinition(bedrockIdentifier, Optional.ofNullable(stack.getHoverName().tryCollapseToString()), predicateStack,
new GeyserBaseDefinition.BedrockOptions(Optional.empty(), true, geometry.handheld(), calculateProtectionValue(stack), tags),

View File

@@ -5,7 +5,7 @@ import net.minecraft.client.resources.model.EquipmentAssetManager;
import net.minecraft.client.resources.model.EquipmentClientInfo;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.equipment.Equippable;
import org.geysermc.rainbow.mapping.AssetResolver;
@@ -32,7 +32,7 @@ public class AttachableMapper {
.mapSecond(info -> info.getLayers(getLayer(assetInfo.getFirst()))))
.filter(assetInfo -> !assetInfo.getSecond().isEmpty())
.map(assetInfo -> {
ResourceLocation equipmentTexture = getTexture(assetInfo.getSecond(), getLayer(assetInfo.getFirst()));
Identifier equipmentTexture = getTexture(assetInfo.getSecond(), getLayer(assetInfo.getFirst()));
textureConsumer.accept(TextureHolder.createBuiltIn(null, equipmentTexture));
return BedrockAttachable.equipment(bedrockIdentifier, assetInfo.getFirst(), equipmentTexture.getPath());
}))
@@ -53,13 +53,13 @@ public class AttachableMapper {
return slot == EquipmentSlot.LEGS ? EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS : EquipmentClientInfo.LayerType.HUMANOID;
}
private static ResourceLocation getTexture(List<EquipmentClientInfo.Layer> info, EquipmentClientInfo.LayerType layer) {
private static Identifier getTexture(List<EquipmentClientInfo.Layer> info, EquipmentClientInfo.LayerType layer) {
return info.getFirst().textureId().withPath(path -> "entity/equipment/" + layer.getSerializedName() + "/" + path);
}
@FunctionalInterface
public interface AttachableCreator {
Optional<BedrockAttachable> create(ResourceLocation bedrockIdentifier, Consumer<TextureHolder> textureConsumer);
Optional<BedrockAttachable> create(Identifier bedrockIdentifier, Consumer<TextureHolder> textureConsumer);
}
}

View File

@@ -4,7 +4,7 @@ import net.minecraft.client.renderer.block.model.TextureSlots;
import net.minecraft.client.resources.model.Material;
import net.minecraft.client.resources.model.ResolvedModel;
import net.minecraft.data.AtlasIds;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.world.item.ItemStack;
import org.geysermc.rainbow.Rainbow;
import org.geysermc.rainbow.mapping.PackContext;
@@ -19,14 +19,14 @@ import java.util.stream.Stream;
public record BedrockGeometryContext(Optional<MappedGeometry> geometry,
Optional<BedrockAnimationContext> animation, TextureHolder icon,
boolean handheld) {
private static final List<ResourceLocation> HANDHELD_MODELS = Stream.of("item/handheld", "item/handheld_rod", "item/handheld_mace")
.map(ResourceLocation::withDefaultNamespace)
private static final List<Identifier> HANDHELD_MODELS = Stream.of("item/handheld", "item/handheld_rod", "item/handheld_mace")
.map(Identifier::withDefaultNamespace)
.toList();
public static BedrockGeometryContext create(ResourceLocation bedrockIdentifier, ResolvedModel model, ItemStack stackToRender, PackContext context) {
public static BedrockGeometryContext create(Identifier bedrockIdentifier, ResolvedModel model, ItemStack stackToRender, PackContext context) {
ResolvedModel parentModel = model.parent();
// debugName() returns the resource location of the model as a string
boolean handheld = parentModel != null && HANDHELD_MODELS.contains(ResourceLocation.parse(parentModel.debugName()));
boolean handheld = parentModel != null && HANDHELD_MODELS.contains(Identifier.parse(parentModel.debugName()));
TextureSlots textures = model.getTopTextureSlots();
Material layer0Texture = textures.getMaterial("layer0");
@@ -43,7 +43,7 @@ public record BedrockGeometryContext(Optional<MappedGeometry> geometry,
// This check should probably be done differently (actually check if the model is 2D or 3D)
geometry = Optional.of(context.geometryCache().mapGeometry(bedrockIdentifier, model, stackToRender, context));
animation = Optional.of(AnimationMapper.mapAnimation(Rainbow.safeResourceLocation(bedrockIdentifier), "bone", model.getTopTransforms()));
animation = Optional.of(AnimationMapper.mapAnimation(Rainbow.bedrockSafeIdentifier(bedrockIdentifier), "bone", model.getTopTransforms()));
icon = geometry.get().icon();
}

View File

@@ -1,10 +1,10 @@
package org.geysermc.rainbow.mapping.geometry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.world.item.ItemStack;
import org.geysermc.rainbow.mapping.texture.TextureHolder;
public interface GeometryRenderer {
TextureHolder render(ResourceLocation location, ItemStack stack);
TextureHolder render(Identifier identifier, ItemStack stack);
}

View File

@@ -1,11 +1,9 @@
package org.geysermc.rainbow.mapping.geometry;
import com.google.common.base.Suppliers;
import net.minecraft.client.renderer.block.model.TextureSlots;
import net.minecraft.client.resources.model.Material;
import net.minecraft.client.resources.model.ResolvedModel;
import net.minecraft.client.resources.model.UnbakedGeometry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.world.item.ItemStack;
import org.geysermc.rainbow.Rainbow;
import org.geysermc.rainbow.mapping.PackContext;
@@ -20,22 +18,22 @@ import java.util.Map;
public class MappedGeometryCache {
private final Map<GeometryCacheKey, MappedGeometryInstance> cachedGeometry = new HashMap<>();
public MappedGeometry mapGeometry(ResourceLocation bedrockIdentifier, ResolvedModel model, ItemStack stackToRender, PackContext context) {
public MappedGeometry mapGeometry(Identifier bedrockIdentifier, ResolvedModel model, ItemStack stackToRender, PackContext context) {
GeometryCacheKey cacheKey = new GeometryCacheKey(model);
MappedGeometry cached = cachedGeometry.get(cacheKey);
if (cached != null) {
return cached.cachedCopy();
}
ResourceLocation modelLocation = ResourceLocation.parse(model.debugName());
ResourceLocation stitchedTexturesLocation = modelLocation.withSuffix("_stitched");
String safeIdentifier = Rainbow.safeResourceLocation(bedrockIdentifier);
Identifier modelIdentifier = Identifier.parse(model.debugName());
Identifier stitchedTexturesIdentifier = modelIdentifier.withSuffix("_stitched");
String safeIdentifier = Rainbow.bedrockSafeIdentifier(bedrockIdentifier);
StitchedTextures stitchedTextures = StitchedTextures.stitchModelTextures(model.getTopTextureSlots(), context);
BedrockGeometry geometry = GeometryMapper.mapGeometry(safeIdentifier, "bone", model, stitchedTextures);
TextureHolder icon = context.geometryRenderer().isPresent() ? context.geometryRenderer().orElseThrow().render(modelLocation, stackToRender)
: TextureHolder.createNonExistent(modelLocation);
MappedGeometryInstance instance = new MappedGeometryInstance(geometry, TextureHolder.createCustom(stitchedTexturesLocation, stitchedTextures.stitched()), icon);
TextureHolder icon = context.geometryRenderer().isPresent() ? context.geometryRenderer().orElseThrow().render(modelIdentifier, stackToRender)
: TextureHolder.createNonExistent(modelIdentifier);
MappedGeometryInstance instance = new MappedGeometryInstance(geometry, TextureHolder.createCustom(stitchedTexturesIdentifier, stitchedTextures.stitched()), icon);
cachedGeometry.put(cacheKey, instance);
return instance;
}

View File

@@ -1,7 +1,7 @@
package org.geysermc.rainbow.mapping.texture;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.ProblemReporter;
import org.geysermc.rainbow.RainbowIO;
import org.geysermc.rainbow.image.NativeImageUtil;
@@ -11,11 +11,11 @@ import java.util.Objects;
import java.util.Optional;
public class BuiltInTextureHolder extends TextureHolder {
private final ResourceLocation atlas;
private final ResourceLocation source;
private final Identifier atlas;
private final Identifier source;
public BuiltInTextureHolder(ResourceLocation location, ResourceLocation atlas, ResourceLocation source) {
super(location);
public BuiltInTextureHolder(Identifier identifier, Identifier atlas, Identifier source) {
super(identifier);
this.atlas = atlas;
this.source = source;
}

View File

@@ -1,6 +1,6 @@
package org.geysermc.rainbow.mapping.texture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.ProblemReporter;
import org.geysermc.rainbow.mapping.AssetResolver;
import org.geysermc.rainbow.mapping.PackSerializer;
@@ -11,8 +11,8 @@ import java.util.concurrent.CompletableFuture;
public class CopyTextureHolder extends TextureHolder {
public CopyTextureHolder(ResourceLocation location) {
super(location);
public CopyTextureHolder(Identifier identifier) {
super(identifier);
}
@Override

View File

@@ -1,7 +1,7 @@
package org.geysermc.rainbow.mapping.texture;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.ProblemReporter;
import org.geysermc.rainbow.RainbowIO;
import org.geysermc.rainbow.image.NativeImageUtil;
@@ -13,8 +13,8 @@ import java.util.function.Supplier;
public class CustomTextureHolder extends TextureHolder {
private final Supplier<NativeImage> supplier;
public CustomTextureHolder(ResourceLocation location, Supplier<NativeImage> supplier) {
super(location);
public CustomTextureHolder(Identifier identifier, Supplier<NativeImage> supplier) {
super(identifier);
this.supplier = supplier;
}

View File

@@ -1,6 +1,6 @@
package org.geysermc.rainbow.mapping.texture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.ProblemReporter;
import org.geysermc.rainbow.mapping.AssetResolver;
@@ -8,8 +8,8 @@ import java.util.Optional;
public class MissingTextureHolder extends TextureHolder {
public MissingTextureHolder(ResourceLocation location) {
super(location);
public MissingTextureHolder(Identifier identifier) {
super(identifier);
}
@Override

View File

@@ -1,14 +1,14 @@
package org.geysermc.rainbow.mapping.texture;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.Util;
import net.minecraft.client.renderer.block.model.TextureSlots;
import net.minecraft.client.renderer.texture.SpriteContents;
import net.minecraft.client.renderer.texture.SpriteLoader;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.Material;
import net.minecraft.data.AtlasIds;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.Util;
import org.geysermc.rainbow.RainbowIO;
import org.geysermc.rainbow.mapping.PackContext;
import org.geysermc.rainbow.mixin.SpriteContentsAccessor;
@@ -50,7 +50,7 @@ public record StitchedTextures(Map<String, TextureAtlasSprite> sprites, Supplier
return new StitchedTextures(Map.copyOf(sprites), () -> stitchTextureAtlas(preparations), preparations.width(), preparations.height());
}
private static SpriteLoader.Preparations prepareStitching(Stream<ResourceLocation> textures, PackContext context) {
private static SpriteLoader.Preparations prepareStitching(Stream<Identifier> textures, PackContext context) {
// Atlas ID doesn't matter much here, but BLOCKS is the most appropriate
SpriteLoader spriteLoader = new SpriteLoader(AtlasIds.BLOCKS, MAX_TEXTURE_SIZE, 16, 16);
List<SpriteContents> sprites = textures.distinct()
@@ -60,11 +60,11 @@ public record StitchedTextures(Map<String, TextureAtlasSprite> sprites, Supplier
return ((SpriteLoaderAccessor) spriteLoader).invokeStitch(sprites, 0, Util.backgroundExecutor());
}
private static Optional<SpriteContents> readSpriteContents(ResourceLocation location, PackContext context) {
private static Optional<SpriteContents> readSpriteContents(Identifier identifier, PackContext context) {
return RainbowIO.safeIO(() -> {
try (TextureResource texture = context.assetResolver().getTexture(AtlasIds.BLOCKS, location).orElse(null)) {
try (TextureResource texture = context.assetResolver().getTexture(AtlasIds.BLOCKS, identifier).orElse(null)) {
if (texture != null) {
return new SpriteContents(location, texture.sizeOfFrame(), texture.getFirstFrame(true));
return new SpriteContents(identifier, texture.sizeOfFrame(), texture.getFirstFrame(true));
}
}
return null;

View File

@@ -1,7 +1,7 @@
package org.geysermc.rainbow.mapping.texture;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.ProblemReporter;
import org.geysermc.rainbow.mapping.AssetResolver;
import org.geysermc.rainbow.mapping.PackSerializer;
@@ -12,10 +12,10 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
public abstract class TextureHolder {
protected final ResourceLocation location;
protected final Identifier identifier;
public TextureHolder(ResourceLocation location) {
this.location = location;
public TextureHolder(Identifier identifier) {
this.identifier = identifier;
}
public abstract Optional<byte[]> load(AssetResolver assetResolver, ProblemReporter reporter);
@@ -26,31 +26,31 @@ public abstract class TextureHolder {
.orElse(CompletableFuture.completedFuture(null));
}
public static TextureHolder createCustom(ResourceLocation location, Supplier<NativeImage> supplier) {
return new CustomTextureHolder(location, supplier);
public static TextureHolder createCustom(Identifier identifier, Supplier<NativeImage> supplier) {
return new CustomTextureHolder(identifier, supplier);
}
public static TextureHolder createBuiltIn(ResourceLocation location, ResourceLocation atlas, ResourceLocation source) {
return new BuiltInTextureHolder(location, atlas, source);
public static TextureHolder createBuiltIn(Identifier identifier, Identifier atlas, Identifier source) {
return new BuiltInTextureHolder(identifier, atlas, source);
}
public static TextureHolder createBuiltIn(ResourceLocation atlas, ResourceLocation location) {
return createBuiltIn(location, atlas, location);
public static TextureHolder createBuiltIn(Identifier atlas, Identifier identifier) {
return createBuiltIn(identifier, atlas, identifier);
}
public static TextureHolder createNonExistent(ResourceLocation location) {
return new MissingTextureHolder(location);
public static TextureHolder createNonExistent(Identifier identifier) {
return new MissingTextureHolder(identifier);
}
public static TextureHolder createCopy(TextureHolder original) {
return new CopyTextureHolder(original.location);
return new CopyTextureHolder(original.identifier);
}
public ResourceLocation location() {
return location;
public Identifier location() {
return identifier;
}
protected void reportMissing(ProblemReporter reporter) {
reporter.report(() -> "missing texture for " + location + "; please provide it manually");
reporter.report(() -> "missing texture for " + identifier + "; please provide it manually");
}
}

View File

@@ -1,6 +1,6 @@
package org.geysermc.rainbow.pack;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import org.geysermc.rainbow.Rainbow;
import org.geysermc.rainbow.mapping.PackSerializer;
import org.geysermc.rainbow.mapping.attachable.AttachableMapper;
@@ -15,7 +15,7 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
public record BedrockItem(ResourceLocation identifier, String textureName, BedrockGeometryContext geometryContext, AttachableMapper.AttachableCreator attachableCreator) {
public record BedrockItem(Identifier identifier, String textureName, BedrockGeometryContext geometryContext, AttachableMapper.AttachableCreator attachableCreator) {
public CompletableFuture<?> save(PackSerializer serializer, Path attachableDirectory, Path geometryDirectory, Path animationDirectory,
Function<TextureHolder, CompletableFuture<?>> textureSaver) {
@@ -26,7 +26,7 @@ public record BedrockItem(ResourceLocation identifier, String textureName, Bedro
createdAttachable.map(attachable -> attachable.save(serializer, attachableDirectory)).orElse(noop()),
CompletableFuture.allOf(attachableTextures.stream().map(textureSaver).toArray(CompletableFuture[]::new)),
geometryContext.geometry().map(geometry -> geometry.save(serializer, geometryDirectory, textureSaver)).orElse(noop()),
geometryContext.animation().map(context -> context.animation().save(serializer, animationDirectory, Rainbow.safeResourceLocation(identifier))).orElse(noop())
geometryContext.animation().map(context -> context.animation().save(serializer, animationDirectory, Rainbow.bedrockSafeIdentifier(identifier))).orElse(noop())
);
}

View File

@@ -4,7 +4,7 @@ import com.mojang.datafixers.util.Pair;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
@@ -42,7 +42,7 @@ public class BedrockPack {
private final BedrockTextures.Builder itemTextures = BedrockTextures.builder();
private final Set<BedrockItem> bedrockItems = new HashSet<>();
private final Set<ResourceLocation> modelsMapped = new HashSet<>();
private final Set<Identifier> modelsMapped = new HashSet<>();
private final Set<Pair<Item, Integer>> customModelDataMapped = new HashSet<>();
private final PackContext context;
@@ -88,7 +88,7 @@ public class BedrockPack {
}
};
Optional<? extends ResourceLocation> patchedModel = stack.getComponentsPatch().get(DataComponents.ITEM_MODEL);
Optional<? extends Identifier> patchedModel = stack.getComponentsPatch().get(DataComponents.ITEM_MODEL);
//noinspection OptionalAssignedToNull - annoying Mojang
if (patchedModel == null || patchedModel.isEmpty()) {
CustomModelData customModelData = stack.get(DataComponents.CUSTOM_MODEL_DATA);
@@ -100,7 +100,7 @@ public class BedrockPack {
BedrockItemMapper.tryMapStack(stack, firstNumber.intValue(), mapReporter, context);
} else {
ResourceLocation model = patchedModel.get();
Identifier model = patchedModel.get();
if (!modelsMapped.add(model)) {
return MappingResult.NONE_MAPPED;
}
@@ -125,8 +125,8 @@ public class BedrockPack {
futures.add(serializer.saveJson(BedrockTextureAtlas.CODEC, BedrockTextureAtlas.itemAtlas(name, itemTextures), paths.itemAtlas()));
Function<TextureHolder, CompletableFuture<?>> textureSaver = texture -> {
ResourceLocation textureLocation = Rainbow.decorateTextureLocation(texture.location());
return texture.save(context.assetResolver(), serializer, paths.packRoot().resolve(textureLocation.getPath()), reporter);
Identifier textureIdentifier = Rainbow.decorateTextureLocation(texture.location());
return texture.save(context.assetResolver(), serializer, paths.packRoot().resolve(textureIdentifier.getPath()), reporter);
};
for (BedrockItem item : bedrockItems) {

View File

@@ -5,7 +5,7 @@ import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.entity.EquipmentSlot;
@@ -37,14 +37,14 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
public CompletableFuture<?> save(PackSerializer serializer, Path attachablesDirectory) {
// Get a safe attachable path by using Geyser's way of getting icons
return serializer.saveJson(CODEC, this, attachablesDirectory.resolve(Rainbow.safeResourceLocation(info.identifier) + ".json"));
return serializer.saveJson(CODEC, this, attachablesDirectory.resolve(Rainbow.bedrockSafeIdentifier(info.identifier) + ".json"));
}
public static Builder builder(ResourceLocation identifier) {
public static Builder builder(Identifier identifier) {
return new Builder(identifier);
}
public static BedrockAttachable.Builder equipment(ResourceLocation identifier, EquipmentSlot slot, String texture) {
public static BedrockAttachable.Builder equipment(Identifier identifier, EquipmentSlot slot, String texture) {
String script = switch (slot) {
case HEAD -> "v.helmet_layer_visible = 0.0;";
case CHEST -> "v.chest_layer_visible = 0.0;";
@@ -62,7 +62,7 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
.withRenderController(VanillaRenderControllers.ARMOR);
}
public static BedrockAttachable.Builder geometry(ResourceLocation identifier, MappedGeometry geometry) {
public static BedrockAttachable.Builder geometry(Identifier identifier, MappedGeometry geometry) {
return builder(identifier)
.withMaterial(DisplaySlot.DEFAULT, VanillaMaterials.ENTITY)
.withMaterial(DisplaySlot.ENCHANTED, VanillaMaterials.ENTITY_ALPHATEST_GLINT)
@@ -73,7 +73,7 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
}
public static class Builder {
private final ResourceLocation identifier;
private final Identifier identifier;
private final EnumMap<DisplaySlot, String> materials = new EnumMap<>(DisplaySlot.class);
private final EnumMap<DisplaySlot, String> textures = new EnumMap<>(DisplaySlot.class);
private final EnumMap<DisplaySlot, String> geometries = new EnumMap<>(DisplaySlot.class);
@@ -81,7 +81,7 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
private final Map<String, List<Script>> scripts = new HashMap<>();
private final List<String> renderControllers = new ArrayList<>();
public Builder(ResourceLocation identifier) {
public Builder(Identifier identifier) {
this.identifier = identifier;
}
@@ -137,13 +137,13 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
}
}
public record AttachableInfo(ResourceLocation identifier, DisplayMap materials, DisplayMap textures,
public record AttachableInfo(Identifier identifier, DisplayMap materials, DisplayMap textures,
DisplayMap geometry, Map<String, String> animations, Scripts scripts,
List<String> renderControllers) {
private static final Codec<Map<String, String>> STRING_MAP_CODEC = Codec.unboundedMap(Codec.STRING, Codec.STRING);
public static final Codec<AttachableInfo> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
ResourceLocation.CODEC.fieldOf("identifier").forGetter(AttachableInfo::identifier),
Identifier.CODEC.fieldOf("identifier").forGetter(AttachableInfo::identifier),
DisplayMap.CODEC.fieldOf("materials").forGetter(AttachableInfo::materials),
DisplayMap.CODEC.fieldOf("textures").forGetter(AttachableInfo::textures),
DisplayMap.CODEC.fieldOf("geometry").forGetter(AttachableInfo::geometry),