Skip to content

Commit cb9a14a

Browse files
committed
Updates trim, food.
1 parent 1bdeecc commit cb9a14a

12 files changed

Lines changed: 262 additions & 10 deletions

File tree

api/src/main/java/kr/toxicity/libraries/datacomponent/api/NMS.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public interface NMS {
4040
@NotNull
4141
DataComponentType<Unit> intangibleProjectile();
4242
@NotNull
43+
DataComponentType<FoodProperties> food();
44+
@NotNull
4345
DataComponentType<Unit> fireResistant();
4446
@NotNull
4547
DataComponentType<Tool> tool();
@@ -60,5 +62,7 @@ public interface NMS {
6062
@NotNull
6163
DataComponentType<WrittenBookContent> writtenBookContent();
6264
@NotNull
65+
DataComponentType<ArmorTrim> trim();
66+
@NotNull
6367
DataComponentType<BlockItemStateProperties> blockState();
6468
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package kr.toxicity.libraries.datacomponent.api;
2+
3+
import net.kyori.adventure.text.Component;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
public record TrimPattern(@NotNull String assetId, @NotNull String templateItem, @NotNull Component description, boolean decal) {
7+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package kr.toxicity.libraries.datacomponent.api.wrapper;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.function.Supplier;
8+
9+
public record ArmorMaterial(
10+
@NotNull Map<Type, Integer> defense,
11+
int enchantmentValue,
12+
@NotNull SoundEvent equipSound,
13+
@NotNull Supplier<Ingredient> repairIngredient,
14+
@NotNull List<Layer> layers,
15+
float toughness,
16+
float knockbackResistance
17+
) {
18+
public enum Type {
19+
HELMET,
20+
CHESTPLATE,
21+
LEGGINGS,
22+
BOOTS,
23+
BODY
24+
}
25+
public record Layer(String id, String suffix, boolean dyeable) {
26+
public Layer(String id) {
27+
this(id, "", false);
28+
}
29+
}
30+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package kr.toxicity.libraries.datacomponent.api.wrapper;
2+
3+
import kr.toxicity.libraries.datacomponent.api.TrimPattern;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
public record ArmorTrim(@NotNull TrimMaterial material, @NotNull TrimPattern pattern, boolean showInTooltip) {
7+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package kr.toxicity.libraries.datacomponent.api.wrapper;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
5+
import java.util.List;
6+
7+
public record FoodProperties(int nutrition, float saturation, boolean canAlwaysEat, float eatSeconds, @NotNull List<PossibleEffect> effects) {
8+
public record PossibleEffect(@NotNull MobEffectInstance effect, float probability) {
9+
}
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package kr.toxicity.libraries.datacomponent.api.wrapper;
2+
3+
import org.bukkit.inventory.ItemStack;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
import java.util.Arrays;
7+
import java.util.stream.Stream;
8+
9+
public record Ingredient(@NotNull Stream<ItemStack> entries) {
10+
public Ingredient(@NotNull ItemStack... stacks) {
11+
this(Arrays.stream(stacks));
12+
}
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package kr.toxicity.libraries.datacomponent.api.wrapper;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
5+
public record SoundEvent(@NotNull String id, float distanceToTravel) {
6+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package kr.toxicity.libraries.datacomponent.api.wrapper;
2+
3+
import net.kyori.adventure.text.Component;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
import java.util.Map;
7+
8+
public record TrimMaterial(
9+
@NotNull String assetName,
10+
@NotNull String ingredient,
11+
float itemModelIndex,
12+
@NotNull Map<ArmorMaterial, String> overrideArmorMaterials,
13+
@NotNull Component description
14+
) {
15+
}

nms/v1_20_R4/src/main/java/kr/toxicity/libraries/datacomponent/nms/v1_20_R4/CodecImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
import net.minecraft.network.chat.ComponentSerialization;
1414
import net.minecraft.resources.RegistryOps;
1515
import net.minecraft.util.Unit;
16+
import net.minecraft.world.food.FoodProperties;
1617
import net.minecraft.world.item.AdventureModePredicate;
1718
import net.minecraft.world.item.Rarity;
1819
import net.minecraft.world.item.alchemy.PotionContents;
20+
import net.minecraft.world.item.armortrim.ArmorTrim;
1921
import net.minecraft.world.item.component.*;
2022
import net.minecraft.world.level.saveddata.maps.MapId;
2123
import org.jetbrains.annotations.NotNull;
@@ -42,6 +44,8 @@ final class CodecImpl<T> implements kr.toxicity.libraries.datacomponent.api.Code
4244
static final CodecImpl<WritableBookContent> WRITABLE_BOOK_CONTENT = of(WritableBookContent.class, WritableBookContent.CODEC, t -> new JsonObject());
4345
static final CodecImpl<WrittenBookContent> WRITTEN_BOOK_CONTENT = of(WrittenBookContent.class, WrittenBookContent.CODEC, t -> new JsonObject());
4446
static final CodecImpl<BlockItemStateProperties> BLOCK_STATE = of(BlockItemStateProperties.class, BlockItemStateProperties.CODEC, t -> new JsonObject());
47+
static final CodecImpl<FoodProperties> FOOD = of(FoodProperties.class, FoodProperties.DIRECT_CODEC, t -> new JsonObject());
48+
static final CodecImpl<ArmorTrim> TRIM = of(ArmorTrim.class, ArmorTrim.CODEC, t -> new JsonObject());
4549

4650
private static <T> @NotNull CodecImpl<T> of(@NotNull Class<T> clazz, @NotNull Codec<T> codec, Function<T, JsonElement> function) {
4751
return new CodecImpl<>(

nms/v1_20_R4/src/main/java/kr/toxicity/libraries/datacomponent/nms/v1_20_R4/Converters.java

Lines changed: 142 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,32 @@
22

33
import io.papermc.paper.adventure.PaperAdventure;
44
import kr.toxicity.libraries.datacomponent.api.Converter;
5+
import kr.toxicity.libraries.datacomponent.api.TrimPattern;
56
import kr.toxicity.libraries.datacomponent.api.wrapper.*;
67
import net.kyori.adventure.text.Component;
78
import net.minecraft.core.Holder;
89
import net.minecraft.core.HolderSet;
910
import net.minecraft.core.registries.BuiltInRegistries;
1011
import net.minecraft.resources.ResourceLocation;
1112
import net.minecraft.world.effect.MobEffect;
13+
import net.minecraft.world.item.ArmorItem;
14+
import net.minecraft.world.item.Item;
1215
import net.minecraft.world.level.block.Block;
1316
import org.bukkit.craftbukkit.inventory.CraftItemStack;
1417
import org.bukkit.inventory.ItemStack;
1518
import org.jetbrains.annotations.NotNull;
1619

17-
import java.util.ArrayList;
18-
import java.util.HashMap;
19-
import java.util.Objects;
20-
import java.util.Optional;
20+
import java.util.*;
21+
import java.util.stream.Collectors;
2122

2223
final class Converters {
24+
static final Converter<Integer, Integer> INTEGER = Converter.of(i -> i, i -> i);
25+
static final Converter<Boolean, Boolean> BOOL = Converter.of(b -> b, b -> b);
26+
static final Converter<Component, net.minecraft.network.chat.Component> COMPONENT = Converter.of(
27+
PaperAdventure::asVanilla,
28+
PaperAdventure::asAdventure
29+
);
30+
2331
private static final Converter<String, ResourceLocation> RESOURCE_LOCATION = Converter.of(
2432
s -> new ResourceLocation("minecraft", s),
2533
ResourceLocation::getPath
@@ -28,6 +36,10 @@ final class Converters {
2836
s -> Objects.requireNonNull(BuiltInRegistries.MOB_EFFECT.get(RESOURCE_LOCATION.asVanilla(s)), s),
2937
e -> RESOURCE_LOCATION.asWrapper(Objects.requireNonNull(BuiltInRegistries.MOB_EFFECT.getKey(e)))
3038
);
39+
private static final Converter<String, Item> ITEM = Converter.of(
40+
s -> Objects.requireNonNull(BuiltInRegistries.ITEM.get(RESOURCE_LOCATION.asVanilla(s)), s),
41+
e -> RESOURCE_LOCATION.asWrapper(Objects.requireNonNull(BuiltInRegistries.ITEM.getKey(e)))
42+
);
3143
private static final Converter<MobEffectInstance, net.minecraft.world.effect.MobEffectInstance> MOB_EFFECT_INSTANCE = MobEffectConverter.INSTANCE;
3244

3345
private static class MobEffectConverter implements Converter<MobEffectInstance, net.minecraft.world.effect.MobEffectInstance> {
@@ -72,13 +84,105 @@ public net.minecraft.world.effect.MobEffectInstance asVanilla(@NotNull MobEffect
7284
s -> new net.minecraft.advancements.critereon.BlockPredicate(s.blocks().map(l -> HolderSet.direct(l.stream().map(n -> Holder.direct(BLOCK.asVanilla(n))).toList())), Optional.empty(), Optional.empty()),
7385
p -> new BlockPredicate(p.blocks().map(h -> h.stream().map(b -> BLOCK.asWrapper(b.value())).toList()))
7486
);
75-
76-
static final Converter<Integer, Integer> INTEGER = Converter.of(i -> i, i -> i);
77-
static final Converter<Boolean, Boolean> BOOL = Converter.of(b -> b, b -> b);
78-
static final Converter<Component, net.minecraft.network.chat.Component> COMPONENT = Converter.of(
79-
PaperAdventure::asVanilla,
80-
PaperAdventure::asAdventure
87+
private static final Converter<Ingredient, net.minecraft.world.item.crafting.Ingredient> INGREDIENT = Converter.of(
88+
i -> net.minecraft.world.item.crafting.Ingredient.of(i.entries().map(CraftItemStack::asNMSCopy)),
89+
i -> new Ingredient(Arrays.stream(i.getItems()).map(net.minecraft.world.item.ItemStack::asBukkitCopy))
8190
);
91+
private static final Converter<SoundEvent, net.minecraft.sounds.SoundEvent> SOUND_EVENT = Converter.of(
92+
s -> net.minecraft.sounds.SoundEvent.createFixedRangeEvent(RESOURCE_LOCATION.asVanilla(s.id()), s.distanceToTravel()),
93+
s -> new SoundEvent(RESOURCE_LOCATION.asWrapper(s.getLocation()), s.getRange(1F))
94+
);
95+
private static final Converter<ArmorMaterial, net.minecraft.world.item.ArmorMaterial> ARMOR_MATERIAL = Converter.of(
96+
a -> {
97+
var get = INGREDIENT.asVanilla(a.repairIngredient().get());
98+
return new net.minecraft.world.item.ArmorMaterial(
99+
a.defense().entrySet().stream().collect(Collectors.toMap(e -> switch (e.getKey()) {
100+
case HELMET -> ArmorItem.Type.HELMET;
101+
case CHESTPLATE -> ArmorItem.Type.CHESTPLATE;
102+
case LEGGINGS -> ArmorItem.Type.LEGGINGS;
103+
case BOOTS -> ArmorItem.Type.BOOTS;
104+
case BODY -> ArmorItem.Type.BODY;
105+
}, Map.Entry::getValue)),
106+
a.enchantmentValue(),
107+
Holder.direct(SOUND_EVENT.asVanilla(a.equipSound())),
108+
() -> get,
109+
a.layers().stream().map(l -> new net.minecraft.world.item.ArmorMaterial.Layer(RESOURCE_LOCATION.asVanilla(l.id()), l.suffix(), l.dyeable())).toList(),
110+
a.toughness(),
111+
a.knockbackResistance()
112+
);
113+
},
114+
a -> {
115+
var assetsName = Arrays.stream(net.minecraft.world.item.ArmorMaterial.Layer.class.getDeclaredFields()).filter(f -> ResourceLocation.class.isAssignableFrom(f.getType())).findFirst().map(f -> {
116+
try {
117+
f.setAccessible(true);
118+
} catch (Exception e) {
119+
throw new RuntimeException(e);
120+
}
121+
return f;
122+
}).orElseThrow();
123+
var suffix = Arrays.stream(net.minecraft.world.item.ArmorMaterial.Layer.class.getDeclaredFields()).filter(f -> String.class.isAssignableFrom(f.getType())).findFirst().map(f -> {
124+
try {
125+
f.setAccessible(true);
126+
} catch (Exception e) {
127+
throw new RuntimeException(e);
128+
}
129+
return f;
130+
}).orElseThrow();
131+
var get = INGREDIENT.asWrapper(a.repairIngredient().get());
132+
return new ArmorMaterial(
133+
a.defense().entrySet().stream().collect(Collectors.toMap(e -> switch (e.getKey()) {
134+
case HELMET -> ArmorMaterial.Type.HELMET;
135+
case CHESTPLATE -> ArmorMaterial.Type.CHESTPLATE;
136+
case LEGGINGS -> ArmorMaterial.Type.LEGGINGS;
137+
case BOOTS -> ArmorMaterial.Type.BOOTS;
138+
case BODY -> ArmorMaterial.Type.BODY;
139+
}, Map.Entry::getValue)),
140+
a.enchantmentValue(),
141+
SOUND_EVENT.asWrapper(a.equipSound().value()),
142+
() -> get,
143+
a.layers().stream().map(l -> {
144+
try {
145+
return new ArmorMaterial.Layer(RESOURCE_LOCATION.asWrapper((ResourceLocation) assetsName.get(l)), (String) suffix.get(l), l.dyeable());
146+
} catch (Exception e) {
147+
throw new RuntimeException(e);
148+
}
149+
}).toList(),
150+
a.toughness(),
151+
a.knockbackResistance()
152+
);
153+
}
154+
);
155+
private static final Converter<TrimMaterial, net.minecraft.world.item.armortrim.TrimMaterial> TRIM_MATERIAL = Converter.of(
156+
t -> new net.minecraft.world.item.armortrim.TrimMaterial(
157+
t.assetName(),
158+
Holder.direct(ITEM.asVanilla(t.ingredient())),
159+
t.itemModelIndex(),
160+
t.overrideArmorMaterials().entrySet().stream().collect(Collectors.toMap(e -> Holder.direct(ARMOR_MATERIAL.asVanilla(e.getKey())), Map.Entry::getValue)),
161+
COMPONENT.asVanilla(t.description())
162+
),
163+
t -> new TrimMaterial(
164+
t.assetName(),
165+
ITEM.asWrapper(t.ingredient().value()),
166+
t.itemModelIndex(),
167+
t.overrideArmorMaterials().entrySet().stream().collect(Collectors.toMap(e -> ARMOR_MATERIAL.asWrapper(e.getKey().value()), Map.Entry::getValue)),
168+
COMPONENT.asWrapper(t.description())
169+
)
170+
);
171+
private static final Converter<TrimPattern, net.minecraft.world.item.armortrim.TrimPattern> TRIM_PATTERN = Converter.of(
172+
t -> new net.minecraft.world.item.armortrim.TrimPattern(
173+
RESOURCE_LOCATION.asVanilla(t.assetId()),
174+
Holder.direct(ITEM.asVanilla(t.templateItem())),
175+
COMPONENT.asVanilla(t.description()),
176+
t.decal()
177+
),
178+
t -> new TrimPattern(
179+
RESOURCE_LOCATION.asWrapper(t.assetId()),
180+
ITEM.asWrapper(t.templateItem().value()),
181+
COMPONENT.asWrapper(t.description()),
182+
t.decal()
183+
)
184+
);
185+
82186
static final Converter<ItemLore, net.minecraft.world.item.component.ItemLore> ITEM_LORE = Converter.of(
83187
l -> new net.minecraft.world.item.component.ItemLore(
84188
l.lines().stream().map(COMPONENT::asVanilla).toList(),
@@ -192,4 +296,32 @@ public net.minecraft.world.effect.MobEffectInstance asVanilla(@NotNull MobEffect
192296
s -> new net.minecraft.world.item.component.BlockItemStateProperties(new HashMap<>(s.properties())),
193297
s -> new BlockItemStateProperties(new HashMap<>(s.properties()))
194298
);
299+
static final Converter<FoodProperties, net.minecraft.world.food.FoodProperties> FOOD = Converter.of(
300+
f -> new net.minecraft.world.food.FoodProperties(
301+
f.nutrition(),
302+
f.saturation(),
303+
f.canAlwaysEat(),
304+
f.eatSeconds(),
305+
f.effects().stream().map(e -> new net.minecraft.world.food.FoodProperties.PossibleEffect(MOB_EFFECT_INSTANCE.asVanilla(e.effect()), e.probability())).toList()
306+
),
307+
f -> new FoodProperties(
308+
f.nutrition(),
309+
f.saturation(),
310+
f.canAlwaysEat(),
311+
f.eatSeconds(),
312+
f.effects().stream().map(e -> new FoodProperties.PossibleEffect(MOB_EFFECT_INSTANCE.asWrapper(e.effect()), e.probability())).toList()
313+
)
314+
);
315+
static final Converter<ArmorTrim, net.minecraft.world.item.armortrim.ArmorTrim> TRIM = Converter.of(
316+
t -> new net.minecraft.world.item.armortrim.ArmorTrim(
317+
Holder.direct(TRIM_MATERIAL.asVanilla(t.material())),
318+
Holder.direct(TRIM_PATTERN.asVanilla(t.pattern())),
319+
t.showInTooltip()
320+
),
321+
t -> new ArmorTrim(
322+
TRIM_MATERIAL.asWrapper(t.material().value()),
323+
TRIM_PATTERN.asWrapper(t.pattern().value()),
324+
t.showInTooltip
325+
)
326+
);
195327
}

0 commit comments

Comments
 (0)