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 { plugins {
id 'java-library' id 'fabric-loom' version '1.3-SNAPSHOT'
id 'fabric-loom' version '0.12-SNAPSHOT'
id 'com.modrinth.minotaur' version '2.+' id 'com.modrinth.minotaur' version '2.+'
id 'org.ajoberstar.reckon' version '0.13.0' id 'org.ajoberstar.reckon' version '0.13.0'
} }

View file

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

View file

@ -11,7 +11,7 @@ public interface UGameEvents {
static GameEvent register(String name, int range) { static GameEvent register(String name, int range) {
Identifier id = Unicopia.id(name); 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() { static void bootstrap() {

View file

@ -189,12 +189,12 @@ public class UnicornTeleportAbility implements Ability<Pos> {
return state.hasSolidTopSurface(w, pos, player) return state.hasSolidTopSurface(w, pos, player)
|| StatePredicate.isFluid(state) || StatePredicate.isFluid(state)
|| (shape = state.getCollisionShape(w, pos, ShapeContext.of(player))).isEmpty() || (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) { private double getTargetYPosition(World world, BlockPos pos, ShapeContext context) {
VoxelShape shape = world.getBlockState(pos).getCollisionShape(world, pos, 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 @Override

View file

@ -6,20 +6,45 @@ import java.util.function.Predicate;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.google.gson.JsonArray; import com.google.gson.JsonParseException;
import com.google.gson.JsonElement;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.item.EnchantableItem; 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.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.collection.DefaultedList;
public class IngredientWithSpell implements Predicate<ItemStack> { 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(); 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<Ingredient> stack = Optional.empty();
private Optional<SpellType<?>> spell = 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); ingredient.spell = buf.readOptional(PacketByteBuf::readIdentifier).flatMap(SpellType.REGISTRY::getOrEmpty);
return ingredient; 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.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; 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.effect.SpellType;
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
import com.minelittlepony.unicopia.container.inventory.SpellbookInventory; 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.item.URecipes;
import com.minelittlepony.unicopia.util.InventoryUtil; import com.minelittlepony.unicopia.util.InventoryUtil;
import com.mojang.datafixers.util.Pair; 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.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.RecipeCodecs;
import net.minecraft.recipe.RecipeSerializer; import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.ShapedRecipe;
import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.collection.DefaultedList;
import net.minecraft.world.World; 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. * A recipe for creating a new spell from input traits and items.
*/ */
public class SpellCraftingRecipe implements SpellbookRecipe { public class SpellCraftingRecipe implements SpellbookRecipe {
private final Identifier id;
/** /**
* The ingredient to modify * The ingredient to modify
*/ */
private final IngredientWithSpell material; final IngredientWithSpell material;
/** /**
* The required traits * The required traits
*/ */
private final TraitIngredient requiredTraits; final TraitIngredient requiredTraits;
/** /**
* Items required for crafting. * Items required for crafting.
*/ */
private final List<IngredientWithSpell> requiredItems; final List<IngredientWithSpell> requiredItems;
/** /**
* The resulting item * The resulting item
*/ */
private final ItemStack output; final ItemStackWithSpell output;
private SpellCraftingRecipe(Identifier id, IngredientWithSpell material, TraitIngredient requiredTraits, List<IngredientWithSpell> requiredItems, ItemStack output) { private SpellCraftingRecipe(IngredientWithSpell material, TraitIngredient requiredTraits, List<IngredientWithSpell> requiredItems, ItemStackWithSpell output) {
this.id = id;
this.material = material; this.material = material;
this.requiredTraits = requiredTraits; this.requiredTraits = requiredTraits;
this.requiredItems = requiredItems; this.requiredItems = requiredItems;
@ -66,7 +64,7 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
requiredTraits.min().ifPresent(min -> { requiredTraits.min().ifPresent(min -> {
min.forEach(e -> builder.input(e.getKey(), e.getValue())); min.forEach(e -> builder.input(e.getKey(), e.getValue()));
}); });
builder.result(output); builder.result(output.toItemStack());
} }
@Override @Override
@ -108,7 +106,7 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
@Override @Override
public ItemStack craft(SpellbookInventory inventory, DynamicRegistryManager registries) { public ItemStack craft(SpellbookInventory inventory, DynamicRegistryManager registries) {
return getOutput(registries).copy(); return getResult(registries).copy();
} }
@Override @Override
@ -117,13 +115,8 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
} }
@Override @Override
public ItemStack getOutput(DynamicRegistryManager registries) { public ItemStack getResult(DynamicRegistryManager registries) {
return output; return output.toItemStack();
}
@Override
public Identifier getId() {
return id;
} }
@Override @Override
@ -131,35 +124,43 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
return URecipes.TRAIT_REQUIREMENT; return URecipes.TRAIT_REQUIREMENT;
} }
public static ItemStack outputFromJson(JsonObject json) { record ItemStackWithSpell(ItemStack stack, Optional<SpellType<?>> spell) {
ItemStack stack = ShapedRecipe.outputFromJson(json); public static final Codec<ItemStackWithSpell> CODEC = RecordCodecBuilder.create(instance -> instance.group(
SpellTraits.fromJson(JsonHelper.getObject(json, "traits", new JsonObject())) RecipeCodecs.CRAFTING_RESULT.fieldOf("stack").forGetter(ItemStackWithSpell::stack),
.map(traits -> traits.applyTo(stack)).orElse(stack); SpellType.REGISTRY.getCodec().optionalFieldOf("spell").forGetter(ItemStackWithSpell::spell)
).apply(instance, ItemStackWithSpell::new));
SpellType<?> spell = SpellType.getKey(Identifier.tryParse(JsonHelper.getString(json, "spell", ""))); public ItemStack toItemStack() {
if (spell != SpellType.EMPTY_KEY) { return spell.filter(s -> s != SpellType.EMPTY_KEY).map(s -> {
return EnchantableItem.enchant(stack, spell); 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> { 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 @Override
public SpellCraftingRecipe read(Identifier id, JsonObject json) { public Codec<SpellCraftingRecipe> codec() {
return new SpellCraftingRecipe(id, return CODEC;
IngredientWithSpell.fromJson(json.get("material")),
TraitIngredient.fromJson(JsonHelper.getObject(json, "traits")),
IngredientWithSpell.fromJson(JsonHelper.asArray(json.get("ingredients"), "ingredients")),
outputFromJson(JsonHelper.getObject(json, "result")));
} }
@Override @Override
public SpellCraftingRecipe read(Identifier id, PacketByteBuf buf) { public SpellCraftingRecipe read(PacketByteBuf buf) {
return new SpellCraftingRecipe(id, return new SpellCraftingRecipe(
IngredientWithSpell.fromPacket(buf), IngredientWithSpell.fromPacket(buf),
TraitIngredient.fromPacket(buf), TraitIngredient.fromPacket(buf),
buf.readCollection(DefaultedList::ofSize, IngredientWithSpell::fromPacket), 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.material.write(buf);
recipe.requiredTraits.write(buf); recipe.requiredTraits.write(buf);
buf.writeCollection(recipe.requiredItems, (b, i) -> i.write(b)); 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; 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.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.container.inventory.SpellbookInventory; import com.minelittlepony.unicopia.container.inventory.SpellbookInventory;
import com.minelittlepony.unicopia.item.*; import com.minelittlepony.unicopia.item.*;
import com.minelittlepony.unicopia.util.InventoryUtil; 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.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.RecipeSerializer; import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.world.World; import net.minecraft.world.World;
/** /**
* A recipe for creating a new spell from input traits and items. * A recipe for creating a new spell from input traits and items.
*/ */
public class SpellDuplicatingRecipe implements SpellbookRecipe { public class SpellDuplicatingRecipe implements SpellbookRecipe {
private final Identifier id; final IngredientWithSpell material;
private final IngredientWithSpell material; private SpellDuplicatingRecipe(IngredientWithSpell material) {
private SpellDuplicatingRecipe(Identifier id, IngredientWithSpell material) {
this.id = id;
this.material = material; this.material = material;
} }
@ -72,31 +69,30 @@ public class SpellDuplicatingRecipe implements SpellbookRecipe {
} }
@Override @Override
public ItemStack getOutput(DynamicRegistryManager registries) { public ItemStack getResult(DynamicRegistryManager registries) {
ItemStack stack = UItems.GEMSTONE.getDefaultStack(); ItemStack stack = UItems.GEMSTONE.getDefaultStack();
stack.setCount(2); stack.setCount(2);
return stack; return stack;
} }
@Override
public Identifier getId() {
return id;
}
@Override @Override
public RecipeSerializer<?> getSerializer() { public RecipeSerializer<?> getSerializer() {
return URecipes.SPELL_DUPLICATING; return URecipes.SPELL_DUPLICATING;
} }
public static class Serializer implements RecipeSerializer<SpellDuplicatingRecipe> { 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 @Override
public SpellDuplicatingRecipe read(Identifier id, JsonObject json) { public Codec<SpellDuplicatingRecipe> codec() {
return new SpellDuplicatingRecipe(id, IngredientWithSpell.fromJson(json.get("material"))); return CODEC;
} }
@Override @Override
public SpellDuplicatingRecipe read(Identifier id, PacketByteBuf buf) { public SpellDuplicatingRecipe read(PacketByteBuf buf) {
return new SpellDuplicatingRecipe(id, IngredientWithSpell.fromPacket(buf)); return new SpellDuplicatingRecipe(IngredientWithSpell.fromPacket(buf));
} }
@Override @Override

View file

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

View file

@ -1,9 +1,11 @@
package com.minelittlepony.unicopia.ability.magic.spell.crafting; 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.EnchantableItem;
import com.minelittlepony.unicopia.item.URecipes; import com.minelittlepony.unicopia.item.URecipes;
import com.minelittlepony.unicopia.util.InventoryUtil; import com.minelittlepony.unicopia.util.InventoryUtil;
import com.mojang.serialization.Codec;
import net.minecraft.inventory.RecipeInputInventory; import net.minecraft.inventory.RecipeInputInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -11,12 +13,11 @@ import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.RecipeSerializer; import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.ShapedRecipe; import net.minecraft.recipe.ShapedRecipe;
import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
public class SpellShapedCraftingRecipe extends ShapedRecipe { public class SpellShapedCraftingRecipe extends ShapedRecipe {
public SpellShapedCraftingRecipe(ShapedRecipe recipe) { 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 @Override
@ -37,13 +38,13 @@ public class SpellShapedCraftingRecipe extends ShapedRecipe {
public static class Serializer extends ShapedRecipe.Serializer { public static class Serializer extends ShapedRecipe.Serializer {
@Override @Override
public ShapedRecipe read(Identifier id, JsonObject json) { public Codec<ShapedRecipe> codec() {
return new SpellShapedCraftingRecipe(super.read(id, json)); return super.codec().xmap(SpellShapedCraftingRecipe::new, Function.identity());
} }
@Override @Override
public ShapedRecipe read(Identifier id, PacketByteBuf buffer) { public ShapedRecipe read(PacketByteBuf buffer) {
return new SpellShapedCraftingRecipe(super.read(id, 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) { if (source.asEntity() instanceof LivingEntity l) {
MODIFIERS.forEach((attribute, modifier) -> { MODIFIERS.forEach((attribute, modifier) -> {
if (l.getAttributes().hasAttribute(attribute)) { 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.Unicopia;
import com.minelittlepony.unicopia.command.CommandArgumentEnum; import com.minelittlepony.unicopia.command.CommandArgumentEnum;
import com.mojang.serialization.Codec;
import net.minecraft.command.argument.EnumArgumentType; import net.minecraft.command.argument.EnumArgumentType;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -165,7 +166,6 @@ public enum Trait implements CommandArgumentEnum<Trait> {
} }
public static final class ArgumentType extends EnumArgumentType<Trait> { public static final class ArgumentType extends EnumArgumentType<Trait> {
@SuppressWarnings("deprecation")
static final Codec<Trait> CODEC = StringIdentifiable.createCodec(Trait::values); static final Codec<Trait> CODEC = StringIdentifiable.createCodec(Trait::values);
protected ArgumentType() { protected ArgumentType() {

View file

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

View file

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

View file

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

View file

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

View file

@ -96,11 +96,11 @@ public class RockCropBlock extends CropBlock {
} }
@Override @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)) { if (world instanceof World && !canGrow((World)world, ((World)world).random, pos, state)) {
return false; return false;
} }
return super.isFertilizable(world, pos, state, isClient); return super.isFertilizable(world, pos, state);
} }
@Override @Override

View file

@ -170,8 +170,8 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock {
} }
@Override @Override
public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state, boolean isClient) { public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state) {
if (super.isFertilizable(world, pos, state, isClient)) { if (super.isFertilizable(world, pos, state)) {
return true; return true;
} }
@ -181,7 +181,7 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock {
pos = pos.up(); pos = pos.up();
state = world.getBlockState(pos); 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 @Override

View file

@ -43,7 +43,7 @@ public class WeatherVaneBlock extends BlockWithEntity {
@Override @Override
@Nullable @Nullable
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) { 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 { 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.ShapeContext;
import net.minecraft.block.SlabBlock; import net.minecraft.block.SlabBlock;
import net.minecraft.block.enums.SlabType; import net.minecraft.block.enums.SlabType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid; import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState; import net.minecraft.fluid.FluidState;
import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemPlacementContext;
@ -92,7 +93,7 @@ public class CloudSlabBlock extends WaterloggableCloudBlock {
} }
@Override @Override
public boolean canFillWithFluid(BlockView world, BlockPos pos, BlockState state, Fluid fluid) { public boolean canFillWithFluid(PlayerEntity player, BlockView world, BlockPos pos, BlockState state, Fluid fluid) {
return state.get(SlabBlock.TYPE) != SlabType.DOUBLE && super.canFillWithFluid(world, pos, state, 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 { public class DiscoveryToast implements Toast {
private static final long MAX_AGE = 5000L; 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 TITLE = Text.translatable("unicopia.toast.discoveries.title");
private static final Text DESCRIPTION = Text.translatable("unicopia.toast.discoveries.description"); 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.setShader(GameRenderer::getPositionTexProgram);
RenderSystem.setShaderColor(1.0F, 1, 1, 1); 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, TITLE, 30, 7, -11534256, false);
context.drawText(manager.getClient().textRenderer, DESCRIPTION, 30, 18, -16777216, false); context.drawText(manager.getClient().textRenderer, DESCRIPTION, 30, 18, -16777216, false);

View file

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

View file

@ -106,7 +106,6 @@ public class SettingsScreen extends GameGui {
@Override @Override
public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) { public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) {
renderBackground(context);
super.render(context, mouseX, mouseY, tickDelta); super.render(context, mouseX, mouseY, tickDelta);
content.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); 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); getStyle().setIcon(icon);
} }

View file

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

View file

@ -10,7 +10,6 @@ import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgRequestSpeciesChange; import com.minelittlepony.unicopia.network.MsgRequestSpeciesChange;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -92,12 +91,6 @@ public class TribeSelectionScreen extends GameGui implements HidesHud {
}).setEnabled(allowedRaces.contains(race)); }).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 @Override
public void finish() { public void finish() {
finished = true; finished = true;

View file

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

View file

@ -149,7 +149,6 @@ public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> imple
@Override @Override
protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
renderBackground(context);
RenderSystem.setShaderColor(1, 1, 1, 1); RenderSystem.setShaderColor(1, 1, 1, 1);
context.drawTexture(TEXTURE, x, y, 0, 0, backgroundWidth, backgroundHeight, 512, 256); 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 com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
record Recipe (DynamicContent.Page page, Identifier id, Bounds bounds) implements PageElement { 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().left = book.getX();
bounds().top = book.getY(); 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) { if (recipe instanceof SpellbookRecipe spellRecipe) {
boolean needsMoreXp = page.getLevel() < 0 || Pony.of(MinecraftClient.getInstance().player).getLevel().get() < page.getLevel(); 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 java.util.UUID;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.IGear; import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer.AmuletModel; import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer.AmuletModel;
import com.minelittlepony.unicopia.item.AmuletItem; import com.minelittlepony.unicopia.item.AmuletItem;
@ -21,7 +20,7 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.registry.Registries; 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<>(); private final Map<Identifier, Identifier> textures = new HashMap<>();
@ -30,7 +29,7 @@ class AmuletGear extends AmuletModel implements IGear {
} }
@Override @Override
public boolean canRender(IModel model, Entity entity) { public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity living && !AmuletItem.getForEntity(living).isEmpty(); return entity instanceof LivingEntity living && !AmuletItem.getForEntity(living).isEmpty();
} }
@ -45,14 +44,14 @@ class AmuletGear extends AmuletModel implements IGear {
} }
@Override @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(); BodyPart part = getGearLocation();
model.transform(part, matrices); model.transform(part, matrices);
matrices.translate(0, 0.25, 0); matrices.translate(0, 0.25, 0);
} }
@Override @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) { if (model instanceof BipedEntityModel<?> biped) {
setAngles((LivingEntity)entity, biped); setAngles((LivingEntity)entity, biped);
} }

View file

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

View file

@ -5,7 +5,7 @@ import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.minelittlepony.api.model.*; 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.ClientPonyModel;
import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.PlayerModelKey; import com.minelittlepony.client.model.PlayerModelKey;
@ -26,7 +26,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier; 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_WINGS = e -> !MineLPDelegate.getInstance().getRace(e).canFly();
private static final Predicate<LivingEntity> MINE_LP_HAS_NO_HORN = e -> !MineLPDelegate.getInstance().getRace(e).canCast(); 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() { 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() { 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() { public static BodyPartGear<HornGearModel> unicornHorn() {
@ -69,7 +69,7 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
private final M model; private final M model;
private final Predicate<LivingEntity> renderTargetPredicate; private final Predicate<LivingEntity> renderTargetPredicate;
private final IPart part; private final SubModel part;
private final Function<Entity, Identifier> textureSupplier; private final Function<Entity, Identifier> textureSupplier;
private final BodyPart gearLocation; private final BodyPart gearLocation;
@ -78,7 +78,7 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
PlayerModelKey<LivingEntity, ? super M> modelKey, PlayerModelKey<LivingEntity, ? super M> modelKey,
Predicate<LivingEntity> renderTargetPredicate, Predicate<LivingEntity> renderTargetPredicate,
MsonModel.Factory<M> modelFactory, MsonModel.Factory<M> modelFactory,
Function<? super M, IPart> partExtractor, Function<? super M, SubModel> partExtractor,
Function<Entity, Identifier> textureSupplier) { Function<Entity, Identifier> textureSupplier) {
this.gearLocation = gearLocation; this.gearLocation = gearLocation;
this.model = modelKey.steveKey().createModel(modelFactory); this.model = modelKey.steveKey().createModel(modelFactory);
@ -93,7 +93,7 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
} }
@Override @Override
public boolean canRender(IModel model, Entity entity) { public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity l return entity instanceof LivingEntity l
&& MineLPDelegate.getInstance().getRace(entity).isEquine() && MineLPDelegate.getInstance().getRace(entity).isEquine()
&& renderTargetPredicate.test(l); && renderTargetPredicate.test(l);
@ -106,7 +106,7 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@Override @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); ((ClientPonyModel)model).copyAttributes(this.model);
part.setPartAngles(this.model.getAttributes(), move, swing, bodySwing, ticks); 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) { public WingsGearModel(ModelPart tree) {
super(tree, false); super(tree, false);
} }
@Override
public boolean canFly() {
return true;
}
} }
static final class BugWingsGearModel extends ChangelingModel<LivingEntity> { static final class BugWingsGearModel extends ChangelingModel<LivingEntity> {
public BugWingsGearModel(ModelPart tree) { public BugWingsGearModel(ModelPart tree) {
super(tree, false); super(tree, false);
} }
@Override
public boolean canFly() {
return true;
}
} }
static final class HornGearModel extends UnicornModel<LivingEntity> { static final class HornGearModel extends UnicornModel<LivingEntity> {
@ -143,11 +133,6 @@ class BodyPartGear<M extends ClientPonyModel<LivingEntity> & MsonModel & IModel>
super(tree, false); super(tree, false);
} }
@Override
public boolean canFly() {
return true;
}
public UnicornHorn getHorn() { public UnicornHorn getHorn() {
return horn; return horn;
} }

View file

@ -5,8 +5,8 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.IGear; import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.unicopia.client.render.GlassesFeatureRenderer.GlassesModel; import com.minelittlepony.unicopia.client.render.GlassesFeatureRenderer.GlassesModel;
import com.minelittlepony.unicopia.item.GlassesItem; import com.minelittlepony.unicopia.item.GlassesItem;
@ -18,7 +18,7 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.registry.Registries; 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<>(); private final Map<Identifier, Identifier> textures = new HashMap<>();
@ -27,7 +27,7 @@ class GlassesGear extends GlassesModel implements IGear {
} }
@Override @Override
public boolean canRender(IModel model, Entity entity) { public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity living && !GlassesItem.getForEntity(living).isEmpty(); 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 java.util.UUID;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.IGear; import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.unicopia.client.render.HeldEntityFeatureRenderer; import com.minelittlepony.unicopia.client.render.HeldEntityFeatureRenderer;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
@ -16,7 +15,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements IGear { class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements Gear {
private LivingEntity entity; private LivingEntity entity;
@ -25,7 +24,7 @@ class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements
} }
@Override @Override
public boolean canRender(IModel model, Entity entity) { public boolean canRender(PonyModel<?> model, Entity entity) {
return entity instanceof LivingEntity; return entity instanceof LivingEntity;
} }
@ -40,12 +39,12 @@ class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements
} }
@Override @Override
public <M extends EntityModel<?> & IPonyModel<?>> void transform(M model, MatrixStack matrices) { public <M extends EntityModel<?> & PonyModel<?>> void transform(M model, MatrixStack matrices) {
// noop // noop
} }
@Override @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; this.entity = (LivingEntity)entity;
} }

View file

@ -6,10 +6,9 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import com.minelittlepony.api.events.PonyModelPrepareCallback;
import com.minelittlepony.api.model.*; import com.minelittlepony.api.model.*;
import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback; import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.api.model.gear.IGear;
import com.minelittlepony.api.pony.IPony;
import com.minelittlepony.unicopia.*; import com.minelittlepony.unicopia.*;
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation; import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
@ -41,16 +40,16 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
public void onInitializeClient() { public void onInitializeClient() {
INSTANCE = this; INSTANCE = this;
PonyModelPrepareCallback.EVENT.register(this::onPonyModelPrepared); PonyModelPrepareCallback.EVENT.register(this::onPonyModelPrepared);
IGear.register(() -> new BangleGear(TrinketsDelegate.MAINHAND)); Gear.register(() -> new BangleGear(TrinketsDelegate.MAINHAND));
IGear.register(() -> new BangleGear(TrinketsDelegate.OFFHAND)); Gear.register(() -> new BangleGear(TrinketsDelegate.OFFHAND));
IGear.register(HeldEntityGear::new); Gear.register(HeldEntityGear::new);
IGear.register(BodyPartGear::pegasusWings); Gear.register(BodyPartGear::pegasusWings);
IGear.register(BodyPartGear::batWings); Gear.register(BodyPartGear::batWings);
IGear.register(BodyPartGear::bugWings); Gear.register(BodyPartGear::bugWings);
IGear.register(BodyPartGear::unicornHorn); Gear.register(BodyPartGear::unicornHorn);
IGear.register(AmuletGear::new); Gear.register(AmuletGear::new);
IGear.register(GlassesGear::new); Gear.register(GlassesGear::new);
IGear.register(SpellEffectGear::new); Gear.register(SpellEffectGear::new);
registerRaceMapping(com.minelittlepony.api.pony.meta.Race.CHANGEDLING, Race.CHANGELING); registerRaceMapping(com.minelittlepony.api.pony.meta.Race.CHANGEDLING, Race.CHANGELING);
registerRaceMapping(com.minelittlepony.api.pony.meta.Race.ZEBRA, Race.EARTH); 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); 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; if (hookErroring) return;
try { try {
if (entity instanceof PlayerEntity) { if (entity instanceof PlayerEntity) {
@ -95,17 +94,17 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
@Override @Override
public Race getPlayerPonyRace(PlayerEntity player) { public Race getPlayerPonyRace(PlayerEntity player) {
return toUnicopiaRace(IPony.getManager().getPony(player).race()); return toUnicopiaRace(com.minelittlepony.api.pony.Pony.getManager().getPony(player).race());
} }
@Override @Override
public Race getRace(Entity entity) { 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 @Override
public float getPonyHeight(Entity entity) { 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) { 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 java.util.UUID;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.IGear; import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer; import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
import com.minelittlepony.unicopia.client.render.spell.SpellEffectsRenderDispatcher; 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.entity.Entity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
class SpellEffectGear implements IGear { class SpellEffectGear implements Gear {
private Caster<?> caster; private Caster<?> caster;
private float limbAngle; private float limbAngle;
private float limbDistance; private float limbDistance;
private float animationProgress; private float animationProgress;
@Override @Override
public boolean canRender(IModel model, Entity entity) { public boolean canRender(PonyModel<?> model, Entity entity) {
return Caster.of(entity).isPresent(); return Caster.of(entity).isPresent();
} }
@ -39,11 +38,11 @@ class SpellEffectGear implements IGear {
} }
@Override @Override
public <M extends EntityModel<?> & IPonyModel<?>> void transform(M model, MatrixStack matrices) { public <M extends EntityModel<?> & PonyModel<?>> void transform(M model, MatrixStack matrices) {
} }
@Override @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); caster = Caster.of(entity).orElse(null);
limbAngle = move; limbAngle = move;
limbDistance = swing; 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.BipedEntityModel;
import net.minecraft.client.render.entity.model.EntityModelPartNames; import net.minecraft.client.render.entity.model.EntityModelPartNames;
import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.SkinTextures;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.decoration.ArmorStandEntity; 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) { 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); 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; BraceletModel model = alex ? alexModel : steveModel;
boolean isLeft = mainArm == Arm.LEFT; 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 -> { FriendshipBraceletItem.getWornBangles(entity, side == entity.getMainArm() ? TrinketsDelegate.MAINHAND : TrinketsDelegate.OFFHAND).findFirst().ifPresent(item -> {
int j = ((DyeableItem)item.getItem()).getColor(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; 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.entity.player.Pony;
import com.minelittlepony.unicopia.item.GlassesItem; import com.minelittlepony.unicopia.item.GlassesItem;
import com.minelittlepony.unicopia.util.AnimationUtil; import com.minelittlepony.unicopia.util.AnimationUtil;
import com.mojang.serialization.Codec;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
@ -450,7 +451,6 @@ public class PlayerPoser {
} }
public static final class ArgumentType extends EnumArgumentType<Animation> { public static final class ArgumentType extends EnumArgumentType<Animation> {
@SuppressWarnings("deprecation")
static final Codec<Animation> CODEC = StringIdentifiable.createCodec(Animation::values); static final Codec<Animation> CODEC = StringIdentifiable.createCodec(Animation::values);
protected ArgumentType() { protected ArgumentType() {
@ -468,7 +468,6 @@ public class PlayerPoser {
} }
public static final class ArgumentType extends EnumArgumentType<Recipient> { public static final class ArgumentType extends EnumArgumentType<Recipient> {
@SuppressWarnings("deprecation")
static final Codec<Recipient> CODEC = StringIdentifiable.createCodec(Recipient::values); static final Codec<Recipient> CODEC = StringIdentifiable.createCodec(Recipient::values);
protected ArgumentType() { protected ArgumentType() {

View file

@ -2,8 +2,7 @@ package com.minelittlepony.unicopia.client.render.shader;
import java.io.IOException; import java.io.IOException;
import javax.annotation.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import com.google.common.collect.*; 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.minelittlepony.unicopia.entity.player.Pony;
import com.mojang.brigadier.arguments.FloatArgumentType; import com.mojang.brigadier.arguments.FloatArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.serialization.Codec;
import net.minecraft.command.argument.EnumArgumentType; import net.minecraft.command.argument.EnumArgumentType;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
@ -69,7 +70,6 @@ public class ManaCommand {
} }
public static final class ArgumentType extends EnumArgumentType<ManaType> { public static final class ArgumentType extends EnumArgumentType<ManaType> {
@SuppressWarnings("deprecation")
static final Codec<ManaType> CODEC = StringIdentifiable.createCodec(ManaType::values); static final Codec<ManaType> CODEC = StringIdentifiable.createCodec(ManaType::values);
protected ArgumentType() { 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.api.stack.EmiStack;
import dev.emi.emi.recipe.EmiShapedRecipe; import dev.emi.emi.recipe.EmiShapedRecipe;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.ShapedRecipe; import net.minecraft.recipe.RecipeEntry;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class MagicalShapedEmiRecipe extends EmiCraftingRecipe { 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), super(padIngredients(recipe, spellEffect), EmiStack.of(output),
new Identifier(recipe.getId().getNamespace(), recipe.getId().getPath() + "/" + spellEffect.type().getId().getPath()), false); new Identifier(recipe.id().getNamespace(), recipe.id().getPath() + "/" + spellEffect.type().getId().getPath()), false);
EmiShapedRecipe.setRemainders(input, recipe); EmiShapedRecipe.setRemainders(input, recipe.value());
} }
private static List<EmiIngredient> padIngredients(ShapedRecipe recipe, CustomisedSpellType<?> spellEffect) { private static List<EmiIngredient> padIngredients(RecipeEntry<? extends CraftingRecipe> recipe, CustomisedSpellType<?> spellEffect) {
List<EmiIngredient> list = recipe.getIngredients().stream() List<EmiIngredient> list = recipe.value().getIngredients().stream()
.map(ingredient -> remapIngredient(ingredient, spellEffect)) .map(ingredient -> remapIngredient(ingredient, spellEffect))
.collect(Collectors.toList()); .collect(Collectors.toList());
while (list.size() < 9) { while (list.size() < 9) {

View file

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

View file

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

View file

@ -18,6 +18,7 @@ import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgServerResources; import com.minelittlepony.unicopia.network.MsgServerResources;
import com.minelittlepony.unicopia.util.Resources; import com.minelittlepony.unicopia.util.Resources;
import com.mojang.logging.LogUtils; import com.mojang.logging.LogUtils;
import com.mojang.serialization.JsonOps;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
@ -227,6 +228,7 @@ public class SpellbookChapterLoader extends JsonDataLoader implements Identifiab
element.toBuffer(buffer); element.toBuffer(buffer);
} }
@Deprecated
static Element read(JsonElement json) { static Element read(JsonElement json) {
if (!json.isJsonPrimitive()) { if (!json.isJsonPrimitive()) {
@ -244,7 +246,7 @@ public class SpellbookChapterLoader extends JsonDataLoader implements Identifiab
} }
if (el.has("item")) { 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")) { if (el.has("ingredients")) {

View file

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

View file

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

View file

@ -160,10 +160,9 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
nbt.getString("playerName") nbt.getString("playerName")
), source); ), source);
SkullBlockEntity.loadProperties(new GameProfile( SkullBlockEntity.fetchProfile(nbt.getString("playerName")).thenAccept(profile -> {
nbt.containsUuid("playerId") ? nbt.getUuid("playerId") : null, profile.ifPresent(p -> createPlayer(nbt, p, source));
nbt.getString("playerName") });
), p -> createPlayer(nbt, p, source));
} else { } else {
if (source.isClient()) { if (source.isClient()) {
entity = EntityType.fromNbt(nbt).map(type -> type.create(source.asWorld())).orElse(null); 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(); Vec3d vel = getVelocity();
double height = box.getYLength(); double height = box.getLengthY();
if (height < 3 || e.getBoundingBox().minY > box.minY + height / 2D) { if (height < 3 || e.getBoundingBox().minY > box.minY + height / 2D) {
if (vel.y > 0 && e.getBoundingBox().minY < box.maxY + 0.02) { if (vel.y > 0 && e.getBoundingBox().minY < box.maxY + 0.02) {
@ -580,7 +580,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
STORM, STORM,
TALE; 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 static final IntFunction<BalloonDesign> BY_ID = ValueLists.<BalloonDesign>createIdToValueFunction(Enum::ordinal, values(), ValueLists.OutOfBoundsHandling.ZERO);
private final String name = name().toLowerCase(Locale.ROOT); private final String name = name().toLowerCase(Locale.ROOT);

View file

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

View file

@ -46,10 +46,10 @@ public class BasketItem extends Item implements Dispensable {
@Override @Override
public TypedActionResult<ItemStack> dispenseStack(BlockPointer source, ItemStack stack) { public TypedActionResult<ItemStack> dispenseStack(BlockPointer source, ItemStack stack) {
Direction facing = source.getBlockState().get(DispenserBlock.FACING); Direction facing = source.state().get(DispenserBlock.FACING);
BlockPos pos = source.getPos().offset(facing); BlockPos pos = source.pos().offset(facing);
float yaw = facing.getOpposite().asRotation(); 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 @Override

View file

@ -5,7 +5,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.annotation.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.magic.Caster; 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.RecipeSerializer;
import net.minecraft.recipe.book.CraftingRecipeCategory; import net.minecraft.recipe.book.CraftingRecipeCategory;
import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair; import net.minecraft.util.Pair;
public class GlowingRecipe extends ItemCombinationRecipe { public class GlowingRecipe extends ItemCombinationRecipe {
public GlowingRecipe(Identifier id, CraftingRecipeCategory category) { public GlowingRecipe(CraftingRecipeCategory category) {
super(id, category); super(category);
} }
@Override @Override

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,48 +1,41 @@
package com.minelittlepony.unicopia.item; package com.minelittlepony.unicopia.item;
import com.google.gson.JsonObject; import com.mojang.serialization.Codec;
import com.google.gson.JsonParseException; import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.google.gson.JsonSyntaxException;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.ShapelessRecipe; import net.minecraft.recipe.ShapelessRecipe;
import net.minecraft.recipe.book.CraftingRecipeCategory; 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.util.collection.DefaultedList;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
public class ZapAppleRecipe extends ShapelessRecipe { public class ZapAppleRecipe extends ShapelessRecipe {
public ZapAppleRecipe(String group, CraftingRecipeCategory category, ItemStack output, DefaultedList<Ingredient> input) {
public ZapAppleRecipe(Identifier id, String group, CraftingRecipeCategory category, ItemStack output, DefaultedList<Ingredient> input) { super(group, category, output, input);
super(id, 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 @Override
public ShapelessRecipe read(Identifier identifier, JsonObject json) { public Codec<ZapAppleRecipe> codec() {
String group = JsonHelper.getString(json, "group", ""); return CODEC;
@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);
} }
@Override @Override
public ShapelessRecipe read(Identifier identifier, PacketByteBuf input) { public ZapAppleRecipe read(PacketByteBuf input) {
String group = input.readString(32767); String group = input.readString(32767);
CraftingRecipeCategory category = input.readEnumConstant(CraftingRecipeCategory.class); CraftingRecipeCategory category = input.readEnumConstant(CraftingRecipeCategory.class);
@ -52,7 +45,18 @@ public class ZapAppleRecipe extends ShapelessRecipe {
ingredients.set(j, Ingredient.fromPacket(input)); 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.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.EntityTrackingListener;
@Mixin(ServerPlayNetworkHandler.class) @Mixin(ServerPlayNetworkHandler.class)
abstract class MixinServerPlayNetworkHandler implements EntityTrackingListener, ServerPlayPacketListener { abstract class MixinServerPlayNetworkHandler implements ServerPlayPacketListener {
@Shadow private boolean floating; @Shadow private boolean floating;
@Shadow private int floatingTicks; @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.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.entity.player.PlayerEntity;
/** /**
* Sent by the server to update block destruction progress on the client. * 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) { MsgBlockDestruction(PacketByteBuf buffer) {
this(new Long2ObjectOpenHashMap<>()); this(new Long2ObjectOpenHashMap<>());
int size = buffer.readInt(); int size = buffer.readInt();

View file

@ -1,13 +1,12 @@
package com.minelittlepony.unicopia.network; package com.minelittlepony.unicopia.network;
import com.sollace.fabwork.api.packets.Packet; import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
/** /**
* Sent to the client when an ability fails its server-side activation checks. * 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 final MsgCancelPlayerAbility INSTANCE = new MsgCancelPlayerAbility();
static MsgCancelPlayerAbility read(PacketByteBuf buffer) { 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.HandledPacket;
import com.sollace.fabwork.api.packets.Packet; import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
/** /**
* Sent to the client when the server needs to know precisely where the player is looking. * 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) { public MsgCasterLookRequest(PacketByteBuf buffer) {
this(buffer.readUuid()); 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.minelittlepony.unicopia.entity.player.Pony;
import com.sollace.fabwork.api.packets.Packet; import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
/** /**
@ -17,7 +16,7 @@ public record MsgPlayerAnimationChange (
UUID playerId, UUID playerId,
AnimationInstance animation, AnimationInstance animation,
int duration int duration
) implements Packet<PlayerEntity> { ) implements Packet {
MsgPlayerAnimationChange(PacketByteBuf buffer) { MsgPlayerAnimationChange(PacketByteBuf buffer) {
this( this(

View file

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

View file

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

View file

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

View file

@ -6,10 +6,9 @@ import java.util.Set;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.sollace.fabwork.api.packets.Packet; import com.sollace.fabwork.api.packets.Packet;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf; 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) { public MsgTribeSelect(PacketByteBuf buffer) {
this( this(
buffer.readCollection(HashSet::new, buf -> buf.readRegistryValue(Race.REGISTRY)), 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 com.sollace.fabwork.api.packets.Packet;
import net.minecraft.network.PacketByteBuf; 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) { MsgUnlockTraits(PacketByteBuf buffer) {
this(new HashSet<>()); this(new HashSet<>());
int length = buffer.readInt(); int length = buffer.readInt();

View file

@ -66,7 +66,8 @@ public class ClientNetworkHandlerImpl {
InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_MAGIC_BEAM, entity.getId()); 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) { private void handleBlockDestruction(PlayerEntity sender, MsgBlockDestruction packet) {

View file

@ -342,6 +342,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
@Override @Override
public Packet<ClientPlayPacketListener> createSpawnPacket() { 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.network.MsgSkyAngle;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
import net.minecraft.datafixer.DataFixTypes;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
@ -79,8 +80,7 @@ public class UnicopiaWorldProperties extends PersistentState {
public static UnicopiaWorldProperties forWorld(ServerWorld world) { public static UnicopiaWorldProperties forWorld(ServerWorld world) {
return world.getPersistentStateManager().getOrCreate( return world.getPersistentStateManager().getOrCreate(
nbt -> new UnicopiaWorldProperties(world, nbt), new Type<>(() -> new UnicopiaWorldProperties(world), nbt -> new UnicopiaWorldProperties(world, nbt), DataFixTypes.LEVEL), "unicopia_tribes"
() -> new UnicopiaWorldProperties(world), "unicopia_tribes"
); );
} }
} }

View file

@ -18,12 +18,12 @@ import net.minecraft.registry.tag.FluidTags;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.*; import net.minecraft.util.math.*;
import net.minecraft.util.math.random.Random; 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.PersistentState;
import net.minecraft.world.World; import net.minecraft.world.World;
public class WeatherConditions extends PersistentState implements Tickable { 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 THERMAL_FIELD = (world, pos) -> (float)getUpdraft(pos, world);
public static final Plane LOCAL_ALTITUDE_FIELD = (world, pos) -> { public static final Plane LOCAL_ALTITUDE_FIELD = (world, pos) -> {
if (!world.isAir(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.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.datafixer.DataFixTypes;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; 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) { 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) { if (world instanceof ServerWorld serverWorld) {
return serverWorld.getPersistentStateManager().getOrCreate( return serverWorld.getPersistentStateManager().getOrCreate(
compound -> loadFunc.apply(world, compound), new Type<>(
() -> factory.apply(world), () -> factory.apply(world),
compound -> loadFunc.apply(world, compound),
DataFixTypes.LEVEL
),
id.getNamespace() + "_" + id.getPath().replace('/', '_') 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 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/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 accessible method net/minecraft/entity/LightningEntity cleanOxidation (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V