76 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.util.datafix.fixes;
 | |
| 
 | |
| import com.mojang.datafixers.DSL;
 | |
| import com.mojang.datafixers.DataFix;
 | |
| import com.mojang.datafixers.OpticFinder;
 | |
| import com.mojang.datafixers.TypeRewriteRule;
 | |
| import com.mojang.datafixers.Typed;
 | |
| import com.mojang.datafixers.schemas.Schema;
 | |
| import com.mojang.datafixers.types.Type;
 | |
| import com.mojang.datafixers.types.templates.List.ListType;
 | |
| import com.mojang.serialization.Dynamic;
 | |
| import java.util.Optional;
 | |
| import net.minecraft.util.Mth;
 | |
| 
 | |
| public class VillagerRebuildLevelAndXpFix extends DataFix {
 | |
| 	private static final int TRADES_PER_LEVEL = 2;
 | |
| 	private static final int[] LEVEL_XP_THRESHOLDS = new int[]{0, 10, 50, 100, 150};
 | |
| 
 | |
| 	public static int getMinXpPerLevel(int level) {
 | |
| 		return LEVEL_XP_THRESHOLDS[Mth.clamp(level - 1, 0, LEVEL_XP_THRESHOLDS.length - 1)];
 | |
| 	}
 | |
| 
 | |
| 	public VillagerRebuildLevelAndXpFix(Schema outputSchema, boolean changesType) {
 | |
| 		super(outputSchema, changesType);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public TypeRewriteRule makeRule() {
 | |
| 		Type<?> type = this.getInputSchema().getChoiceType(References.ENTITY, "minecraft:villager");
 | |
| 		OpticFinder<?> opticFinder = DSL.namedChoice("minecraft:villager", type);
 | |
| 		OpticFinder<?> opticFinder2 = type.findField("Offers");
 | |
| 		Type<?> type2 = opticFinder2.type();
 | |
| 		OpticFinder<?> opticFinder3 = type2.findField("Recipes");
 | |
| 		ListType<?> listType = (ListType<?>)opticFinder3.type();
 | |
| 		OpticFinder<?> opticFinder4 = listType.getElement().finder();
 | |
| 		return this.fixTypeEverywhereTyped(
 | |
| 			"Villager level and xp rebuild",
 | |
| 			this.getInputSchema().getType(References.ENTITY),
 | |
| 			typed -> typed.updateTyped(
 | |
| 				opticFinder,
 | |
| 				type,
 | |
| 				typedx -> {
 | |
| 					Dynamic<?> dynamic = typedx.get(DSL.remainderFinder());
 | |
| 					int i = dynamic.get("VillagerData").get("level").asInt(0);
 | |
| 					Typed<?> typed2 = typedx;
 | |
| 					if (i == 0 || i == 1) {
 | |
| 						int j = (Integer)typedx.getOptionalTyped(opticFinder2)
 | |
| 							.flatMap(typedxx -> typedxx.getOptionalTyped(opticFinder3))
 | |
| 							.map(typedxx -> typedxx.getAllTyped(opticFinder4).size())
 | |
| 							.orElse(0);
 | |
| 						i = Mth.clamp(j / 2, 1, 5);
 | |
| 						if (i > 1) {
 | |
| 							typed2 = addLevel(typedx, i);
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					Optional<Number> optional = dynamic.get("Xp").asNumber().result();
 | |
| 					if (optional.isEmpty()) {
 | |
| 						typed2 = addXpFromLevel(typed2, i);
 | |
| 					}
 | |
| 
 | |
| 					return typed2;
 | |
| 				}
 | |
| 			)
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	private static Typed<?> addLevel(Typed<?> typed, int level) {
 | |
| 		return typed.update(DSL.remainderFinder(), dynamic -> dynamic.update("VillagerData", dynamicx -> dynamicx.set("level", dynamicx.createInt(level))));
 | |
| 	}
 | |
| 
 | |
| 	private static Typed<?> addXpFromLevel(Typed<?> typed, int xp) {
 | |
| 		int i = getMinXpPerLevel(xp);
 | |
| 		return typed.update(DSL.remainderFinder(), dynamic -> dynamic.set("Xp", dynamic.createInt(i)));
 | |
| 	}
 | |
| }
 |