1.20.1 -> 1.20.2

This commit is contained in:
Sollace 2023-09-29 19:15:04 +01:00
parent 35ac79bf3d
commit 24f1f4bdcd
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
76 changed files with 353 additions and 411 deletions

View file

@ -4,8 +4,7 @@ buildscript {
}
}
plugins {
id 'java-library'
id 'fabric-loom' version '0.12-SNAPSHOT'
id 'fabric-loom' version '1.3-SNAPSHOT'
id 'com.modrinth.minotaur' version '2.+'
id 'org.ajoberstar.reckon' version '0.13.0'
}

View file

@ -3,10 +3,10 @@ org.gradle.daemon=false
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.20.1
yarn_mappings=1.20.1+build.9
loader_version=0.14.21
fabric_version=0.85.0+1.20.1
minecraft_version=1.20.2-rc1
yarn_mappings=1.20.2-rc1+build.2
loader_version=0.14.22
fabric_version=0.88.5+1.20.2
# Mod Properties
group=com.minelittlepony
@ -15,19 +15,19 @@ org.gradle.daemon=false
description=Magical Abilities for Mine Little Pony!
# Publishing
minecraft_version_range=>=1.20.1
minecraft_version_range=>=1.20.2
modrinth_loader_type=fabric
modrinth_project_id=9K7RJlvM
# Dependencies
fabwork_version=1.2.0
modmenu_version=7.0.0-beta.2
minelp_version=4.10.1+1.20
kirin_version=1.15.4+1.20
fabwork_version=1.3.0+1.20.2
modmenu_version=8.0.0-beta.1
minelp_version=4.11.1+1.20.2
kirin_version=1.16.0+1.20.2
reach_attributes_version=2.3.3
trinkets_version=3.7.1
terraformer_api_version=7.0.0-beta.1
trinkets_version=3.8.0
terraformer_api_version=8.0.0-beta.1
# TMI Testing
tmi_type=emi
emi_version=1.0.19+1.20.1
emi_version=1.0.20+1.20.1

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View file

