mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Added friendship bracelets!
This commit is contained in:
parent
6ffff32718
commit
120fd6eb38
17 changed files with 420 additions and 16 deletions
|
@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||||
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
||||||
|
@ -114,7 +115,8 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements Attached {
|
||||||
return source.findAllEntitiesInRange(radius)
|
return source.findAllEntitiesInRange(radius)
|
||||||
.filter(entity -> {
|
.filter(entity -> {
|
||||||
return
|
return
|
||||||
(entity instanceof LivingEntity
|
!FriendshipBraceletItem.isComrade(source, entity)
|
||||||
|
&& (entity instanceof LivingEntity
|
||||||
|| entity instanceof TntEntity
|
|| entity instanceof TntEntity
|
||||||
|| entity instanceof FallingBlockEntity
|
|| entity instanceof FallingBlockEntity
|
||||||
|| entity instanceof EyeOfEnderEntity
|
|| entity instanceof EyeOfEnderEntity
|
||||||
|
|
|
@ -9,15 +9,18 @@ import com.minelittlepony.unicopia.client.particle.RainboomParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle;
|
import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.RaindropsParticle;
|
import com.minelittlepony.unicopia.client.particle.RaindropsParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.SphereParticle;
|
import com.minelittlepony.unicopia.client.particle.SphereParticle;
|
||||||
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
||||||
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.PendingParticleFactory;
|
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.PendingParticleFactory;
|
||||||
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
|
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
|
||||||
import net.minecraft.client.particle.Particle;
|
import net.minecraft.client.particle.Particle;
|
||||||
import net.minecraft.client.particle.SpriteProvider;
|
import net.minecraft.client.particle.SpriteProvider;
|
||||||
import net.minecraft.client.render.entity.FlyingItemEntityRenderer;
|
import net.minecraft.client.render.entity.FlyingItemEntityRenderer;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.item.DyeableItem;
|
||||||
import net.minecraft.particle.ParticleEffect;
|
import net.minecraft.particle.ParticleEffect;
|
||||||
|
|
||||||
public interface URenderers {
|
public interface URenderers {
|
||||||
|
@ -32,6 +35,8 @@ public interface URenderers {
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new);
|
||||||
|
|
||||||
EntityRendererRegistry.INSTANCE.register(UEntities.THROWN_ITEM, (manager, context) -> new FlyingItemEntityRenderer<>(manager, context.getItemRenderer()));
|
EntityRendererRegistry.INSTANCE.register(UEntities.THROWN_ITEM, (manager, context) -> new FlyingItemEntityRenderer<>(manager, context.getItemRenderer()));
|
||||||
|
|
||||||
|
ColorProviderRegistry.ITEM.register((stack, i) -> i > 0 ? -1 : ((DyeableItem)stack.getItem()).getColor(stack), UItems.FRIENDSHIP_BRACELET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static <T extends ParticleEffect> PendingParticleFactory<T> createFactory(ParticleSupplier<T> supplier) {
|
static <T extends ParticleEffect> PendingParticleFactory<T> createFactory(ParticleSupplier<T> supplier) {
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.minelittlepony.unicopia.client.render;
|
||||||
|
|
||||||
|
import com.minelittlepony.common.util.Color;
|
||||||
|
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||||
|
import com.minelittlepony.unicopia.item.GlowableItem;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.Model;
|
||||||
|
import net.minecraft.client.model.ModelPart;
|
||||||
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
|
import net.minecraft.client.render.OverlayTexture;
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
|
import net.minecraft.client.render.entity.feature.FeatureRenderer;
|
||||||
|
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
|
||||||
|
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
||||||
|
import net.minecraft.client.render.item.ItemRenderer;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.item.DyeableItem;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Arm;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class BraceletFeatureRenderer<
|
||||||
|
E extends LivingEntity,
|
||||||
|
M extends BipedEntityModel<E>> extends FeatureRenderer<E, M> {
|
||||||
|
|
||||||
|
private static final Identifier TEXTURE = new Identifier("unicopia", "textures/models/armor/bracelet.png");
|
||||||
|
|
||||||
|
private final BraceletModel steveModel = new BraceletModel(0.3F, false);
|
||||||
|
private final BraceletModel alexModel = new BraceletModel(0.3F, true);
|
||||||
|
|
||||||
|
public BraceletFeatureRenderer(FeatureRendererContext<E, M> context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
|
||||||
|
|
||||||
|
ItemStack item = entity.getEquippedStack(EquipmentSlot.CHEST);
|
||||||
|
|
||||||
|
if (item.getItem() instanceof FriendshipBraceletItem) {
|
||||||
|
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(TEXTURE), false, false);
|
||||||
|
|
||||||
|
int j = ((DyeableItem)item.getItem()).getColor(item);
|
||||||
|
|
||||||
|
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getModel().startsWith("slim");
|
||||||
|
|
||||||
|
BraceletModel model = alex ? alexModel : steveModel;
|
||||||
|
|
||||||
|
model.setAngles(getContextModel());
|
||||||
|
model.setVisible(entity.getMainArm());
|
||||||
|
model.render(stack, consumer, ((GlowableItem)item.getItem()).isGlowing(item) ? 0x0F00F0 : lightUv, OverlayTexture.DEFAULT_UV, Color.r(j), Color.g(j), Color.b(j), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class BraceletModel extends Model {
|
||||||
|
|
||||||
|
private final ModelPart leftArm;
|
||||||
|
private final ModelPart rightArm;
|
||||||
|
|
||||||
|
private final boolean alex;
|
||||||
|
|
||||||
|
public BraceletModel(float dilate, boolean alex) {
|
||||||
|
super(RenderLayer::getEntityTranslucent);
|
||||||
|
this.alex = alex;
|
||||||
|
rightArm = new ModelPart(this, 0, alex ? 6 : 0);
|
||||||
|
rightArm.addCuboid(-3, 7, -2, alex ? 3 : 4, 2, 4, dilate);
|
||||||
|
leftArm = new ModelPart(this, 0, alex ? 6 : 0);
|
||||||
|
leftArm.mirror = true;
|
||||||
|
leftArm.addCuboid(-1, 7, -2, alex ? 3 : 4, 2, 4, dilate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAngles(BipedEntityModel<?> biped) {
|
||||||
|
leftArm.copyPositionAndRotation(biped.leftArm);
|
||||||
|
rightArm.copyPositionAndRotation(biped.rightArm);
|
||||||
|
if (alex) {
|
||||||
|
rightArm.pivotX++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisible(Arm arm) {
|
||||||
|
leftArm.visible = arm == Arm.LEFT;
|
||||||
|
rightArm.visible = arm == Arm.RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack matrixStack, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) {
|
||||||
|
leftArm.render(matrixStack, vertexConsumer, i, j, f, g, h, k);
|
||||||
|
rightArm.render(matrixStack, vertexConsumer, i, j, f, g, h, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.EquinePredicates;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.block.DispenserBlock;
|
||||||
|
import net.minecraft.client.item.TooltipContext;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ArmorItem;
|
||||||
|
import net.minecraft.item.DyeableItem;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Wearable;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.stat.Stats;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class FriendshipBraceletItem extends Item implements DyeableItem, Wearable, GlowableItem {
|
||||||
|
|
||||||
|
public FriendshipBraceletItem(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
DispenserBlock.registerBehavior(this, ArmorItem.DISPENSER_BEHAVIOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
|
||||||
|
ItemStack stack = player.getStackInHand(hand);
|
||||||
|
|
||||||
|
if (!isSigned(stack) && EquinePredicates.PLAYER_UNICORN.test(player)) {
|
||||||
|
player.setCurrentHand(hand);
|
||||||
|
|
||||||
|
ItemStack result = stack.copy();
|
||||||
|
result.setCount(1);
|
||||||
|
result.getOrCreateTag().putString("issuer", player.getName().asString());
|
||||||
|
|
||||||
|
if (!player.abilities.creativeMode) {
|
||||||
|
stack.decrement(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.incrementStat(Stats.USED.getOrCreateStat(this));
|
||||||
|
player.playSound(SoundEvents.ITEM_BOOK_PUT, 1, 1);
|
||||||
|
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
return TypedActionResult.consume(result);
|
||||||
|
}
|
||||||
|
if (!player.giveItemStack(result)) {
|
||||||
|
player.dropStack(result);
|
||||||
|
}
|
||||||
|
return TypedActionResult.consume(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
EquipmentSlot slot = MobEntity.getPreferredEquipmentSlot(stack);
|
||||||
|
ItemStack currentArmor = player.getEquippedStack(slot);
|
||||||
|
|
||||||
|
if (currentArmor.isEmpty()) {
|
||||||
|
ItemStack result = stack.copy();
|
||||||
|
result.setCount(1);
|
||||||
|
|
||||||
|
if (!player.abilities.creativeMode) {
|
||||||
|
stack.decrement(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.equipStack(slot, result);
|
||||||
|
return TypedActionResult.success(stack, world.isClient());
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypedActionResult.fail(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> list, TooltipContext tooltipContext) {
|
||||||
|
if (isSigned(stack)) {
|
||||||
|
list.add(new TranslatableText("item.unicopia.friendship_bracelet.issuer", getSignature(stack)));
|
||||||
|
}
|
||||||
|
if (isGlowing(stack)) {
|
||||||
|
list.add(new TranslatableText("item.unicopia.friendship_bracelet.glowing").formatted(Formatting.ITALIC, Formatting.GRAY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkSignature(ItemStack stack, PlayerEntity player) {
|
||||||
|
return player.getName().asString().contentEquals(getSignature(stack));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getSignature(ItemStack stack) {
|
||||||
|
return isSigned(stack) ? stack.getTag().getString("issuer") : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSigned(ItemStack stack) {
|
||||||
|
return stack.hasTag() && stack.getTag().contains("issuer");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSignedBy(ItemStack stack, PlayerEntity player) {
|
||||||
|
return stack.getItem() instanceof FriendshipBraceletItem
|
||||||
|
&& ((FriendshipBraceletItem)stack.getItem()).checkSignature(stack, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isComrade(Caster<?> caster, Entity entity) {
|
||||||
|
Entity master = caster.getMaster();
|
||||||
|
if (master instanceof PlayerEntity && entity instanceof LivingEntity) {
|
||||||
|
return isSignedBy(((LivingEntity)entity).getOffHandStack(), (PlayerEntity)master)
|
||||||
|
|| isSignedBy(((LivingEntity)entity).getEquippedStack(EquipmentSlot.CHEST), (PlayerEntity)master);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EquipmentSlot getPreferredEquipmentSlot(ItemStack stack) {
|
||||||
|
return isSigned(stack) ? EquipmentSlot.CHEST : EquipmentSlot.OFFHAND;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
||||||
|
public interface GlowableItem {
|
||||||
|
default boolean isGlowing(ItemStack stack) {
|
||||||
|
CompoundTag tag = stack.getSubTag("display");
|
||||||
|
return tag != null && tag.getBoolean("glowing");
|
||||||
|
}
|
||||||
|
|
||||||
|
default void setGlowing(ItemStack stack, boolean glowing) {
|
||||||
|
stack.getOrCreateSubTag("display").putBoolean("glowing", glowing);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import net.minecraft.inventory.CraftingInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.recipe.RecipeSerializer;
|
||||||
|
import net.minecraft.recipe.SpecialCraftingRecipe;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.Pair;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class GlowingRecipe extends SpecialCraftingRecipe {
|
||||||
|
|
||||||
|
public GlowingRecipe(Identifier id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(CraftingInventory inventory, World world) {
|
||||||
|
Pair<ItemStack, ItemStack> result = runMatch(inventory);
|
||||||
|
|
||||||
|
return !result.getLeft().isEmpty() && !result.getRight().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack craft(CraftingInventory inventory) {
|
||||||
|
Pair<ItemStack, ItemStack> pair = runMatch(inventory);
|
||||||
|
|
||||||
|
ItemStack result = pair.getLeft().copy();
|
||||||
|
((GlowableItem)result.getItem()).setGlowing(result, pair.getRight().getItem() == Items.GLOWSTONE_DUST);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<ItemStack, ItemStack> runMatch(CraftingInventory inventory) {
|
||||||
|
ItemStack bangle = ItemStack.EMPTY;
|
||||||
|
ItemStack dust = ItemStack.EMPTY;
|
||||||
|
|
||||||
|
for(int i = 0; i < inventory.size(); i++) {
|
||||||
|
ItemStack stack = inventory.getStack(i);
|
||||||
|
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
if (stack.getItem() instanceof GlowableItem) {
|
||||||
|
if (!bangle.isEmpty()) {
|
||||||
|
return new Pair<>(bangle, dust);
|
||||||
|
}
|
||||||
|
|
||||||
|
bangle = stack;
|
||||||
|
} else {
|
||||||
|
if (!(stack.getItem() == Items.GLOWSTONE_DUST || stack.getItem() == Items.INK_SAC)) {
|
||||||
|
return new Pair<>(bangle, dust);
|
||||||
|
}
|
||||||
|
|
||||||
|
dust = stack;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bangle.isEmpty()) {
|
||||||
|
if ((dust.getItem() == Items.GLOWSTONE_DUST) == ((GlowableItem)bangle.getItem()).isGlowing(bangle)) {
|
||||||
|
return new Pair<>(ItemStack.EMPTY, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Pair<>(bangle, dust);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fits(int i, int j) {
|
||||||
|
return i * j >= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getSerializer() {
|
||||||
|
return URecipes.GLOWING_SERIALIZER;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.Item.Settings;
|
import net.minecraft.item.Item.Settings;
|
||||||
import net.minecraft.item.ItemGroup;
|
import net.minecraft.item.ItemGroup;
|
||||||
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
|
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
|
||||||
|
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.FoodComponents;
|
import net.minecraft.item.FoodComponents;
|
||||||
import net.minecraft.item.MusicDiscItem;
|
import net.minecraft.item.MusicDiscItem;
|
||||||
|
@ -39,6 +40,13 @@ public interface UItems {
|
||||||
Item MUSIC_DISC_POPULAR = register("music_disc_popular", USounds.RECORD_POPULAR);
|
Item MUSIC_DISC_POPULAR = register("music_disc_popular", USounds.RECORD_POPULAR);
|
||||||
Item MUSIC_DISC_FUNK = register("music_disc_funk", USounds.RECORD_FUNK);
|
Item MUSIC_DISC_FUNK = register("music_disc_funk", USounds.RECORD_FUNK);
|
||||||
|
|
||||||
|
FriendshipBraceletItem FRIENDSHIP_BRACELET = register("friendship_bracelet", new FriendshipBraceletItem(
|
||||||
|
new FabricItemSettings()
|
||||||
|
.rarity(Rarity.UNCOMMON)
|
||||||
|
.group(ItemGroup.TOOLS)
|
||||||
|
.equipmentSlot(FriendshipBraceletItem::getPreferredEquipmentSlot)
|
||||||
|
));
|
||||||
|
|
||||||
static <T extends Item> T register(String name, T item) {
|
static <T extends Item> T register(String name, T item) {
|
||||||
ITEMS.add(item);
|
ITEMS.add(item);
|
||||||
if (item instanceof BlockItem) {
|
if (item instanceof BlockItem) {
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
|
||||||
|
import net.minecraft.recipe.Ingredient;
|
||||||
import net.minecraft.recipe.Recipe;
|
import net.minecraft.recipe.Recipe;
|
||||||
import net.minecraft.recipe.RecipeSerializer;
|
import net.minecraft.recipe.RecipeSerializer;
|
||||||
import net.minecraft.recipe.RecipeType;
|
import net.minecraft.recipe.RecipeType;
|
||||||
import net.minecraft.recipe.ShapelessRecipe;
|
import net.minecraft.recipe.ShapelessRecipe;
|
||||||
|
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.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
public interface URecipes {
|
public interface URecipes {
|
||||||
|
|
||||||
RecipeSerializer<ShapelessRecipe> ZAP_APPLE_SERIALIZER = register("crafting_zap_apple", new ZapAppleRecipe.Serializer());
|
RecipeSerializer<ShapelessRecipe> ZAP_APPLE_SERIALIZER = register("crafting_zap_apple", new ZapAppleRecipe.Serializer());
|
||||||
|
RecipeSerializer<GlowingRecipe> GLOWING_SERIALIZER = register("crafting_glowing", new SpecialRecipeSerializer<>(GlowingRecipe::new));
|
||||||
|
|
||||||
static <T extends Recipe<?>> RecipeType<T> register(final String id) {
|
static <T extends Recipe<?>> RecipeType<T> register(final String id) {
|
||||||
return Registry.register(Registry.RECIPE_TYPE, new Identifier("unicopia", id), new RecipeType<T>() {
|
return Registry.register(Registry.RECIPE_TYPE, new Identifier("unicopia", id), new RecipeType<T>() {
|
||||||
|
@ -24,5 +30,19 @@ public interface URecipes {
|
||||||
return Registry.register(Registry.RECIPE_SERIALIZER, new Identifier("unicopia", id), serializer);
|
return Registry.register(Registry.RECIPE_SERIALIZER, new Identifier("unicopia", id), serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DefaultedList<Ingredient> getIngredients(JsonArray json) {
|
||||||
|
DefaultedList<Ingredient> defaultedList = DefaultedList.of();
|
||||||
|
|
||||||
|
for (int i = 0; i < json.size(); ++i) {
|
||||||
|
Ingredient ingredient = Ingredient.fromJson(json.get(i));
|
||||||
|
if (!ingredient.isEmpty()) {
|
||||||
|
defaultedList.add(ingredient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultedList;
|
||||||
|
}
|
||||||
|
|
||||||
static void bootstrap() {}
|
static void bootstrap() {}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ public class ZapAppleRecipe extends ShapelessRecipe {
|
||||||
@Override
|
@Override
|
||||||
public ShapelessRecipe read(Identifier identifier, JsonObject json) {
|
public ShapelessRecipe read(Identifier identifier, JsonObject json) {
|
||||||
String group = JsonHelper.getString(json, "group", "");
|
String group = JsonHelper.getString(json, "group", "");
|
||||||
DefaultedList<Ingredient> ingredients = getIngredients(JsonHelper.getArray(json, "ingredients"));
|
DefaultedList<Ingredient> ingredients = URecipes.getIngredients(JsonHelper.getArray(json, "ingredients"));
|
||||||
|
|
||||||
if (ingredients.isEmpty()) {
|
if (ingredients.isEmpty()) {
|
||||||
throw new JsonParseException("No ingredients for shapeless recipe");
|
throw new JsonParseException("No ingredients for shapeless recipe");
|
||||||
|
@ -48,18 +47,5 @@ public class ZapAppleRecipe extends ShapelessRecipe {
|
||||||
|
|
||||||
return new ZapAppleRecipe(identifier, group, input.readItemStack(), ingredients);
|
return new ZapAppleRecipe(identifier, group, input.readItemStack(), ingredients);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DefaultedList<Ingredient> getIngredients(JsonArray json) {
|
|
||||||
DefaultedList<Ingredient> defaultedList = DefaultedList.of();
|
|
||||||
|
|
||||||
for (int i = 0; i < json.size(); ++i) {
|
|
||||||
Ingredient ingredient = Ingredient.fromJson(json.get(i));
|
|
||||||
if (!ingredient.isEmpty()) {
|
|
||||||
defaultedList.add(ingredient);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultedList;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.minelittlepony.unicopia.mixin.client;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
|
import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
|
||||||
|
import net.minecraft.client.render.entity.feature.FeatureRenderer;
|
||||||
|
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
|
||||||
|
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
|
||||||
|
@Mixin(ArmorFeatureRenderer.class)
|
||||||
|
abstract class MixinArmorFeatureRenderer<T extends LivingEntity, M extends BipedEntityModel<T>, A extends BipedEntityModel<T>> extends FeatureRenderer<T, M> {
|
||||||
|
|
||||||
|
private BraceletFeatureRenderer<T, M> bracelet;
|
||||||
|
|
||||||
|
MixinArmorFeatureRenderer() { super(null); }
|
||||||
|
|
||||||
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
|
private void onInit(FeatureRendererContext<T, M> context, A inner, A outer, CallbackInfo info) {
|
||||||
|
bracelet = new BraceletFeatureRenderer<>(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "render", at = @At("RETURN"))
|
||||||
|
private void onRender(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch, CallbackInfo info) {
|
||||||
|
bracelet.render(stack, renderContext, lightUv, entity, limbDistance, limbAngle, tickDelta, age, headYaw, headPitch);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,10 @@
|
||||||
"itemGroup.unicopia.items": "Unicopia - Misc.",
|
"itemGroup.unicopia.items": "Unicopia - Misc.",
|
||||||
"itemGroup.unicopia.horsefeed": "Unicopia - Horse Feed",
|
"itemGroup.unicopia.horsefeed": "Unicopia - Horse Feed",
|
||||||
|
|
||||||
|
"item.unicopia.friendship_bracelet": "Bangle of Comradery",
|
||||||
|
"item.unicopia.friendship_bracelet.issuer": "Signed by %s",
|
||||||
|
"item.unicopia.friendship_bracelet.glowing": "Glowing",
|
||||||
|
|
||||||
"item.unicopia.green_apple": "Granny Smith Apple",
|
"item.unicopia.green_apple": "Granny Smith Apple",
|
||||||
"item.unicopia.sweet_apple": "Sweet Apple Acres Apple",
|
"item.unicopia.sweet_apple": "Sweet Apple Acres Apple",
|
||||||
"item.unicopia.sour_apple": "Sour Apple",
|
"item.unicopia.sour_apple": "Sour Apple",
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/friendship_bracelet"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"pattern": [
|
||||||
|
"*#*",
|
||||||
|
"# #",
|
||||||
|
"*#*"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"*": {
|
||||||
|
"item": "minecraft:string"
|
||||||
|
},
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:leather"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "unicopia:friendship_bracelet"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"type": "unicopia:crafting_glowing"
|
||||||
|
}
|
|
@ -24,6 +24,7 @@
|
||||||
"MixinWorld"
|
"MixinWorld"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
|
"client.MixinArmorFeatureRenderer",
|
||||||
"client.MixinCamera",
|
"client.MixinCamera",
|
||||||
"client.MixinClientPlayerInteractionManager",
|
"client.MixinClientPlayerInteractionManager",
|
||||||
"client.MixinEntityRenderDispatcher",
|
"client.MixinEntityRenderDispatcher",
|
||||||
|
|
Loading…
Reference in a new issue