Skip to content

Commit

Permalink
More fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
modmuss50 committed Feb 29, 2024
1 parent eb3000e commit 1454e00
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,4 @@ private static void getCommonNodeType(BlockView world, BlockPos pos, CallbackInf
cir.setReturnValue(nodeType);
}
}

/**
* Overrides the node type for the specified position, if the position is found as neighbor block in a path.
*/
// TODO 1.20.5
// @Inject(method = "getNodeTypeFromNeighbors", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/entity/ai/pathing/LandPathNodeMaker;getCommonNodeType(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/entity/ai/pathing/PathNodeType;"), cancellable = true)
// private static void getNodeTypeFromNeighbors(BlockView world, BlockPos.Mutable pos, PathNodeType nodeType, CallbackInfoReturnable<PathNodeType> cir) {
// PathNodeType neighborNodeType = LandPathNodeTypesRegistry.getPathNodeType(world.getBlockState(pos), world, pos, true);
//
// if (neighborNodeType != null) {
// cir.setReturnValue(neighborNodeType);
// }
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.mixin.content.registry;

import com.llamalad7.mixinextras.sugar.Local;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import net.minecraft.block.BlockState;
import net.minecraft.class_9316;
import net.minecraft.entity.ai.pathing.PathNodeType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.CollisionView;

import net.fabricmc.fabric.api.registry.LandPathNodeTypesRegistry;

