Added filled jars

This commit is contained in:
Sollace 2021-02-14 22:15:30 +02:00
parent a94db2025a
commit b5dc84a139
15 changed files with 274 additions and 83 deletions

View file

@ -10,16 +10,23 @@ import com.minelittlepony.unicopia.client.particle.RainboomParticle;
import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle;
import com.minelittlepony.unicopia.client.particle.RaindropsParticle;
import com.minelittlepony.unicopia.client.particle.SphereParticle;
import com.minelittlepony.unicopia.item.ChameleonItem;
import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.particle.UParticles;
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.rendereregistry.v1.EntityRendererRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.client.render.DiffuseLighting;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.FlyingItemEntityRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.DyeableItem;
import net.minecraft.particle.ParticleEffect;
@ -39,6 +46,37 @@ public interface URenderers {
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);
BuiltinItemRendererRegistry.INSTANCE.register(UItems.FILLED_JAR, (stack, mode, matrices, vertexConsumers, light, overlay) -> {
ItemRenderer renderer = MinecraftClient.getInstance().getItemRenderer();
ChameleonItem item = (ChameleonItem)stack.getItem();
// Reset stuff done in the beforelands
matrices.pop();
if (mode == ModelTransformation.Mode.GUI) {
DiffuseLighting.disableGuiDepthLighting();
}
VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
if (item.hasAppearance(stack)) {
matrices.push();
matrices.scale(0.5F, 0.5F, 0.5F);
matrices.translate(0.0125, 0.1, 0);
renderer.renderItem(item.getAppearanceStack(stack), mode, light, overlay, matrices, immediate);
matrices.pop();
}
renderer.renderItem(item.createAppearanceStack(stack, UItems.EMPTY_JAR), mode, light, OverlayTexture.DEFAULT_UV, matrices, immediate);
immediate.draw();
if (mode == ModelTransformation.Mode.GUI) {
DiffuseLighting.enableGuiDepthLighting();
}
matrices.push();
});
}
static <T extends ParticleEffect> PendingParticleFactory<T> createFactory(ParticleSupplier<T> supplier) {

View file

@ -0,0 +1,47 @@
package com.minelittlepony.unicopia.item;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public interface ChameleonItem {
default boolean isFullyDisguised() {
return true;
}
default ItemStack getAppearanceStack(ItemStack stack) {
Item appearance = getAppearance(stack);
if (appearance != Items.AIR) {
return createAppearanceStack(stack, appearance);
}
return stack;
}
default ItemStack createAppearanceStack(ItemStack stack, Item appearance) {
ItemStack newAppearance = new ItemStack(appearance, stack.getCount());
if (stack.hasTag()) {
newAppearance.setTag(stack.getTag().copy());
}
newAppearance.removeSubTag("appearance");
return newAppearance;
}
default boolean hasAppearance(ItemStack stack) {
return getAppearance(stack) != Items.AIR;
}
default Item getAppearance(ItemStack stack) {
if (stack.hasTag() && stack.getTag().contains("appearance")) {
return Registry.ITEM.get(new Identifier(stack.getTag().getString("appearance")));
}
return Items.AIR;
}
default void setAppearance(ItemStack stack, Item appearance) {
stack.getOrCreateTag().putString("appearance", Registry.ITEM.getId(appearance).toString());
}
}

View file

@ -0,0 +1,39 @@
package com.minelittlepony.unicopia.item;
import com.minelittlepony.unicopia.entity.IItemEntity;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import com.minelittlepony.unicopia.util.WorldEvent;
import net.minecraft.block.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
public class FilledJarItem extends JarItem implements ChameleonItem {
public FilledJarItem(Settings settings) {
super(settings, false, false, false);
}
@Override
public Text getName(ItemStack stack) {
return hasAppearance(stack) ? new TranslatableText(getTranslationKey(stack), getAppearanceStack(stack).getName()) : UItems.EMPTY_JAR.getName(UItems.EMPTY_JAR.getDefaultStack());
}
@Override
public boolean isFullyDisguised() {
return false;
}
@Override
public ActionResult onGroundTick(IItemEntity item) {
return ActionResult.PASS;
}
@Override
protected void onImpact(MagicProjectileEntity projectile) {
projectile.dropStack(getAppearanceStack(projectile.getStack()));
WorldEvent.play(WorldEvent.DESTROY_BLOCK, projectile.world, projectile.getBlockPos(), Blocks.GLASS.getDefaultState());
}
}

View file

@ -4,72 +4,39 @@ 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 class GlowingRecipe extends ItemCombinationRecipe {
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) {
public final 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
protected boolean isContainerItem(ItemStack stack) {
return stack.getItem() instanceof GlowableItem;
}
@Override
public boolean fits(int i, int j) {
return i * j >= 2;
protected boolean isInsertItem(ItemStack stack) {
return stack.getItem() == Items.GLOWSTONE_DUST || stack.getItem() == Items.INK_SAC;
}
@Override
protected boolean isCombinationInvalid(ItemStack bangle, ItemStack dust) {
return (dust.getItem() == Items.GLOWSTONE_DUST) == ((GlowableItem)bangle.getItem()).isGlowing(bangle);
}
@Override

View file

@ -0,0 +1,66 @@
package com.minelittlepony.unicopia.item;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.SpecialCraftingRecipe;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
import net.minecraft.world.World;
public abstract class ItemCombinationRecipe extends SpecialCraftingRecipe {
public ItemCombinationRecipe(Identifier id) {
super(id);
}
@Override
public final boolean fits(int i, int j) {
return i * j >= 2;
}
@Override
public final boolean matches(CraftingInventory inventory, World world) {
Pair<ItemStack, ItemStack> result = runMatch(inventory);
return !result.getLeft().isEmpty() && !result.getRight().isEmpty();
}
protected 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 (isContainerItem(stack)) {
if (!bangle.isEmpty()) {
return new Pair<>(bangle, dust);
}
bangle = stack;
} else {
if (!isInsertItem(stack)) {
return new Pair<>(bangle, dust);
}
dust = stack;
}
}
}
if (!bangle.isEmpty() && isCombinationInvalid(bangle, dust)) {
return new Pair<>(ItemStack.EMPTY, ItemStack.EMPTY);
}
return new Pair<>(bangle, dust);
}
protected boolean isCombinationInvalid(ItemStack bangle, ItemStack dust) {
return false;
}
protected abstract boolean isContainerItem(ItemStack stack);
protected abstract boolean isInsertItem(ItemStack stack);
}