@ -11,7 +11,7 @@ public interface UGameEvents {
static GameEvent register(String name, int range) {
Identifier id = Unicopia.id(name);
return Registry.register(Registries.GAME_EVENT, id, new GameEvent(id.toString(), range));
return Registry.register(Registries.GAME_EVENT, id, new GameEvent(range));
}
static void bootstrap() {

View file

@ -189,12 +189,12 @@ public class UnicornTeleportAbility implements Ability<Pos> {
return state.hasSolidTopSurface(w, pos, player)
|| StatePredicate.isFluid(state)
|| (shape = state.getCollisionShape(w, pos, ShapeContext.of(player))).isEmpty()
|| shape.getBoundingBox().getYLength() > 1;
|| shape.getBoundingBox().getLengthY() > 1;
}
private double getTargetYPosition(World world, BlockPos pos, ShapeContext context) {
VoxelShape shape = world.getBlockState(pos).getCollisionShape(world, pos, context);
return pos.getY() + (shape.isEmpty() ? 0 : shape.getBoundingBox().getYLength());
return pos.getY() + (shape.isEmpty() ? 0 : shape.getBoundingBox().getLengthY());
}
@Override

View file

@ -6,20 +6,45 @@ import java.util.function.Predicate;
import org.jetbrains.annotations.Nullable;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.item.EnchantableItem;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Decoder;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.Encoder;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.Ingredient;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.collection.DefaultedList;
public class IngredientWithSpell implements Predicate<ItemStack> {
private static final IngredientWithSpell EMPTY = new IngredientWithSpell();
private static final Predicate<Ingredient> INGREDIENT_IS_PRESENT = ((Predicate<Ingredient>)(Ingredient::isEmpty)).negate();
public static final Codec<IngredientWithSpell> CODEC = Codec.of(new Encoder<IngredientWithSpell>() {
@Override
public <T> DataResult<T> encode(IngredientWithSpell input, DynamicOps<T> ops, T prefix) {
throw new JsonParseException("cannot serialize this type");
}
}, new Decoder<IngredientWithSpell>() {
@Override
public <T> DataResult<Pair<IngredientWithSpell, T>> decode(DynamicOps<T> ops, T input) {
// TODO: Doing codecs properly is an exercise left to the readers
DataResult<Pair<Ingredient, T>> stack = Ingredient.ALLOW_EMPTY_CODEC.decode(ops, input);
IngredientWithSpell ingredient = new IngredientWithSpell();
ingredient.stack = stack.result().map(Pair::getFirst);
ingredient.spell = Optional.ofNullable(((com.mojang.serialization.MapLike)input).get("Spell")).flatMap(unserializedSpell -> {
return SpellType.REGISTRY.getCodec().parse((DynamicOps)ops, unserializedSpell).result();
});
return DataResult.success(new Pair<>(ingredient, null));
}
});
public static final Codec<DefaultedList<IngredientWithSpell>> LIST_CODEC = CODEC.listOf().xmap(list -> {
return DefaultedList.<IngredientWithSpell>copyOf(EMPTY, list.toArray(IngredientWithSpell[]::new));
}, a -> a);
private Optional<Ingredient> stack = Optional.empty();
private Optional<SpellType<?>> spell = Optional.empty();
@ -62,24 +87,4 @@ public class IngredientWithSpell implements Predicate<ItemStack> {
ingredient.spell = buf.readOptional(PacketByteBuf::readIdentifier).flatMap(SpellType.REGISTRY::getOrEmpty);
return ingredient;
}
public static IngredientWithSpell fromJson(JsonElement json) {
IngredientWithSpell ingredient = new IngredientWithSpell();
ingredient.stack = Optional.ofNullable(Ingredient.fromJson(json));
if (json.isJsonObject() && json.getAsJsonObject().has("spell")) {
ingredient.spell = SpellType.REGISTRY.getOrEmpty(Identifier.tryParse(JsonHelper.getString(json.getAsJsonObject(), "spell")));
}
return ingredient;
}
public static DefaultedList<IngredientWithSpell> fromJson(JsonArray json) {
DefaultedList<IngredientWithSpell> ingredients = DefaultedList.of();
for (int i = 0; i < json.size(); i++) {
IngredientWithSpell ingredient = fromJson(json.get(i));
if (ingredient.isEmpty()) continue;
ingredients.add(ingredient);
}
return ingredients;
}
}

View file

@ -2,9 +2,9 @@ package com.minelittlepony.unicopia.ability.magic.spell.crafting;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import com.google.gson.JsonObject;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
import com.minelittlepony.unicopia.container.inventory.SpellbookInventory;
@ -12,14 +12,15 @@ import com.minelittlepony.unicopia.item.EnchantableItem;
import com.minelittlepony.unicopia.item.URecipes;
import com.minelittlepony.unicopia.util.InventoryUtil;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.RecipeCodecs;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.ShapedRecipe;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.world.World;
@ -27,30 +28,27 @@ import net.minecraft.world.World;
* A recipe for creating a new spell from input traits and items.
*/
public class SpellCraftingRecipe implements SpellbookRecipe {
private final Identifier id;
/**
* The ingredient to modify
*/
private final IngredientWithSpell material;
final IngredientWithSpell material;
/**
* The required traits
*/
private final TraitIngredient requiredTraits;
final TraitIngredient requiredTraits;
/**
* Items required for crafting.
*/
private final List<IngredientWithSpell> requiredItems;
final List<IngredientWithSpell> requiredItems;
/**
* The resulting item
*/
private final ItemStack output;
final ItemStackWithSpell output;
private SpellCraftingRecipe(Identifier id, IngredientWithSpell material, TraitIngredient requiredTraits, List<IngredientWithSpell> requiredItems, ItemStack output) {
this.id = id;
private SpellCraftingRecipe(IngredientWithSpell material, TraitIngredient requiredTraits, List<IngredientWithSpell> requiredItems, ItemStackWithSpell output) {
this.material = material;
this.requiredTraits = requiredTraits;
this.requiredItems = requiredItems;
@ -66,7 +64,7 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
requiredTraits.min().ifPresent(min -> {
min.forEach(e -> builder.input(e.getKey(), e.getValue()));
});
builder.result(output);
builder.result(output.toItemStack());
}
@Override
@ -108,7 +106,7 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
@Override
public ItemStack craft(SpellbookInventory inventory, DynamicRegistryManager registries) {
return getOutput(registries).copy();
return getResult(registries).copy();
}
@Override
@ -117,13 +115,8 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
}
@Override
public ItemStack getOutput(DynamicRegistryManager registries) {
return output;
}
@Override
public Identifier getId() {
return id;
public ItemStack getResult(DynamicRegistryManager registries) {
return output.toItemStack();
}
@Override
@ -131,35 +124,43 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
return URecipes.TRAIT_REQUIREMENT;
}
public static ItemStack outputFromJson(JsonObject json) {
ItemStack stack = ShapedRecipe.outputFromJson(json);
SpellTraits.fromJson(JsonHelper.getObject(json, "traits", new JsonObject()))
.map(traits -> traits.applyTo(stack)).orElse(stack);
record ItemStackWithSpell(ItemStack stack, Optional<SpellType<?>> spell) {
public static final Codec<ItemStackWithSpell> CODEC = RecordCodecBuilder.create(instance -> instance.group(
RecipeCodecs.CRAFTING_RESULT.fieldOf("stack").forGetter(ItemStackWithSpell::stack),
SpellType.REGISTRY.getCodec().optionalFieldOf("spell").forGetter(ItemStackWithSpell::spell)
).apply(instance, ItemStackWithSpell::new));
SpellType<?> spell = SpellType.getKey(Identifier.tryParse(JsonHelper.getString(json, "spell", "")));
if (spell != SpellType.EMPTY_KEY) {
return EnchantableItem.enchant(stack, spell);
public ItemStack toItemStack() {
return spell.filter(s -> s != SpellType.EMPTY_KEY).map(s -> {
return EnchantableItem.enchant(stack.copy(), s);
}).orElse(stack);
}
public ItemStackWithSpell(ItemStack stack) {
this(EnchantableItem.unenchant(stack), Optional.of(EnchantableItem.getSpellKey(stack)));
}
return stack;
}
public static class Serializer implements RecipeSerializer<SpellCraftingRecipe> {
private static final Codec<SpellCraftingRecipe> CODEC = RecordCodecBuilder.<SpellCraftingRecipe>create(instance -> instance.group(
IngredientWithSpell.CODEC.fieldOf("material").forGetter(recipe -> recipe.material),
((MapCodec<TraitIngredient>)null).forGetter(recipe -> recipe.requiredTraits),
IngredientWithSpell.CODEC.listOf().fieldOf("ingredients").forGetter(recipe -> recipe.requiredItems),
ItemStackWithSpell.CODEC.fieldOf("result").forGetter(recipe -> recipe.output)
).apply(instance, SpellCraftingRecipe::new));
@Override
public SpellCraftingRecipe read(Identifier id, JsonObject json) {
return new SpellCraftingRecipe(id,
IngredientWithSpell.fromJson(json.get("material")),
TraitIngredient.fromJson(JsonHelper.getObject(json, "traits")),
IngredientWithSpell.fromJson(JsonHelper.asArray(json.get("ingredients"), "ingredients")),
outputFromJson(JsonHelper.getObject(json, "result")));
public Codec<SpellCraftingRecipe> codec() {
return CODEC;
}
@Override
public SpellCraftingRecipe read(Identifier id, PacketByteBuf buf) {
return new SpellCraftingRecipe(id,
public SpellCraftingRecipe read(PacketByteBuf buf) {
return new SpellCraftingRecipe(
IngredientWithSpell.fromPacket(buf),
TraitIngredient.fromPacket(buf),
buf.readCollection(DefaultedList::ofSize, IngredientWithSpell::fromPacket),
buf.readItemStack()
new ItemStackWithSpell(buf.readItemStack())
);
}
@ -168,7 +169,7 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
recipe.material.write(buf);
recipe.requiredTraits.write(buf);
buf.writeCollection(recipe.requiredItems, (b, i) -> i.write(b));
buf.writeItemStack(recipe.output);
buf.writeItemStack(recipe.output.toItemStack());
}
}
}

View file

@ -1,28 +1,25 @@
package com.minelittlepony.unicopia.ability.magic.spell.crafting;
import com.google.gson.JsonObject;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.container.inventory.SpellbookInventory;
import com.minelittlepony.unicopia.item.*;
import com.minelittlepony.unicopia.util.InventoryUtil;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
/**
* A recipe for creating a new spell from input traits and items.
*/
public class SpellDuplicatingRecipe implements SpellbookRecipe {
private final Identifier id;
final IngredientWithSpell material;
private final IngredientWithSpell material;
private SpellDuplicatingRecipe(Identifier id, IngredientWithSpell material) {
this.id = id;
private SpellDuplicatingRecipe(IngredientWithSpell material) {
this.material = material;
}
@ -72,31 +69,30 @@ public class SpellDuplicatingRecipe implements SpellbookRecipe {
}
@Override
public ItemStack getOutput(DynamicRegistryManager registries) {
public ItemStack getResult(DynamicRegistryManager registries) {
ItemStack stack = UItems.GEMSTONE.getDefaultStack();
stack.setCount(2);
return stack;
}
@Override
public Identifier getId() {
return id;
}
@Override
public RecipeSerializer<?> getSerializer() {
return URecipes.SPELL_DUPLICATING;
}
public static class Serializer implements RecipeSerializer<SpellDuplicatingRecipe> {
private static final Codec<SpellDuplicatingRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
IngredientWithSpell.CODEC.fieldOf("material").forGetter(recipe -> recipe.material)
).apply(instance, SpellDuplicatingRecipe::new));
@Override
public SpellDuplicatingRecipe read(Identifier id, JsonObject json) {
return new SpellDuplicatingRecipe(id, IngredientWithSpell.fromJson(json.get("material")));
public Codec<SpellDuplicatingRecipe> codec() {
return CODEC;
}
@Override
public SpellDuplicatingRecipe read(Identifier id, PacketByteBuf buf) {
return new SpellDuplicatingRecipe(id, IngredientWithSpell.fromPacket(buf));
public SpellDuplicatingRecipe read(PacketByteBuf buf) {
return new SpellDuplicatingRecipe(IngredientWithSpell.fromPacket(buf));
}
@Override

View file

@ -1,27 +1,24 @@
package com.minelittlepony.unicopia.ability.magic.spell.crafting;
import com.google.gson.JsonObject;
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
import com.minelittlepony.unicopia.container.inventory.SpellbookInventory;
import com.minelittlepony.unicopia.item.*;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
/**
* Recipe for adding traits to an existing spell.
*/
public class SpellEnhancingRecipe implements SpellbookRecipe {
private final Identifier id;
final IngredientWithSpell material;
private final IngredientWithSpell material;
private SpellEnhancingRecipe(Identifier id, IngredientWithSpell material) {
this.id = id;
private SpellEnhancingRecipe(IngredientWithSpell material) {
this.material = material;
}
@ -58,29 +55,28 @@ public class SpellEnhancingRecipe implements SpellbookRecipe {
}
@Override
public ItemStack getOutput(DynamicRegistryManager registries) {
public ItemStack getResult(DynamicRegistryManager registries) {
return UItems.GEMSTONE.getDefaultStack();
}
@Override
public Identifier getId() {
return id;
}
@Override
public RecipeSerializer<?> getSerializer() {
return URecipes.TRAIT_COMBINING;
}
public static class Serializer implements RecipeSerializer<SpellEnhancingRecipe> {
private static final Codec<SpellEnhancingRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
IngredientWithSpell.CODEC.fieldOf("material").forGetter(recipe -> recipe.material)
).apply(instance, SpellEnhancingRecipe::new));
@Override
public SpellEnhancingRecipe read(Identifier id, JsonObject json) {
return new SpellEnhancingRecipe(id, IngredientWithSpell.fromJson(json.get("material")));
public Codec<SpellEnhancingRecipe> codec() {
return CODEC;
}
@Override
public SpellEnhancingRecipe read(Identifier id, PacketByteBuf buf) {
return new SpellEnhancingRecipe(id, IngredientWithSpell.fromPacket(buf));
public SpellEnhancingRecipe read(PacketByteBuf buf) {
return new SpellEnhancingRecipe(IngredientWithSpell.fromPacket(buf));
}
@Override

View file

@ -1,9 +1,11 @@
package com.minelittlepony.unicopia.ability.magic.spell.crafting;
import com.google.gson.JsonObject;
import java.util.function.Function;
import com.minelittlepony.unicopia.item.EnchantableItem;
import com.minelittlepony.unicopia.item.URecipes;
import com.minelittlepony.unicopia.util.InventoryUtil;
import com.mojang.serialization.Codec;
import net.minecraft.inventory.RecipeInputInventory;
import net.minecraft.item.ItemStack;
@ -11,12 +13,11 @@ import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.ShapedRecipe;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
public class SpellShapedCraftingRecipe extends ShapedRecipe {
public SpellShapedCraftingRecipe(ShapedRecipe recipe) {
super(recipe.getId(), recipe.getGroup(), recipe.getCategory(), recipe.getWidth(), recipe.getHeight(), recipe.getIngredients(), recipe.getOutput(null));
super(recipe.getGroup(), recipe.getCategory(), recipe.getWidth(), recipe.getHeight(), recipe.getIngredients(), recipe.getResult(null));
}
@Override
@ -37,13 +38,13 @@ public class SpellShapedCraftingRecipe extends ShapedRecipe {
public static class Serializer extends ShapedRecipe.Serializer {
@Override
public ShapedRecipe read(Identifier id, JsonObject json) {
return new SpellShapedCraftingRecipe(super.read(id, json));
public Codec<ShapedRecipe> codec() {
return super.codec().xmap(SpellShapedCraftingRecipe::new, Function.identity());
}
@Override
public ShapedRecipe read(Identifier id, PacketByteBuf buffer) {
return new SpellShapedCraftingRecipe(super.read(id, buffer));
public ShapedRecipe read(PacketByteBuf buffer) {
return new SpellShapedCraftingRecipe(super.read(buffer));
}
}
}

View file

@ -143,7 +143,7 @@ public class BubbleSpell extends AbstractSpell implements TimedSpell,
if (source.asEntity() instanceof LivingEntity l) {
MODIFIERS.forEach((attribute, modifier) -> {
if (l.getAttributes().hasAttribute(attribute)) {
l.getAttributeInstance(attribute).removeModifier(modifier);
l.getAttributeInstance(attribute).tryRemoveModifier(modifier.getId());
}
});
}

View file

@ -7,6 +7,7 @@ import java.util.stream.Stream;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.command.CommandArgumentEnum;
import com.mojang.serialization.Codec;
import net.minecraft.command.argument.EnumArgumentType;
import net.minecraft.item.Item;
@ -165,7 +166,6 @@ public enum Trait implements CommandArgumentEnum<Trait> {
}
public static final class ArgumentType extends EnumArgumentType<Trait> {
@SuppressWarnings("deprecation")
static final Codec<Trait> CODEC = StringIdentifiable.createCodec(Trait::values);
protected ArgumentType() {

View file

@ -1,32 +1,23 @@
package com.minelittlepony.unicopia.advancement;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.google.gson.JsonObject;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.entity.Entity;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer;
import net.minecraft.predicate.entity.LootContextPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
public class CustomEventCriterion extends AbstractCriterion<CustomEventCriterion.Conditions> {
private static final Identifier ID = Unicopia.id("custom");
@Override
public Identifier getId() {
return ID;
}
@Override
protected Conditions conditionsFromJson(JsonObject json, LootContextPredicate playerPredicate, AdvancementEntityPredicateDeserializer deserializer) {
protected Conditions conditionsFromJson(JsonObject json, Optional<LootContextPredicate> playerPredicate, AdvancementEntityPredicateDeserializer deserializer) {
return new Conditions(
playerPredicate,
JsonHelper.getString(json, "event"),
@ -59,8 +50,8 @@ public class CustomEventCriterion extends AbstractCriterion<CustomEventCriterion
private final int repeatCount;
public Conditions(LootContextPredicate playerPredicate, String event, RacePredicate races, Boolean flying, int repeatCount) {
super(ID, playerPredicate);
public Conditions(Optional<LootContextPredicate> playerPredicate, String event, RacePredicate races, Boolean flying, int repeatCount) {
super(playerPredicate);
this.event = event;
this.races = races;
this.flying = flying;
@ -75,8 +66,8 @@ public class CustomEventCriterion extends AbstractCriterion<CustomEventCriterion
}
@Override
public JsonObject toJson(AdvancementEntityPredicateSerializer serializer) {
JsonObject json = super.toJson(serializer);
public JsonObject toJson() {
JsonObject json = super.toJson();
json.addProperty("event", event);
json.add("race", races.toJson());
if (flying != null) {

View file

@ -1,31 +1,23 @@
package com.minelittlepony.unicopia.advancement;
import java.util.Optional;
import com.google.gson.JsonObject;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer;
import net.minecraft.predicate.entity.LootContextPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
public class RaceChangeCriterion extends AbstractCriterion<RaceChangeCriterion.Conditions> {
private static final Identifier ID = Unicopia.id("player_change_race");
@Override
public Identifier getId() {
return ID;
}
@Override
protected Conditions conditionsFromJson(JsonObject json, LootContextPredicate playerPredicate, AdvancementEntityPredicateDeserializer deserializer) {
protected Conditions conditionsFromJson(JsonObject json, Optional<LootContextPredicate> playerPredicate, AdvancementEntityPredicateDeserializer deserializer) {
return new Conditions(playerPredicate, Race.fromName(JsonHelper.getString(json, "race"), Race.EARTH));
}
@ -38,8 +30,8 @@ public class RaceChangeCriterion extends AbstractCriterion<RaceChangeCriterion.C
public static class Conditions extends AbstractCriterionConditions {
private final Race race;
public Conditions(LootContextPredicate playerPredicate, Race race) {
super(ID, playerPredicate);
public Conditions(Optional<LootContextPredicate> playerPredicate, Race race) {
super(playerPredicate);
this.race = race;
}
@ -48,8 +40,8 @@ public class RaceChangeCriterion extends AbstractCriterion<RaceChangeCriterion.C
}
@Override
public JsonObject toJson(AdvancementEntityPredicateSerializer serializer) {
JsonObject json = super.toJson(serializer);
public JsonObject toJson() {
JsonObject json = super.toJson();
json.addProperty("race", Race.REGISTRY.getId(race).toString());
return json;

View file

@ -4,7 +4,6 @@ import java.util.Optional;
import java.util.function.BiConsumer;
import com.google.gson.JsonObject;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.fabricmc.fabric.api.util.TriState;
@ -14,25 +13,16 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer;
import net.minecraft.predicate.entity.LootContextPredicate;
import net.minecraft.predicate.item.ItemPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.TypeFilter;
public class SendViaDragonBreathScrollCriterion extends AbstractCriterion<SendViaDragonBreathScrollCriterion.Conditions> {
private static final Identifier ID = Unicopia.id("send_dragon_breath");
@Override
public Identifier getId() {
return ID;
}
@Override
protected Conditions conditionsFromJson(JsonObject json, LootContextPredicate playerPredicate, AdvancementEntityPredicateDeserializer deserializer) {
protected Conditions conditionsFromJson(JsonObject json, Optional<LootContextPredicate> playerPredicate, AdvancementEntityPredicateDeserializer deserializer) {
return new Conditions(playerPredicate,
ItemPredicate.fromJson(json.get("item")),
JsonHelper.getBoolean(json, "is_receiving_end", false),
@ -64,15 +54,15 @@ public class SendViaDragonBreathScrollCriterion extends AbstractCriterion<SendVi
}
public static class Conditions extends AbstractCriterionConditions {
private final ItemPredicate item;
private final Optional<ItemPredicate> item;
private final boolean isReceivingEnd;
private final Optional<String> recipientName;
private final TriState recipientPresent;
private final Optional<String> counter;
private final RacePredicate races;
public Conditions(LootContextPredicate playerPredicate, ItemPredicate item, boolean isReceivingEnd, Optional<String> recipient, TriState recipientPresent, Optional<String> counter, RacePredicate races) {
super(ID, playerPredicate);
public Conditions(Optional<LootContextPredicate> playerPredicate, Optional<ItemPredicate> item, boolean isReceivingEnd, Optional<String> recipient, TriState recipientPresent, Optional<String> counter, RacePredicate races) {
super(playerPredicate);
this.item = item;
this.isReceivingEnd = isReceivingEnd;
this.recipientName = recipient;
@ -84,7 +74,7 @@ public class SendViaDragonBreathScrollCriterion extends AbstractCriterion<SendVi
public boolean test(ServerPlayerEntity player, ItemStack payload, String recipient, boolean receiving) {
return isReceivingEnd == receiving
&& races.test(player)
&& item.test(payload)
&& (item.isEmpty() || item.get().test(payload))
&& recipientName.map(expectedRecipientname -> recipient.equalsIgnoreCase(expectedRecipientname)).orElse(true)
&& (recipientPresent == TriState.DEFAULT || isRecipientAbsent(player.getServerWorld(), recipient) != recipientPresent.get());
}
@ -94,9 +84,9 @@ public class SendViaDragonBreathScrollCriterion extends AbstractCriterion<SendVi
}
@Override
public JsonObject toJson(AdvancementEntityPredicateSerializer serializer) {
JsonObject json = super.toJson(serializer);
json.add("item", item.toJson());
public JsonObject toJson() {
JsonObject json = super.toJson();
item.ifPresent(item -> json.add("item", item.toJson()));
json.add("race", races.toJson());
recipientName.ifPresent(recipient -> json.addProperty("recipient_name", recipient));
if (recipientPresent != TriState.DEFAULT) {

View file

@ -3,9 +3,9 @@ package com.minelittlepony.unicopia.advancement;
import net.minecraft.advancement.criterion.Criteria;
public interface UCriteria {
CustomEventCriterion CUSTOM_EVENT = Criteria.register(new CustomEventCriterion());
RaceChangeCriterion PLAYER_CHANGE_RACE = Criteria.register(new RaceChangeCriterion());
SendViaDragonBreathScrollCriterion SEND_DRAGON_BREATH = Criteria.register(new SendViaDragonBreathScrollCriterion());
CustomEventCriterion CUSTOM_EVENT = Criteria.register("unicopia:send_dragon_breath", new CustomEventCriterion());
RaceChangeCriterion PLAYER_CHANGE_RACE = Criteria.register("unicopia:player_change_race", new RaceChangeCriterion());
SendViaDragonBreathScrollCriterion SEND_DRAGON_BREATH = Criteria.register("unicopia:custom", new SendViaDragonBreathScrollCriterion());
CustomEventCriterion.Trigger LOOK_INTO_SUN = CUSTOM_EVENT.createTrigger("look_into_sun");
CustomEventCriterion.Trigger WEAR_SHADES = CUSTOM_EVENT.createTrigger("wear_shades");

View file

@ -96,11 +96,11 @@ public class RockCropBlock extends CropBlock {
}
@Override
public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state, boolean isClient) {
public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state) {
if (world instanceof World && !canGrow((World)world, ((World)world).random, pos, state)) {
return false;
}
return super.isFertilizable(world, pos, state, isClient);
return super.isFertilizable(world, pos, state);
}
@Override

View file

@ -170,8 +170,8 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock {
}
@Override
public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state, boolean isClient) {
if (super.isFertilizable(world, pos, state, isClient)) {
public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state) {
if (super.isFertilizable(world, pos, state)) {
return true;
}
@ -181,7 +181,7 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock {
pos = pos.up();
state = world.getBlockState(pos);
return state.isAir() || (isNext(state) && state.getBlock() instanceof Fertilizable f && f.isFertilizable(world, pos, state, isClient));
return state.isAir() || (isNext(state) && state.getBlock() instanceof Fertilizable f && f.isFertilizable(world, pos, state));
}
@Override

View file

@ -43,7 +43,7 @@ public class WeatherVaneBlock extends BlockWithEntity {
@Override
@Nullable
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return BellBlock.checkType(type, UBlockEntities.WEATHER_VANE, world.isClient ? WeatherVane::clientTick : WeatherVane::serverTick);
return validateTicker(type, UBlockEntities.WEATHER_VANE, world.isClient ? WeatherVane::clientTick : WeatherVane::serverTick);
}
public static class WeatherVane extends BlockEntity {

View file

@ -11,6 +11,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.SlabBlock;
import net.minecraft.block.enums.SlabType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.item.ItemPlacementContext;
@ -92,7 +93,7 @@ public class CloudSlabBlock extends WaterloggableCloudBlock {
}
@Override
public boolean canFillWithFluid(BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
return state.get(SlabBlock.TYPE) != SlabType.DOUBLE && super.canFillWithFluid(world, pos, state, fluid);
public boolean canFillWithFluid(PlayerEntity player, BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
return state.get(SlabBlock.TYPE) != SlabType.DOUBLE && super.canFillWithFluid(player, world, pos, state, fluid);
}
}

View file

@ -17,6 +17,7 @@ import net.minecraft.util.Identifier;
public class DiscoveryToast implements Toast {
private static final long MAX_AGE = 5000L;
private static final Identifier TEXTURE = new Identifier("toast/advancement");
private static final Text TITLE = Text.translatable("unicopia.toast.discoveries.title");
private static final Text DESCRIPTION = Text.translatable("unicopia.toast.discoveries.description");
@ -39,7 +40,7 @@ public class DiscoveryToast implements Toast {
RenderSystem.setShader(GameRenderer::getPositionTexProgram);
RenderSystem.setShaderColor(1.0F, 1, 1, 1);
context.drawTexture(TEXTURE, 0, 0, 0, 32, getWidth(), getHeight());
context.drawGuiTexture(TEXTURE, 0, 0, getWidth(), getHeight());
context.drawText(manager.getClient().textRenderer, TITLE, 30, 7, -11534256, false);
context.drawText(manager.getClient().textRenderer, DESCRIPTION, 30, 18, -16777216, false);

View file

@ -136,7 +136,6 @@ public class LanSettingsScreen extends GameGui {
@Override
public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) {
renderBackground(context);
super.render(context, mouseX, mouseY, tickDelta);
content.render(context, mouseX, mouseY, tickDelta);
}

View file

@ -106,7 +106,6 @@ public class SettingsScreen extends GameGui {
@Override
public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) {
renderBackground(context);
super.render(context, mouseX, mouseY, tickDelta);
content.render(context, mouseX, mouseY, tickDelta);
}

View file

@ -67,7 +67,7 @@ public class TribeButton extends Button {
getStyle().setIcon(ISprite.EMPTY);
renderForground(context, mc, mouseX, mouseY, foreColor | MathHelper.ceil(alpha * 255.0F) << 24);
renderForeground(context, mc, mouseX, mouseY, foreColor | MathHelper.ceil(alpha * 255.0F) << 24);
getStyle().setIcon(icon);
}

View file

@ -81,8 +81,8 @@ public class TribeConfirmationScreen extends GameGui implements HidesHud {
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
renderBackground(context);
public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) {
super.renderBackground(context, mouseX, mouseY, delta);
final int columnHeight = 180;
final int columnWidth = 310;
@ -110,8 +110,6 @@ public class TribeConfirmationScreen extends GameGui implements HidesHud {
context.drawTexture(TribeSelectionScreen.TEXTURE, left - 35, top, 10, 70, 69, 50);
context.drawTexture(TribeSelectionScreen.TEXTURE, left + 35, top, 148, 70, 21, 50);
super.render(context, mouseX, mouseY, delta);
}
@Override

View file

@ -10,7 +10,6 @@ import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgRequestSpeciesChange;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
@ -92,12 +91,6 @@ public class TribeSelectionScreen extends GameGui implements HidesHud {
}).setEnabled(allowedRaces.contains(race));
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
renderBackground(context);
super.render(context, mouseX, mouseY, delta);
}
@Override
public void finish() {
finished = true;

View file

@ -11,6 +11,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
@ -71,10 +72,10 @@ public class SpellbookCraftingPageContent extends ScrollContainer implements Spe
if (state.getOffset() == 1) {
int top = 0;
for (SpellbookRecipe recipe : this.client.world.getRecipeManager().listAllOfType(URecipes.SPELLBOOK)) {
for (RecipeEntry<SpellbookRecipe> recipe : this.client.world.getRecipeManager().listAllOfType(URecipes.SPELLBOOK)) {
if (client.player.getRecipeBook().contains(recipe)) {
IngredientTree tree = new IngredientTree(0, top, width - verticalScrollbar.getBounds().width + 2);
recipe.buildCraftingTree(tree);
recipe.value().buildCraftingTree(tree);
top += tree.build(this);
}
}

View file

@ -149,7 +149,6 @@ public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> imple
@Override
protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
renderBackground(context);
RenderSystem.setShaderColor(1, 1, 1, 1);
context.drawTexture(TEXTURE, x, y, 0, 0, backgroundWidth, backgroundHeight, 512, 256);

View file

@ -8,6 +8,7 @@ import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.client.MinecraftClient;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.util.Identifier;
record Recipe (DynamicContent.Page page, Identifier id, Bounds bounds) implements PageElement {
@ -17,7 +18,7 @@ record Recipe (DynamicContent.Page page, Identifier id, Bounds bounds) implement
bounds().left = book.getX();
bounds().top = book.getY();
}
MinecraftClient.getInstance().world.getRecipeManager().get(id).ifPresent(recipe -> {
MinecraftClient.getInstance().world.getRecipeManager().get(id).map(RecipeEntry::value).ifPresent(recipe -> {
if (recipe instanceof SpellbookRecipe spellRecipe) {
boolean needsMoreXp = page.getLevel() < 0 || Pony.of(MinecraftClient.getInstance().player).getLevel().get() < page.getLevel();

View file

@ -5,9 +5,8 @@ import java.util.Map;
import java.util.UUID;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel;
import com.minelittlepony.api.model.gear.IGear;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer.AmuletModel;
import com.minelittlepony.unicopia.item.AmuletItem;
@ -21,7 +20,7 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
import net.minecraft.registry.Registries;
class AmuletGear extends AmuletModel implements IGear {
class AmuletGear extends AmuletModel implements Gear {
private final Map<Identifier, Identifier> textures = new HashMap<>();
@ -30,7 +29,7 @@ class AmuletGear extends AmuletModel implements IGear {
}
@Override
public boolean canRender(IModel model, Entity entity) {
public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity living && !AmuletItem.getForEntity(living).isEmpty();
}
@ -45,14 +44,14 @@ class AmuletGear extends AmuletModel implements IGear {
}
@Override
public <M extends EntityModel<?> & IPonyModel<?>> void transform(M model, MatrixStack matrices) {
public <M extends EntityModel<?> & PonyModel<?>> void transform(M model, MatrixStack matrices) {
BodyPart part = getGearLocation();
model.transform(part, matrices);
matrices.translate(0, 0.25, 0);
}
@Override
public void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
if (model instanceof BipedEntityModel<?> biped) {
setAngles((LivingEntity)entity, biped);
}

View file

@ -3,9 +3,8 @@ package com.minelittlepony.unicopia.client.minelittlepony;
import java.util.UUID;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel;
import com.minelittlepony.api.model.gear.IGear;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.common.util.Color;
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer.BraceletModel;
@ -18,6 +17,7 @@ import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.util.SkinTextures.Model;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
@ -25,7 +25,7 @@ import net.minecraft.item.DyeableItem;
import net.minecraft.util.Arm;
import net.minecraft.util.Identifier;
class BangleGear implements IGear {
class BangleGear implements Gear {
private boolean glowing;
private int color;
private boolean alex;
@ -43,7 +43,7 @@ class BangleGear implements IGear {
}
@Override
public boolean canRender(IModel model, Entity entity) {
public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity living && FriendshipBraceletItem.getWornBangles(living, slot).findFirst().isPresent();
}
@ -58,14 +58,14 @@ class BangleGear implements IGear {
}
@Override
public <M extends EntityModel<?> & IPonyModel<?>> void transform(M model, MatrixStack matrices) {
public <M extends EntityModel<?> & PonyModel<?>> void transform(M model, MatrixStack matrices) {
BodyPart part = getGearLocation();
model.transform(part, matrices);
}
@Override
public void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getModel().startsWith("slim");
public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).method_52814().model() == Model.SLIM;
FriendshipBraceletItem.getWornBangles((LivingEntity)entity, slot).findFirst().ifPresent(bracelet -> {
color = ((DyeableItem)bracelet.getItem()).getColor(bracelet);
glowing = ((GlowableItem)bracelet.getItem()).isGlowing(bracelet);

View file

@ -5,7 +5,7 @@ import java.util.function.Function;
import java.util.function.Predicate;
import com.minelittlepony.api.model.*;
import com.minelittlepony.api.model.gear.IGear;
import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.PlayerModelKey;
@ -26,7 +26,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel> implements IGear {
class BodyPartGear<M extends ClientPonyModel<LivingEntity>> implements Gear {
private static final Predicate<LivingEntity> MINE_LP_HAS_NO_WINGS = e -> !MineLPDelegate.getInstance().getRace(e).canFly();
private static final Predicate<LivingEntity> MINE_LP_HAS_NO_HORN = e -> !MineLPDelegate.getInstance().getRace(e).canCast();
@ -56,11 +56,11 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
}
public static BodyPartGear<WingsGearModel> batWings() {
return new BodyPartGear<>(BodyPart.BODY, ModelType.BAT_PONY, BAT_WINGS_PREDICATE, WingsGearModel::new, IPegasus::getWings, e -> BAT_WINGS);
return new BodyPartGear<>(BodyPart.BODY, ModelType.BAT_PONY, BAT_WINGS_PREDICATE, WingsGearModel::new, WingedPonyModel::getWings, e -> BAT_WINGS);
}
public static BodyPartGear<BugWingsGearModel> bugWings() {
return new BodyPartGear<>(BodyPart.BODY, ModelType.CHANGELING, BUG_WINGS_PREDICATE, BugWingsGearModel::new, IPegasus::getWings, e -> BUG_WINGS);
return new BodyPartGear<>(BodyPart.BODY, ModelType.CHANGELING, BUG_WINGS_PREDICATE, BugWingsGearModel::new, WingedPonyModel::getWings, e -> BUG_WINGS);
}
public static BodyPartGear<HornGearModel> unicornHorn() {
@ -69,7 +69,7 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
private final M model;
private final Predicate<LivingEntity> renderTargetPredicate;
private final IPart part;
private final SubModel part;
private final Function<Entity, Identifier> textureSupplier;
private final BodyPart gearLocation;
@ -78,7 +78,7 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
PlayerModelKey<LivingEntity, ? super M> modelKey,
Predicate<LivingEntity> renderTargetPredicate,
MsonModel.Factory<M> modelFactory,
Function<? super M, IPart> partExtractor,
Function<? super M, SubModel> partExtractor,
Function<Entity, Identifier> textureSupplier) {
this.gearLocation = gearLocation;
this.model = modelKey.steveKey().createModel(modelFactory);
@ -93,7 +93,7 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
}
@Override
public boolean canRender(IModel model, Entity entity) {
public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity l
&& MineLPDelegate.getInstance().getRace(entity).isEquine()
&& renderTargetPredicate.test(l);
@ -106,7 +106,7 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
((ClientPonyModel)model).copyAttributes(this.model);
part.setPartAngles(this.model.getAttributes(), move, swing, bodySwing, ticks);
}
@ -120,22 +120,12 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
public WingsGearModel(ModelPart tree) {
super(tree, false);
}
@Override
public boolean canFly() {
return true;
}
}
static final class BugWingsGearModel extends ChangelingModel<LivingEntity> {
public BugWingsGearModel(ModelPart tree) {
super(tree, false);
}
@Override
public boolean canFly() {
return true;
}
}
static final class HornGearModel extends UnicornModel<LivingEntity> {
@ -143,11 +133,6 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
super(tree, false);
}
@Override
public boolean canFly() {
return true;
}
public UnicornHorn getHorn() {
return horn;
}

View file

@ -5,8 +5,8 @@ import java.util.Map;
import java.util.UUID;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel;
import com.minelittlepony.api.model.gear.IGear;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.unicopia.client.render.GlassesFeatureRenderer.GlassesModel;
import com.minelittlepony.unicopia.item.GlassesItem;
@ -18,7 +18,7 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
import net.minecraft.registry.Registries;
class GlassesGear extends GlassesModel implements IGear {
class GlassesGear extends GlassesModel implements Gear {
private final Map<Identifier, Identifier> textures = new HashMap<>();
@ -27,7 +27,7 @@ class GlassesGear extends GlassesModel implements IGear {
}
@Override
public boolean canRender(IModel model, Entity entity) {
public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity living && !GlassesItem.getForEntity(living).isEmpty();
}

View file

@ -3,9 +3,8 @@ package com.minelittlepony.unicopia.client.minelittlepony;
import java.util.UUID;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel;
import com.minelittlepony.api.model.gear.IGear;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.unicopia.client.render.HeldEntityFeatureRenderer;
import net.minecraft.client.MinecraftClient;
@ -16,7 +15,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements IGear {
class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements Gear {
private LivingEntity entity;
@ -25,7 +24,7 @@ class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements
}
@Override
public boolean canRender(IModel model, Entity entity) {
public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity;
}
@ -40,12 +39,12 @@ class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements
}
@Override
public <M extends EntityModel<?> & IPonyModel<?>> void transform(M model, MatrixStack matrices) {
public <M extends EntityModel<?> & PonyModel<?>> void transform(M model, MatrixStack matrices) {
// noop
}
@Override
public void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
this.entity = (LivingEntity)entity;
}

View file

@ -6,10 +6,9 @@ import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import com.minelittlepony.api.events.PonyModelPrepareCallback;
import com.minelittlepony.api.model.*;
import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback;
import com.minelittlepony.api.model.gear.IGear;
import com.minelittlepony.api.pony.IPony;
import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.unicopia.*;
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
@ -41,16 +40,16 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
public void onInitializeClient() {
INSTANCE = this;
PonyModelPrepareCallback.EVENT.register(this::onPonyModelPrepared);
IGear.register(() -> new BangleGear(TrinketsDelegate.MAINHAND));
IGear.register(() -> new BangleGear(TrinketsDelegate.OFFHAND));
IGear.register(HeldEntityGear::new);
IGear.register(BodyPartGear::pegasusWings);
IGear.register(BodyPartGear::batWings);
IGear.register(BodyPartGear::bugWings);
IGear.register(BodyPartGear::unicornHorn);
IGear.register(AmuletGear::new);
IGear.register(GlassesGear::new);
IGear.register(SpellEffectGear::new);
Gear.register(() -> new BangleGear(TrinketsDelegate.MAINHAND));
Gear.register(() -> new BangleGear(TrinketsDelegate.OFFHAND));
Gear.register(HeldEntityGear::new);
Gear.register(BodyPartGear::pegasusWings);
Gear.register(BodyPartGear::batWings);
Gear.register(BodyPartGear::bugWings);
Gear.register(BodyPartGear::unicornHorn);
Gear.register(AmuletGear::new);
Gear.register(GlassesGear::new);
Gear.register(SpellEffectGear::new);
registerRaceMapping(com.minelittlepony.api.pony.meta.Race.CHANGEDLING, Race.CHANGELING);
registerRaceMapping(com.minelittlepony.api.pony.meta.Race.ZEBRA, Race.EARTH);
@ -60,7 +59,7 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
registerRaceMapping(com.minelittlepony.api.pony.meta.Race.SEAPONY, Race.UNICORN);
}
private void onPonyModelPrepared(Entity entity, IModel model, ModelAttributes.Mode mode) {
private void onPonyModelPrepared(Entity entity, PonyModel<?> model, ModelAttributes.Mode mode) {
if (hookErroring) return;
try {
if (entity instanceof PlayerEntity) {
@ -95,17 +94,17 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
@Override
public Race getPlayerPonyRace(PlayerEntity player) {
return toUnicopiaRace(IPony.getManager().getPony(player).race());
return toUnicopiaRace(com.minelittlepony.api.pony.Pony.getManager().getPony(player).race());
}
@Override
public Race getRace(Entity entity) {
return IPony.getManager().getPony(entity).map(IPony::race).map(Main::toUnicopiaRace).orElse(Race.UNSET);
return com.minelittlepony.api.pony.Pony.getManager().getPony(entity).map(com.minelittlepony.api.pony.Pony::race).map(Main::toUnicopiaRace).orElse(Race.HUMAN);
}
@Override
public float getPonyHeight(Entity entity) {
return super.getPonyHeight(entity) * IPony.getManager().getPony(entity).map(pony -> pony.metadata().getSize().getScaleFactor() + 0.1F).orElse(1F);
return super.getPonyHeight(entity) * com.minelittlepony.api.pony.Pony.getManager().getPony(entity).map(pony -> pony.metadata().size().scaleFactor() + 0.1F).orElse(1F);
}
private static Race toUnicopiaRace(com.minelittlepony.api.pony.meta.Race race) {

View file

@ -3,9 +3,8 @@ package com.minelittlepony.unicopia.client.minelittlepony;
import java.util.UUID;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel;
import com.minelittlepony.api.model.gear.IGear;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
import com.minelittlepony.unicopia.client.render.spell.SpellEffectsRenderDispatcher;
@ -17,14 +16,14 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.util.Identifier;
class SpellEffectGear implements IGear {
class SpellEffectGear implements Gear {
private Caster<?> caster;
private float limbAngle;
private float limbDistance;
private float animationProgress;
@Override
public boolean canRender(IModel model, Entity entity) {
public boolean canRender(PonyModel<?> model, Entity entity) {
return Caster.of(entity).isPresent();
}
@ -39,11 +38,11 @@ class SpellEffectGear implements IGear {
}
@Override
public <M extends EntityModel<?> & IPonyModel<?>> void transform(M model, MatrixStack matrices) {
public <M extends EntityModel<?> & PonyModel<?>> void transform(M model, MatrixStack matrices) {
}
@Override
public void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
caster = Caster.of(entity).orElse(null);
limbAngle = move;
limbDistance = swing;

View file

@ -23,6 +23,7 @@ import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.model.EntityModelPartNames;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.SkinTextures;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.decoration.ArmorStandEntity;
@ -59,7 +60,7 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
private void renderBangleThirdPerson(ItemStack item, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch, Arm mainArm) {
int j = ((DyeableItem)item.getItem()).getColor(item);
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getModel().startsWith("slim");
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).method_52814().model() == SkinTextures.Model.SLIM;
BraceletModel model = alex ? alexModel : steveModel;
boolean isLeft = mainArm == Arm.LEFT;
@ -85,7 +86,7 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
FriendshipBraceletItem.getWornBangles(entity, side == entity.getMainArm() ? TrinketsDelegate.MAINHAND : TrinketsDelegate.OFFHAND).findFirst().ifPresent(item -> {
int j = ((DyeableItem)item.getItem()).getColor(item);
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getModel().startsWith("slim");
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).method_52814().model() == SkinTextures.Model.SLIM;
BraceletModel model = alex ? alexModel : steveModel;

View file

@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.command.CommandArgumentEnum;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.item.GlassesItem;
import com.minelittlepony.unicopia.util.AnimationUtil;
import com.mojang.serialization.Codec;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.model.ModelPart;
@ -450,7 +451,6 @@ public class PlayerPoser {
}
public static final class ArgumentType extends EnumArgumentType<Animation> {
@SuppressWarnings("deprecation")
static final Codec<Animation> CODEC = StringIdentifiable.createCodec(Animation::values);
protected ArgumentType() {
@ -468,7 +468,6 @@ public class PlayerPoser {
}
public static final class ArgumentType extends EnumArgumentType<Recipient> {
@SuppressWarnings("deprecation")
static final Codec<Recipient> CODEC = StringIdentifiable.createCodec(Recipient::values);
protected ArgumentType() {

View file

@ -2,8 +2,7 @@ package com.minelittlepony.unicopia.client.render.shader;
import java.io.IOException;
import javax.annotation.Nullable;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import com.google.common.collect.*;

View file

@ -7,6 +7,7 @@ import com.minelittlepony.unicopia.entity.player.MagicReserves;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.mojang.brigadier.arguments.FloatArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.serialization.Codec;
import net.minecraft.command.argument.EnumArgumentType;
import net.minecraft.server.command.CommandManager;
@ -69,7 +70,6 @@ public class ManaCommand {
}
public static final class ArgumentType extends EnumArgumentType<ManaType> {
@SuppressWarnings("deprecation")
static final Codec<ManaType> CODEC = StringIdentifiable.createCodec(ManaType::values);
protected ArgumentType() {

View file

@ -12,19 +12,20 @@ import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.recipe.EmiShapedRecipe;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.ShapedRecipe;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.util.Identifier;
public class MagicalShapedEmiRecipe extends EmiCraftingRecipe {
public MagicalShapedEmiRecipe(ShapedRecipe recipe, CustomisedSpellType<?> spellEffect, ItemStack output) {
public MagicalShapedEmiRecipe(RecipeEntry<? extends CraftingRecipe> recipe, CustomisedSpellType<?> spellEffect, ItemStack output) {
super(padIngredients(recipe, spellEffect), EmiStack.of(output),
new Identifier(recipe.getId().getNamespace(), recipe.getId().getPath() + "/" + spellEffect.type().getId().getPath()), false);
EmiShapedRecipe.setRemainders(input, recipe);
new Identifier(recipe.id().getNamespace(), recipe.id().getPath() + "/" + spellEffect.type().getId().getPath()), false);
EmiShapedRecipe.setRemainders(input, recipe.value());
}
private static List<EmiIngredient> padIngredients(ShapedRecipe recipe, CustomisedSpellType<?> spellEffect) {
List<EmiIngredient> list = recipe.getIngredients().stream()
private static List<EmiIngredient> padIngredients(RecipeEntry<? extends CraftingRecipe> recipe, CustomisedSpellType<?> spellEffect) {
List<EmiIngredient> list = recipe.value().getIngredients().stream()
.map(ingredient -> remapIngredient(ingredient, spellEffect))
.collect(Collectors.toList());
while (list.size() < 9) {

View file

@ -41,15 +41,15 @@ public class Main implements EmiPlugin {
registry.addWorkstation(SPELL_BOOK_CATEGORY, SPELL_BOOK_STATION);
registry.getRecipeManager().listAllOfType(URecipes.SPELLBOOK).forEach(recipe -> {
if (recipe instanceof SpellDuplicatingRecipe) {
if (recipe.value() instanceof SpellDuplicatingRecipe) {
registry.addRecipe(new SpellDuplicatingEmiRecipe(recipe));
} else if (recipe instanceof SpellEnhancingRecipe enhancingRecipe) {
} else if (recipe.value() instanceof SpellEnhancingRecipe enhancingRecipe) {
Trait.all().forEach(trait -> {
registry.addRecipe(new SpellDuplicatingEmiRecipe(recipe) {
private final Identifier id;
{
id = recipe.getId().withPath(p -> p + "/" + trait.getId().getPath());
id = recipe.id().withPath(p -> p + "/" + trait.getId().getPath());
input(trait);
this.getOutputs().addAll(
Arrays.stream(enhancingRecipe.getBaseMaterial().getMatchingStacks())
@ -76,9 +76,9 @@ public class Main implements EmiPlugin {
DynamicRegistryManager registries = DynamicRegistryManager.of(Registries.REGISTRIES);
registry.getRecipeManager().listAllOfType(RecipeType.CRAFTING).stream()
.filter(recipe -> recipe instanceof SpellShapedCraftingRecipe)
.map(SpellShapedCraftingRecipe.class::cast).forEach(recipe -> {
ItemStack output = recipe.getOutput(registries);
.filter(recipe -> recipe.value() instanceof SpellShapedCraftingRecipe)
.forEach(recipe -> {
ItemStack output = recipe.value().getResult(registries);
if (output.getItem() instanceof MultiItem multiItem && output.getItem() instanceof EnchantableItem enchantable) {
multiItem.getDefaultStacks().forEach(outputVariation -> {
var spellEffect = enchantable.getSpellEffect(outputVariation);

View file

@ -14,10 +14,11 @@ import dev.emi.emi.runtime.EmiDrawContext;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeEntry;
public class SpellDuplicatingEmiRecipe extends SpellbookEmiRecipe {
public SpellDuplicatingEmiRecipe(SpellbookRecipe recipe) {
public SpellDuplicatingEmiRecipe(RecipeEntry<SpellbookRecipe> recipe) {
super(recipe);
}

View file

@ -20,18 +20,19 @@ import dev.emi.emi.api.widget.TextureWidget;
import dev.emi.emi.api.widget.WidgetHolder;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.util.Identifier;
class SpellbookEmiRecipe implements EmiRecipe, SpellbookRecipe.CraftingTreeBuilder {
private final SpellbookRecipe recipe;
private final RecipeEntry<SpellbookRecipe> recipe;
private final List<EmiIngredient> inputs = new ArrayList<>();
private final List<EmiStack> outputs = new ArrayList<>();
public SpellbookEmiRecipe(SpellbookRecipe recipe) {
public SpellbookEmiRecipe(RecipeEntry<SpellbookRecipe> recipe) {
this.recipe = recipe;
recipe.buildCraftingTree(this);
recipe.value().buildCraftingTree(this);
}
@Override
@ -42,7 +43,7 @@ class SpellbookEmiRecipe implements EmiRecipe, SpellbookRecipe.CraftingTreeBuild
@Nullable
@Override
public Identifier getId() {
return recipe.getId();
return recipe.id();
}
@Override

View file

@ -18,6 +18,7 @@ import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgServerResources;
import com.minelittlepony.unicopia.util.Resources;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.JsonOps;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.network.PacketByteBuf;
@ -227,6 +228,7 @@ public class SpellbookChapterLoader extends JsonDataLoader implements Identifiab
element.toBuffer(buffer);
}
@Deprecated
static Element read(JsonElement json) {
if (!json.isJsonPrimitive()) {
@ -244,7 +246,7 @@ public class SpellbookChapterLoader extends JsonDataLoader implements Identifiab
}
if (el.has("item")) {
return new Stack(IngredientWithSpell.fromJson(el.get("item")), boundsFromJson(el));
return new Stack(IngredientWithSpell.CODEC.decode(JsonOps.INSTANCE, el.get("item")).result().get().getFirst(), boundsFromJson(el));
}
if (el.has("ingredients")) {

View file

@ -23,6 +23,7 @@ import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerContext;
@ -188,12 +189,13 @@ public class SpellbookScreenHandler extends ScreenHandler {
super.onContentChanged(inventory);
context.run((world, pos) -> {
if (!world.isClient && !gemSlot.getStack().isEmpty()) {
Comparator<RecipeEntry<SpellbookRecipe>> comparator = Comparator.comparing(e -> e.value().getPriority());
ItemStack resultStack = input.hasIngredients() ? world.getServer().getRecipeManager()
.getAllMatches(URecipes.SPELLBOOK, input, world)
.stream().sorted(Comparator.comparing(SpellbookRecipe::getPriority))
.stream().sorted(comparator)
.findFirst()
.filter(recipe -> result.shouldCraftRecipe(world, (ServerPlayerEntity)this.inventory.player, recipe))
.map(recipe -> recipe.craft(input, world.getRegistryManager()))
.map(recipe -> recipe.value().craft(input, world.getRegistryManager()))
.orElseGet(this::getFallbackStack) : ItemStack.EMPTY;
outputSlot.setStack(resultStack);

View file

@ -232,7 +232,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
newServerPos = newServerPos.subtract(posChange);
entity.updateTrackedPositionAndAngles(
newServerPos.x, newServerPos.y, newServerPos.z,
entity.getYaw(), entity.getPitch(), 3, true);
entity.getYaw(), entity.getPitch(), 3);
}
} else {
entity.updateTrackedPosition(newPos.x, newPos.y, newPos.z);
@ -366,9 +366,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
EntityAttributeModifier modifier = instance.getModifier(id);
if (!MathHelper.approximatelyEquals(desiredValue, modifier == null ? 0 : modifier.getValue())) {
if (modifier != null) {
instance.removeModifier(modifier);
}
instance.tryRemoveModifier(id);
if (desiredValue != 0) {
if (permanent) {

View file

@ -160,10 +160,9 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
nbt.getString("playerName")
), source);
SkullBlockEntity.loadProperties(new GameProfile(
nbt.containsUuid("playerId") ? nbt.getUuid("playerId") : null,
nbt.getString("playerName")
), p -> createPlayer(nbt, p, source));
SkullBlockEntity.fetchProfile(nbt.getString("playerName")).thenAccept(profile -> {
profile.ifPresent(p -> createPlayer(nbt, p, source));
});
} else {
if (source.isClient()) {
entity = EntityType.fromNbt(nbt).map(type -> type.create(source.asWorld())).orElse(null);

View file

@ -296,7 +296,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
Vec3d vel = getVelocity();
double height = box.getYLength();
double height = box.getLengthY();
if (height < 3 || e.getBoundingBox().minY > box.minY + height / 2D) {
if (vel.y > 0 && e.getBoundingBox().minY < box.maxY + 0.02) {
@ -580,7 +580,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
STORM,
TALE;
public static final Codec<BalloonDesign> CODEC = StringIdentifiable.createCodec(BalloonDesign::values);
public static final EnumCodec<BalloonDesign> CODEC = StringIdentifiable.createCodec(BalloonDesign::values);
private static final IntFunction<BalloonDesign> BY_ID = ValueLists.<BalloonDesign>createIdToValueFunction(Enum::ordinal, values(), ValueLists.OutOfBoundsHandling.ZERO);
private final String name = name().toLowerCase(Locale.ROOT);

View file

@ -207,7 +207,7 @@ public class SombraEntity extends HostileEntity implements ArenaCombatant, Parti
@Override
protected boolean isAtValidPosition() {
return canSwim() && isInLiquid() || !entity.hasVehicle();
return canSwim() && isInFluid() || !entity.hasVehicle();
}
@Override

View file

@ -46,10 +46,10 @@ public class BasketItem extends Item implements Dispensable {
@Override
public TypedActionResult<ItemStack> dispenseStack(BlockPointer source, ItemStack stack) {
Direction facing = source.getBlockState().get(DispenserBlock.FACING);
BlockPos pos = source.getPos().offset(facing);
Direction facing = source.state().get(DispenserBlock.FACING);
BlockPos pos = source.pos().offset(facing);
float yaw = facing.getOpposite().asRotation();
return placeEntity(stack, source.getWorld(), pos.getX(), pos.getY(), pos.getZ(), yaw, null);
return placeEntity(stack, source.world(), pos.getX(), pos.getY(), pos.getZ(), yaw, null);
}
@Override

View file

@ -5,7 +5,7 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.magic.Caster;

View file

@ -6,13 +6,12 @@ import net.minecraft.item.Items;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.book.CraftingRecipeCategory;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
public class GlowingRecipe extends ItemCombinationRecipe {
public GlowingRecipe(Identifier id, CraftingRecipeCategory category) {
super(id, category);
public GlowingRecipe(CraftingRecipeCategory category) {
super(category);
}
@Override

View file

@ -4,14 +4,13 @@ import net.minecraft.inventory.RecipeInputInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.SpecialCraftingRecipe;
import net.minecraft.recipe.book.CraftingRecipeCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
import net.minecraft.world.World;
public abstract class ItemCombinationRecipe extends SpecialCraftingRecipe {
public ItemCombinationRecipe(Identifier id, CraftingRecipeCategory category) {
super(id, category);
public ItemCombinationRecipe(CraftingRecipeCategory category) {
super(category);
}
@Override

View file

@ -8,12 +8,11 @@ import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.SpecialCraftingRecipe;
import net.minecraft.recipe.book.CraftingRecipeCategory;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
public class JarExtractRecipe extends SpecialCraftingRecipe {
public JarExtractRecipe(Identifier id, CraftingRecipeCategory category) {
super(id, category);
public JarExtractRecipe(CraftingRecipeCategory category) {
super(category);
}
@Override

View file

@ -5,14 +5,13 @@ import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.book.CraftingRecipeCategory;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
import net.minecraft.util.collection.DefaultedList;
public class JarInsertRecipe extends ItemCombinationRecipe {
public JarInsertRecipe(Identifier id, CraftingRecipeCategory category) {
super(id, category);
public JarInsertRecipe(CraftingRecipeCategory category) {
super(category);
}
@Override

View file

@ -30,11 +30,11 @@ public class SpellbookItem extends BookItem implements Dispensable {
@Override
public TypedActionResult<ItemStack> dispenseStack(BlockPointer source, ItemStack stack) {
Direction facing = source.getBlockState().get(DispenserBlock.FACING);
BlockPos pos = source.getPos().offset(facing);
Direction facing = source.state().get(DispenserBlock.FACING);
BlockPos pos = source.pos().offset(facing);
float yaw = facing.getOpposite().asRotation();
placeBook(stack, source.getWorld(), pos.getX(), pos.getY(), pos.getZ(), yaw, null);
placeBook(stack, source.world(), pos.getX(), pos.getY(), pos.getZ(), yaw, null);
stack.decrement(1);
return new TypedActionResult<>(ActionResult.SUCCESS, stack);

View file

@ -1,18 +1,17 @@
package com.minelittlepony.unicopia.item;
import java.util.List;
import com.google.gson.JsonArray;
import com.minelittlepony.unicopia.ability.magic.spell.crafting.*;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
import net.minecraft.loot.LootPool;
import net.minecraft.loot.LootTable;
import net.minecraft.loot.context.LootContextTypes;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.RecipeType;
import net.minecraft.recipe.ShapedRecipe;
import net.minecraft.recipe.ShapelessRecipe;
import net.minecraft.recipe.SpecialRecipeSerializer;
import net.minecraft.util.Identifier;
import net.minecraft.util.collection.DefaultedList;
@ -20,7 +19,7 @@ import net.minecraft.util.collection.DefaultedList;
public interface URecipes {
RecipeType<SpellbookRecipe> SPELLBOOK = RecipeType.register("unicopia:spellbook");
RecipeSerializer<ShapelessRecipe> ZAP_APPLE_SERIALIZER = RecipeSerializer.register("unicopia:crafting_zap_apple", new ZapAppleRecipe.Serializer());
RecipeSerializer<ZapAppleRecipe> ZAP_APPLE_SERIALIZER = RecipeSerializer.register("unicopia:crafting_zap_apple", new ZapAppleRecipe.Serializer());
RecipeSerializer<GlowingRecipe> GLOWING_SERIALIZER = RecipeSerializer.register("unicopia:crafting_glowing", new SpecialRecipeSerializer<>(GlowingRecipe::new));
RecipeSerializer<JarInsertRecipe> JAR_INSERT_SERIALIZER = RecipeSerializer.register("unicopia:jar_insert", new SpecialRecipeSerializer<>(JarInsertRecipe::new));
RecipeSerializer<JarExtractRecipe> JAR_EXTRACT_SERIALIZER = RecipeSerializer.register("unicopia:jar_extract", new SpecialRecipeSerializer<>(JarExtractRecipe::new));
@ -29,18 +28,16 @@ public interface URecipes {
RecipeSerializer<SpellEnhancingRecipe> TRAIT_COMBINING = RecipeSerializer.register("unicopia:spellbook/combining", new SpellEnhancingRecipe.Serializer());
RecipeSerializer<SpellDuplicatingRecipe> SPELL_DUPLICATING = RecipeSerializer.register("unicopia:spellbook/duplicating", new SpellDuplicatingRecipe.Serializer());
static DefaultedList<Ingredient> getIngredients(JsonArray json) {
DefaultedList<Ingredient> defaultedList = DefaultedList.of();
for (int i = 0; i < json.size(); ++i) {
Ingredient ingredient = Ingredient.fromJson(json.get(i));
if (!ingredient.isEmpty()) {
defaultedList.add(ingredient);
}
Codec<DefaultedList<Ingredient>> SHAPELESS_RECIPE_INGREDIENTS_CODEC = Ingredient.DISALLOW_EMPTY_CODEC.listOf().flatXmap(ingredients -> {
Ingredient[] ingredients2 = ingredients.stream().filter(ingredient -> !ingredient.isEmpty()).toArray(Ingredient[]::new);
if (ingredients2.length == 0) {
return DataResult.error(() -> "No ingredients for shapeless recipe");
}
return defaultedList;
}
if (ingredients2.length > 9) {
return DataResult.error(() -> "Too many ingredients for shapeless recipe");
}
return DataResult.success(DefaultedList.copyOf(Ingredient.EMPTY, ingredients2));
}, DataResult::success);
static void bootstrap() {
LootTableEvents.MODIFY.register((res, manager, id, supplier, setter) -> {
@ -54,12 +51,12 @@ public interface URecipes {
if (table != LootTable.EMPTY) {
if (table.getType() == LootContextTypes.ARCHAEOLOGY) {
supplier.modifyPools(poolBuilder -> {
for (var pool : table.pools) {
poolBuilder.with(List.of(pool.entries));
for (LootPool pool : table.pools) {
poolBuilder.with(pool.entries);
}
});
} else {
supplier.pools(List.of(table.pools));
supplier.pools(table.pools);
}
}
});

View file

@ -59,9 +59,9 @@ public abstract class WearableItem extends Item implements Equipment {
}
public static boolean dispenseArmor(BlockPointer pointer, ItemStack armor) {
return pointer.getWorld().getEntitiesByClass(
return pointer.world().getEntitiesByClass(
LivingEntity.class,
new Box(pointer.getPos().offset(pointer.getBlockState().get(DispenserBlock.FACING))),
new Box(pointer.pos().offset(pointer.state().get(DispenserBlock.FACING))),
EntityPredicates.EXCEPT_SPECTATOR
)
.stream()

View file

@ -1,48 +1,41 @@
package com.minelittlepony.unicopia.item;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSyntaxException;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.ShapelessRecipe;
import net.minecraft.recipe.book.CraftingRecipeCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.registry.Registries;
public class ZapAppleRecipe extends ShapelessRecipe {
public ZapAppleRecipe(Identifier id, String group, CraftingRecipeCategory category, ItemStack output, DefaultedList<Ingredient> input) {
super(id, group, category, output, input);
public ZapAppleRecipe(String group, CraftingRecipeCategory category, ItemStack output, DefaultedList<Ingredient> input) {
super(group, category, output, input);
}
public static class Serializer extends ShapelessRecipe.Serializer {
public static class Serializer implements RecipeSerializer<ZapAppleRecipe> {
private static final Codec<ZapAppleRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.STRING.optionalFieldOf("group", "").forGetter(ZapAppleRecipe::getGroup),
CraftingRecipeCategory.CODEC.fieldOf("category").forGetter(ZapAppleRecipe::getCategory),
Registries.ITEM.getCodec().xmap(item -> {
return UItems.ZAP_APPLE.setAppearance(UItems.ZAP_APPLE.getDefaultStack(), item.getDefaultStack());
}, stack -> {
return UItems.ZAP_APPLE.getAppearance(stack);
}).fieldOf("appearance").forGetter(recipe -> recipe.getResult(null)),
URecipes.SHAPELESS_RECIPE_INGREDIENTS_CODEC.fieldOf("ingredients").forGetter(ZapAppleRecipe::getIngredients)
).apply(instance, ZapAppleRecipe::new));
@Override
public ShapelessRecipe read(Identifier identifier, JsonObject json) {
String group = JsonHelper.getString(json, "group", "");
@SuppressWarnings("deprecation")
CraftingRecipeCategory category = CraftingRecipeCategory.CODEC.byId(JsonHelper.getString(json, "category", null), CraftingRecipeCategory.MISC);
DefaultedList<Ingredient> ingredients = URecipes.getIngredients(JsonHelper.getArray(json, "ingredients"));
if (ingredients.isEmpty()) {
throw new JsonParseException("No ingredients for shapeless recipe");
} else if (ingredients.size() > 9) {
throw new JsonParseException("Too many ingredients for shapeless recipe");
}
Identifier id = new Identifier(JsonHelper.getString(json, "appearance"));
return new ZapAppleRecipe(identifier, group, category, UItems.ZAP_APPLE.setAppearance(UItems.ZAP_APPLE.getDefaultStack(), Registries.ITEM.getOrEmpty(id).orElseThrow(() -> {
return new JsonSyntaxException("Unknown item '" + id + "'");
}).getDefaultStack()), ingredients);
public Codec<ZapAppleRecipe> codec() {
return CODEC;
}
@Override
public ShapelessRecipe read(Identifier identifier, PacketByteBuf input) {
public ZapAppleRecipe read(PacketByteBuf input) {
String group = input.readString(32767);
CraftingRecipeCategory category = input.readEnumConstant(CraftingRecipeCategory.class);
@ -52,7 +45,18 @@ public class ZapAppleRecipe extends ShapelessRecipe {
ingredients.set(j, Ingredient.fromPacket(input));
}
return new ZapAppleRecipe(identifier, group, category, input.readItemStack(), ingredients);
return new ZapAppleRecipe(group, category, input.readItemStack(), ingredients);
}
@Override
public void write(PacketByteBuf buffer, ZapAppleRecipe recipe) {
buffer.writeString(recipe.getGroup());
buffer.writeEnumConstant(recipe.getCategory());
buffer.writeVarInt(recipe.getIngredients().size());
for (Ingredient ingredient : recipe.getIngredients()) {
ingredient.write(buffer);
}
buffer.writeItemStack(recipe.getResult(null));
}
}
}

View file

@ -13,10 +13,9 @@ import net.minecraft.network.listener.ServerPlayPacketListener;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.EntityTrackingListener;
@Mixin(ServerPlayNetworkHandler.class)
abstract class MixinServerPlayNetworkHandler implements EntityTrackingListener, ServerPlayPacketListener {
abstract class MixinServerPlayNetworkHandler implements ServerPlayPacketListener {
@Shadow private boolean floating;
@Shadow private int floatingTicks;

View file

@ -5,12 +5,11 @@ import com.sollace.fabwork.api.packets.Packet;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.entity.player.PlayerEntity;
/**
* Sent by the server to update block destruction progress on the client.
*/
public record MsgBlockDestruction (Long2ObjectMap<Float> destructions) implements Packet<PlayerEntity> {
public record MsgBlockDestruction (Long2ObjectMap<Float> destructions) implements Packet {
MsgBlockDestruction(PacketByteBuf buffer) {
this(new Long2ObjectOpenHashMap<>());
int size = buffer.readInt();

View file

@ -1,13 +1,12 @@
package com.minelittlepony.unicopia.network;
import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
/**
* Sent to the client when an ability fails its server-side activation checks.
*/
public final class MsgCancelPlayerAbility implements Packet<PlayerEntity> {
public final class MsgCancelPlayerAbility implements Packet {
static final MsgCancelPlayerAbility INSTANCE = new MsgCancelPlayerAbility();
static MsgCancelPlayerAbility read(PacketByteBuf buffer) {

View file

@ -10,14 +10,13 @@ import com.minelittlepony.unicopia.entity.player.Pony;
import com.sollace.fabwork.api.packets.HandledPacket;
import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.network.ServerPlayerEntity;
/**
* Sent to the client when the server needs to know precisely where the player is looking.
*/
public record MsgCasterLookRequest (UUID spellId) implements Packet<PlayerEntity> {
public record MsgCasterLookRequest (UUID spellId) implements Packet {
public MsgCasterLookRequest(PacketByteBuf buffer) {
this(buffer.readUuid());

View file

@ -7,7 +7,6 @@ import com.minelittlepony.unicopia.client.render.PlayerPoser.AnimationInstance;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
/**
@ -17,7 +16,7 @@ public record MsgPlayerAnimationChange (
UUID playerId,
AnimationInstance animation,
int duration
) implements Packet<PlayerEntity> {
) implements Packet {
MsgPlayerAnimationChange(PacketByteBuf buffer) {
this(

View file

@ -8,7 +8,6 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
import com.minelittlepony.unicopia.container.SpellbookChapterLoader;
import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier;
@ -16,7 +15,7 @@ public record MsgServerResources (
Map<Identifier, SpellTraits> traits,
Map<Identifier, ?> chapters,
Map<Identifier, TreeTypeLoader.TreeTypeDef> treeTypes
) implements Packet<PlayerEntity> {
) implements Packet {
public MsgServerResources() {
this(
SpellTraits.all(),

View file

@ -2,12 +2,11 @@ package com.minelittlepony.unicopia.network;
import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
public record MsgSkyAngle (
float tangentalSkyAngle
) implements Packet<PlayerEntity> {
) implements Packet {
public MsgSkyAngle(PacketByteBuf buffer) {
this(buffer.readFloat());

View file

@ -6,14 +6,13 @@ import com.minelittlepony.unicopia.Owned;
import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;
/**
* Sent by the server to spawn a projectile entity on the client.
*/
public class MsgSpawnProjectile extends EntitySpawnS2CPacket implements Packet<PlayerEntity> {
public class MsgSpawnProjectile extends EntitySpawnS2CPacket implements Packet {
MsgSpawnProjectile(PacketByteBuf buffer) {
super(buffer);

View file

@ -6,10 +6,9 @@ import java.util.Set;
import com.minelittlepony.unicopia.Race;
import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
public record MsgTribeSelect (Set<Race> availableRaces, String serverMessage) implements Packet<PlayerEntity> {
public record MsgTribeSelect (Set<Race> availableRaces, String serverMessage) implements Packet {
public MsgTribeSelect(PacketByteBuf buffer) {
this(
buffer.readCollection(HashSet::new, buf -> buf.readRegistryValue(Race.REGISTRY)),

View file

@ -7,9 +7,8 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.entity.player.PlayerEntity;
public record MsgUnlockTraits (Set<Trait> traits) implements Packet<PlayerEntity> {
public record MsgUnlockTraits (Set<Trait> traits) implements Packet {
MsgUnlockTraits(PacketByteBuf buffer) {
this(new HashSet<>());
int length = buffer.readInt();

View file

@ -66,7 +66,8 @@ public class ClientNetworkHandlerImpl {
InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_MAGIC_BEAM, entity.getId());
}
world.addEntity(packet.getId(), entity);
entity.onSpawnPacket(packet);
world.addEntity(entity);
}
private void handleBlockDestruction(PlayerEntity sender, MsgBlockDestruction packet) {

View file

@ -342,6 +342,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
@Override
public Packet<ClientPlayPacketListener> createSpawnPacket() {
return Channel.SERVER_SPAWN_PROJECTILE.toPacket(new MsgSpawnProjectile(this));
return (Packet<ClientPlayPacketListener>)(Object)Channel.SERVER_SPAWN_PROJECTILE.toPacket(new MsgSpawnProjectile(this));
}
}

View file

@ -8,6 +8,7 @@ import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgSkyAngle;
import com.minelittlepony.unicopia.util.NbtSerialisable;
import net.minecraft.datafixer.DataFixTypes;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.server.world.ServerWorld;
@ -79,8 +80,7 @@ public class UnicopiaWorldProperties extends PersistentState {
public static UnicopiaWorldProperties forWorld(ServerWorld world) {
return world.getPersistentStateManager().getOrCreate(
nbt -> new UnicopiaWorldProperties(world, nbt),
() -> new UnicopiaWorldProperties(world), "unicopia_tribes"
new Type<>(() -> new UnicopiaWorldProperties(world), nbt -> new UnicopiaWorldProperties(world, nbt), DataFixTypes.LEVEL), "unicopia_tribes"
);
}
}

View file

@ -18,12 +18,12 @@ import net.minecraft.registry.tag.FluidTags;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.Heightmap.Type;
import net.minecraft.world.Heightmap;
import net.minecraft.world.PersistentState;
import net.minecraft.world.World;
public class WeatherConditions extends PersistentState implements Tickable {
public static final Plane HEIGHT_MAP_FIELD = (world, pos) -> world.getTopY(Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
public static final Plane HEIGHT_MAP_FIELD = (world, pos) -> world.getTopY(Heightmap.Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
public static final Plane THERMAL_FIELD = (world, pos) -> (float)getUpdraft(pos, world);
public static final Plane LOCAL_ALTITUDE_FIELD = (world, pos) -> {
if (!world.isAir(pos)) {

View file

@ -13,6 +13,7 @@ import com.minelittlepony.unicopia.util.Tickable;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.datafixer.DataFixTypes;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
@ -38,8 +39,11 @@ public class WorldOverlay<T extends WorldOverlay.State> extends PersistentState
public static <T extends PersistentState> T getPersistableStorage(World world, Identifier id, BiFunction<World, NbtCompound, T> loadFunc, Function<World, T> factory) {
if (world instanceof ServerWorld serverWorld) {
return serverWorld.getPersistentStateManager().getOrCreate(
compound -> loadFunc.apply(world, compound),
() -> factory.apply(world),
new Type<>(
() -> factory.apply(world),
compound -> loadFunc.apply(world, compound),
DataFixTypes.LEVEL
),
id.getNamespace() + "_" + id.getPath().replace('/', '_')
);
}

View file

@ -18,4 +18,7 @@ accessible method net/minecraft/client/render/RenderLayer$MultiPhase
accessible method net/minecraft/client/render/RenderPhase$TextureBase getId ()Ljava/util/Optional;
accessible field net/minecraft/client/render/RenderLayer$MultiPhaseParameters texture Lnet/minecraft/client/render/RenderPhase$TextureBase;
accessible field net/minecraft/loot/LootTable pools Ljava/util/List;
accessible method net/minecraft/block/entity/SkullBlockEntity fetchProfile (Ljava/lang/String;)Ljava/util/concurrent/CompletableFuture;
accessible method net/minecraft/entity/LightningEntity cleanOxidation (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V