9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-26 18:39:20 +00:00

添加更多的equipment layer类型

This commit is contained in:
XiaoMoMi
2025-06-29 01:11:32 +08:00
parent c86da467c0
commit 729cba32b0
9 changed files with 236 additions and 230 deletions

View File

@@ -4,10 +4,11 @@ import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehaviors;
import net.momirealms.craftengine.core.item.modifier.*;
import net.momirealms.craftengine.core.item.setting.EquipmentData;
import net.momirealms.craftengine.core.item.setting.ItemEquipment;
import net.momirealms.craftengine.core.pack.LoadingSequence;
import net.momirealms.craftengine.core.pack.Pack;
import net.momirealms.craftengine.core.pack.ResourceLocation;
import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration;
import net.momirealms.craftengine.core.pack.misc.Equipment;
import net.momirealms.craftengine.core.pack.model.*;
import net.momirealms.craftengine.core.pack.model.generation.AbstractModelGenerator;
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
@@ -50,7 +51,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
protected final Map<Key, TreeSet<LegacyOverridesModel>> modernItemModels1_21_2;
protected final Map<Key, TreeSet<LegacyOverridesModel>> legacyOverrides;
protected final Map<Key, TreeMap<Integer, ModernItemModel>> modernOverrides;
protected final Set<EquipmentGeneration> equipmentsToGenerate;
protected final Map<Key, Equipment> equipmentsToGenerate;
// Cached command suggestions
protected final List<Suggestion> cachedSuggestions = new ArrayList<>();
protected final List<Suggestion> cachedTotemSuggestions = new ArrayList<>();
@@ -65,7 +66,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
this.cmdConflictChecker = new HashMap<>();
this.modernItemModels1_21_4 = new HashMap<>();
this.modernItemModels1_21_2 = new HashMap<>();
this.equipmentsToGenerate = new HashSet<>();
this.equipmentsToGenerate = new HashMap<>();
}
@Override
@@ -151,14 +152,11 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
this.customItemTags.computeIfAbsent(tag, k -> new ArrayList<>()).add(customItem.idHolder());
}
// equipment generation
EquipmentGeneration equipment = customItem.settings().equipment();
ItemEquipment equipment = customItem.settings().equipment();
if (equipment != null) {
EquipmentData modern = equipment.modernData();
// 1.21.2+
if (modern != null) {
this.equipmentsToGenerate.add(equipment);
}
// TODO 1.20
EquipmentData data = equipment.data();
Equipment equipmentJson = this.equipmentsToGenerate.computeIfAbsent(data.assetId(), k -> new Equipment());
equipmentJson.addAll(equipment);
}
return true;
}
@@ -250,8 +248,8 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
}
@Override
public Collection<EquipmentGeneration> equipmentsToGenerate() {
return Collections.unmodifiableCollection(this.equipmentsToGenerate);
public Map<Key, Equipment> equipmentsToGenerate() {
return Collections.unmodifiableMap(this.equipmentsToGenerate);
}
@Override

View File

@@ -3,7 +3,7 @@ package net.momirealms.craftengine.core.item;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration;
import net.momirealms.craftengine.core.pack.misc.Equipment;
import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel;
import net.momirealms.craftengine.core.pack.model.ModernItemModel;
import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator;
@@ -27,7 +27,7 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
Map<Key, TreeMap<Integer, ModernItemModel>> modernItemOverrides();
Collection<EquipmentGeneration> equipmentsToGenerate();
Map<Key, Equipment> equipmentsToGenerate();
Map<Key, ModernItemModel> modernItemModels1_21_4();

View File

@@ -7,11 +7,8 @@ import net.momirealms.craftengine.core.entity.projectile.ProjectileType;
import net.momirealms.craftengine.core.item.modifier.EquippableModifier;
import net.momirealms.craftengine.core.item.modifier.FoodModifier;
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.item.setting.AnvilRepairItem;
import net.momirealms.craftengine.core.item.setting.EquipmentData;
import net.momirealms.craftengine.core.item.setting.FoodData;
import net.momirealms.craftengine.core.item.setting.Helmet;
import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration;
import net.momirealms.craftengine.core.item.setting.*;
import net.momirealms.craftengine.core.pack.misc.EquipmentLayerType;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.sound.SoundData;
import net.momirealms.craftengine.core.util.*;
@@ -26,7 +23,7 @@ public class ItemSettings {
int fuelTime;
Set<Key> tags = Set.of();
@Nullable
EquipmentGeneration equipment;
ItemEquipment equipment;
boolean canRepair = true;
List<AnvilRepairItem> anvilRepairItems = List.of();
boolean renameable = true;
@@ -45,8 +42,8 @@ public class ItemSettings {
public <I> List<ItemDataModifier<I>> modifiers() {
ArrayList<ItemDataModifier<I>> modifiers = new ArrayList<>();
if (VersionHelper.isOrAbove1_21_2() && this.equipment != null && this.equipment.modernData() != null) {
modifiers.add(new EquippableModifier<>(this.equipment.modernData()));
if (VersionHelper.isOrAbove1_21_2() && this.equipment != null) {
modifiers.add(new EquippableModifier<>(this.equipment.data()));
}
if (VersionHelper.isOrAbove1_20_5() && this.foodData != null) {
modifiers.add(new FoodModifier<>(this.foodData.nutrition(), this.foodData.saturation(), false));
@@ -153,7 +150,7 @@ public class ItemSettings {
}
@Nullable
public EquipmentGeneration equipment() {
public ItemEquipment equipment() {
return equipment;
}
@@ -225,7 +222,7 @@ public class ItemSettings {
return this;
}
public ItemSettings equipment(EquipmentGeneration equipment) {
public ItemSettings equipment(ItemEquipment equipment) {
this.equipment = equipment;
return this;
}
@@ -302,20 +299,15 @@ public class ItemSettings {
}));
registerFactory("equippable", (value -> {
Map<String, Object> args = MiscUtils.castToMap(value, false);
EquipmentData data;
if (VersionHelper.isOrAbove1_21_2() && args.containsKey("slot")) data = EquipmentData.fromMap(args);
else data = null;
EquipmentGeneration equipment = new EquipmentGeneration(
EquipmentGeneration.Layer.fromConfig(args.get("humanoid")),
EquipmentGeneration.Layer.fromConfig(args.get("humanoid-leggings")),
EquipmentGeneration.Layer.fromConfig(args.get("llama-body")),
EquipmentGeneration.Layer.fromConfig(args.get("horse-body")),
EquipmentGeneration.Layer.fromConfig(args.get("wolf-body")),
EquipmentGeneration.Layer.fromConfig(args.get("wings")),
data,
ResourceConfigUtils.getAsInt(args.getOrDefault("trim", -1), "trim")
);
return settings -> settings.equipment(equipment);
EquipmentData data = EquipmentData.fromMap(args);
ItemEquipment itemEquipment = new ItemEquipment(data);
for (Map.Entry<String, Object> entry : args.entrySet()) {
EquipmentLayerType layerType = EquipmentLayerType.byId(entry.getKey());
if (layerType != null) {
itemEquipment.addLayer(layerType, ItemEquipment.Layer.fromConfig(entry.getValue()));
}
}
return settings -> settings.equipment(itemEquipment);
}));
registerFactory("can-place", (value -> {
boolean bool = ResourceConfigUtils.getAsBoolean(value, "can-place");

View File

@@ -0,0 +1,101 @@
package net.momirealms.craftengine.core.item.setting;
import com.google.gson.JsonObject;
import net.momirealms.craftengine.core.pack.misc.EquipmentLayerType;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public class ItemEquipment {
private final EquipmentData data;
private final EnumMap<EquipmentLayerType, List<Layer>> layers;
public ItemEquipment(EquipmentData data) {
this.data = data;
this.layers = new EnumMap<>(EquipmentLayerType.class);
}
public void addLayer(EquipmentLayerType layerType, List<Layer> layer) {
this.layers.put(layerType, layer);
}
public EnumMap<EquipmentLayerType, List<Layer>> layers() {
return layers;
}
public EquipmentData data() {
return data;
}
public record Layer(String texture, DyeableData data, boolean usePlayerTexture) implements Supplier<JsonObject> {
@NotNull
public static List<Layer> fromConfig(Object obj) {
switch (obj) {
case String texture -> {
return List.of(new Layer(texture, null, false));
}
case Map<?, ?> map -> {
Map<String, Object> data = MiscUtils.castToMap(map, false);
String texture = data.get("texture").toString();
return List.of(new Layer(texture,
DyeableData.fromObj(data.get("dyeable")),
ResourceConfigUtils.getAsBoolean(data.getOrDefault("use-player-texture", false), "use-player-texture")
));
}
case List<?> list -> {
List<Layer> layers = new ArrayList<>();
for (Object inner : list) {
layers.addAll(fromConfig(inner));
}
return layers;
}
case null, default -> {
return List.of();
}
}
}
@Override
public JsonObject get() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("texture", texture);
if (this.data != null) {
jsonObject.add("dyeable", this.data.get());
}
if (this.usePlayerTexture) {
jsonObject.addProperty("use_player_texture", true);
}
return jsonObject;
}
public record DyeableData(@Nullable Integer colorWhenUndyed) implements Supplier<JsonObject> {
public static DyeableData fromObj(Object obj) {
if (obj instanceof Map<?,?> map) {
Map<String, Object> data = MiscUtils.castToMap(map, false);
if (data.containsKey("color-when-undyed")) {
return new DyeableData(ResourceConfigUtils.getAsInt(data.get("color-when-undyed"), "color-when-undyed"));
}
}
return new DyeableData(null);
}
@Override
public JsonObject get() {
JsonObject dyeData = new JsonObject();
if (this.colorWhenUndyed != null) {
dyeData.addProperty("color_when_undyed", this.colorWhenUndyed);
}
return dyeData;
}
}
}
}

View File

@@ -10,13 +10,12 @@ import dev.dejvokep.boostedyaml.block.implementation.Section;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.momirealms.craftengine.core.font.BitmapImage;
import net.momirealms.craftengine.core.font.Font;
import net.momirealms.craftengine.core.item.setting.EquipmentData;
import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.pack.conflict.resolution.ResolutionConditional;
import net.momirealms.craftengine.core.pack.host.ResourcePackHost;
import net.momirealms.craftengine.core.pack.host.ResourcePackHosts;
import net.momirealms.craftengine.core.pack.host.impl.NoneHost;
import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration;
import net.momirealms.craftengine.core.pack.misc.Equipment;
import net.momirealms.craftengine.core.pack.model.ItemModel;
import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel;
import net.momirealms.craftengine.core.pack.model.ModernItemModel;
@@ -1053,14 +1052,14 @@ public abstract class AbstractPackManager implements PackManager {
}
private void generateEquipments(Path generatedPackPath) {
for (EquipmentGeneration generator : this.plugin.itemManager().equipmentsToGenerate()) {
EquipmentData equipmentData = generator.modernData();
if (equipmentData != null && Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) {
for (Map.Entry<Key, Equipment> entry : this.plugin.itemManager().equipmentsToGenerate().entrySet()) {
Key assetId = entry.getKey();
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) {
Path equipmentPath = generatedPackPath
.resolve("assets")
.resolve(equipmentData.assetId().namespace())
.resolve(assetId.namespace())
.resolve("equipment")
.resolve(equipmentData.assetId().value() + ".json");
.resolve(assetId.value() + ".json");
JsonObject equipmentJson = null;
if (Files.exists(equipmentPath)) {
@@ -1072,9 +1071,9 @@ public abstract class AbstractPackManager implements PackManager {
}
}
if (equipmentJson != null) {
equipmentJson = GsonHelper.deepMerge(equipmentJson, generator.get());
equipmentJson = GsonHelper.deepMerge(equipmentJson, entry.getValue().get());
} else {
equipmentJson = generator.get();
equipmentJson = entry.getValue().get();
}
try {
Files.createDirectories(equipmentPath.getParent());
@@ -1088,13 +1087,13 @@ public abstract class AbstractPackManager implements PackManager {
this.plugin.logger().severe("Error writing equipment file", e);
}
}
if (equipmentData != null && Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && Config.packMinVersion().isBelow(MinecraftVersions.V1_21_4)) {
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && Config.packMinVersion().isBelow(MinecraftVersions.V1_21_4)) {
Path equipmentPath = generatedPackPath
.resolve("assets")
.resolve(equipmentData.assetId().namespace())
.resolve(assetId.namespace())
.resolve("models")
.resolve("equipment")
.resolve(equipmentData.assetId().value() + ".json");
.resolve(assetId.value() + ".json");
JsonObject equipmentJson = null;
if (Files.exists(equipmentPath)) {
@@ -1106,9 +1105,9 @@ public abstract class AbstractPackManager implements PackManager {
}
}
if (equipmentJson != null) {
equipmentJson = GsonHelper.deepMerge(equipmentJson, generator.get());
equipmentJson = GsonHelper.deepMerge(equipmentJson, entry.getValue().get());
} else {
equipmentJson = generator.get();
equipmentJson = entry.getValue().get();
}
try {
Files.createDirectories(equipmentPath.getParent());

View File

@@ -0,0 +1,50 @@
package net.momirealms.craftengine.core.pack.misc;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.momirealms.craftengine.core.item.setting.ItemEquipment;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public class Equipment implements Supplier<JsonObject> {
private final EnumMap<EquipmentLayerType, List<ItemEquipment.Layer>> layers;
public Equipment() {
this.layers = new EnumMap<>(EquipmentLayerType.class);
}
public void addAll(ItemEquipment equipment) {
for (Map.Entry<EquipmentLayerType, List<ItemEquipment.Layer>> entry : equipment.layers().entrySet()) {
List<ItemEquipment.Layer> layers = entry.getValue();
List<ItemEquipment.Layer> previous = this.layers.put(entry.getKey(), layers);
if (previous != null && !previous.equals(layers)) {
// todo 是否异常
}
}
}
@Override
public JsonObject get() {
JsonObject jsonObject = new JsonObject();
JsonObject layersJson = new JsonObject();
jsonObject.add("layers", layersJson);
for (Map.Entry<EquipmentLayerType, List<ItemEquipment.Layer>> entry : layers.entrySet()) {
EquipmentLayerType type = entry.getKey();
List<ItemEquipment.Layer> layerList = entry.getValue();
setLayers(layersJson, layerList, type.id());
}
return jsonObject;
}
private void setLayers(JsonObject layersJson, List<ItemEquipment.Layer> layers, String key) {
if (layers == null || layers.isEmpty()) return;
JsonArray layersArray = new JsonArray();
for (ItemEquipment.Layer layer : layers) {
layersArray.add(layer.get());
}
layersJson.add(key, layersArray);
}
}

View File

@@ -1,177 +0,0 @@
package net.momirealms.craftengine.core.pack.misc;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.momirealms.craftengine.core.item.setting.EquipmentData;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
public class EquipmentGeneration implements Supplier<JsonObject> {
private final List<Layer> humanoid;
private final List<Layer> humanoidLeggings;
private final List<Layer> llamaBody;
private final List<Layer> horseBody;
private final List<Layer> wolfBody;
private final List<Layer> wings;
private final EquipmentData modernData;
private final int trim;
public EquipmentGeneration(List<Layer> humanoid,
List<Layer> humanoidLeggings,
List<Layer> llamaBody,
List<Layer> horseBody,
List<Layer> wolfBody,
List<Layer> wings,
EquipmentData modernData,
int trim) {
this.humanoid = humanoid;
this.humanoidLeggings = humanoidLeggings;
this.llamaBody = llamaBody;
this.horseBody = horseBody;
this.wolfBody = wolfBody;
this.wings = wings;
this.trim = trim;
this.modernData = modernData;
}
public EquipmentData modernData() {
return modernData;
}
public int trim() {
return trim;
}
public List<Layer> humanoid() {
return humanoid;
}
public List<Layer> humanoidLeggings() {
return humanoidLeggings;
}
public List<Layer> llamaBody() {
return llamaBody;
}
public List<Layer> horseBody() {
return horseBody;
}
public List<Layer> wolfBody() {
return wolfBody;
}
public List<Layer> wings() {
return wings;
}
@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof EquipmentGeneration that)) return false;
return trim == that.trim && Objects.equals(humanoid, that.humanoid) && Objects.equals(humanoidLeggings, that.humanoidLeggings) && Objects.equals(llamaBody, that.llamaBody) && Objects.equals(horseBody, that.horseBody) && Objects.equals(wolfBody, that.wolfBody) && Objects.equals(wings, that.wings) && Objects.equals(modernData, that.modernData);
}
@Override
public int hashCode() {
return Objects.hash(humanoid, humanoidLeggings, llamaBody, horseBody, wolfBody, wings, modernData, trim);
}
@Override
public JsonObject get() {
JsonObject jsonObject = new JsonObject();
JsonObject layersJson = new JsonObject();
jsonObject.add("layers", layersJson);
setLayerJson(layersJson, humanoid(), "humanoid");
setLayerJson(layersJson, humanoidLeggings(), "humanoid_leggings");
setLayerJson(layersJson, llamaBody(), "llama_body");
setLayerJson(layersJson, horseBody(), "horse_body");
setLayerJson(layersJson, wolfBody(), "wolf_body");
setLayerJson(layersJson, wings(), "wings");
return jsonObject;
}
private void setLayerJson(JsonObject layersJson, List<Layer> layers, String key) {
if (layers.isEmpty()) return;
JsonArray layersArray = new JsonArray();
for (Layer layer : layers) {
layersArray.add(layer.get());
}
layersJson.add(key, layersArray);
}
public record Layer(String texture, DyeableData data, boolean usePlayerTexture) implements Supplier<JsonObject> {
@NotNull
public static List<Layer> fromConfig(Object obj) {
switch (obj) {
case String texture -> {
return List.of(new Layer(texture, null, false));
}
case Map<?, ?> map -> {
Map<String, Object> data = MiscUtils.castToMap(map, false);
String texture = data.get("texture").toString();
return List.of(new Layer(texture,
DyeableData.fromObj(data.get("dyeable")),
ResourceConfigUtils.getAsBoolean(data.getOrDefault("use-player-texture", false), "use-player-texture")
));
}
case List<?> list -> {
List<Layer> layers = new ArrayList<>();
for (Object inner : list) {
layers.addAll(fromConfig(inner));
}
return layers;
}
case null, default -> {
return List.of();
}
}
}
@Override
public JsonObject get() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("texture", texture);
if (this.data != null) {
jsonObject.add("dyeable", this.data.get());
}
if (this.usePlayerTexture) {
jsonObject.addProperty("use_player_texture", true);
}
return jsonObject;
}
public record DyeableData(@Nullable Integer colorWhenUndyed) implements Supplier<JsonObject> {
public static DyeableData fromObj(Object obj) {
if (obj instanceof Map<?,?> map) {
Map<String, Object> data = MiscUtils.castToMap(map, false);
if (data.containsKey("color-when-undyed")) {
return new DyeableData(ResourceConfigUtils.getAsInt(data.get("color-when-undyed"), "color-when-undyed"));
}
}
return new DyeableData(null);
}
@Override
public JsonObject get() {
JsonObject dyeData = new JsonObject();
if (this.colorWhenUndyed != null) {
dyeData.addProperty("color_when_undyed", this.colorWhenUndyed);
}
return dyeData;
}
}
}
}

View File

@@ -0,0 +1,44 @@
package net.momirealms.craftengine.core.pack.misc;
import java.util.HashMap;
import java.util.Map;
public enum EquipmentLayerType {
WOLF_BODY("wolf_body"),
HORSE_BODY("horse_body"),
LLAMA_BODY("llama_body"),
HUMANOID("humanoid"),
HUMANOID_LEGGINGS("humanoid_leggings"),
WINGS("wings"),
PIG_SADDLE("pig_saddle"),
STRIDER_SADDLE("strider_saddle"),
CAMEL_SADDLE("camel_saddle"),
HORSE_SADDLE("horse_saddle"),
DONKEY_SADDLE("donkey_saddle"),
MULE_SADDLE("mule_saddle"),
SKELETON_HORSE_SADDLE("skeleton_horse_saddle"),
ZOMBIE_HORSE_SADDLE("zombie_horse_saddle"),
HAPPY_GHAST_BODY("happy_ghast_body");
private final String id;
EquipmentLayerType(String id) {
this.id = id;
}
public String id() {
return id;
}
public static final Map<String, EquipmentLayerType> BY_ID = new HashMap<>();
static {
for (EquipmentLayerType type : EquipmentLayerType.values()) {
BY_ID.put(type.id(), type);
BY_ID.put(type.id().replace("_", "-"), type);
}
}
public static EquipmentLayerType byId(String id) {
return BY_ID.get(id);
}
}