View file

@ -0,0 +1,44 @@
package com.minelittlepony.unicopia.item;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
public class JarInsertRecipe extends ItemCombinationRecipe {
public JarInsertRecipe(Identifier id) {
super(id);
}
@Override
public final ItemStack craft(CraftingInventory inventory) {
Pair<ItemStack, ItemStack> pair = runMatch(inventory);
ItemStack result = new ItemStack(UItems.FILLED_JAR);
UItems.FILLED_JAR.setAppearance(result, pair.getRight().getItem());
return result;
}
@Override
protected boolean isContainerItem(ItemStack stack) {
return stack.getItem() == UItems.EMPTY_JAR;
}
@Override
protected boolean isInsertItem(ItemStack stack) {
return !(stack.getItem() instanceof JarItem);
}
@Override
protected boolean isCombinationInvalid(ItemStack bangle, ItemStack dust) {
return false;
}
@Override
public RecipeSerializer<?> getSerializer() {
return URecipes.JAR_INSERT_SERIALIZER;
}
}

View file

@ -8,13 +8,11 @@ import com.minelittlepony.unicopia.util.WorldEvent;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.DispenserBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LightningEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
@ -39,8 +37,6 @@ public class JarItem extends Item implements ProjectileDelegate, ItemImpl.Tickab
this.rain = rain;
this.thunder = thunder;
this.lightning = lightning;
DispenserBlock.registerBehavior(this, ArmorItem.DISPENSER_BEHAVIOR);
}
@Override
@ -70,7 +66,6 @@ public class JarItem extends Item implements ProjectileDelegate, ItemImpl.Tickab
return TypedActionResult.success(stack, world.isClient());
}
@Override
public ActionResult onGroundTick(IItemEntity item) {
ItemEntity entity = item.get().getMaster();
@ -118,9 +113,7 @@ public class JarItem extends Item implements ProjectileDelegate, ItemImpl.Tickab
onImpact(projectile);
}
private void onImpact(MagicProjectileEntity projectile) {
protected void onImpact(MagicProjectileEntity projectile) {
if (!projectile.isClient()) {
ServerWorld world = (ServerWorld)projectile.world;

View file

@ -48,6 +48,7 @@ public interface UItems {
));
Item EMPTY_JAR = register("empty_jar", new JarItem(new Item.Settings().group(ItemGroup.DECORATIONS).maxCount(16).fireproof(), false, false, false));
FilledJarItem FILLED_JAR = register("filled_jar", new FilledJarItem(new Item.Settings().maxCount(1)));
Item RAIN_CLOUD_JAR = register("rain_cloud_jar", new JarItem(new Item.Settings().group(ItemGroup.DECORATIONS).maxCount(1).fireproof(), true, false, false));
Item STORM_CLOUD_JAR = register("storm_cloud_jar", new JarItem(new Item.Settings().group(ItemGroup.DECORATIONS).maxCount(1).fireproof(), true, true, false));
Item LIGHTNING_JAR = register("lightning_jar", new JarItem(new Item.Settings().group(ItemGroup.DECORATIONS).maxCount(1).fireproof(), false, false, true));
@ -75,7 +76,11 @@ public interface UItems {
FabricItemGroupBuilder.create(new Identifier("unicopia", "items")).appendItems(list -> {
list.addAll(VanillaOverrides.REGISTRY.stream().map(Item::getDefaultStack).collect(Collectors.toList()));
list.addAll(ITEMS.stream().map(Item::getDefaultStack).collect(Collectors.toList()));
list.addAll(ITEMS.stream()
.filter(item -> !(item instanceof ChameleonItem) || ((ChameleonItem)item).isFullyDisguised())
.map(Item::getDefaultStack)
.collect(Collectors.toList())
);
}).icon(ZAP_APPLE::getDefaultStack).build();
FabricItemGroupBuilder.create(new Identifier("unicopia", "horsefeed")).appendItems(list -> {

View file

@ -16,6 +16,7 @@ public interface URecipes {
RecipeSerializer<ShapelessRecipe> ZAP_APPLE_SERIALIZER = register("crafting_zap_apple", new ZapAppleRecipe.Serializer());
RecipeSerializer<GlowingRecipe> GLOWING_SERIALIZER = register("crafting_glowing", new SpecialRecipeSerializer<>(GlowingRecipe::new));
RecipeSerializer<JarInsertRecipe> JAR_INSERT_SERIALIZER = register("jar_insert", new SpecialRecipeSerializer<>(JarInsertRecipe::new));
static <T extends Recipe<?>> RecipeType<T> register(final String id) {
return Registry.register(Registry.RECIPE_TYPE, new Identifier("unicopia", id), new RecipeType<T>() {

View file

@ -24,13 +24,12 @@ import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.Rarity;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
public class ZapAppleItem extends AppleItem {
public class ZapAppleItem extends AppleItem implements ChameleonItem {
public ZapAppleItem(Settings settings) {
super(settings);
@ -101,25 +100,6 @@ public class ZapAppleItem extends AppleItem {
}
}
public ItemStack getAppearanceStack(ItemStack stack) {
Item appearance = ((ZapAppleItem)stack.getItem()).getAppearance(stack);
if (appearance != Items.AIR) {
ItemStack newAppearance = new ItemStack(appearance, stack.getCount());
newAppearance.setTag(stack.getTag().copy());
newAppearance.removeSubTag("appearance");
return newAppearance;
}
return stack;
}
public Item getAppearance(ItemStack stack) {
if (stack.hasTag() && stack.getTag().contains("appearance")) {
return Registry.ITEM.get(new Identifier(stack.getTag().getString("appearance")));
}
return Items.AIR;
}
@Override
public String getTranslationKey(ItemStack stack) {
Item appearance = getAppearance(stack);

View file

@ -4,8 +4,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import com.minelittlepony.unicopia.item.ZapAppleItem;
import com.minelittlepony.unicopia.item.ChameleonItem;
import net.minecraft.client.render.item.ItemModels;
import net.minecraft.item.ItemStack;
@ -15,8 +14,8 @@ abstract class MixinItemModels {
at = @At("HEAD"),
index = 1)
private ItemStack modifyStack(ItemStack stack) {
if (stack.getItem() instanceof ZapAppleItem) {
return ((ZapAppleItem)stack.getItem()).getAppearanceStack(stack);
if (stack.getItem() instanceof ChameleonItem && ((ChameleonItem)stack.getItem()).isFullyDisguised()) {
return ((ChameleonItem)stack.getItem()).getAppearanceStack(stack);
}
return stack;
}

View file

@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.entity.EntityPhysics;
import com.minelittlepony.unicopia.entity.Physics;
import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.EffectSync;
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
@ -193,6 +194,10 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
return ParticleTypes.ITEM_SNOWBALL;
}
if (stack.getItem() == UItems.FILLED_JAR) {
stack = UItems.EMPTY_JAR.getDefaultStack();
}
return new ItemStackParticleEffect(ParticleTypes.ITEM, stack);
}

View file

@ -17,8 +17,9 @@
"item.unicopia.zap_apple": "Zap Apple",
"item.unicopia.empty_jar": "Glass Jar",
"item.unicopia.rain_cloud_jar": "Rain Cloud in a Jar",
"item.unicopia.storm_cloud_jar": "Storm Cloud in a Jar",
"item.unicopia.filled_jar": "%s in a Jar",
"item.unicopia.rain_cloud_jar": "Rain in a Jar",
"item.unicopia.storm_cloud_jar": "Storm in a Jar",
"item.unicopia.lightning_jar": "Lightning in a Jar",
"item.unicopia.zap_apple_jam_jar": "Zap Apple Jam",

View file

@ -0,0 +1,3 @@
{
"parent": "builtin/entity"
}

View file

@ -0,0 +1,3 @@
{
"type": "unicopia:jar_insert"
}