Compare commits
8 commits
master
...
flower-lay
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ad6d36fecb | ||
![]() |
d393812448 | ||
![]() |
67ae714c64 | ||
![]() |
9bcabeb8f7 | ||
![]() |
f73affdb2c | ||
![]() |
1f633e88be | ||
![]() |
3afde78414 | ||
![]() |
a8990da272 |
|
@ -4,11 +4,14 @@ import fr.sushi.charmsnfabrics.CharmsAndFabrics;
|
||||||
import fr.sushi.charmsnfabrics.client.datagen.CnFBlockLootProvider;
|
import fr.sushi.charmsnfabrics.client.datagen.CnFBlockLootProvider;
|
||||||
import fr.sushi.charmsnfabrics.client.datagen.CnFBlockTagsProvider;
|
import fr.sushi.charmsnfabrics.client.datagen.CnFBlockTagsProvider;
|
||||||
import fr.sushi.charmsnfabrics.client.datagen.CnFModelProvider;
|
import fr.sushi.charmsnfabrics.client.datagen.CnFModelProvider;
|
||||||
|
import fr.sushi.charmsnfabrics.client.model.FlowerCrownItemModel;
|
||||||
import fr.sushi.charmsnfabrics.client.model.FlowerCrownModel;
|
import fr.sushi.charmsnfabrics.client.model.FlowerCrownModel;
|
||||||
import fr.sushi.charmsnfabrics.client.renderer.FloralWorkbenchRenderer;
|
import fr.sushi.charmsnfabrics.client.renderer.FloralWorkbenchRenderer;
|
||||||
import fr.sushi.charmsnfabrics.client.renderer.FlowerCrownRenderer;
|
import fr.sushi.charmsnfabrics.client.renderer.FlowerCrownRenderer;
|
||||||
|
import fr.sushi.charmsnfabrics.client.util.FlowersTint;
|
||||||
import fr.sushi.charmsnfabrics.common.CnFRegistries;
|
import fr.sushi.charmsnfabrics.common.CnFRegistries;
|
||||||
import net.minecraft.data.loot.LootTableProvider;
|
import net.minecraft.data.loot.LootTableProvider;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||||
import net.neoforged.api.distmarker.Dist;
|
import net.neoforged.api.distmarker.Dist;
|
||||||
import net.neoforged.bus.api.SubscribeEvent;
|
import net.neoforged.bus.api.SubscribeEvent;
|
||||||
|
@ -17,6 +20,8 @@ import net.neoforged.fml.common.EventBusSubscriber;
|
||||||
import net.neoforged.fml.common.Mod;
|
import net.neoforged.fml.common.Mod;
|
||||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||||
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
||||||
|
import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent;
|
||||||
|
import net.neoforged.neoforge.client.event.RegisterItemModelsEvent;
|
||||||
import net.neoforged.neoforge.client.gui.ConfigurationScreen;
|
import net.neoforged.neoforge.client.gui.ConfigurationScreen;
|
||||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
||||||
import net.neoforged.neoforge.data.event.GatherDataEvent;
|
import net.neoforged.neoforge.data.event.GatherDataEvent;
|
||||||
|
@ -39,7 +44,8 @@ public class CnFClient
|
||||||
private static void onClientSetup(final FMLClientSetupEvent event)
|
private static void onClientSetup(final FMLClientSetupEvent event)
|
||||||
{
|
{
|
||||||
ICurioRenderer.register(CnFRegistries.Items.FLOWER_CROWN.get(),
|
ICurioRenderer.register(CnFRegistries.Items.FLOWER_CROWN.get(),
|
||||||
FlowerCrownRenderer::new);
|
() -> new FlowerCrownRenderer(
|
||||||
|
FlowerCrownRenderer.createModel()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -70,4 +76,32 @@ public class CnFClient
|
||||||
LootContextParamSets.BLOCK)), lookup));
|
LootContextParamSets.BLOCK)), lookup));
|
||||||
event.createProvider(CnFBlockTagsProvider::new);
|
event.createProvider(CnFBlockTagsProvider::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
private static void onRegisterItemModels(
|
||||||
|
final RegisterItemModelsEvent event)
|
||||||
|
{
|
||||||
|
event.register(
|
||||||
|
ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
|
||||||
|
"flower_crown_loader"),
|
||||||
|
FlowerCrownItemModel.Unbaked.MAP_CODEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
private static void onRegisterTinters(
|
||||||
|
RegisterColorHandlersEvent.ItemTintSources event)
|
||||||
|
{
|
||||||
|
event.register(
|
||||||
|
ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
|
||||||
|
"flower_tint"), FlowersTint.MAP_CODEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @SubscribeEvent
|
||||||
|
// private static void onRegisterStandaloneModels(
|
||||||
|
// ModelEvent.RegisterStandalone event)
|
||||||
|
// {
|
||||||
|
// event.register(new StandaloneModelKey<>(
|
||||||
|
// ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
|
||||||
|
// "item/flower")), StandaloneModelBaker.quadCollection());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
package fr.sushi.charmsnfabrics.client.model;
|
||||||
|
|
||||||
|
import com.mojang.math.Transformation;
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import fr.sushi.charmsnfabrics.CharmsAndFabrics;
|
||||||
|
import fr.sushi.charmsnfabrics.client.util.FlowersTint;
|
||||||
|
import fr.sushi.charmsnfabrics.common.CnFRegistries;
|
||||||
|
import fr.sushi.charmsnfabrics.common.data.FlowerCrownContent;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockElement;
|
||||||
|
import net.minecraft.client.renderer.block.model.TextureSlots;
|
||||||
|
import net.minecraft.client.renderer.item.*;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.client.resources.model.*;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.item.ItemDisplayContext;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.neoforged.neoforge.client.ClientHooks;
|
||||||
|
import net.neoforged.neoforge.client.model.ComposedModelState;
|
||||||
|
import net.neoforged.neoforge.client.model.UnbakedElementsHelper;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.joml.Quaternionf;
|
||||||
|
import org.joml.Vector2f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class FlowerCrownItemModel implements ItemModel
|
||||||
|
{
|
||||||
|
private static final Map<Integer, Vector2f> TRANSLATIONS = new HashMap<>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Position the flower on the item model based on the layer (anticlockwise)
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
{
|
||||||
|
TRANSLATIONS.put(0, new Vector2f(1, -4));
|
||||||
|
TRANSLATIONS.put(1, new Vector2f(5, -3));
|
||||||
|
TRANSLATIONS.put(2, new Vector2f(5, 2));
|
||||||
|
TRANSLATIONS.put(3, new Vector2f(2, 4));
|
||||||
|
TRANSLATIONS.put(4, new Vector2f(-3, 4));
|
||||||
|
TRANSLATIONS.put(5, new Vector2f(-5, 0));
|
||||||
|
TRANSLATIONS.put(6, new Vector2f(-4, -3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ModelDebugName DEBUG_NAME =
|
||||||
|
() -> "FlowerCrownItemModel";
|
||||||
|
|
||||||
|
private final Unbaked rawModel;
|
||||||
|
private final BakingContext context;
|
||||||
|
private ModelRenderProperties renderProperties;
|
||||||
|
|
||||||
|
public FlowerCrownItemModel(Unbaked rawModel, BakingContext context)
|
||||||
|
{
|
||||||
|
this.rawModel = rawModel;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Transformation getTransform(int layer)
|
||||||
|
{
|
||||||
|
Vector2f uv = TRANSLATIONS.get(layer);
|
||||||
|
return new Transformation(
|
||||||
|
new Vector3f(uv.x * 0.0625f, uv.y * 0.0625f, 0.0f),
|
||||||
|
new Quaternionf(), new Vector3f(1.001f), new Quaternionf());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceLocation getFlowerLocation(int layer)
|
||||||
|
{
|
||||||
|
|
||||||
|
return ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
|
||||||
|
"flower/flower_" + (layer % 2 == 0 ? "large" : "small"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceLocation getOutlineLocation(int layer)
|
||||||
|
{
|
||||||
|
|
||||||
|
return ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
|
||||||
|
"flower/flower_outline_" +
|
||||||
|
(layer % 2 == 0 ? "large" : "small"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextureAtlasSprite getSprite(ResourceLocation textureLocation)
|
||||||
|
{
|
||||||
|
SpriteGetter sprites = this.context.blockModelBaker().sprites();
|
||||||
|
Material material = ClientHooks.getBlockMaterial(textureLocation);
|
||||||
|
return sprites.get(material, DEBUG_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bakes the base and updates the LayerRenderState quads
|
||||||
|
*/
|
||||||
|
private ItemModel bakeBase()
|
||||||
|
{
|
||||||
|
ModelBaker baker = this.context.blockModelBaker();
|
||||||
|
ResolvedModel resolvedModel = baker.getModel(this.rawModel.base);
|
||||||
|
TextureSlots slots = resolvedModel.getTopTextureSlots();
|
||||||
|
|
||||||
|
List<BakedQuad> quads = resolvedModel
|
||||||
|
.bakeTopGeometry(slots, baker, BlockModelRotation.X0_Y0)
|
||||||
|
.getAll();
|
||||||
|
this.renderProperties =
|
||||||
|
ModelRenderProperties.fromResolvedModel(baker, resolvedModel,
|
||||||
|
slots);
|
||||||
|
return new BlockModelWrapper(List.of(), quads, this.renderProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<BakedQuad> bakeModel(ResourceLocation textureLocation,
|
||||||
|
int layer)
|
||||||
|
{
|
||||||
|
TextureAtlasSprite sprite = this.getSprite(textureLocation);
|
||||||
|
List<BlockElement> bits =
|
||||||
|
UnbakedElementsHelper.createUnbakedItemElements(0, sprite);
|
||||||
|
return UnbakedElementsHelper.bakeElements(bits, $ -> sprite,
|
||||||
|
new ComposedModelState(BlockModelRotation.X0_Y0,
|
||||||
|
this.getTransform(layer)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemModel bakeOutline(int layer)
|
||||||
|
{
|
||||||
|
List<BakedQuad> quads =
|
||||||
|
this.bakeModel(this.getOutlineLocation(layer), layer);
|
||||||
|
return new BlockModelWrapper(List.of(new FlowersTint(layer)), quads,
|
||||||
|
this.renderProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemModel bakeFlower(int layer)
|
||||||
|
{
|
||||||
|
List<ItemModel> models = new ArrayList<>();
|
||||||
|
models.add(this.bakeOutline(layer));
|
||||||
|
|
||||||
|
List<BakedQuad> quads =
|
||||||
|
this.bakeModel(this.getFlowerLocation(layer), layer);
|
||||||
|
models.add(
|
||||||
|
new BlockModelWrapper(List.of(), quads, this.renderProperties));
|
||||||
|
return new CompositeModel(models);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemModel bakeFlowerCrown(FlowerCrownContent content)
|
||||||
|
{
|
||||||
|
List<ItemModel> models = new ArrayList<>();
|
||||||
|
models.add(this.bakeBase());
|
||||||
|
for (int i = 0; i < content.flowers().size(); i++)
|
||||||
|
{
|
||||||
|
if (content.flowers().get(i).isEmpty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
models.add(this.bakeFlower(i));
|
||||||
|
}
|
||||||
|
return new CompositeModel(models);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(ItemStackRenderState renderState, ItemStack stack,
|
||||||
|
ItemModelResolver itemModelResolver,
|
||||||
|
ItemDisplayContext displayContext, @Nullable ClientLevel level,
|
||||||
|
@Nullable LivingEntity entity, int seed)
|
||||||
|
{
|
||||||
|
FlowerCrownContent comp = stack.get(
|
||||||
|
CnFRegistries.DataComponents.FLOWER_CROWN_CONTENT.get());
|
||||||
|
if (comp != null)
|
||||||
|
{
|
||||||
|
this.bakeFlowerCrown(comp)
|
||||||
|
.update(renderState, stack, itemModelResolver, displayContext,
|
||||||
|
level, entity, seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Unbaked(ResourceLocation base) implements ItemModel.Unbaked
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final MapCodec<Unbaked> MAP_CODEC =
|
||||||
|
RecordCodecBuilder.mapCodec(unbaked -> unbaked
|
||||||
|
.group(ResourceLocation.CODEC.fieldOf("base")
|
||||||
|
.forGetter(Unbaked::base))
|
||||||
|
.apply(unbaked, Unbaked::new));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapCodec<? extends ItemModel.Unbaked> type()
|
||||||
|
{
|
||||||
|
return MAP_CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemModel bake(BakingContext context)
|
||||||
|
{
|
||||||
|
return new FlowerCrownItemModel(this, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveDependencies(Resolver resolver)
|
||||||
|
{
|
||||||
|
resolver.markDependency(this.base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import fr.sushi.charmsnfabrics.client.model.FlowerCrownModel;
|
||||||
import fr.sushi.charmsnfabrics.common.item.FlowerCrown;
|
import fr.sushi.charmsnfabrics.common.item.FlowerCrown;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.model.EntityModel;
|
import net.minecraft.client.model.EntityModel;
|
||||||
|
import net.minecraft.client.model.geom.EntityModelSet;
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||||
|
@ -24,11 +25,15 @@ public class FlowerCrownRenderer implements ICurioRenderer
|
||||||
{
|
{
|
||||||
private final FlowerCrownModel model;
|
private final FlowerCrownModel model;
|
||||||
|
|
||||||
public FlowerCrownRenderer()
|
public FlowerCrownRenderer(FlowerCrownModel model)
|
||||||
{
|
{
|
||||||
this.model = new FlowerCrownModel(
|
this.model = model;
|
||||||
Minecraft.getInstance().getEntityModels()
|
}
|
||||||
.bakeLayer(CnFLayers.CROWN_LAYER));
|
|
||||||
|
public static FlowerCrownModel createModel()
|
||||||
|
{
|
||||||
|
EntityModelSet modelSet = Minecraft.getInstance().getEntityModels();
|
||||||
|
return new FlowerCrownModel(modelSet.bakeLayer(CnFLayers.CROWN_LAYER));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package fr.sushi.charmsnfabrics.client.util;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import fr.sushi.charmsnfabrics.common.CnFRegistries;
|
||||||
|
import fr.sushi.charmsnfabrics.common.data.FlowerCrownContent;
|
||||||
|
import net.minecraft.client.color.item.ItemTintSource;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.item.DyeColor;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public record FlowersTint(int layer) implements ItemTintSource
|
||||||
|
{
|
||||||
|
public static final MapCodec<FlowersTint> MAP_CODEC =
|
||||||
|
RecordCodecBuilder.mapCodec(instance -> instance
|
||||||
|
.group(Codec.INT.fieldOf("layer")
|
||||||
|
.forGetter(FlowersTint::layer))
|
||||||
|
.apply(instance, FlowersTint::new));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int calculate(ItemStack stack, @Nullable ClientLevel level,
|
||||||
|
@Nullable LivingEntity entity)
|
||||||
|
{
|
||||||
|
FlowerCrownContent data = stack.get(
|
||||||
|
CnFRegistries.DataComponents.FLOWER_CROWN_CONTENT.get());
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
ItemStack flower = data.flowers().get(this.layer);
|
||||||
|
if (flower.is(Items.BLUE_ORCHID))
|
||||||
|
{
|
||||||
|
return DyeColor.LIGHT_BLUE.getTextureDiffuseColor();
|
||||||
|
}
|
||||||
|
else if (flower.is(Items.LILY_OF_THE_VALLEY))
|
||||||
|
{
|
||||||
|
return DyeColor.WHITE.getTextureDiffuseColor();
|
||||||
|
}
|
||||||
|
else if (flower.is(Items.PINK_TULIP))
|
||||||
|
{
|
||||||
|
return DyeColor.MAGENTA.getTextureDiffuseColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapCodec<FlowersTint> type()
|
||||||
|
{
|
||||||
|
return MAP_CODEC;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,8 +2,10 @@ package fr.sushi.charmsnfabrics.common;
|
||||||
|
|
||||||
import fr.sushi.charmsnfabrics.CharmsAndFabrics;
|
import fr.sushi.charmsnfabrics.CharmsAndFabrics;
|
||||||
import fr.sushi.charmsnfabrics.common.block.FloralWorkbench;
|
import fr.sushi.charmsnfabrics.common.block.FloralWorkbench;
|
||||||
|
import fr.sushi.charmsnfabrics.common.data.FlowerCrownContent;
|
||||||
import fr.sushi.charmsnfabrics.common.entities.block.FloralWorkbenchBlockEntity;
|
import fr.sushi.charmsnfabrics.common.entities.block.FloralWorkbenchBlockEntity;
|
||||||
import fr.sushi.charmsnfabrics.common.item.FlowerCrown;
|
import fr.sushi.charmsnfabrics.common.item.FlowerCrown;
|
||||||
|
import net.minecraft.core.component.DataComponentType;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
@ -22,6 +24,7 @@ import net.neoforged.neoforge.registries.DeferredHolder;
|
||||||
import net.neoforged.neoforge.registries.DeferredItem;
|
import net.neoforged.neoforge.registries.DeferredItem;
|
||||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@ -33,8 +36,11 @@ public class CnFRegistries
|
||||||
DeferredRegister.createItems(CharmsAndFabrics.MODID);
|
DeferredRegister.createItems(CharmsAndFabrics.MODID);
|
||||||
public static final DeferredItem<Item> FLOWER_CROWN =
|
public static final DeferredItem<Item> FLOWER_CROWN =
|
||||||
ITEMS.registerItem("flower_crown",
|
ITEMS.registerItem("flower_crown",
|
||||||
(properties) -> new FlowerCrown(
|
(properties) -> new FlowerCrown(properties.stacksTo(1)
|
||||||
properties.stacksTo(1)));
|
.component(
|
||||||
|
DataComponents.FLOWER_CROWN_CONTENT,
|
||||||
|
new FlowerCrownContent(
|
||||||
|
List.of()))));
|
||||||
/* BlockItems */
|
/* BlockItems */
|
||||||
public static final DeferredItem<BlockItem> FLORAL_WORKBENCH =
|
public static final DeferredItem<BlockItem> FLORAL_WORKBENCH =
|
||||||
ITEMS.registerItem("floral_workbench",
|
ITEMS.registerItem("floral_workbench",
|
||||||
|
@ -100,11 +106,26 @@ public class CnFRegistries
|
||||||
Set.of(Blocks.FLORAL_WORKBENCH.get())));
|
Set.of(Blocks.FLORAL_WORKBENCH.get())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class DataComponents
|
||||||
|
{
|
||||||
|
public static final DeferredRegister.DataComponents COMPONENT_TYPES =
|
||||||
|
DeferredRegister.createDataComponents(
|
||||||
|
Registries.DATA_COMPONENT_TYPE, CharmsAndFabrics.MODID);
|
||||||
|
|
||||||
|
public static final Supplier<DataComponentType<FlowerCrownContent>>
|
||||||
|
FLOWER_CROWN_CONTENT =
|
||||||
|
COMPONENT_TYPES.registerComponentType("flower_crown_content",
|
||||||
|
builder -> builder.persistent(FlowerCrownContent.CODEC)
|
||||||
|
.networkSynchronized(
|
||||||
|
FlowerCrownContent.STREAM_CODEC));
|
||||||
|
}
|
||||||
|
|
||||||
public static void register(IEventBus bus)
|
public static void register(IEventBus bus)
|
||||||
{
|
{
|
||||||
Items.ITEMS.register(bus);
|
Items.ITEMS.register(bus);
|
||||||
Blocks.BLOCKS.register(bus);
|
Blocks.BLOCKS.register(bus);
|
||||||
Tabs.CREATIVE_MODE_TABS.register(bus);
|
Tabs.CREATIVE_MODE_TABS.register(bus);
|
||||||
Entities.BLOCK_ENTITY_TYPES.register(bus);
|
Entities.BLOCK_ENTITY_TYPES.register(bus);
|
||||||
|
DataComponents.COMPONENT_TYPES.register(bus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package fr.sushi.charmsnfabrics.common.data;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||||
|
import net.minecraft.network.codec.ByteBufCodecs;
|
||||||
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record FlowerCrownContent(List<ItemStack> flowers)
|
||||||
|
{
|
||||||
|
public static final FlowerCrownContent EMPTY =
|
||||||
|
new FlowerCrownContent(List.of());
|
||||||
|
public static final Codec<FlowerCrownContent> CODEC =
|
||||||
|
ItemStack.CODEC.listOf().flatXmap((items) -> DataResult.success(
|
||||||
|
new FlowerCrownContent(items)),
|
||||||
|
content -> DataResult.success(content.flowers));
|
||||||
|
public static final StreamCodec<RegistryFriendlyByteBuf, FlowerCrownContent>
|
||||||
|
STREAM_CODEC = ItemStack.STREAM_CODEC.apply(ByteBufCodecs.list())
|
||||||
|
.map(FlowerCrownContent::new,
|
||||||
|
content -> content.flowers);
|
||||||
|
|
||||||
|
public static int MAX_SIZE = 7;
|
||||||
|
}
|
|
@ -1,14 +1,19 @@
|
||||||
package fr.sushi.charmsnfabrics.common.item;
|
package fr.sushi.charmsnfabrics.common.item;
|
||||||
|
|
||||||
import fr.sushi.charmsnfabrics.CharmsAndFabrics;
|
import fr.sushi.charmsnfabrics.CharmsAndFabrics;
|
||||||
|
import fr.sushi.charmsnfabrics.common.CnFRegistries;
|
||||||
|
import fr.sushi.charmsnfabrics.common.data.FlowerCrownContent;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
import top.theillusivec4.curios.api.SlotContext;
|
import top.theillusivec4.curios.api.SlotContext;
|
||||||
import top.theillusivec4.curios.api.type.capability.ICurioItem;
|
import top.theillusivec4.curios.api.type.capability.ICurioItem;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class FlowerCrown extends Item implements ICurioItem
|
public class FlowerCrown extends Item implements ICurioItem
|
||||||
{
|
{
|
||||||
public FlowerCrown(Properties properties)
|
public FlowerCrown(Properties properties)
|
||||||
|
@ -31,6 +36,35 @@ public class FlowerCrown extends Item implements ICurioItem
|
||||||
public ResourceLocation getModelTexture()
|
public ResourceLocation getModelTexture()
|
||||||
{
|
{
|
||||||
return ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
|
return ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
|
||||||
"textures/models/accessory/flower_crown.png");
|
"textures/models/accessory/flower_crown.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResult useOn(UseOnContext context)
|
||||||
|
{
|
||||||
|
var player = context.getPlayer();
|
||||||
|
var hand = context.getHand();
|
||||||
|
|
||||||
|
ItemStack stack = player.getItemInHand(hand);
|
||||||
|
ItemStack offStack = player.getOffhandItem();
|
||||||
|
|
||||||
|
if (stack.isEmpty() || offStack.isEmpty())
|
||||||
|
{
|
||||||
|
return InteractionResult.PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlowerCrownContent content = stack.get(
|
||||||
|
CnFRegistries.DataComponents.FLOWER_CROWN_CONTENT.get());
|
||||||
|
if (content == null ||
|
||||||
|
content.flowers().size() >= FlowerCrownContent.MAX_SIZE)
|
||||||
|
{
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
List<ItemStack> list = new ArrayList<>(content.flowers());
|
||||||
|
list.add(offStack);
|
||||||
|
stack.set(CnFRegistries.DataComponents.FLOWER_CROWN_CONTENT.get(),
|
||||||
|
new FlowerCrownContent(list));
|
||||||
|
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
After Width: | Height: | Size: 108 B |
After Width: | Height: | Size: 123 B |
After Width: | Height: | Size: 103 B |
After Width: | Height: | Size: 95 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 362 B After Width: | Height: | Size: 201 B |
After Width: | Height: | Size: 362 B |
9
src/main/resources/assets/minecraft/atlases/blocks.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:directory",
|
||||||
|
"prefix": "flower/",
|
||||||
|
"source": "flower"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|