@Mixin(class_9316.class)
public abstract class class_9316Mixin {
@Shadow
public abstract BlockState method_57623(BlockPos blockPos);

@Shadow
public abstract CollisionView method_57621();

/**
* Overrides the node type for the specified position, if the position is found as neighbor block in a path.
*/
@Inject(method = "method_57622", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/math/BlockPos$Mutable;set(III)Lnet/minecraft/util/math/BlockPos$Mutable;"), cancellable = true)
private void method_57622(int x, int y, int z, CallbackInfoReturnable<PathNodeType> cir, @Local BlockPos pos) {
final PathNodeType neighborNodeType = LandPathNodeTypesRegistry.getPathNodeType(method_57623(pos), method_57621(), pos, true);

if (neighborNodeType != null) {
cir.setReturnValue(neighborNodeType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"compatibilityLevel": "JAVA_17",
"mixins": [
"AxeItemAccessor",
"class_9316Mixin",
"FarmerWorkTaskAccessor",
"GiveGiftsToHeroTaskAccessor",
"HoeItemAccessor",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableG
transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Lnet/minecraft/data/client/Model;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Ljava/lang/String;Lnet/minecraft/data/client/Model;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Lnet/minecraft/item/Item;Lnet/minecraft/data/client/Model;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator registerWolfArmor (Lnet/minecraft/item/Item;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator registerCompass (Lnet/minecraft/item/Item;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator registerClock (Lnet/minecraft/item/Item;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator uploadArmor (Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)V
Expand All @@ -322,6 +323,7 @@ transitive-extendable method net/minecraft/data/dev/NbtProvider getName ()Ljava/
transitive-extendable method net/minecraft/data/report/BlockListProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/report/CommandSyntaxProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/report/DynamicRegistriesProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/report/ItemListProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/report/RegistryDumpProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/server/BiomeParametersProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/server/advancement/AdvancementProvider getName ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import net.minecraft.block.Block;
import net.minecraft.block.BlockKeys;
import net.minecraft.block.Blocks;
import net.minecraft.component.ComponentChanges;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.data.DataOutput;
import net.minecraft.data.client.BlockStateModelGenerator;
Expand Down Expand Up @@ -194,7 +195,13 @@ public void generate(RecipeExporter exporter) {
.input(Ingredient.ofItems(Items.DIAMOND_PICKAXE))
.input(Ingredient.ofItems(Items.DIAMOND_PICKAXE))
.input(Ingredient.ofItems(Items.DIAMOND_PICKAXE))
.input(DefaultCustomIngredients.component(new ItemStack(Items.DIAMOND_PICKAXE), false))
.input(DefaultCustomIngredients.components(
Ingredient.ofItems(Items.DIAMOND_PICKAXE),
ComponentChanges.builder()
.add(DataComponentTypes.DAMAGE, 0)
.build()
)
)
.input(Ingredient.ofItems(Items.DIAMOND_PICKAXE))
.input(Ingredient.ofItems(Items.DIAMOND_PICKAXE))
.input(Ingredient.ofItems(Items.DIAMOND_PICKAXE))
Expand All @@ -209,7 +216,7 @@ public void generate(RecipeExporter exporter) {
appleWithGoldenName.set(DataComponentTypes.CUSTOM_NAME, Text.literal("Golden Apple"));
appleWithGoldenName.set(DataComponentTypes.REPAIR_COST, 0);
ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.GOLDEN_APPLE)
.input(DefaultCustomIngredients.component(appleWithGoldenName, true))
.input(DefaultCustomIngredients.components(appleWithGoldenName))
.criterion("has_apple", conditionsFromItem(Items.APPLE))
.offerTo(exporter);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}
],
"result": {
"item": "minecraft:diamond",
"id": "minecraft:diamond",
"count": 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,19 @@

import java.util.stream.Stream;

import com.llamalad7.mixinextras.sugar.Local;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

import net.minecraft.class_9306;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.DefaultedRegistry;
import net.minecraft.util.math.random.Random;
import net.minecraft.village.TradeOffer;
import net.minecraft.village.TradeOffers;
import net.minecraft.village.VillagerDataContainer;
import net.minecraft.village.VillagerType;

@Mixin(TradeOffers.TypeAwareBuyForOneEmeraldFactory.class)
Expand All @@ -50,9 +49,9 @@ private <T> Stream<T> disableVanillaCheck(DefaultedRegistry<VillagerType> instan
/**
* To prevent "item" -> "air" trades, if the result of a type aware trade is air, make sure no offer is created.
*/
@Inject(method = "create", at = @At(value = "NEW", target = "net/minecraft/village/TradeOffer"), locals = LocalCapture.CAPTURE_FAILEXCEPTION, cancellable = true)
private void failOnNullItem(Entity entity, Random random, CallbackInfoReturnable<TradeOffer> cir, VillagerDataContainer villagerDataContainer, ItemStack buyingItem) {
if (buyingItem.isEmpty()) { // Will return true for an "empty" item stack that had null passed in the ctor
@Inject(method = "create", at = @At(value = "NEW", target = "net/minecraft/village/TradeOffer"), cancellable = true)
private void failOnNullItem(Entity entity, Random random, CallbackInfoReturnable<TradeOffer> cir, @Local() class_9306 buyingItem) {
if (buyingItem.itemStack().isEmpty()) { // Will return true for an "empty" item stack that had null passed in the ctor
cir.setReturnValue(null); // Return null to prevent creation of empty trades
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@

import java.util.List;
import java.util.Objects;
import java.util.function.UnaryOperator;

import net.minecraft.component.ComponentChanges;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.recipe.Ingredient;

import net.fabricmc.fabric.impl.recipe.ingredient.builtin.AllIngredient;
Expand Down Expand Up @@ -99,43 +99,38 @@ public static Ingredient difference(Ingredient base, Ingredient subtracted) {
}

/**
* Creates an ingredient that wraps another ingredient to also check for stack NBT.
* This check can either be strict (the exact NBT must match) or non-strict aka. partial (the ingredient NBT must be a subset of the stack NBT).
* Creates an ingredient that wraps another ingredient to also check for matching components.
*
* <p>In strict mode, passing a {@code null} {@code nbt} is allowed, and will only match stacks with {@code null} NBT.
* In partial mode, passing a {@code null} {@code nbt} is <strong>not</strong> allowed, as it would always match.
* <p>Use {@link ComponentChanges#builder()} to add or remove components.
* Added components are checked to match on the target stack.
* Removed components are checked to not exist in the target stack
*
* <p>See {@link NbtHelper#matches} for the non-strict matching.
*
* <p>The JSON format is as follows:
* <pre>{@code
* {
* "fabric:type": "fabric:nbt",
* "base": // base ingredient,
* "nbt": // NBT tag to match, either in JSON directly or a string representation (default: null),
* "strict": // whether to use strict matching (default: false)
* }
* }</pre>
*
* @throws IllegalArgumentException if {@code strict} is {@code false} and the NBT is {@code null}
* @throws IllegalArgumentException if {@link ComponentChanges#isEmpty} is true
*/
public static Ingredient component(Ingredient base, ComponentChanges components, boolean strict) {
public static Ingredient components(Ingredient base, ComponentChanges components) {
Objects.requireNonNull(base, "Base ingredient cannot be null");
Objects.requireNonNull(components, "Component changes cannot be null");

return new ComponentIngredient(base, components, strict).toVanilla();
return new ComponentIngredient(base, components).toVanilla();
}

/**
* @see #components(Ingredient, ComponentChanges)
*/
public static Ingredient components(Ingredient base, UnaryOperator<ComponentChanges.Builder> operator) {
return components(base, operator.apply(ComponentChanges.builder()).build());
}

/**
* Creates an ingredient that matches the passed template stack, including NBT.
* Creates an ingredient that matches the passed template stack, including {@link ItemStack#getComponentChanges()}.
* Note that the count of the stack is ignored.
*
* @see #component(Ingredient, ComponentChanges, boolean)
* @see #components(Ingredient, ComponentChanges)
*/
public static Ingredient component(ItemStack stack, boolean strict) {
public static Ingredient components(ItemStack stack) {
Objects.requireNonNull(stack, "Stack cannot be null");

return component(Ingredient.ofItems(stack.getItem()), stack.getComponentChanges(), strict);
return components(Ingredient.ofItems(stack.getItem()), stack.getComponentChanges());
}

private DefaultCustomIngredients() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import org.jetbrains.annotations.Nullable;

import net.minecraft.component.ComponentChanges;
import net.minecraft.component.DataComponentType;
import net.minecraft.item.ItemStack;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.recipe.Ingredient;
import net.minecraft.util.Identifier;

Expand All @@ -40,29 +42,43 @@ public class ComponentIngredient implements CustomIngredient {

private final Ingredient base;
private final ComponentChanges components;
private final boolean strict;

public ComponentIngredient(Ingredient base, ComponentChanges components, boolean strict) {
if (components.isEmpty() && !strict) {
throw new IllegalArgumentException("ComponentIngredient can only have empty components in strict mode");
public ComponentIngredient(Ingredient base, ComponentChanges components) {
if (components.isEmpty()) {
throw new IllegalArgumentException("ComponentIngredient must have at least one defined component");
}

this.base = base;
this.components = components;
this.strict = strict;
}

@Override
public boolean test(ItemStack stack) {
if (!base.test(stack)) return false;

if (strict) {
return Objects.equals(components, stack.getComponentChanges());
} else {
// TODO 1.20.5
// return NbtHelper.matches(components, stack.getComponentChanges(), true);
return false;
// None strict matching
for (Map.Entry<DataComponentType<?>, Optional<?>> entry : components.entrySet()) {
final DataComponentType<?> type = entry.getKey();
final Optional<?> value = entry.getValue();

if (value.isPresent()) {
// Expect the stack to contain a matching component
if (!stack.contains(type)) {
return false;
}

if (!Objects.equals(value.get(), stack.get(type))) {
return false;
}
} else {
// Expect the target stack to not contain this component
if (stack.contains(type)) {
return false;
}
}
}

return true;
}

@Override
Expand Down Expand Up @@ -98,27 +114,21 @@ private ComponentChanges getComponents() {
return components;
}

private boolean isStrict() {
return strict;
}

private static class Serializer implements CustomIngredientSerializer<ComponentIngredient> {
private static final Identifier ID = new Identifier("fabric", "component");
private static final Codec<ComponentIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
private static final Codec<ComponentIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
private static final PacketCodec<RegistryByteBuf, ComponentIngredient> PACKET_CODEC = PacketCodec.tuple(
Ingredient.PACKET_CODEC, ComponentIngredient::getBase,
ComponentChanges.PACKET_CODEC, ComponentIngredient::getComponents,
PacketCodecs.BOOL, ComponentIngredient::isStrict,
ComponentIngredient::new
);

private static Codec<ComponentIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
return RecordCodecBuilder.create(instance ->
instance.group(
ingredientCodec.fieldOf("base").forGetter(ComponentIngredient::getBase),
ComponentChanges.CODEC.fieldOf("components").forGetter(ComponentIngredient::getComponents),
Codec.BOOL.optionalFieldOf("strict", false).forGetter(ComponentIngredient::isStrict)
ComponentChanges.CODEC.fieldOf("components").forGetter(ComponentIngredient::getComponents)
).apply(instance, ComponentIngredient::new)
);
}
Expand Down
Loading

0 comments on commit 1454e00

Please sign in to comment.