mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-27 02:49:15 +00:00
Merge remote-tracking branch 'upstream/dev' into dev
# Conflicts: # gradle.properties
This commit is contained in:
@@ -263,15 +263,13 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
|
||||
public class ItemParser implements ConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] {"items", "item"};
|
||||
private static final float VERSION_1_21_2 = 21.2f;
|
||||
private static final float VERSION_1_21_4 = 21.4f;
|
||||
|
||||
private boolean isModernFormatRequired() {
|
||||
return Config.packMaxVersion() >= VERSION_1_21_4;
|
||||
return Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_4);
|
||||
}
|
||||
|
||||
private boolean needsLegacyCompatibility() {
|
||||
return Config.packMinVersion() < VERSION_1_21_4;
|
||||
return Config.packMinVersion().isBelow(MinecraftVersions.V1_21_4);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -433,7 +431,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
ResourceConfigUtils.getAsBoolean(section.getOrDefault("hand-animation-on-swap", true), "hand-animation-on-swap")
|
||||
));
|
||||
}
|
||||
if (Config.packMaxVersion() >= VERSION_1_21_2 && needsLegacyCompatibility() && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) {
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && needsLegacyCompatibility() && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) {
|
||||
TreeSet<LegacyOverridesModel> lom = AbstractItemManager.this.modernItemModels1_21_2.computeIfAbsent(itemModelKey, k -> new TreeSet<>());
|
||||
lom.addAll(legacyOverridesModels);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
|
||||
@@ -17,11 +17,15 @@ 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.model.ItemModel;
|
||||
import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel;
|
||||
import net.momirealms.craftengine.core.pack.model.ModernItemModel;
|
||||
import net.momirealms.craftengine.core.pack.model.RangeDispatchItemModel;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator;
|
||||
import net.momirealms.craftengine.core.pack.model.rangedisptach.CustomModelDataRangeDispatchProperty;
|
||||
import net.momirealms.craftengine.core.pack.obfuscation.ObfA;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
@@ -54,11 +58,12 @@ import java.util.function.Predicate;
|
||||
|
||||
import static net.momirealms.craftengine.core.util.MiscUtils.castToMap;
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public abstract class AbstractPackManager implements PackManager {
|
||||
public static final Map<Key, JsonObject> PRESET_MODERN_MODELS_ITEM = new HashMap<>();
|
||||
public static final Map<Key, JsonObject> PRESET_LEGACY_MODELS_ITEM = new HashMap<>();
|
||||
public static final Map<Key, JsonObject> PRESET_MODELS_BLOCK = new HashMap<>();
|
||||
public static final Map<Key, JsonObject> PRESET_ITEMS = new HashMap<>();
|
||||
public static final Map<Key, ModernItemModel> PRESET_ITEMS = new HashMap<>();
|
||||
public static final Set<Key> VANILLA_TEXTURES = new HashSet<>();
|
||||
public static final Set<Key> VANILLA_MODELS = new HashSet<>();
|
||||
private static final byte[] EMPTY_IMAGE;
|
||||
@@ -103,7 +108,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
loadInternalData("internal/models/item/legacy/_all.json", PRESET_LEGACY_MODELS_ITEM::put);
|
||||
loadInternalData("internal/models/item/_all.json", PRESET_MODERN_MODELS_ITEM::put);
|
||||
loadInternalData("internal/models/block/_all.json", PRESET_MODELS_BLOCK::put);
|
||||
loadInternalData("internal/items/_all.json", PRESET_ITEMS::put);
|
||||
loadModernItemModel("internal/items/_all.json", PRESET_ITEMS::put);
|
||||
|
||||
loadInternalList("textures", "block/", VANILLA_TEXTURES::add);
|
||||
loadInternalList("textures", "item/", VANILLA_TEXTURES::add);
|
||||
@@ -122,6 +127,21 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadModernItemModel(String path, BiConsumer<Key, ModernItemModel> callback) {
|
||||
try (InputStream inputStream = this.plugin.resourceStream(path)) {
|
||||
if (inputStream != null) {
|
||||
JsonObject allModelsItems = JsonParser.parseReader(new InputStreamReader(inputStream)).getAsJsonObject();
|
||||
for (Map.Entry<String, JsonElement> entry : allModelsItems.entrySet()) {
|
||||
if (entry.getValue() instanceof JsonObject modelJson) {
|
||||
callback.accept(Key.of(entry.getKey()), ModernItemModel.fromJson(modelJson));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to load " + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadInternalData(String path, BiConsumer<Key, JsonObject> callback) {
|
||||
try (InputStream inputStream = this.plugin.resourceStream(path)) {
|
||||
if (inputStream != null) {
|
||||
@@ -311,7 +331,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
// internal
|
||||
plugin.saveResource("resources/remove_shulker_head/resourcepack/pack.mcmeta");
|
||||
plugin.saveResource("resources/remove_shulker_head/resourcepack/assets/minecraft/shaders/core/rendertype_entity_solid.fsh");
|
||||
plugin.saveResource("resources/remove_shulker_head/resourcepack/1_20_5_assets/minecraft/shaders/core/rendertype_entity_solid.fsh");
|
||||
plugin.saveResource("resources/remove_shulker_head/resourcepack/1_20_5_remove_shulker_head_overlay/minecraft/shaders/core/rendertype_entity_solid.fsh");
|
||||
plugin.saveResource("resources/remove_shulker_head/resourcepack/assets/minecraft/textures/entity/shulker/shulker_white.png");
|
||||
plugin.saveResource("resources/remove_shulker_head/pack.yml");
|
||||
// internal
|
||||
@@ -602,19 +622,21 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<Revision> revisions = new HashSet<>();
|
||||
this.generateFonts(generatedPackPath);
|
||||
this.generateItemModels(generatedPackPath, this.plugin.itemManager());
|
||||
this.generateItemModels(generatedPackPath, this.plugin.blockManager());
|
||||
this.generateBlockOverrides(generatedPackPath);
|
||||
this.generateLegacyItemOverrides(generatedPackPath);
|
||||
this.generateModernItemOverrides(generatedPackPath);
|
||||
this.generateModernItemOverrides(generatedPackPath, revisions::add);
|
||||
this.generateModernItemModels1_21_2(generatedPackPath);
|
||||
this.generateModernItemModels1_21_4(generatedPackPath);
|
||||
this.generateModernItemModels1_21_4(generatedPackPath, revisions::add);
|
||||
this.generateOverrideSounds(generatedPackPath);
|
||||
this.generateCustomSounds(generatedPackPath);
|
||||
this.generateClientLang(generatedPackPath);
|
||||
this.generateEquipments(generatedPackPath);
|
||||
this.generateParticle(generatedPackPath);
|
||||
this.generatePackMetadata(generatedPackPath.resolve("pack.mcmeta"), revisions);
|
||||
if (Config.excludeShaders()) {
|
||||
this.removeAllShaders(generatedPackPath);
|
||||
}
|
||||
@@ -634,6 +656,57 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void generatePackMetadata(Path path, Set<Revision> revisions) throws IOException {
|
||||
JsonObject rawMeta;
|
||||
boolean changed = false;
|
||||
if (!Files.exists(path)) {
|
||||
rawMeta = new JsonObject();
|
||||
changed = true;
|
||||
} else {
|
||||
rawMeta = GsonHelper.readJsonFile(path).getAsJsonObject();
|
||||
}
|
||||
if (!rawMeta.has("pack")) {
|
||||
JsonObject pack = new JsonObject();
|
||||
rawMeta.add("pack", pack);
|
||||
pack.addProperty("pack_format", Config.packMinVersion().packFormat());
|
||||
JsonObject supportedFormats = new JsonObject();
|
||||
supportedFormats.addProperty("min_inclusive", Config.packMinVersion().packFormat());
|
||||
supportedFormats.addProperty("max_inclusive", Config.packMaxVersion().packFormat());
|
||||
pack.add("supported_formats", supportedFormats);
|
||||
changed = true;
|
||||
}
|
||||
if (revisions.isEmpty()) {
|
||||
if (changed) {
|
||||
GsonHelper.writeJsonFile(rawMeta, path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
JsonObject overlays;
|
||||
if (rawMeta.has("overlays")) {
|
||||
overlays = rawMeta.get("overlays").getAsJsonObject();
|
||||
} else {
|
||||
overlays = new JsonObject();
|
||||
rawMeta.add("overlays", overlays);
|
||||
}
|
||||
JsonArray entries;
|
||||
if (overlays.has("entries")) {
|
||||
entries = overlays.get("entries").getAsJsonArray();
|
||||
} else {
|
||||
entries = new JsonArray();
|
||||
overlays.add("entries", entries);
|
||||
}
|
||||
for (Revision revision : revisions) {
|
||||
JsonObject entry = new JsonObject();
|
||||
JsonObject formats = new JsonObject();
|
||||
entry.add("formats", formats);
|
||||
formats.addProperty("min_inclusive", revision.minPackVersion());
|
||||
formats.addProperty("max_inclusive", revision.maxPackVersion());
|
||||
entry.addProperty("directory", Config.createOverlayFolderName(revision.versionString()));
|
||||
entries.add(entry);
|
||||
}
|
||||
GsonHelper.writeJsonFile(rawMeta, path);
|
||||
}
|
||||
|
||||
private void removeAllShaders(Path path) {
|
||||
List<Path> rootPaths;
|
||||
try {
|
||||
@@ -945,7 +1018,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
|
||||
private void generateParticle(Path generatedPackPath) {
|
||||
if (!Config.removeTintedLeavesParticle()) return;
|
||||
if (Config.packMaxVersion() < 21.49f) return;
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersions.V1_21_5)) return;
|
||||
JsonObject particleJson = new JsonObject();
|
||||
JsonArray textures = new JsonArray();
|
||||
textures.add("empty");
|
||||
@@ -979,7 +1052,7 @@ 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() >= 21.4f) {
|
||||
if (equipmentData != null && Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) {
|
||||
Path equipmentPath = generatedPackPath
|
||||
.resolve("assets")
|
||||
.resolve(equipmentData.assetId().namespace())
|
||||
@@ -1012,7 +1085,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
this.plugin.logger().severe("Error writing equipment file", e);
|
||||
}
|
||||
}
|
||||
if (equipmentData != null && Config.packMaxVersion() >= 21.2f && Config.packMinVersion() < 21.4f) {
|
||||
if (equipmentData != null && Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && Config.packMinVersion().isBelow(MinecraftVersions.V1_21_4)) {
|
||||
Path equipmentPath = generatedPackPath
|
||||
.resolve("assets")
|
||||
.resolve(equipmentData.assetId().namespace())
|
||||
@@ -1257,8 +1330,8 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
|
||||
private void generateModernItemModels1_21_2(Path generatedPackPath) {
|
||||
if (Config.packMaxVersion() < 21.19f) return;
|
||||
if (Config.packMinVersion() > 21.39f) return;
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersions.V1_21_2)) return;
|
||||
if (Config.packMinVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) return;
|
||||
|
||||
// 此段代码生成1.21.2专用的item model文件,情况非常复杂!
|
||||
for (Map.Entry<Key, TreeSet<LegacyOverridesModel>> entry : this.plugin.itemManager().modernItemModels1_21_2().entrySet()) {
|
||||
@@ -1323,8 +1396,8 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateModernItemModels1_21_4(Path generatedPackPath) {
|
||||
if (Config.packMaxVersion() < 21.39f) return;
|
||||
private void generateModernItemModels1_21_4(Path generatedPackPath, Consumer<Revision> callback) {
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersions.V1_21_4)) return;
|
||||
for (Map.Entry<Key, ModernItemModel> entry : this.plugin.itemManager().modernItemModels1_21_4().entrySet()) {
|
||||
Key key = entry.getKey();
|
||||
Path itemPath = generatedPackPath
|
||||
@@ -1347,25 +1420,43 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
this.plugin.logger().severe("Error creating " + itemPath.toAbsolutePath(), e);
|
||||
continue;
|
||||
}
|
||||
JsonObject model = new JsonObject();
|
||||
ModernItemModel modernItemModel = entry.getValue();
|
||||
model.add("model", modernItemModel.itemModel().get());
|
||||
if (!modernItemModel.handAnimationOnSwap()) {
|
||||
model.addProperty("hand_animation_on_swap", false);
|
||||
}
|
||||
if (modernItemModel.oversizedInGui()) {
|
||||
model.addProperty("oversized_in_gui", true);
|
||||
}
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(itemPath)) {
|
||||
GsonHelper.get().toJson(model, writer);
|
||||
GsonHelper.get().toJson(modernItemModel.toJson(Config.packMinVersion()), writer);
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to save item model for " + key, e);
|
||||
}
|
||||
|
||||
List<Revision> revisions = modernItemModel.revisions();
|
||||
if (!revisions.isEmpty()) {
|
||||
for (Revision revision : revisions) {
|
||||
if (revision.matches(Config.packMinVersion(), Config.packMaxVersion())) {
|
||||
Path overlayItemPath = generatedPackPath
|
||||
.resolve(Config.createOverlayFolderName(revision.versionString()))
|
||||
.resolve("assets")
|
||||
.resolve(key.namespace())
|
||||
.resolve("items")
|
||||
.resolve(key.value() + ".json");
|
||||
try {
|
||||
Files.createDirectories(overlayItemPath.getParent());
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().severe("Error creating " + overlayItemPath.toAbsolutePath(), e);
|
||||
continue;
|
||||
}
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(overlayItemPath)) {
|
||||
GsonHelper.get().toJson(modernItemModel.toJson(revision.minVersion()), writer);
|
||||
callback.accept(revision);
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to save item model for " + key, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateModernItemOverrides(Path generatedPackPath) {
|
||||
if (Config.packMaxVersion() < 21.39f) return;
|
||||
private void generateModernItemOverrides(Path generatedPackPath, Consumer<Revision> callback) {
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersions.V1_21_4)) return;
|
||||
for (Map.Entry<Key, TreeMap<Integer, ModernItemModel>> entry : this.plugin.itemManager().modernItemOverrides().entrySet()) {
|
||||
Key vanillaItemModel = entry.getKey();
|
||||
Path overridedItemPath = generatedPackPath
|
||||
@@ -1374,10 +1465,10 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
.resolve("items")
|
||||
.resolve(vanillaItemModel.value() + ".json");
|
||||
|
||||
JsonObject originalItemModel;
|
||||
ModernItemModel originalItemModel;
|
||||
if (Files.exists(overridedItemPath)) {
|
||||
try {
|
||||
originalItemModel = GsonHelper.readJsonFile(overridedItemPath).getAsJsonObject();
|
||||
originalItemModel = ModernItemModel.fromJson(GsonHelper.readJsonFile(overridedItemPath).getAsJsonObject());
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to load existing item model (modern)", e);
|
||||
continue;
|
||||
@@ -1390,24 +1481,13 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
}
|
||||
|
||||
boolean handAnimationOnSwap = Optional.ofNullable(originalItemModel.get("hand_animation_on_swap")).map(JsonElement::getAsBoolean).orElse(true);
|
||||
boolean oversizedInGui = Optional.ofNullable(originalItemModel.get("oversized_in_gui")).map(JsonElement::getAsBoolean).orElse(false);
|
||||
JsonObject fallbackModel = originalItemModel.get("model").getAsJsonObject();
|
||||
JsonObject newJson = new JsonObject();
|
||||
JsonObject model = new JsonObject();
|
||||
newJson.add("model", model);
|
||||
model.addProperty("type", "minecraft:range_dispatch");
|
||||
model.addProperty("property", "minecraft:custom_model_data");
|
||||
// 将原有的json读成fallback
|
||||
model.add("fallback", fallbackModel);
|
||||
JsonArray entries = new JsonArray();
|
||||
model.add("entries", entries);
|
||||
boolean handAnimationOnSwap = originalItemModel.handAnimationOnSwap();
|
||||
boolean oversizedInGui = originalItemModel.oversizedInGui();
|
||||
|
||||
Map<Float, ItemModel> entries = new HashMap<>();
|
||||
for (Map.Entry<Integer, ModernItemModel> modelWithDataEntry : entry.getValue().entrySet()) {
|
||||
JsonObject entryObject = new JsonObject();
|
||||
ModernItemModel modernItemModel = modelWithDataEntry.getValue();
|
||||
entryObject.addProperty("threshold", modelWithDataEntry.getKey());
|
||||
entryObject.add("model", modernItemModel.itemModel().get());
|
||||
entries.add(entryObject);
|
||||
entries.put(modelWithDataEntry.getKey().floatValue(), modernItemModel.itemModel());
|
||||
if (modernItemModel.handAnimationOnSwap()) {
|
||||
handAnimationOnSwap = true;
|
||||
}
|
||||
@@ -1415,28 +1495,58 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
oversizedInGui = true;
|
||||
}
|
||||
}
|
||||
if (!handAnimationOnSwap) {
|
||||
newJson.addProperty("hand_animation_on_swap", false);
|
||||
}
|
||||
if (oversizedInGui) {
|
||||
newJson.addProperty("oversized_in_gui", true);
|
||||
}
|
||||
|
||||
RangeDispatchItemModel rangeDispatch = new RangeDispatchItemModel(
|
||||
new CustomModelDataRangeDispatchProperty(0),
|
||||
1f,
|
||||
originalItemModel.itemModel(),
|
||||
entries
|
||||
);
|
||||
|
||||
ModernItemModel newItemModel = new ModernItemModel(rangeDispatch, handAnimationOnSwap, oversizedInGui);
|
||||
try {
|
||||
Files.createDirectories(overridedItemPath.getParent());
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().severe("Error creating " + overridedItemPath.toAbsolutePath(), e);
|
||||
continue;
|
||||
}
|
||||
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(overridedItemPath)) {
|
||||
GsonHelper.get().toJson(newJson, writer);
|
||||
GsonHelper.get().toJson(newItemModel.toJson(Config.packMinVersion()), writer);
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to save item model for " + vanillaItemModel, e);
|
||||
}
|
||||
|
||||
List<Revision> revisions = newItemModel.revisions();
|
||||
if (!revisions.isEmpty()) {
|
||||
for (Revision revision : revisions) {
|
||||
if (revision.matches(Config.packMinVersion(), Config.packMaxVersion())) {
|
||||
Path overlayItemPath = generatedPackPath
|
||||
.resolve(Config.createOverlayFolderName(revision.versionString()))
|
||||
.resolve("assets")
|
||||
.resolve(vanillaItemModel.namespace())
|
||||
.resolve("items")
|
||||
.resolve(vanillaItemModel.value() + ".json");
|
||||
try {
|
||||
Files.createDirectories(overlayItemPath.getParent());
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().severe("Error creating " + overlayItemPath.toAbsolutePath(), e);
|
||||
continue;
|
||||
}
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(overlayItemPath)) {
|
||||
GsonHelper.get().toJson(newItemModel.toJson(revision.minVersion()), writer);
|
||||
callback.accept(revision);
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to save item model for " + vanillaItemModel, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateLegacyItemOverrides(Path generatedPackPath) {
|
||||
if (Config.packMinVersion() > 21.39f) return;
|
||||
if (Config.packMinVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) return;
|
||||
for (Map.Entry<Key, TreeSet<LegacyOverridesModel>> entry : this.plugin.itemManager().legacyItemOverrides().entrySet()) {
|
||||
Key vanillaLegacyModel = entry.getKey();
|
||||
Path overridedItemPath = generatedPackPath
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.ResourceLocation;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.model.tint.Tint;
|
||||
import net.momirealms.craftengine.core.pack.model.tint.Tints;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -18,6 +21,7 @@ import java.util.Map;
|
||||
|
||||
public class BaseItemModel implements ItemModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String path;
|
||||
private final List<Tint> tints;
|
||||
private final ModelGeneration modelGeneration;
|
||||
@@ -29,21 +33,21 @@ public class BaseItemModel implements ItemModel {
|
||||
}
|
||||
|
||||
public List<Tint> tints() {
|
||||
return tints;
|
||||
return this.tints;
|
||||
}
|
||||
|
||||
public String path() {
|
||||
return path;
|
||||
return this.path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.addProperty("model", path);
|
||||
if (!tints.isEmpty()) {
|
||||
json.addProperty("model", this.path);
|
||||
if (!this.tints.isEmpty()) {
|
||||
JsonArray array = new JsonArray();
|
||||
for (Tint tint : tints) {
|
||||
for (Tint tint : this.tints) {
|
||||
array.add(tint.get());
|
||||
}
|
||||
json.add("tints", array);
|
||||
@@ -65,6 +69,11 @@ public class BaseItemModel implements ItemModel {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public static class Factory implements ItemModelFactory {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -91,4 +100,26 @@ public class BaseItemModel implements ItemModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ItemModelReader {
|
||||
|
||||
@Override
|
||||
public ItemModel read(JsonObject json) {
|
||||
String model = json.get("model").getAsString();
|
||||
if (json.has("tints")) {
|
||||
JsonArray array = json.getAsJsonArray("tints");
|
||||
List<Tint> tints = new ArrayList<>(array.size());
|
||||
for (JsonElement element : array) {
|
||||
if (element instanceof JsonObject jo) {
|
||||
tints.add(Tints.fromJson(jo));
|
||||
} else {
|
||||
throw new IllegalArgumentException("tint is expected to be a json object");
|
||||
}
|
||||
}
|
||||
return new BaseItemModel(model, tints, null);
|
||||
} else {
|
||||
return new BaseItemModel(model, List.of(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BundleSelectedItemModel implements ItemModel {
|
||||
public static final BundleSelectedItemModel INSTANCE = new BundleSelectedItemModel();
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return ItemModels.BUNDLE_SELECTED_ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelGeneration> modelsToGenerate() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Factory implements ItemModelFactory {
|
||||
@Override
|
||||
public ItemModel create(Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ItemModelReader {
|
||||
@Override
|
||||
public ItemModel read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -13,6 +16,7 @@ import java.util.Map;
|
||||
|
||||
public class CompositeItemModel implements ItemModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final List<ItemModel> models;
|
||||
|
||||
public CompositeItemModel(List<ItemModel> models) {
|
||||
@@ -20,16 +24,16 @@ public class CompositeItemModel implements ItemModel {
|
||||
}
|
||||
|
||||
public List<ItemModel> models() {
|
||||
return models;
|
||||
return this.models;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
JsonArray array = new JsonArray();
|
||||
for (ItemModel model : models) {
|
||||
array.add(model.get());
|
||||
for (ItemModel model : this.models) {
|
||||
array.add(model.apply(version));
|
||||
}
|
||||
json.add("models", array);
|
||||
return json;
|
||||
@@ -40,6 +44,15 @@ public class CompositeItemModel implements ItemModel {
|
||||
return ItemModels.COMPOSITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
List<Revision> versions = new ArrayList<>();
|
||||
for (ItemModel model : this.models) {
|
||||
versions.addAll(model.revisions());
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelGeneration> modelsToGenerate() {
|
||||
List<ModelGeneration> models = new ArrayList<>(4);
|
||||
@@ -72,4 +85,24 @@ public class CompositeItemModel implements ItemModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ItemModelReader {
|
||||
|
||||
@Override
|
||||
public ItemModel read(JsonObject json) {
|
||||
JsonArray models = json.getAsJsonArray("models");
|
||||
if (models == null) {
|
||||
throw new IllegalArgumentException("models is expected to be a JsonArray");
|
||||
}
|
||||
List<ItemModel> modelList = new ArrayList<>();
|
||||
for (JsonElement model : models) {
|
||||
if (model instanceof JsonObject jo) {
|
||||
modelList.add(ItemModels.fromJson(jo));
|
||||
} else {
|
||||
throw new IllegalArgumentException("model is expected to be a JsonObject");
|
||||
}
|
||||
}
|
||||
return new CompositeItemModel(modelList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.model.condition.ConditionProperties;
|
||||
import net.momirealms.craftengine.core.pack.model.condition.ConditionProperty;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -14,6 +16,7 @@ import java.util.Map;
|
||||
|
||||
public class ConditionItemModel implements ItemModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final ConditionProperty property;
|
||||
private final ItemModel onTrue;
|
||||
private final ItemModel onFalse;
|
||||
@@ -25,15 +28,15 @@ public class ConditionItemModel implements ItemModel {
|
||||
}
|
||||
|
||||
public ConditionProperty property() {
|
||||
return property;
|
||||
return this.property;
|
||||
}
|
||||
|
||||
public ItemModel onTrue() {
|
||||
return onTrue;
|
||||
return this.onTrue;
|
||||
}
|
||||
|
||||
public ItemModel onFalse() {
|
||||
return onFalse;
|
||||
return this.onFalse;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,21 +44,35 @@ public class ConditionItemModel implements ItemModel {
|
||||
return ItemModels.CONDITION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
List<Revision> onTrueVersions = this.onTrue.revisions();
|
||||
List<Revision> onFalseVersions = this.onFalse.revisions();
|
||||
if (onTrueVersions.isEmpty() && onFalseVersions.isEmpty()) return List.of();
|
||||
List<Revision> versions = new ArrayList<>(onTrueVersions.size() + onFalseVersions.size());
|
||||
versions.addAll(onTrueVersions);
|
||||
versions.addAll(onFalseVersions);
|
||||
return versions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelGeneration> modelsToGenerate() {
|
||||
List<ModelGeneration> models = new ArrayList<>(4);
|
||||
models.addAll(onTrue.modelsToGenerate());
|
||||
models.addAll(onFalse.modelsToGenerate());
|
||||
List<ModelGeneration> onTrueModels = this.onTrue.modelsToGenerate();
|
||||
List<ModelGeneration> onFalseModels = this.onFalse.modelsToGenerate();
|
||||
if (onTrueModels.isEmpty() && onFalseModels.isEmpty()) return List.of();
|
||||
List<ModelGeneration> models = new ArrayList<>(onTrueModels.size() + onFalseModels.size());
|
||||
models.addAll(onTrueModels);
|
||||
models.addAll(onFalseModels);
|
||||
return models;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.add("on_true", onTrue.get());
|
||||
json.add("on_false", onFalse.get());
|
||||
property.accept(json);
|
||||
json.add("on_true", this.onTrue.apply(version));
|
||||
json.add("on_false", this.onFalse.apply(version));
|
||||
this.property.accept(json);
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -79,4 +96,15 @@ public class ConditionItemModel implements ItemModel {
|
||||
return new ConditionItemModel(property, onTrue, onFalse);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ItemModelReader {
|
||||
|
||||
@Override
|
||||
public ItemModel read(JsonObject json) {
|
||||
ConditionProperty property = ConditionProperties.fromJson(json);
|
||||
ItemModel onTrue = ItemModels.fromJson(json.getAsJsonObject("on_true"));
|
||||
ItemModel onFalse = ItemModels.fromJson(json.getAsJsonObject("on_false"));
|
||||
return new ConditionItemModel(property, onTrue, onFalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,20 @@ package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EmptyItemModel implements ItemModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private static final EmptyItemModel INSTANCE = new EmptyItemModel();
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
return json;
|
||||
@@ -28,11 +31,22 @@ public class EmptyItemModel implements ItemModel {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public static class Factory implements ItemModelFactory {
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public static class Factory implements ItemModelFactory {
|
||||
@Override
|
||||
public ItemModel create(Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ItemModelReader {
|
||||
@Override
|
||||
public ItemModel read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,18 @@ package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface ItemModel extends Supplier<JsonObject> {
|
||||
public interface ItemModel extends Function<MinecraftVersion, JsonObject> {
|
||||
|
||||
Key type();
|
||||
|
||||
List<ModelGeneration> modelsToGenerate();
|
||||
|
||||
List<Revision> revisions();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface ItemModelReader {
|
||||
|
||||
ItemModel read(JsonObject json);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
@@ -18,23 +19,39 @@ public class ItemModels {
|
||||
public static final Key RANGE_DISPATCH = Key.of("minecraft:range_dispatch");
|
||||
public static final Key SELECT = Key.of("minecraft:select");
|
||||
public static final Key SPECIAL = Key.of("minecraft:special");
|
||||
public static final Key BUNDLE_SELECTED_ITEM = Key.of("minecraft:bundle/selected_item");
|
||||
|
||||
static {
|
||||
register(EMPTY, EmptyItemModel.FACTORY);
|
||||
register(COMPOSITE, CompositeItemModel.FACTORY);
|
||||
register(MODEL, BaseItemModel.FACTORY);
|
||||
register(CONDITION, ConditionItemModel.FACTORY);
|
||||
register(SPECIAL, SpecialItemModel.FACTORY);
|
||||
register(RANGE_DISPATCH, RangeDispatchItemModel.FACTORY);
|
||||
register(SELECT, SelectItemModel.FACTORY);
|
||||
registerFactory(EMPTY, EmptyItemModel.FACTORY);
|
||||
registerReader(EMPTY, EmptyItemModel.READER);
|
||||
registerFactory(COMPOSITE, CompositeItemModel.FACTORY);
|
||||
registerReader(COMPOSITE, CompositeItemModel.READER);
|
||||
registerFactory(MODEL, BaseItemModel.FACTORY);
|
||||
registerReader(MODEL, BaseItemModel.READER);
|
||||
registerFactory(CONDITION, ConditionItemModel.FACTORY);
|
||||
registerReader(CONDITION, ConditionItemModel.READER);
|
||||
registerFactory(SPECIAL, SpecialItemModel.FACTORY);
|
||||
registerReader(SPECIAL, SpecialItemModel.READER);
|
||||
registerFactory(RANGE_DISPATCH, RangeDispatchItemModel.FACTORY);
|
||||
registerReader(RANGE_DISPATCH, RangeDispatchItemModel.READER);
|
||||
registerFactory(SELECT, SelectItemModel.FACTORY);
|
||||
registerReader(SELECT, SelectItemModel.READER);
|
||||
registerFactory(BUNDLE_SELECTED_ITEM, BundleSelectedItemModel.FACTORY);
|
||||
registerReader(BUNDLE_SELECTED_ITEM, BundleSelectedItemModel.READER);
|
||||
}
|
||||
|
||||
public static void register(Key key, ItemModelFactory factory) {
|
||||
public static void registerFactory(Key key, ItemModelFactory factory) {
|
||||
Holder.Reference<ItemModelFactory> holder = ((WritableRegistry<ItemModelFactory>) BuiltInRegistries.ITEM_MODEL_FACTORY)
|
||||
.registerForHolder(new ResourceKey<>(Registries.ITEM_MODEL_FACTORY.location(), key));
|
||||
holder.bindValue(factory);
|
||||
}
|
||||
|
||||
public static void registerReader(Key key, ItemModelReader reader) {
|
||||
Holder.Reference<ItemModelReader> holder = ((WritableRegistry<ItemModelReader>) BuiltInRegistries.ITEM_MODEL_READER)
|
||||
.registerForHolder(new ResourceKey<>(Registries.ITEM_MODEL_READER.location(), key));
|
||||
holder.bindValue(reader);
|
||||
}
|
||||
|
||||
public static ItemModel fromMap(Map<String, Object> map) {
|
||||
String type = map.getOrDefault("type", "minecraft:model").toString();
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
@@ -44,4 +61,14 @@ public class ItemModels {
|
||||
}
|
||||
return factory.create(map);
|
||||
}
|
||||
|
||||
public static ItemModel fromJson(JsonObject json) {
|
||||
String type = json.get("type").getAsString();
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
ItemModelReader reader = BuiltInRegistries.ITEM_MODEL_READER.getValue(key);
|
||||
if (reader == null) {
|
||||
throw new IllegalArgumentException("Invalid item model type: " + key);
|
||||
}
|
||||
return reader.read(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ModernItemModel {
|
||||
private final ItemModel itemModel;
|
||||
private final boolean oversizedInGui;
|
||||
@@ -11,6 +17,31 @@ public class ModernItemModel {
|
||||
this.oversizedInGui = oversizedInGui;
|
||||
}
|
||||
|
||||
public static ModernItemModel fromJson(JsonObject json) {
|
||||
ItemModel model = ItemModels.fromJson(json.getAsJsonObject("model"));
|
||||
return new ModernItemModel(
|
||||
model,
|
||||
!json.has("hand_animation_on_swap") || json.get("hand_animation_on_swap").getAsBoolean(),
|
||||
json.has("oversized_in_gui") && json.get("oversized_in_gui").getAsBoolean()
|
||||
);
|
||||
}
|
||||
|
||||
public JsonObject toJson(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
if (this.oversizedInGui) {
|
||||
json.addProperty("oversized_in_gui", true);
|
||||
}
|
||||
if (!this.handAnimationOnSwap) {
|
||||
json.addProperty("hand_animation_on_swap", false);
|
||||
}
|
||||
json.add("model", this.itemModel.apply(version));
|
||||
return json;
|
||||
}
|
||||
|
||||
public List<Revision> revisions() {
|
||||
return this.itemModel.revisions().stream().distinct().toList();
|
||||
}
|
||||
|
||||
public boolean handAnimationOnSwap() {
|
||||
return handAnimationOnSwap;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.model.rangedisptach.RangeDispatchProperties;
|
||||
import net.momirealms.craftengine.core.pack.model.rangedisptach.RangeDispatchProperty;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -19,6 +22,7 @@ import java.util.Map;
|
||||
|
||||
public class RangeDispatchItemModel implements ItemModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final RangeDispatchProperty property;
|
||||
private final float scale;
|
||||
private final ItemModel fallBack;
|
||||
@@ -35,42 +39,42 @@ public class RangeDispatchItemModel implements ItemModel {
|
||||
}
|
||||
|
||||
public RangeDispatchProperty property() {
|
||||
return property;
|
||||
return this.property;
|
||||
}
|
||||
|
||||
public float scale() {
|
||||
return scale;
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemModel fallBack() {
|
||||
return fallBack;
|
||||
return this.fallBack;
|
||||
}
|
||||
|
||||
public Map<Float, ItemModel> entries() {
|
||||
return entries;
|
||||
return this.entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
property.accept(json);
|
||||
this.property.accept(json);
|
||||
JsonArray array = new JsonArray();
|
||||
for (Map.Entry<Float, ItemModel> entry : entries.entrySet()) {
|
||||
float threshold = entry.getKey();
|
||||
ItemModel model = entry.getValue();
|
||||
JsonObject jo = new JsonObject();
|
||||
jo.addProperty("threshold", threshold);
|
||||
jo.add("model", model.get());
|
||||
jo.add("model", model.apply(version));
|
||||
array.add(jo);
|
||||
}
|
||||
json.add("entries", array);
|
||||
if (scale != 1) {
|
||||
json.addProperty("scale", scale);
|
||||
if (this.scale != 1) {
|
||||
json.addProperty("scale", this.scale);
|
||||
}
|
||||
if (fallBack != null) {
|
||||
json.add("fallback", fallBack.get());
|
||||
if (this.fallBack != null) {
|
||||
json.add("fallback", this.fallBack.apply(version));
|
||||
}
|
||||
return json;
|
||||
}
|
||||
@@ -80,13 +84,25 @@ public class RangeDispatchItemModel implements ItemModel {
|
||||
return ItemModels.RANGE_DISPATCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
List<Revision> versions = new ArrayList<>(4);
|
||||
if (this.fallBack != null) {
|
||||
versions.addAll(this.fallBack.revisions());
|
||||
}
|
||||
for (ItemModel model : this.entries.values()) {
|
||||
versions.addAll(model.revisions());
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelGeneration> modelsToGenerate() {
|
||||
List<ModelGeneration> models = new ArrayList<>(4);
|
||||
if (fallBack != null) {
|
||||
models.addAll(fallBack.modelsToGenerate());
|
||||
if (this.fallBack != null) {
|
||||
models.addAll(this.fallBack.modelsToGenerate());
|
||||
}
|
||||
for (ItemModel model : entries.values()) {
|
||||
for (ItemModel model : this.entries.values()) {
|
||||
models.addAll(model.modelsToGenerate());
|
||||
}
|
||||
return models;
|
||||
@@ -122,4 +138,28 @@ public class RangeDispatchItemModel implements ItemModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ItemModelReader {
|
||||
|
||||
@Override
|
||||
public ItemModel read(JsonObject json) {
|
||||
JsonArray entriesObj = json.getAsJsonArray("entries");
|
||||
if (entriesObj == null) {
|
||||
throw new IllegalArgumentException("entries is expected to be a JsonArray");
|
||||
}
|
||||
Map<Float, ItemModel> entries = new HashMap<>();
|
||||
for (JsonElement entry : entriesObj) {
|
||||
if (entry instanceof JsonObject entryObj) {
|
||||
float threshold = entryObj.getAsJsonPrimitive("threshold").getAsFloat();
|
||||
ItemModel model = ItemModels.fromJson(entryObj.getAsJsonObject("model"));
|
||||
entries.put(threshold, model);
|
||||
}
|
||||
}
|
||||
return new RangeDispatchItemModel(RangeDispatchProperties.fromJson(json),
|
||||
json.has("scale") ? json.get("scale").getAsFloat() : 1f,
|
||||
json.has("fallback") ? ItemModels.fromJson(json.getAsJsonObject("fallback")) : null,
|
||||
entries
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package net.momirealms.craftengine.core.pack.model;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.model.select.SelectProperties;
|
||||
import net.momirealms.craftengine.core.pack.model.select.SelectProperty;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import org.incendo.cloud.type.Either;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -19,6 +23,7 @@ import java.util.Map;
|
||||
|
||||
public class SelectItemModel implements ItemModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final SelectProperty property;
|
||||
private final Map<Either<String, List<String>>, ItemModel> whenMap;
|
||||
private final ItemModel fallBack;
|
||||
@@ -32,28 +37,28 @@ public class SelectItemModel implements ItemModel {
|
||||
}
|
||||
|
||||
public SelectProperty property() {
|
||||
return property;
|
||||
return this.property;
|
||||
}
|
||||
|
||||
public Map<Either<String, List<String>>, ItemModel> whenMap() {
|
||||
return whenMap;
|
||||
return this.whenMap;
|
||||
}
|
||||
|
||||
public ItemModel fallBack() {
|
||||
return fallBack;
|
||||
return this.fallBack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
property.accept(json);
|
||||
this.property.accept(json);
|
||||
JsonArray array = new JsonArray();
|
||||
json.add("cases", array);
|
||||
for (Map.Entry<Either<String, List<String>>, ItemModel> entry : whenMap.entrySet()) {
|
||||
for (Map.Entry<Either<String, List<String>>, ItemModel> entry : this.whenMap.entrySet()) {
|
||||
JsonObject item = new JsonObject();
|
||||
ItemModel itemModel = entry.getValue();
|
||||
item.add("model", itemModel.get());
|
||||
item.add("model", itemModel.apply(version));
|
||||
Either<String, List<String>> either = entry.getKey();
|
||||
if (either.primary().isPresent()) {
|
||||
item.addProperty("when", either.primary().get());
|
||||
@@ -67,8 +72,8 @@ public class SelectItemModel implements ItemModel {
|
||||
}
|
||||
array.add(item);
|
||||
}
|
||||
if (fallBack != null) {
|
||||
json.add("fallback", fallBack.get());
|
||||
if (this.fallBack != null) {
|
||||
json.add("fallback", this.fallBack.apply(version));
|
||||
}
|
||||
return json;
|
||||
}
|
||||
@@ -78,13 +83,25 @@ public class SelectItemModel implements ItemModel {
|
||||
return ItemModels.SELECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
List<Revision> versions = new ArrayList<>();
|
||||
if (this.fallBack != null) {
|
||||
versions.addAll(this.fallBack.revisions());
|
||||
}
|
||||
for (ItemModel itemModel : this.whenMap.values()) {
|
||||
versions.addAll(itemModel.revisions());
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelGeneration> modelsToGenerate() {
|
||||
List<ModelGeneration> models = new ArrayList<>(4);
|
||||
if (fallBack != null) {
|
||||
models.addAll(fallBack.modelsToGenerate());
|
||||
if (this.fallBack != null) {
|
||||
models.addAll(this.fallBack.modelsToGenerate());
|
||||
}
|
||||
for (ItemModel itemModel : whenMap.values()) {
|
||||
for (ItemModel itemModel : this.whenMap.values()) {
|
||||
models.addAll(itemModel.modelsToGenerate());
|
||||
}
|
||||
return models;
|
||||
@@ -132,4 +149,38 @@ public class SelectItemModel implements ItemModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ItemModelReader {
|
||||
|
||||
@Override
|
||||
public ItemModel read(JsonObject json) {
|
||||
JsonArray cases = json.getAsJsonArray("cases");
|
||||
if (cases == null) {
|
||||
throw new IllegalArgumentException("cases is expected to be a JsonArray");
|
||||
}
|
||||
Map<Either<String, List<String>>, ItemModel> whenMap = new HashMap<>(cases.size());
|
||||
for (JsonElement e : cases) {
|
||||
if (e instanceof JsonObject caseObj) {
|
||||
ItemModel model = ItemModels.fromJson(caseObj.getAsJsonObject("model"));
|
||||
JsonElement whenObj = caseObj.get("when");
|
||||
Either<String, List<String>> either;
|
||||
if (whenObj instanceof JsonArray array) {
|
||||
List<String> whens = new ArrayList<>(array.size());
|
||||
for (JsonElement o : array) {
|
||||
whens.add(o.toString());
|
||||
}
|
||||
either = Either.ofFallback(whens);
|
||||
} else if (whenObj instanceof JsonPrimitive primitive) {
|
||||
either = Either.ofPrimary(primitive.toString());
|
||||
} else {
|
||||
throw new IllegalArgumentException("when is expected to be either JsonPrimitive or JsonArray");
|
||||
}
|
||||
whenMap.put(either, model);
|
||||
} else {
|
||||
throw new IllegalArgumentException("case is expected to be a JsonObject");
|
||||
}
|
||||
}
|
||||
return new SelectItemModel(SelectProperties.fromJson(json), whenMap, json.has("fallback") ? ItemModels.fromJson(json.getAsJsonObject("fallback")) : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@ import net.momirealms.craftengine.core.pack.ResourceLocation;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.model.special.SpecialModel;
|
||||
import net.momirealms.craftengine.core.pack.model.special.SpecialModels;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -16,6 +18,7 @@ import java.util.Map;
|
||||
|
||||
public class SpecialItemModel implements ItemModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final SpecialModel specialModel;
|
||||
private final String base;
|
||||
private final ModelGeneration modelGeneration;
|
||||
@@ -27,19 +30,19 @@ public class SpecialItemModel implements ItemModel {
|
||||
}
|
||||
|
||||
public SpecialModel specialModel() {
|
||||
return specialModel;
|
||||
return this.specialModel;
|
||||
}
|
||||
|
||||
public String base() {
|
||||
return base;
|
||||
return this.base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.add("model", specialModel.get());
|
||||
json.addProperty("base", base);
|
||||
json.add("model", this.specialModel.apply(version));
|
||||
json.addProperty("base", this.base);
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -57,6 +60,11 @@ public class SpecialItemModel implements ItemModel {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
return this.specialModel.revisions();
|
||||
}
|
||||
|
||||
public static class Factory implements ItemModelFactory {
|
||||
|
||||
@Override
|
||||
@@ -74,4 +82,14 @@ public class SpecialItemModel implements ItemModel {
|
||||
return new SpecialItemModel(SpecialModels.fromMap(model), base, modelGeneration);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ItemModelReader {
|
||||
|
||||
@Override
|
||||
public ItemModel read(JsonObject json) {
|
||||
String base = json.get("base").getAsString();
|
||||
SpecialModel sm = SpecialModels.fromJson(json.getAsJsonObject("model"));
|
||||
return new SpecialItemModel(sm, base, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Map;
|
||||
|
||||
public class BrokenConditionProperty implements ConditionProperty, LegacyModelPredicate<Boolean> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final BrokenConditionProperty INSTANCE = new BrokenConditionProperty();
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
@@ -34,7 +36,14 @@ public class BrokenConditionProperty implements ConditionProperty, LegacyModelPr
|
||||
public static class Factory implements ConditionPropertyFactory {
|
||||
@Override
|
||||
public ConditionProperty create(Map<String, Object> arguments) {
|
||||
return new BrokenConditionProperty();
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package net.momirealms.craftengine.core.pack.model.condition;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ComponentConditionProperty implements ConditionProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String predicate;
|
||||
private final String value;
|
||||
|
||||
public ComponentConditionProperty(String predicate, String value) {
|
||||
this.predicate = predicate;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return ConditionProperties.COMPONENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(JsonObject jsonObject) {
|
||||
jsonObject.addProperty("property", type().toString());
|
||||
jsonObject.addProperty("predicate", this.predicate);
|
||||
jsonObject.addProperty("value", this.value);
|
||||
}
|
||||
|
||||
public static class Factory implements ConditionPropertyFactory {
|
||||
@Override
|
||||
public ConditionProperty create(Map<String, Object> arguments) {
|
||||
String predicate = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("predicate"), "warning.config.item.model.condition.component.missing_predicate");
|
||||
String value = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("value"), "warning.config.item.model.condition.component.missing_value");
|
||||
return new ComponentConditionProperty(predicate, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
String predicate = json.get("predicate").getAsString();
|
||||
String value = json.get("value").getAsString();
|
||||
return new ComponentConditionProperty(predicate, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.pack.model.condition;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
@@ -21,31 +22,52 @@ public class ConditionProperties {
|
||||
public static final Key FISHING_ROD_CAST = Key.of("minecraft:fishing_rod/cast");
|
||||
public static final Key HAS_COMPONENT = Key.of("minecraft:has_component");
|
||||
public static final Key KEYBIND_DOWN = Key.of("minecraft:keybind_down");
|
||||
public static final Key COMPONENT = Key.of("minecraft:component");
|
||||
public static final Key SELECTED = Key.of("minecraft:selected");
|
||||
public static final Key USING_ITEM = Key.of("minecraft:using_item");
|
||||
public static final Key VIEW_ENTITY = Key.of("minecraft:view_entity");
|
||||
|
||||
static {
|
||||
register(BROKEN, BrokenConditionProperty.FACTORY);
|
||||
register(BUNDLE_HAS_SELECTED_ITEM, SimpleConditionProperty.FACTORY);
|
||||
register(CARRIED, SimpleConditionProperty.FACTORY);
|
||||
register(DAMAGED, DamagedConditionProperty.FACTORY);
|
||||
register(EXTENDED_VIEW, SimpleConditionProperty.FACTORY);
|
||||
register(FISHING_ROD_CAST, RodCastConditionProperty.FACTORY);
|
||||
register(SELECTED, SimpleConditionProperty.FACTORY);
|
||||
register(USING_ITEM, UsingItemConditionProperty.FACTORY);
|
||||
register(VIEW_ENTITY, SimpleConditionProperty.FACTORY);
|
||||
register(CUSTOM_MODEL_DATA, CustomModelDataConditionProperty.FACTORY);
|
||||
register(HAS_COMPONENT, HasComponentConditionProperty.FACTORY);
|
||||
register(KEYBIND_DOWN, KeyBindDownConditionProperty.FACTORY);
|
||||
registerFactory(BROKEN, BrokenConditionProperty.FACTORY);
|
||||
registerReader(BROKEN, BrokenConditionProperty.READER);
|
||||
registerFactory(BUNDLE_HAS_SELECTED_ITEM, SimpleConditionProperty.FACTORY);
|
||||
registerReader(BUNDLE_HAS_SELECTED_ITEM, SimpleConditionProperty.READER);
|
||||
registerFactory(CARRIED, SimpleConditionProperty.FACTORY);
|
||||
registerReader(CARRIED, SimpleConditionProperty.READER);
|
||||
registerFactory(DAMAGED, DamagedConditionProperty.FACTORY);
|
||||
registerReader(DAMAGED, DamagedConditionProperty.READER);
|
||||
registerFactory(EXTENDED_VIEW, SimpleConditionProperty.FACTORY);
|
||||
registerReader(EXTENDED_VIEW, SimpleConditionProperty.READER);
|
||||
registerFactory(FISHING_ROD_CAST, RodCastConditionProperty.FACTORY);
|
||||
registerReader(FISHING_ROD_CAST, RodCastConditionProperty.READER);
|
||||
registerFactory(SELECTED, SimpleConditionProperty.FACTORY);
|
||||
registerReader(SELECTED, SimpleConditionProperty.READER);
|
||||
registerFactory(USING_ITEM, UsingItemConditionProperty.FACTORY);
|
||||
registerReader(USING_ITEM, UsingItemConditionProperty.READER);
|
||||
registerFactory(VIEW_ENTITY, SimpleConditionProperty.FACTORY);
|
||||
registerReader(VIEW_ENTITY, SimpleConditionProperty.READER);
|
||||
registerFactory(CUSTOM_MODEL_DATA, CustomModelDataConditionProperty.FACTORY);
|
||||
registerReader(CUSTOM_MODEL_DATA, CustomModelDataConditionProperty.READER);
|
||||
registerFactory(HAS_COMPONENT, HasComponentConditionProperty.FACTORY);
|
||||
registerReader(HAS_COMPONENT, HasComponentConditionProperty.READER);
|
||||
registerFactory(KEYBIND_DOWN, KeyBindDownConditionProperty.FACTORY);
|
||||
registerReader(KEYBIND_DOWN, KeyBindDownConditionProperty.READER);
|
||||
registerFactory(COMPONENT, ComponentConditionProperty.FACTORY);
|
||||
registerReader(COMPONENT, ComponentConditionProperty.READER);
|
||||
}
|
||||
|
||||
public static void register(Key key, ConditionPropertyFactory factory) {
|
||||
public static void registerFactory(Key key, ConditionPropertyFactory factory) {
|
||||
Holder.Reference<ConditionPropertyFactory> holder = ((WritableRegistry<ConditionPropertyFactory>) BuiltInRegistries.CONDITION_PROPERTY_FACTORY)
|
||||
.registerForHolder(new ResourceKey<>(Registries.CONDITION_PROPERTY_FACTORY.location(), key));
|
||||
holder.bindValue(factory);
|
||||
}
|
||||
|
||||
public static void registerReader(Key key, ConditionPropertyReader reader) {
|
||||
Holder.Reference<ConditionPropertyReader> holder = ((WritableRegistry<ConditionPropertyReader>) BuiltInRegistries.CONDITION_PROPERTY_READER)
|
||||
.registerForHolder(new ResourceKey<>(Registries.CONDITION_PROPERTY_READER.location(), key));
|
||||
holder.bindValue(reader);
|
||||
}
|
||||
|
||||
public static ConditionProperty fromMap(Map<String, Object> map) {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("property"), "warning.config.item.model.condition.missing_property");
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
@@ -55,4 +77,14 @@ public class ConditionProperties {
|
||||
}
|
||||
return factory.create(map);
|
||||
}
|
||||
|
||||
public static ConditionProperty fromJson(JsonObject json) {
|
||||
String type = json.get("property").getAsString();
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
ConditionPropertyReader reader = BuiltInRegistries.CONDITION_PROPERTY_READER.getValue(key);
|
||||
if (reader == null) {
|
||||
throw new IllegalArgumentException("Invalid condition property type: " + key);
|
||||
}
|
||||
return reader.read(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.momirealms.craftengine.core.pack.model.condition;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface ConditionPropertyReader {
|
||||
|
||||
ConditionProperty read(JsonObject json);
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
public class CustomModelDataConditionProperty implements ConditionProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final int index;
|
||||
|
||||
public CustomModelDataConditionProperty(int index) {
|
||||
@@ -22,16 +23,23 @@ public class CustomModelDataConditionProperty implements ConditionProperty {
|
||||
@Override
|
||||
public void accept(JsonObject jsonObject) {
|
||||
jsonObject.addProperty("property", type().toString());
|
||||
if (index != 0)
|
||||
jsonObject.addProperty("index", index);
|
||||
if (this.index != 0)
|
||||
jsonObject.addProperty("index", this.index);
|
||||
}
|
||||
|
||||
public static class Factory implements ConditionPropertyFactory {
|
||||
|
||||
@Override
|
||||
public ConditionProperty create(Map<String, Object> arguments) {
|
||||
int index = ResourceConfigUtils.getAsInt(arguments.getOrDefault("index", 0), "index");
|
||||
return new CustomModelDataConditionProperty(index);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
int index = json.has("index") ? json.get("index").getAsInt() : 0;
|
||||
return new CustomModelDataConditionProperty(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import java.util.Map;
|
||||
|
||||
public class DamagedConditionProperty implements ConditionProperty, LegacyModelPredicate<Boolean> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final DamagedConditionProperty INSTANCE = new DamagedConditionProperty();
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
@@ -32,7 +34,14 @@ public class DamagedConditionProperty implements ConditionProperty, LegacyModelP
|
||||
public static class Factory implements ConditionPropertyFactory {
|
||||
@Override
|
||||
public ConditionProperty create(Map<String, Object> arguments) {
|
||||
return new DamagedConditionProperty();
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
public class HasComponentConditionProperty implements ConditionProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String component;
|
||||
private final boolean ignoreDefault;
|
||||
|
||||
@@ -47,4 +48,13 @@ public class HasComponentConditionProperty implements ConditionProperty {
|
||||
return new HasComponentConditionProperty(componentObj, ignoreDefault);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
String component = json.get("component").getAsString();
|
||||
boolean ignoreDefault = json.has("ignore_default") && json.get("ignore_default").getAsBoolean();
|
||||
return new HasComponentConditionProperty(component, ignoreDefault);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
public class KeyBindDownConditionProperty implements ConditionProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String keybind;
|
||||
|
||||
public KeyBindDownConditionProperty(String keybind) {
|
||||
@@ -26,11 +27,18 @@ public class KeyBindDownConditionProperty implements ConditionProperty {
|
||||
}
|
||||
|
||||
public static class Factory implements ConditionPropertyFactory {
|
||||
|
||||
@Override
|
||||
public ConditionProperty create(Map<String, Object> arguments) {
|
||||
String keybindObj = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("keybind"), "warning.config.item.model.condition.keybind.missing");
|
||||
String keybindObj = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("keybind"), "warning.config.item.model.condition.keybind.missing_keybind");
|
||||
return new KeyBindDownConditionProperty(keybindObj);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
String keybind = json.get("keybind").getAsString();
|
||||
return new KeyBindDownConditionProperty(keybind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Map;
|
||||
|
||||
public class RodCastConditionProperty implements ConditionProperty, LegacyModelPredicate<Boolean> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final RodCastConditionProperty INSTANCE = new RodCastConditionProperty();
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
@@ -34,7 +36,14 @@ public class RodCastConditionProperty implements ConditionProperty, LegacyModelP
|
||||
public static class Factory implements ConditionPropertyFactory {
|
||||
@Override
|
||||
public ConditionProperty create(Map<String, Object> arguments) {
|
||||
return new RodCastConditionProperty();
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.Map;
|
||||
|
||||
public class SimpleConditionProperty implements ConditionProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final Key type;
|
||||
|
||||
public SimpleConditionProperty(Key type) {
|
||||
@@ -30,4 +31,11 @@ public class SimpleConditionProperty implements ConditionProperty {
|
||||
return new SimpleConditionProperty(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
return new SimpleConditionProperty(Key.of(json.get("property").toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Map;
|
||||
|
||||
public class UsingItemConditionProperty implements ConditionProperty, LegacyModelPredicate<Boolean> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final UsingItemConditionProperty INSTANCE = new UsingItemConditionProperty();
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
@@ -37,7 +39,14 @@ public class UsingItemConditionProperty implements ConditionProperty, LegacyMode
|
||||
public static class Factory implements ConditionPropertyFactory {
|
||||
@Override
|
||||
public ConditionProperty create(Map<String, Object> arguments) {
|
||||
return new UsingItemConditionProperty();
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements ConditionPropertyReader {
|
||||
@Override
|
||||
public ConditionProperty read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,13 @@ import java.util.Map;
|
||||
|
||||
public class CompassRangeDispatchProperty implements RangeDispatchProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String target;
|
||||
private final boolean wobble;
|
||||
|
||||
public CompassRangeDispatchProperty(String target) {
|
||||
public CompassRangeDispatchProperty(String target, boolean wobble) {
|
||||
this.target = target;
|
||||
this.wobble = wobble;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -22,15 +25,27 @@ public class CompassRangeDispatchProperty implements RangeDispatchProperty {
|
||||
@Override
|
||||
public void accept(JsonObject jsonObject) {
|
||||
jsonObject.addProperty("property", type().toString());
|
||||
jsonObject.addProperty("target", target);
|
||||
jsonObject.addProperty("target", this.target);
|
||||
if (!this.wobble) {
|
||||
jsonObject.addProperty("wobble", false);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
String targetObj = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("target"), "warning.config.item.model.range_dispatch.compass.missing_target");
|
||||
return new CompassRangeDispatchProperty(targetObj);
|
||||
boolean wobble = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("wobble", true), "wobble");
|
||||
return new CompassRangeDispatchProperty(targetObj, wobble);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
String target = json.get("target").getAsString();
|
||||
boolean wobble = !json.has("wobble") || json.get("wobble").getAsBoolean();
|
||||
return new CompassRangeDispatchProperty(target, wobble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Map;
|
||||
|
||||
public class CrossBowPullingRangeDispatchProperty implements RangeDispatchProperty, LegacyModelPredicate<Float> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final CrossBowPullingRangeDispatchProperty INSTANCE = new CrossBowPullingRangeDispatchProperty();
|
||||
|
||||
@Override
|
||||
public void accept(JsonObject jsonObject) {
|
||||
@@ -32,10 +34,16 @@ public class CrossBowPullingRangeDispatchProperty implements RangeDispatchProper
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
return new CrossBowPullingRangeDispatchProperty();
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
|
||||
public class CustomModelDataRangeDispatchProperty implements RangeDispatchProperty, LegacyModelPredicate<Float> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final int index;
|
||||
|
||||
public CustomModelDataRangeDispatchProperty(int index) {
|
||||
@@ -37,11 +38,18 @@ public class CustomModelDataRangeDispatchProperty implements RangeDispatchProper
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
int index = ResourceConfigUtils.getAsInt(arguments.getOrDefault("index", 0), "index");
|
||||
return new CustomModelDataRangeDispatchProperty(index);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
int index = json.has("index") ? json.get("index").getAsInt() : 0;
|
||||
return new CustomModelDataRangeDispatchProperty(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
|
||||
public class DamageRangeDispatchProperty implements RangeDispatchProperty, LegacyModelPredicate<Float> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final boolean normalize;
|
||||
|
||||
public DamageRangeDispatchProperty(boolean normalize) {
|
||||
@@ -41,11 +42,18 @@ public class DamageRangeDispatchProperty implements RangeDispatchProperty, Legac
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
boolean normalize = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("normalize", true), "normalize");
|
||||
return new DamageRangeDispatchProperty(normalize);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
boolean normalize = !json.has("normalize") || json.get("normalize").getAsBoolean();
|
||||
return new DamageRangeDispatchProperty(normalize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
public class NormalizeRangeDispatchProperty implements RangeDispatchProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final Key type;
|
||||
private final boolean normalize;
|
||||
|
||||
@@ -30,7 +31,6 @@ public class NormalizeRangeDispatchProperty implements RangeDispatchProperty {
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
Key type = Key.of(arguments.get("property").toString());
|
||||
@@ -38,4 +38,13 @@ public class NormalizeRangeDispatchProperty implements RangeDispatchProperty {
|
||||
return new NormalizeRangeDispatchProperty(type, normalize);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
Key type = Key.of(json.get("property").toString());
|
||||
boolean normalize = !json.has("normalize") || json.get("normalize").getAsBoolean();
|
||||
return new NormalizeRangeDispatchProperty(type, normalize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.pack.model.rangedisptach;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
@@ -24,24 +25,40 @@ public class RangeDispatchProperties {
|
||||
public static final Key USE_DURATION = Key.of("minecraft:use_duration");
|
||||
|
||||
static {
|
||||
register(BUNDLE_FULLNESS, SimpleRangeDispatchProperty.FACTORY);
|
||||
register(COOLDOWN, SimpleRangeDispatchProperty.FACTORY);
|
||||
register(CROSSBOW_PULL, CrossBowPullingRangeDispatchProperty.FACTORY);
|
||||
register(COMPASS, CompassRangeDispatchProperty.FACTORY);
|
||||
register(COUNT, NormalizeRangeDispatchProperty.FACTORY);
|
||||
register(DAMAGE, DamageRangeDispatchProperty.FACTORY);
|
||||
register(CUSTOM_MODEL_DATA, CustomModelDataRangeDispatchProperty.FACTORY);
|
||||
register(TIME, TimeRangeDispatchProperty.FACTORY);
|
||||
register(USE_CYCLE, UseCycleRangeDispatchProperty.FACTORY);
|
||||
register(USE_DURATION, UseDurationRangeDispatchProperty.FACTORY);
|
||||
registerFactory(BUNDLE_FULLNESS, SimpleRangeDispatchProperty.FACTORY);
|
||||
registerReader(BUNDLE_FULLNESS, SimpleRangeDispatchProperty.READER);
|
||||
registerFactory(COOLDOWN, SimpleRangeDispatchProperty.FACTORY);
|
||||
registerReader(COOLDOWN, SimpleRangeDispatchProperty.READER);
|
||||
registerFactory(CROSSBOW_PULL, CrossBowPullingRangeDispatchProperty.FACTORY);
|
||||
registerReader(CROSSBOW_PULL, CrossBowPullingRangeDispatchProperty.READER);
|
||||
registerFactory(COMPASS, CompassRangeDispatchProperty.FACTORY);
|
||||
registerReader(COMPASS, CompassRangeDispatchProperty.READER);
|
||||
registerFactory(COUNT, NormalizeRangeDispatchProperty.FACTORY);
|
||||
registerReader(COUNT, NormalizeRangeDispatchProperty.READER);
|
||||
registerFactory(DAMAGE, DamageRangeDispatchProperty.FACTORY);
|
||||
registerReader(DAMAGE, DamageRangeDispatchProperty.READER);
|
||||
registerFactory(CUSTOM_MODEL_DATA, CustomModelDataRangeDispatchProperty.FACTORY);
|
||||
registerReader(CUSTOM_MODEL_DATA, CustomModelDataRangeDispatchProperty.READER);
|
||||
registerFactory(TIME, TimeRangeDispatchProperty.FACTORY);
|
||||
registerReader(TIME, TimeRangeDispatchProperty.READER);
|
||||
registerFactory(USE_CYCLE, UseCycleRangeDispatchProperty.FACTORY);
|
||||
registerReader(USE_CYCLE, UseCycleRangeDispatchProperty.READER);
|
||||
registerFactory(USE_DURATION, UseDurationRangeDispatchProperty.FACTORY);
|
||||
registerReader(USE_DURATION, UseDurationRangeDispatchProperty.READER);
|
||||
}
|
||||
|
||||
public static void register(Key key, RangeDispatchPropertyFactory factory) {
|
||||
public static void registerFactory(Key key, RangeDispatchPropertyFactory factory) {
|
||||
Holder.Reference<RangeDispatchPropertyFactory> holder = ((WritableRegistry<RangeDispatchPropertyFactory>) BuiltInRegistries.RANGE_DISPATCH_PROPERTY_FACTORY)
|
||||
.registerForHolder(new ResourceKey<>(Registries.RANGE_DISPATCH_PROPERTY_FACTORY.location(), key));
|
||||
holder.bindValue(factory);
|
||||
}
|
||||
|
||||
public static void registerReader(Key key, RangeDispatchPropertyReader reader) {
|
||||
Holder.Reference<RangeDispatchPropertyReader> holder = ((WritableRegistry<RangeDispatchPropertyReader>) BuiltInRegistries.RANGE_DISPATCH_PROPERTY_READER)
|
||||
.registerForHolder(new ResourceKey<>(Registries.RANGE_DISPATCH_PROPERTY_READER.location(), key));
|
||||
holder.bindValue(reader);
|
||||
}
|
||||
|
||||
public static RangeDispatchProperty fromMap(Map<String, Object> map) {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("property"), "warning.config.item.model.range_dispatch.missing_property");
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
@@ -51,4 +68,14 @@ public class RangeDispatchProperties {
|
||||
}
|
||||
return factory.create(map);
|
||||
}
|
||||
|
||||
public static RangeDispatchProperty fromJson(JsonObject json) {
|
||||
String type = json.get("property").getAsString();
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
RangeDispatchPropertyReader reader = BuiltInRegistries.RANGE_DISPATCH_PROPERTY_READER.getValue(key);
|
||||
if (reader == null) {
|
||||
throw new IllegalArgumentException("Invalid range dispatch property type: " + key);
|
||||
}
|
||||
return reader.read(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.momirealms.craftengine.core.pack.model.rangedisptach;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface RangeDispatchPropertyReader {
|
||||
|
||||
RangeDispatchProperty read(JsonObject json);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import java.util.Map;
|
||||
|
||||
public class SimpleRangeDispatchProperty implements RangeDispatchProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final Key type;
|
||||
|
||||
public SimpleRangeDispatchProperty(Key type) {
|
||||
@@ -24,11 +25,18 @@ public class SimpleRangeDispatchProperty implements RangeDispatchProperty {
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
Key type = Key.of(arguments.get("property").toString());
|
||||
return new SimpleRangeDispatchProperty(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
Key type = Key.of(json.get("property").toString());
|
||||
return new SimpleRangeDispatchProperty(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
public class TimeRangeDispatchProperty implements RangeDispatchProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String source;
|
||||
private final boolean wobble;
|
||||
|
||||
@@ -31,7 +32,6 @@ public class TimeRangeDispatchProperty implements RangeDispatchProperty {
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
String sourceObj = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("source"), "warning.config.item.model.range_dispatch.time.missing_source");
|
||||
@@ -39,4 +39,13 @@ public class TimeRangeDispatchProperty implements RangeDispatchProperty {
|
||||
return new TimeRangeDispatchProperty(sourceObj, wobble);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
String source = json.get("source").getAsString();
|
||||
boolean wobble = !json.has("wobble") || json.get("wobble").getAsBoolean();
|
||||
return new TimeRangeDispatchProperty(source, wobble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ import java.util.Map;
|
||||
|
||||
public class UseCycleRangeDispatchProperty implements RangeDispatchProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final int period;
|
||||
public static final Reader READER = new Reader();
|
||||
private final float period;
|
||||
|
||||
public UseCycleRangeDispatchProperty(int period) {
|
||||
public UseCycleRangeDispatchProperty(float period) {
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
@@ -26,10 +27,17 @@ public class UseCycleRangeDispatchProperty implements RangeDispatchProperty {
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
int period = ResourceConfigUtils.getAsInt(arguments.getOrDefault("period", 0), "period");
|
||||
float period = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("period", 0), "period");
|
||||
return new UseCycleRangeDispatchProperty(period);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
float period = json.has("period") ? json.get("period").getAsFloat() : 1.0f;
|
||||
return new UseCycleRangeDispatchProperty(period);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.Map;
|
||||
|
||||
public class UseDurationRangeDispatchProperty implements RangeDispatchProperty, LegacyModelPredicate<Float> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final boolean remaining;
|
||||
|
||||
public UseDurationRangeDispatchProperty(boolean remaining) {
|
||||
@@ -41,11 +42,18 @@ public class UseDurationRangeDispatchProperty implements RangeDispatchProperty,
|
||||
}
|
||||
|
||||
public static class Factory implements RangeDispatchPropertyFactory {
|
||||
|
||||
@Override
|
||||
public RangeDispatchProperty create(Map<String, Object> arguments) {
|
||||
boolean remaining = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("remaining", false), "remaining");
|
||||
return new UseDurationRangeDispatchProperty(remaining);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements RangeDispatchPropertyReader {
|
||||
@Override
|
||||
public RangeDispatchProperty read(JsonObject json) {
|
||||
boolean remaining = json.has("remaining") && json.get("remaining").getAsBoolean();
|
||||
return new UseDurationRangeDispatchProperty(remaining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
public class BlockStateSelectProperty implements SelectProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String blockStateProperty;
|
||||
|
||||
public BlockStateSelectProperty(String blockStateProperty) {
|
||||
@@ -26,11 +27,18 @@ public class BlockStateSelectProperty implements SelectProperty {
|
||||
}
|
||||
|
||||
public static class Factory implements SelectPropertyFactory {
|
||||
|
||||
@Override
|
||||
public SelectProperty create(Map<String, Object> arguments) {
|
||||
String property = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("block-state-property"), "warning.config.item.model.select.block_state.missing_property");
|
||||
return new BlockStateSelectProperty(property);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SelectPropertyReader {
|
||||
@Override
|
||||
public SelectProperty read(JsonObject json) {
|
||||
String property = json.get("block_state_property").getAsString();
|
||||
return new BlockStateSelectProperty(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Map;
|
||||
|
||||
public class ChargeTypeSelectProperty implements SelectProperty, LegacyModelPredicate<String> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final ChargeTypeSelectProperty INSTANCE = new ChargeTypeSelectProperty();
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
@@ -33,10 +35,16 @@ public class ChargeTypeSelectProperty implements SelectProperty, LegacyModelPred
|
||||
}
|
||||
|
||||
public static class Factory implements SelectPropertyFactory {
|
||||
|
||||
@Override
|
||||
public SelectProperty create(Map<String, Object> arguments) {
|
||||
return new ChargeTypeSelectProperty();
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SelectPropertyReader {
|
||||
@Override
|
||||
public SelectProperty read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.momirealms.craftengine.core.pack.model.select;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ComponentSelectProperty implements SelectProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String component;
|
||||
|
||||
public ComponentSelectProperty(String component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return SelectProperties.COMPONENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(JsonObject jsonObject) {
|
||||
jsonObject.addProperty("property", type().toString());
|
||||
jsonObject.addProperty("component", this.component);
|
||||
}
|
||||
|
||||
public static class Factory implements SelectPropertyFactory {
|
||||
@Override
|
||||
public SelectProperty create(Map<String, Object> arguments) {
|
||||
String component = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("component"), "warning.config.item.model.select.component.missing_component");
|
||||
return new ComponentSelectProperty(component);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SelectPropertyReader {
|
||||
@Override
|
||||
public SelectProperty read(JsonObject json) {
|
||||
String component = json.get("component").getAsString();
|
||||
return new ComponentSelectProperty(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
public class CustomModelDataSelectProperty implements SelectProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final int index;
|
||||
|
||||
public CustomModelDataSelectProperty(int index) {
|
||||
@@ -26,11 +27,18 @@ public class CustomModelDataSelectProperty implements SelectProperty {
|
||||
}
|
||||
|
||||
public static class Factory implements SelectPropertyFactory {
|
||||
|
||||
@Override
|
||||
public SelectProperty create(Map<String, Object> arguments) {
|
||||
int index = ResourceConfigUtils.getAsInt(arguments.getOrDefault("index", 0), "index");
|
||||
return new CustomModelDataSelectProperty(index);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SelectPropertyReader {
|
||||
@Override
|
||||
public SelectProperty read(JsonObject json) {
|
||||
int index = json.has("index") ? json.get("index").getAsInt() : 0;
|
||||
return new CustomModelDataSelectProperty(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.Map;
|
||||
|
||||
public class LocalTimeSelectProperty implements SelectProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String pattern;
|
||||
private final String locale;
|
||||
private final String timeZone;
|
||||
@@ -30,17 +31,16 @@ public class LocalTimeSelectProperty implements SelectProperty {
|
||||
@Override
|
||||
public void accept(JsonObject jsonObject) {
|
||||
jsonObject.addProperty("property", type().toString());
|
||||
jsonObject.addProperty("pattern", pattern);
|
||||
if (locale != null) {
|
||||
jsonObject.addProperty("locale", locale);
|
||||
jsonObject.addProperty("pattern", this.pattern);
|
||||
if (this.locale != null) {
|
||||
jsonObject.addProperty("locale", this.locale);
|
||||
}
|
||||
if (timeZone != null) {
|
||||
jsonObject.addProperty("time_zone", timeZone);
|
||||
if (this.timeZone != null) {
|
||||
jsonObject.addProperty("time_zone", this.timeZone);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory implements SelectPropertyFactory {
|
||||
|
||||
@Override
|
||||
public SelectProperty create(Map<String, Object> arguments) {
|
||||
String pattern = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("pattern"), "warning.config.item.model.select.local_time.missing_pattern");
|
||||
@@ -49,4 +49,14 @@ public class LocalTimeSelectProperty implements SelectProperty {
|
||||
return new LocalTimeSelectProperty(pattern, locale, timeZone);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SelectPropertyReader {
|
||||
@Override
|
||||
public SelectProperty read(JsonObject json) {
|
||||
String pattern = json.get("pattern").getAsString();
|
||||
String locale = json.has("locale") ? json.get("locale").getAsString() : null;
|
||||
String timeZone = json.has("time_zone") ? json.get("time_zone").getAsString() : null;
|
||||
return new LocalTimeSelectProperty(pattern, locale, timeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import java.util.Map;
|
||||
|
||||
public class MainHandSelectProperty implements SelectProperty, LegacyModelPredicate<String> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final MainHandSelectProperty INSTANCE = new MainHandSelectProperty();
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
@@ -31,10 +33,16 @@ public class MainHandSelectProperty implements SelectProperty, LegacyModelPredic
|
||||
}
|
||||
|
||||
public static class Factory implements SelectPropertyFactory {
|
||||
|
||||
@Override
|
||||
public SelectProperty create(Map<String, Object> arguments) {
|
||||
return new MainHandSelectProperty();
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SelectPropertyReader {
|
||||
@Override
|
||||
public SelectProperty read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.pack.model.select;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
@@ -21,25 +22,43 @@ public class SelectProperties {
|
||||
public static final Key LOCAL_TIME = Key.of("minecraft:local_time");
|
||||
public static final Key MAIN_HAND = Key.of("minecraft:main_hand");
|
||||
public static final Key TRIM_MATERIAL = Key.of("minecraft:trim_material");
|
||||
public static final Key COMPONENT = Key.of("minecraft:component");
|
||||
|
||||
static {
|
||||
register(CHARGE_TYPE, ChargeTypeSelectProperty.FACTORY);
|
||||
register(CONTEXT_DIMENSION, SimpleSelectProperty.FACTORY);
|
||||
register(CONTEXT_ENTITY_TYPE, SimpleSelectProperty.FACTORY);
|
||||
register(DISPLAY_CONTEXT, SimpleSelectProperty.FACTORY);
|
||||
register(MAIN_HAND, MainHandSelectProperty.FACTORY);
|
||||
register(TRIM_MATERIAL, TrimMaterialSelectProperty.FACTORY);
|
||||
register(BLOCK_STATE, BlockStateSelectProperty.FACTORY);
|
||||
register(CUSTOM_MODEL_DATA, CustomModelDataSelectProperty.FACTORY);
|
||||
register(LOCAL_TIME, LocalTimeSelectProperty.FACTORY);
|
||||
registerFactory(CHARGE_TYPE, ChargeTypeSelectProperty.FACTORY);
|
||||
registerReader(CHARGE_TYPE, ChargeTypeSelectProperty.READER);
|
||||
registerFactory(CONTEXT_DIMENSION, SimpleSelectProperty.FACTORY);
|
||||
registerReader(CONTEXT_DIMENSION, SimpleSelectProperty.READER);
|
||||
registerFactory(CONTEXT_ENTITY_TYPE, SimpleSelectProperty.FACTORY);
|
||||
registerReader(CONTEXT_ENTITY_TYPE, SimpleSelectProperty.READER);
|
||||
registerFactory(DISPLAY_CONTEXT, SimpleSelectProperty.FACTORY);
|
||||
registerReader(DISPLAY_CONTEXT, SimpleSelectProperty.READER);
|
||||
registerFactory(MAIN_HAND, MainHandSelectProperty.FACTORY);
|
||||
registerReader(MAIN_HAND, MainHandSelectProperty.READER);
|
||||
registerFactory(TRIM_MATERIAL, TrimMaterialSelectProperty.FACTORY);
|
||||
registerReader(TRIM_MATERIAL, TrimMaterialSelectProperty.READER);
|
||||
registerFactory(BLOCK_STATE, BlockStateSelectProperty.FACTORY);
|
||||
registerReader(BLOCK_STATE, BlockStateSelectProperty.READER);
|
||||
registerFactory(CUSTOM_MODEL_DATA, CustomModelDataSelectProperty.FACTORY);
|
||||
registerReader(CUSTOM_MODEL_DATA, CustomModelDataSelectProperty.READER);
|
||||
registerFactory(LOCAL_TIME, LocalTimeSelectProperty.FACTORY);
|
||||
registerReader(LOCAL_TIME, LocalTimeSelectProperty.READER);
|
||||
registerFactory(COMPONENT, ComponentSelectProperty.FACTORY);
|
||||
registerReader(COMPONENT, ComponentSelectProperty.READER);
|
||||
}
|
||||
|
||||
public static void register(Key key, SelectPropertyFactory factory) {
|
||||
public static void registerFactory(Key key, SelectPropertyFactory factory) {
|
||||
Holder.Reference<SelectPropertyFactory> holder = ((WritableRegistry<SelectPropertyFactory>) BuiltInRegistries.SELECT_PROPERTY_FACTORY)
|
||||
.registerForHolder(new ResourceKey<>(Registries.SELECT_PROPERTY_FACTORY.location(), key));
|
||||
holder.bindValue(factory);
|
||||
}
|
||||
|
||||
public static void registerReader(Key key, SelectPropertyReader reader) {
|
||||
Holder.Reference<SelectPropertyReader> holder = ((WritableRegistry<SelectPropertyReader>) BuiltInRegistries.SELECT_PROPERTY_READER)
|
||||
.registerForHolder(new ResourceKey<>(Registries.SELECT_PROPERTY_READER.location(), key));
|
||||
holder.bindValue(reader);
|
||||
}
|
||||
|
||||
public static SelectProperty fromMap(Map<String, Object> map) {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("property"), "warning.config.item.model.select.missing_property");
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
@@ -49,4 +68,14 @@ public class SelectProperties {
|
||||
}
|
||||
return factory.create(map);
|
||||
}
|
||||
|
||||
public static SelectProperty fromJson(JsonObject json) {
|
||||
String type = json.get("property").getAsString();
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
SelectPropertyReader reader = BuiltInRegistries.SELECT_PROPERTY_READER.getValue(key);
|
||||
if (reader == null) {
|
||||
throw new IllegalArgumentException("Invalid select property type: " + key);
|
||||
}
|
||||
return reader.read(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.momirealms.craftengine.core.pack.model.select;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface SelectPropertyReader {
|
||||
|
||||
SelectProperty read(JsonObject json);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import java.util.Map;
|
||||
|
||||
public class SimpleSelectProperty implements SelectProperty {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final Key type;
|
||||
|
||||
public SimpleSelectProperty(Key type) {
|
||||
@@ -24,11 +25,18 @@ public class SimpleSelectProperty implements SelectProperty {
|
||||
}
|
||||
|
||||
public static class Factory implements SelectPropertyFactory {
|
||||
|
||||
@Override
|
||||
public SelectProperty create(Map<String, Object> arguments) {
|
||||
Key type = Key.of(arguments.get("property").toString());
|
||||
return new SimpleSelectProperty(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SelectPropertyReader {
|
||||
@Override
|
||||
public SelectProperty read(JsonObject json) {
|
||||
Key type = Key.of(json.get("property").toString());
|
||||
return new SimpleSelectProperty(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Map;
|
||||
|
||||
public class TrimMaterialSelectProperty implements SelectProperty, LegacyModelPredicate<String> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final TrimMaterialSelectProperty INSTANCE = new TrimMaterialSelectProperty();
|
||||
private static final Map<String, Float> LEGACY_TRIM_DATA = new HashMap<>();
|
||||
static {
|
||||
LEGACY_TRIM_DATA.put("minecraft:quartz", 0.1f);
|
||||
@@ -58,10 +60,16 @@ public class TrimMaterialSelectProperty implements SelectProperty, LegacyModelPr
|
||||
}
|
||||
|
||||
public static class Factory implements SelectPropertyFactory {
|
||||
|
||||
@Override
|
||||
public SelectProperty create(Map<String, Object> arguments) {
|
||||
return new TrimMaterialSelectProperty();
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SelectPropertyReader {
|
||||
@Override
|
||||
public SelectProperty read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BannerSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String color;
|
||||
|
||||
public BannerSpecialModel(String color) {
|
||||
@@ -20,19 +24,31 @@ public class BannerSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.addProperty("color", color);
|
||||
json.addProperty("color", this.color);
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
|
||||
@Override
|
||||
public SpecialModel create(Map<String, Object> arguments) {
|
||||
String color = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("color"), "warning.config.item.model.special.banner.missing_color");
|
||||
return new BannerSpecialModel(color);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SpecialModelReader {
|
||||
@Override
|
||||
public SpecialModel read(JsonObject json) {
|
||||
String color = json.get("color").getAsString();
|
||||
return new BannerSpecialModel(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BedSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String texture;
|
||||
|
||||
public BedSpecialModel(String texture) {
|
||||
@@ -20,19 +24,31 @@ public class BedSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.addProperty("texture", texture);
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
@Override
|
||||
public SpecialModel create(Map<String, Object> arguments) {
|
||||
String color = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("texture"), "warning.config.item.model.special.bed.missing_texture");
|
||||
return new BedSpecialModel(color);
|
||||
String texture = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("texture"), "warning.config.item.model.special.bed.missing_texture");
|
||||
return new BedSpecialModel(texture);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SpecialModelReader {
|
||||
@Override
|
||||
public SpecialModel read(JsonObject json) {
|
||||
String texture = json.get("texture").getAsString();
|
||||
return new BedSpecialModel(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChestSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String texture;
|
||||
private final float openness;
|
||||
|
||||
@@ -23,7 +27,12 @@ public class ChestSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.addProperty("texture", texture);
|
||||
@@ -34,7 +43,6 @@ public class ChestSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
|
||||
@Override
|
||||
public SpecialModel create(Map<String, Object> arguments) {
|
||||
float openness = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("openness", 0), "openness");
|
||||
@@ -45,4 +53,12 @@ public class ChestSpecialModel implements SpecialModel {
|
||||
return new ChestSpecialModel(texture, openness);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SpecialModelReader {
|
||||
@Override
|
||||
public SpecialModel read(JsonObject json) {
|
||||
float openness = json.has("openness") ? json.get("openness").getAsFloat() : 0;
|
||||
return new ChestSpecialModel(json.get("texture").getAsString(), openness);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class HeadSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String kind;
|
||||
private final String texture;
|
||||
private final int animation;
|
||||
private final float animation;
|
||||
|
||||
public HeadSpecialModel(String kind, String texture, int animation) {
|
||||
public HeadSpecialModel(String kind, String texture, float animation) {
|
||||
this.kind = kind;
|
||||
this.texture = texture;
|
||||
this.animation = animation;
|
||||
@@ -25,26 +29,40 @@ public class HeadSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.addProperty("kind", kind);
|
||||
if (texture != null) {
|
||||
json.addProperty("texture", texture);
|
||||
json.addProperty("kind", this.kind);
|
||||
if (this.texture != null) {
|
||||
json.addProperty("texture", this.texture);
|
||||
}
|
||||
if (animation != 0) {
|
||||
json.addProperty("animation", animation);
|
||||
if (this.animation != 0) {
|
||||
json.addProperty("animation", this.animation);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
|
||||
@Override
|
||||
public SpecialModel create(Map<String, Object> arguments) {
|
||||
String kind = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("kind"), "warning.config.item.model.special.head.missing_kind");
|
||||
String texture = Optional.ofNullable(arguments.get("texture")).map(String::valueOf).orElse(null);
|
||||
int animation = ResourceConfigUtils.getAsInt(arguments.getOrDefault("animation", 0), "animation");
|
||||
float animation = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("animation", 0), "animation");
|
||||
return new HeadSpecialModel(kind, texture, animation);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SpecialModelReader {
|
||||
@Override
|
||||
public SpecialModel read(JsonObject json) {
|
||||
String kind = json.get("kind").getAsString();
|
||||
String texture = json.has("texture") ? json.get("texture").getAsString() : null;
|
||||
float animation = json.has("animation") ? json.get("animation").getAsFloat() : 0f;
|
||||
return new HeadSpecialModel(kind, texture, animation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revisions;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlayerHeadSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
public static final PlayerHeadSpecialModel INSTANCE = new PlayerHeadSpecialModel();
|
||||
|
||||
public PlayerHeadSpecialModel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return SpecialModels.PLAYER_HEAD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
return List.of(Revisions.SINCE_1_21_6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
if (version.isAtOrAbove(MinecraftVersions.V1_21_6)) {
|
||||
json.addProperty("type", type().toString());
|
||||
} else {
|
||||
json.addProperty("type", SpecialModels.HEAD.toString());
|
||||
json.addProperty("kind", "player");
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
@Override
|
||||
public SpecialModel create(Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SpecialModelReader {
|
||||
@Override
|
||||
public SpecialModel read(JsonObject json) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,22 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ShulkerBoxSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final String texture;
|
||||
private final float openness;
|
||||
private final Direction orientation;
|
||||
@@ -23,13 +27,18 @@ public class ShulkerBoxSpecialModel implements SpecialModel {
|
||||
this.orientation = orientation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return SpecialModels.SHULKER_BOX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.addProperty("texture", texture);
|
||||
@@ -41,7 +50,6 @@ public class ShulkerBoxSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
|
||||
@Override
|
||||
public SpecialModel create(Map<String, Object> arguments) {
|
||||
float openness = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("openness", 0), "openness");
|
||||
@@ -53,4 +61,14 @@ public class ShulkerBoxSpecialModel implements SpecialModel {
|
||||
return new ShulkerBoxSpecialModel(texture, openness, orientation);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SpecialModelReader {
|
||||
@Override
|
||||
public SpecialModel read(JsonObject json) {
|
||||
float openness = json.has("openness") ? json.get("openness").getAsFloat() : 0f;
|
||||
Direction orientation = json.has("orientation") ? Direction.valueOf(json.get("orientation").getAsString().toUpperCase(Locale.ENGLISH)) : null;
|
||||
String texture = json.get("texture").getAsString();
|
||||
return new ShulkerBoxSpecialModel(texture, openness, orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SignSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final Key type;
|
||||
private final String woodType;
|
||||
private final String texture;
|
||||
@@ -24,7 +28,12 @@ public class SignSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
json.addProperty("wood_type", woodType);
|
||||
@@ -33,7 +42,6 @@ public class SignSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
|
||||
@Override
|
||||
public SpecialModel create(Map<String, Object> arguments) {
|
||||
Key type = Key.of(arguments.get("type").toString());
|
||||
@@ -42,4 +50,14 @@ public class SignSpecialModel implements SpecialModel {
|
||||
return new SignSpecialModel(type, woodType, texture);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SpecialModelReader {
|
||||
@Override
|
||||
public SpecialModel read(JsonObject json) {
|
||||
Key type = Key.of(json.get("type").toString());
|
||||
String woodType = json.get("wood_type").getAsString();
|
||||
String texture = json.get("texture").getAsString();
|
||||
return new SignSpecialModel(type, woodType, texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SimpleSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final Key type;
|
||||
|
||||
public SimpleSpecialModel(Key type) {
|
||||
@@ -19,18 +23,30 @@ public class SimpleSpecialModel implements SpecialModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject get() {
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
@Override
|
||||
public List<Revision> revisions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public static class Factory implements SpecialModelFactory {
|
||||
@Override
|
||||
public SpecialModel create(Map<String, Object> arguments) {
|
||||
Key type = Key.of(arguments.get("type").toString());
|
||||
return new SimpleSpecialModel(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements SpecialModelReader {
|
||||
@Override
|
||||
public SpecialModel read(JsonObject json) {
|
||||
Key type = Key.of(json.get("type").toString());
|
||||
return new SimpleSpecialModel(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface SpecialModel extends Supplier<JsonObject> {
|
||||
public interface SpecialModel extends Function<MinecraftVersion, JsonObject> {
|
||||
|
||||
Key type();
|
||||
|
||||
List<Revision> revisions();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface SpecialModelReader {
|
||||
|
||||
SpecialModel read(JsonObject json);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.pack.model.special;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
@@ -23,26 +24,47 @@ public class SpecialModels {
|
||||
public static final Key SHULKER_BOX = Key.of("minecraft:shulker_box");
|
||||
public static final Key STANDING_SIGN = Key.of("minecraft:standing_sign");
|
||||
public static final Key TRIDENT = Key.of("minecraft:trident");
|
||||
public static final Key PLAYER_HEAD = Key.of("minecraft:player_head");
|
||||
|
||||
static {
|
||||
register(TRIDENT, SimpleSpecialModel.FACTORY);
|
||||
register(DECORATED_POT, SimpleSpecialModel.FACTORY);
|
||||
register(CONDUIT, SimpleSpecialModel.FACTORY);
|
||||
register(SHIELD, SimpleSpecialModel.FACTORY);
|
||||
register(HANGING_SIGN, SignSpecialModel.FACTORY);
|
||||
register(STANDING_SIGN, SignSpecialModel.FACTORY);
|
||||
register(CHEST, ChestSpecialModel.FACTORY);
|
||||
register(BANNER, BannerSpecialModel.FACTORY);
|
||||
register(BED, BedSpecialModel.FACTORY);
|
||||
register(HEAD, HeadSpecialModel.FACTORY);
|
||||
registerFactory(TRIDENT, SimpleSpecialModel.FACTORY);
|
||||
registerReader(TRIDENT, SimpleSpecialModel.READER);
|
||||
registerFactory(DECORATED_POT, SimpleSpecialModel.FACTORY);
|
||||
registerReader(DECORATED_POT, SimpleSpecialModel.READER);
|
||||
registerFactory(CONDUIT, SimpleSpecialModel.FACTORY);
|
||||
registerReader(CONDUIT, SimpleSpecialModel.READER);
|
||||
registerFactory(SHIELD, SimpleSpecialModel.FACTORY);
|
||||
registerReader(SHIELD, SimpleSpecialModel.READER);
|
||||
registerFactory(HANGING_SIGN, SignSpecialModel.FACTORY);
|
||||
registerReader(HANGING_SIGN, SignSpecialModel.READER);
|
||||
registerFactory(STANDING_SIGN, SignSpecialModel.FACTORY);
|
||||
registerReader(STANDING_SIGN, SignSpecialModel.READER);
|
||||
registerFactory(PLAYER_HEAD, PlayerHeadSpecialModel.FACTORY);
|
||||
registerReader(PLAYER_HEAD, PlayerHeadSpecialModel.READER);
|
||||
registerFactory(CHEST, ChestSpecialModel.FACTORY);
|
||||
registerReader(CHEST, ChestSpecialModel.READER);
|
||||
registerFactory(BANNER, BannerSpecialModel.FACTORY);
|
||||
registerReader(BANNER, BannerSpecialModel.READER);
|
||||
registerFactory(BED, BedSpecialModel.FACTORY);
|
||||
registerReader(BED, BedSpecialModel.READER);
|
||||
registerFactory(HEAD, HeadSpecialModel.FACTORY);
|
||||
registerReader(HEAD, HeadSpecialModel.READER);
|
||||
registerFactory(SHULKER_BOX, ShulkerBoxSpecialModel.FACTORY);
|
||||
registerReader(SHULKER_BOX, ShulkerBoxSpecialModel.READER);
|
||||
}
|
||||
|
||||
public static void register(Key key, SpecialModelFactory factory) {
|
||||
public static void registerFactory(Key key, SpecialModelFactory factory) {
|
||||
Holder.Reference<SpecialModelFactory> holder = ((WritableRegistry<SpecialModelFactory>) BuiltInRegistries.SPECIAL_MODEL_FACTORY)
|
||||
.registerForHolder(new ResourceKey<>(Registries.SPECIAL_MODEL_FACTORY.location(), key));
|
||||
holder.bindValue(factory);
|
||||
}
|
||||
|
||||
public static void registerReader(Key key, SpecialModelReader factory) {
|
||||
Holder.Reference<SpecialModelReader> holder = ((WritableRegistry<SpecialModelReader>) BuiltInRegistries.SPECIAL_MODEL_READER)
|
||||
.registerForHolder(new ResourceKey<>(Registries.SPECIAL_MODEL_READER.location(), key));
|
||||
holder.bindValue(factory);
|
||||
}
|
||||
|
||||
public static SpecialModel fromMap(Map<String, Object> map) {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.item.model.special.missing_type");
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
@@ -52,4 +74,14 @@ public class SpecialModels {
|
||||
}
|
||||
return factory.create(map);
|
||||
}
|
||||
|
||||
public static SpecialModel fromJson(JsonObject json) {
|
||||
String type = json.get("type").getAsString();
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
SpecialModelReader reader = BuiltInRegistries.SPECIAL_MODEL_READER.getValue(key);
|
||||
if (reader == null) {
|
||||
throw new IllegalArgumentException("Invalid special model type: " + key);
|
||||
}
|
||||
return reader.read(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.Map;
|
||||
|
||||
public class ConstantTint implements Tint {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final Either<Integer, List<Float>> value;
|
||||
|
||||
public ConstantTint(Either<Integer, List<Float>> value) {
|
||||
@@ -30,11 +31,17 @@ public class ConstantTint implements Tint {
|
||||
}
|
||||
|
||||
public static class Factory implements TintFactory {
|
||||
|
||||
@Override
|
||||
public Tint create(Map<String, Object> arguments) {
|
||||
Object value = ResourceConfigUtils.requireNonNullOrThrow(arguments.get("value"), "warning.config.item.model.tint.constant.missing_value");
|
||||
Object value = ResourceConfigUtils.requireNonNullOrThrow(ResourceConfigUtils.get(arguments, "value", "default"), "warning.config.item.model.tint.constant.missing_value");
|
||||
return new ConstantTint(parseTintValue(value));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements TintReader {
|
||||
@Override
|
||||
public Tint read(JsonObject json) {
|
||||
return new ConstantTint(parseTintValue(json.get("value")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.Map;
|
||||
|
||||
public class CustomModelDataTint implements Tint {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final Either<Integer, List<Float>> value;
|
||||
private final int index;
|
||||
|
||||
@@ -28,18 +29,27 @@ public class CustomModelDataTint implements Tint {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
if (index != 0)
|
||||
json.addProperty("index", index);
|
||||
applyAnyTint(json, value, "default");
|
||||
json.addProperty("index", this.index);
|
||||
applyAnyTint(json, this.value, "default");
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Factory implements TintFactory {
|
||||
|
||||
@Override
|
||||
public Tint create(Map<String, Object> arguments) {
|
||||
Object value = arguments.getOrDefault("default", 0);
|
||||
Object value = arguments.containsKey("default") ? arguments.getOrDefault("default", 0) : arguments.getOrDefault("value", 0);
|
||||
int index = ResourceConfigUtils.getAsInt(arguments.getOrDefault("index", 0), "index");
|
||||
return new CustomModelDataTint(parseTintValue(value), index);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements TintReader {
|
||||
@Override
|
||||
public Tint read(JsonObject json) {
|
||||
return new CustomModelDataTint(
|
||||
parseTintValue(json.get("default")),
|
||||
json.has("index") ? json.get("index").getAsInt() : 0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
|
||||
public class GrassTint implements Tint {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final Reader READER = new Reader();
|
||||
private final float temperature;
|
||||
private final float downfall;
|
||||
|
||||
@@ -32,7 +33,6 @@ public class GrassTint implements Tint {
|
||||
}
|
||||
|
||||
public static class Factory implements TintFactory {
|
||||
|
||||
@Override
|
||||
public Tint create(Map<String, Object> arguments) {
|
||||
float temperature = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("temperature", 0), "temperature");
|
||||
@@ -46,4 +46,13 @@ public class GrassTint implements Tint {
|
||||
return new GrassTint(temperature, downfall);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements TintReader {
|
||||
@Override
|
||||
public Tint read(JsonObject json) {
|
||||
float temperature = json.has("temperature") ? json.get("temperature").getAsFloat() : 0;
|
||||
float downfall = json.has("downfall") ? json.get("downfall").getAsFloat() : 0;
|
||||
return new GrassTint(temperature, downfall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,19 @@ package net.momirealms.craftengine.core.pack.model.tint;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.incendo.cloud.type.Either;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SimpleDefaultTint implements Tint {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final Either<Integer, List<Float>> value;
|
||||
public static final Reader READER = new Reader();
|
||||
private final Either<Integer, List<Float>> defaultValue;
|
||||
private final Key type;
|
||||
|
||||
public SimpleDefaultTint(Either<Integer, List<Float>> value, Key type) {
|
||||
this.value = value;
|
||||
public SimpleDefaultTint(Key type, @Nullable Either<Integer, List<Float>> defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@@ -26,17 +28,23 @@ public class SimpleDefaultTint implements Tint {
|
||||
public JsonObject get() {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", type().toString());
|
||||
applyAnyTint(json, value, "default");
|
||||
applyAnyTint(json, this.defaultValue, "default");
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Factory implements TintFactory {
|
||||
|
||||
@Override
|
||||
public Tint create(Map<String, Object> arguments) {
|
||||
Object value = arguments.getOrDefault("default", 0);
|
||||
Object value = arguments.containsKey("default") ? arguments.getOrDefault("default", 0) : arguments.getOrDefault("value", 0);
|
||||
Key type = Key.of(arguments.get("type").toString());
|
||||
return new SimpleDefaultTint(parseTintValue(value), type);
|
||||
return new SimpleDefaultTint(type, parseTintValue(value));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reader implements TintReader {
|
||||
@Override
|
||||
public Tint read(JsonObject json) {
|
||||
return new SimpleDefaultTint(Key.of(json.get("type").getAsString()), parseTintValue(json.get("default")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public interface Tint extends Supplier<JsonObject> {
|
||||
Key type();
|
||||
|
||||
default void applyAnyTint(JsonObject json, Either<Integer, List<Float>> value, String key) {
|
||||
if (value == null) return;
|
||||
if (value.primary().isPresent()) {
|
||||
json.addProperty(key, value.primary().get());
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.momirealms.craftengine.core.pack.model.tint;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.incendo.cloud.type.Either;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public interface TintReader {
|
||||
|
||||
Tint read(JsonObject json);
|
||||
|
||||
default Either<Integer, List<Float>> parseTintValue(JsonElement element) {
|
||||
if (element instanceof JsonPrimitive jsonPrimitive) {
|
||||
return Either.ofPrimary(jsonPrimitive.getAsInt());
|
||||
} else if (element instanceof JsonArray array) {
|
||||
List<Float> result = new ArrayList<>();
|
||||
for (JsonElement jsonElement : array) {
|
||||
result.add(jsonElement.getAsFloat());
|
||||
}
|
||||
return Either.ofFallback(result);
|
||||
} else if (element instanceof JsonObject object) {
|
||||
throw new IllegalArgumentException("Can't parse tint value: " + object);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.pack.model.tint;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
@@ -22,22 +23,36 @@ public class Tints {
|
||||
public static final Key TEAM = Key.of("minecraft:team");
|
||||
|
||||
static {
|
||||
register(CONSTANT, ConstantTint.FACTORY);
|
||||
register(CUSTOM_MODEL_DATA, CustomModelDataTint.FACTORY);
|
||||
register(GRASS, GrassTint.FACTORY);
|
||||
register(DYE, SimpleDefaultTint.FACTORY);
|
||||
register(FIREWORK, SimpleDefaultTint.FACTORY);
|
||||
register(MAP_COLOR, SimpleDefaultTint.FACTORY);
|
||||
register(POTION, SimpleDefaultTint.FACTORY);
|
||||
register(TEAM, SimpleDefaultTint.FACTORY);
|
||||
registerFactory(CONSTANT, ConstantTint.FACTORY);
|
||||
registerReader(CONSTANT, ConstantTint.READER);
|
||||
registerFactory(CUSTOM_MODEL_DATA, CustomModelDataTint.FACTORY);
|
||||
registerReader(CUSTOM_MODEL_DATA, CustomModelDataTint.READER);
|
||||
registerFactory(GRASS, GrassTint.FACTORY);
|
||||
registerReader(GRASS, GrassTint.READER);
|
||||
registerFactory(DYE, SimpleDefaultTint.FACTORY);
|
||||
registerReader(DYE, SimpleDefaultTint.READER);
|
||||
registerFactory(FIREWORK, SimpleDefaultTint.FACTORY);
|
||||
registerReader(FIREWORK, SimpleDefaultTint.READER);
|
||||
registerFactory(MAP_COLOR, SimpleDefaultTint.FACTORY);
|
||||
registerReader(MAP_COLOR, SimpleDefaultTint.READER);
|
||||
registerFactory(POTION, SimpleDefaultTint.FACTORY);
|
||||
registerReader(POTION, SimpleDefaultTint.READER);
|
||||
registerFactory(TEAM, SimpleDefaultTint.FACTORY);
|
||||
registerReader(TEAM, SimpleDefaultTint.READER);
|
||||
}
|
||||
|
||||
public static void register(Key key, TintFactory factory) {
|
||||
public static void registerFactory(Key key, TintFactory factory) {
|
||||
Holder.Reference<TintFactory> holder = ((WritableRegistry<TintFactory>) BuiltInRegistries.TINT_FACTORY)
|
||||
.registerForHolder(new ResourceKey<>(Registries.TINT_FACTORY.location(), key));
|
||||
holder.bindValue(factory);
|
||||
}
|
||||
|
||||
public static void registerReader(Key key, TintReader reader) {
|
||||
Holder.Reference<TintReader> holder = ((WritableRegistry<TintReader>) BuiltInRegistries.TINT_READER)
|
||||
.registerForHolder(new ResourceKey<>(Registries.TINT_READER.location(), key));
|
||||
holder.bindValue(reader);
|
||||
}
|
||||
|
||||
public static Tint fromMap(Map<String, Object> map) {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.item.model.tint.missing_type");
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
@@ -47,4 +62,14 @@ public class Tints {
|
||||
}
|
||||
return factory.create(map);
|
||||
}
|
||||
|
||||
public static Tint fromJson(JsonObject json) {
|
||||
String type = json.get("type").getAsString();
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
TintReader reader = BuiltInRegistries.TINT_READER.getValue(key);
|
||||
if (reader == null) {
|
||||
throw new IllegalArgumentException("Invalid tint type: " + type);
|
||||
}
|
||||
return reader.read(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
package net.momirealms.craftengine.core.pack.revision;
|
||||
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersions;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public interface Revision {
|
||||
|
||||
int minPackVersion();
|
||||
|
||||
int maxPackVersion();
|
||||
|
||||
String versionString();
|
||||
|
||||
boolean matches(MinecraftVersion min, MinecraftVersion max);
|
||||
|
||||
MinecraftVersion minVersion();
|
||||
|
||||
MinecraftVersion maxVersion();
|
||||
|
||||
static Revision since(MinecraftVersion minecraftVersion) {
|
||||
return new Since(minecraftVersion);
|
||||
}
|
||||
|
||||
static Revision fromTo(MinecraftVersion from, MinecraftVersion to) {
|
||||
return new FromTo(from, to);
|
||||
}
|
||||
|
||||
class Since implements Revision {
|
||||
private final MinecraftVersion minVersion;
|
||||
private String versionString;
|
||||
|
||||
public Since(MinecraftVersion minVersion) {
|
||||
this.minVersion = minVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion maxVersion() {
|
||||
return MinecraftVersions.FUTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion minVersion() {
|
||||
return this.minVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String versionString() {
|
||||
if (this.versionString == null) {
|
||||
this.versionString = this.minVersion.version().replace(".", "_");
|
||||
}
|
||||
return this.versionString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(MinecraftVersion min, MinecraftVersion max) {
|
||||
return this.minVersion.isAtOrBelow(max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxPackVersion() {
|
||||
return MinecraftVersions.FUTURE.packFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int minPackVersion() {
|
||||
return this.minVersion.packFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object object) {
|
||||
if (!(object instanceof Since since)) return false;
|
||||
return this.minVersion.equals(since.minVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.minVersion.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
class FromTo implements Revision {
|
||||
private final MinecraftVersion minVersion;
|
||||
private final MinecraftVersion maxVersion;
|
||||
private String versionString;
|
||||
|
||||
public FromTo(MinecraftVersion minVersion, MinecraftVersion maxVersion) {
|
||||
this.minVersion = minVersion;
|
||||
this.maxVersion = maxVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion maxVersion() {
|
||||
return this.maxVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion minVersion() {
|
||||
return this.minVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(MinecraftVersion min, MinecraftVersion max) {
|
||||
return !min.isAbove(this.maxVersion) || !max.isBelow(this.minVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int minPackVersion() {
|
||||
return this.minVersion.packFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxPackVersion() {
|
||||
return this.maxVersion.packFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String versionString() {
|
||||
if (this.versionString == null) {
|
||||
this.versionString = this.minVersion.version().replace(".", "_") + "-" + this.maxVersion.version().replace(".", "_");
|
||||
}
|
||||
return this.versionString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object object) {
|
||||
if (!(object instanceof FromTo fromTo)) return false;
|
||||
return Objects.equals(minVersion, fromTo.minVersion) && Objects.equals(maxVersion, fromTo.maxVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hashCode(minVersion);
|
||||
result = 31 * result + Objects.hashCode(maxVersion);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.momirealms.craftengine.core.pack.revision;
|
||||
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersions;
|
||||
|
||||
public final class Revisions {
|
||||
private Revisions() {}
|
||||
|
||||
public static final Revision SINCE_1_21_6 = Revision.since(MinecraftVersions.V1_21_6);
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
|
||||
import net.momirealms.craftengine.core.plugin.logger.filter.DisconnectLogFilter;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.world.InjectionTarget;
|
||||
import net.momirealms.craftengine.core.world.chunk.storage.CompressionMethod;
|
||||
@@ -80,8 +81,9 @@ public class Config {
|
||||
protected List<String> resource_pack$protection$obfuscation$resource_location$bypass_sounds;
|
||||
protected List<String> resource_pack$protection$obfuscation$resource_location$bypass_equipments;
|
||||
|
||||
protected float resource_pack$supported_version$min;
|
||||
protected float resource_pack$supported_version$max;
|
||||
protected MinecraftVersion resource_pack$supported_version$min;
|
||||
protected MinecraftVersion resource_pack$supported_version$max;
|
||||
protected String resource_pack$overlay_format;
|
||||
|
||||
protected boolean resource_pack$delivery$kick_if_declined;
|
||||
protected boolean resource_pack$delivery$send_on_join;
|
||||
@@ -264,6 +266,10 @@ public class Config {
|
||||
resource_pack$protection$obfuscation$resource_location$bypass_equipments = config.getStringList("resource-pack.protection.obfuscation.resource-location.bypass-equipments");
|
||||
resource_pack$validate$enable = config.getBoolean("resource-pack.validate.enable", true);
|
||||
resource_pack$exclude_core_shaders = config.getBoolean("resource-pack.exclude-core-shaders", false);
|
||||
resource_pack$overlay_format = config.getString("resource-pack.overlay-format", "overlay_{version}");
|
||||
if (!resource_pack$overlay_format.contains("{version}")) {
|
||||
TranslationManager.instance().log("warning.config.resource_pack.invalid_overlay_format", resource_pack$overlay_format);
|
||||
}
|
||||
|
||||
try {
|
||||
resource_pack$duplicated_files_handler = config.getMapList("resource-pack.duplicated-files-handler").stream().map(it -> {
|
||||
@@ -363,15 +369,11 @@ public class Config {
|
||||
firstTime = false;
|
||||
}
|
||||
|
||||
private static float getVersion(String version) {
|
||||
private static MinecraftVersion getVersion(String version) {
|
||||
if (version.equalsIgnoreCase("LATEST")) {
|
||||
version = PluginProperties.getValue("latest-version");
|
||||
return new MinecraftVersion(PluginProperties.getValue("latest-version"));
|
||||
}
|
||||
String[] split = version.split("\\.", 2);
|
||||
if (split.length != 2) {
|
||||
throw new IllegalArgumentException("Invalid version: " + version);
|
||||
}
|
||||
return Float.parseFloat(split[1]);
|
||||
return MinecraftVersion.parse(version);
|
||||
}
|
||||
|
||||
public static String configVersion() {
|
||||
@@ -422,11 +424,11 @@ public class Config {
|
||||
return instance.light_system$enable;
|
||||
}
|
||||
|
||||
public static float packMinVersion() {
|
||||
public static MinecraftVersion packMinVersion() {
|
||||
return instance.resource_pack$supported_version$min;
|
||||
}
|
||||
|
||||
public static float packMaxVersion() {
|
||||
public static MinecraftVersion packMaxVersion() {
|
||||
return instance.resource_pack$supported_version$max;
|
||||
}
|
||||
|
||||
@@ -742,6 +744,10 @@ public class Config {
|
||||
return instance.resource_pack$exclude_core_shaders;
|
||||
}
|
||||
|
||||
public static String createOverlayFolderName(String version) {
|
||||
return instance.resource_pack$overlay_format.replace("{version}", version);
|
||||
}
|
||||
|
||||
public YamlDocument loadOrCreateYamlData(String fileName) {
|
||||
Path path = this.plugin.dataFolderPath().resolve(fileName);
|
||||
if (!Files.exists(path)) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.momirealms.craftengine.core.plugin.Manageable;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.SNBTReader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -76,7 +77,8 @@ public interface TemplateManager extends Manageable {
|
||||
this.placeholder = placeholderContent.substring(0, separatorIndex);
|
||||
String defaultValueString = placeholderContent.substring(separatorIndex + 2);
|
||||
try {
|
||||
this.defaultValue = CraftEngine.instance().platform().snbtToJava(defaultValueString);
|
||||
// TODO 改进报错检测
|
||||
this.defaultValue = new SNBTReader(defaultValueString).deserializeAsJava();
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
e.appendTailArgument(this.placeholder);
|
||||
throw e;
|
||||
|
||||
@@ -129,7 +129,9 @@ public interface GuiElement {
|
||||
|
||||
@Override
|
||||
public Item<?> item() {
|
||||
return gui().itemAt(this.index).item();
|
||||
ItemWithAction item = gui().itemAt(this.index);
|
||||
if (item == null) return null;
|
||||
return item.item();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,11 +15,17 @@ import net.momirealms.craftengine.core.pack.conflict.PathContext;
|
||||
import net.momirealms.craftengine.core.pack.conflict.resolution.ResolutionFactory;
|
||||
import net.momirealms.craftengine.core.pack.host.ResourcePackHostFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.ItemModelFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.ItemModelReader;
|
||||
import net.momirealms.craftengine.core.pack.model.condition.ConditionPropertyFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.condition.ConditionPropertyReader;
|
||||
import net.momirealms.craftengine.core.pack.model.rangedisptach.RangeDispatchPropertyFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.rangedisptach.RangeDispatchPropertyReader;
|
||||
import net.momirealms.craftengine.core.pack.model.select.SelectPropertyFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.select.SelectPropertyReader;
|
||||
import net.momirealms.craftengine.core.pack.model.special.SpecialModelFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.special.SpecialModelReader;
|
||||
import net.momirealms.craftengine.core.pack.model.tint.TintFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.tint.TintReader;
|
||||
import net.momirealms.craftengine.core.plugin.config.template.TemplateArgumentFactory;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
|
||||
@@ -41,11 +47,17 @@ public class BuiltInRegistries {
|
||||
public static final Registry<NumberProviderFactory> NUMBER_PROVIDER_FACTORY = createRegistry(Registries.NUMBER_PROVIDER_FACTORY);
|
||||
public static final Registry<TemplateArgumentFactory> TEMPLATE_ARGUMENT_FACTORY = createRegistry(Registries.TEMPLATE_ARGUMENT_FACTORY);
|
||||
public static final Registry<ItemModelFactory> ITEM_MODEL_FACTORY = createRegistry(Registries.ITEM_MODEL_FACTORY);
|
||||
public static final Registry<ItemModelReader> ITEM_MODEL_READER = createRegistry(Registries.ITEM_MODEL_READER);
|
||||
public static final Registry<TintFactory> TINT_FACTORY = createRegistry(Registries.TINT_FACTORY);
|
||||
public static final Registry<TintReader> TINT_READER = createRegistry(Registries.TINT_READER);
|
||||
public static final Registry<SpecialModelFactory> SPECIAL_MODEL_FACTORY = createRegistry(Registries.SPECIAL_MODEL_FACTORY);
|
||||
public static final Registry<SpecialModelReader> SPECIAL_MODEL_READER = createRegistry(Registries.SPECIAL_MODEL_READER);
|
||||
public static final Registry<RangeDispatchPropertyFactory> RANGE_DISPATCH_PROPERTY_FACTORY = createRegistry(Registries.RANGE_DISPATCH_PROPERTY_FACTORY);
|
||||
public static final Registry<RangeDispatchPropertyReader> RANGE_DISPATCH_PROPERTY_READER = createRegistry(Registries.RANGE_DISPATCH_PROPERTY_READER);
|
||||
public static final Registry<ConditionPropertyFactory> CONDITION_PROPERTY_FACTORY = createRegistry(Registries.CONDITION_PROPERTY_FACTORY);
|
||||
public static final Registry<ConditionPropertyReader> CONDITION_PROPERTY_READER = createRegistry(Registries.CONDITION_PROPERTY_READER);
|
||||
public static final Registry<SelectPropertyFactory> SELECT_PROPERTY_FACTORY = createRegistry(Registries.SELECT_PROPERTY_FACTORY);
|
||||
public static final Registry<SelectPropertyReader> SELECT_PROPERTY_READER = createRegistry(Registries.SELECT_PROPERTY_READER);
|
||||
public static final Registry<RecipeFactory<?>> RECIPE_FACTORY = createRegistry(Registries.RECIPE_FACTORY);
|
||||
public static final Registry<ApplyBonusCountFunction.FormulaFactory> FORMULA_FACTORY = createRegistry(Registries.FORMULA_FACTORY);
|
||||
public static final Registry<ConditionFactory<PathContext>> PATH_MATCHER_FACTORY = createRegistry(Registries.PATH_MATCHER_FACTORY);
|
||||
|
||||
@@ -15,11 +15,17 @@ import net.momirealms.craftengine.core.pack.conflict.PathContext;
|
||||
import net.momirealms.craftengine.core.pack.conflict.resolution.ResolutionFactory;
|
||||
import net.momirealms.craftengine.core.pack.host.ResourcePackHostFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.ItemModelFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.ItemModelReader;
|
||||
import net.momirealms.craftengine.core.pack.model.condition.ConditionPropertyFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.condition.ConditionPropertyReader;
|
||||
import net.momirealms.craftengine.core.pack.model.rangedisptach.RangeDispatchPropertyFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.rangedisptach.RangeDispatchPropertyReader;
|
||||
import net.momirealms.craftengine.core.pack.model.select.SelectPropertyFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.select.SelectPropertyReader;
|
||||
import net.momirealms.craftengine.core.pack.model.special.SpecialModelFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.special.SpecialModelReader;
|
||||
import net.momirealms.craftengine.core.pack.model.tint.TintFactory;
|
||||
import net.momirealms.craftengine.core.pack.model.tint.TintReader;
|
||||
import net.momirealms.craftengine.core.plugin.config.template.TemplateArgumentFactory;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
|
||||
@@ -42,11 +48,17 @@ public class Registries {
|
||||
public static final ResourceKey<Registry<NumberProviderFactory>> NUMBER_PROVIDER_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("number_provider_factory"));
|
||||
public static final ResourceKey<Registry<TemplateArgumentFactory>> TEMPLATE_ARGUMENT_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("template_argument_factory"));
|
||||
public static final ResourceKey<Registry<ItemModelFactory>> ITEM_MODEL_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("item_model_factory"));
|
||||
public static final ResourceKey<Registry<ItemModelReader>> ITEM_MODEL_READER = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("item_model_reader"));
|
||||
public static final ResourceKey<Registry<TintFactory>> TINT_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("tint_factory"));
|
||||
public static final ResourceKey<Registry<TintReader>> TINT_READER = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("tint_reader"));
|
||||
public static final ResourceKey<Registry<SpecialModelFactory>> SPECIAL_MODEL_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("special_model_factory"));
|
||||
public static final ResourceKey<Registry<SpecialModelReader>> SPECIAL_MODEL_READER = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("special_model_reader"));
|
||||
public static final ResourceKey<Registry<RangeDispatchPropertyFactory>> RANGE_DISPATCH_PROPERTY_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("range_dispatch_property_factory"));
|
||||
public static final ResourceKey<Registry<RangeDispatchPropertyReader>> RANGE_DISPATCH_PROPERTY_READER = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("range_dispatch_property_reader"));
|
||||
public static final ResourceKey<Registry<ConditionPropertyFactory>> CONDITION_PROPERTY_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("condition_property_factory"));
|
||||
public static final ResourceKey<Registry<ConditionPropertyReader>> CONDITION_PROPERTY_READER = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("condition_property_reader"));
|
||||
public static final ResourceKey<Registry<SelectPropertyFactory>> SELECT_PROPERTY_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("select_property_factory"));
|
||||
public static final ResourceKey<Registry<SelectPropertyReader>> SELECT_PROPERTY_READER = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("select_property_reader"));
|
||||
public static final ResourceKey<Registry<RecipeFactory<?>>> RECIPE_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("recipe_factory"));
|
||||
public static final ResourceKey<Registry<ApplyBonusCountFunction.FormulaFactory>> FORMULA_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("formula_factory"));
|
||||
public static final ResourceKey<Registry<ConditionFactory<PathContext>>> PATH_MATCHER_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("path_matcher_factory"));
|
||||
|
||||
@@ -4,9 +4,9 @@ public class DefaultStringReader implements StringReader {
|
||||
private static final char SYNTAX_ESCAPE = '\\';
|
||||
private static final char SYNTAX_DOUBLE_QUOTE = '"';
|
||||
private static final char SYNTAX_SINGLE_QUOTE = '\'';
|
||||
private final String string;
|
||||
private int cursor;
|
||||
private int marker;
|
||||
protected final String string;
|
||||
protected int cursor;
|
||||
protected int marker;
|
||||
|
||||
public DefaultStringReader(DefaultStringReader other) {
|
||||
this.string = other.string;
|
||||
@@ -112,10 +112,24 @@ public class DefaultStringReader implements StringReader {
|
||||
this.cursor += count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charAt(int index) {
|
||||
return this.string.charAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String substring(int start, int end) {
|
||||
return this.string.substring(start, end);
|
||||
}
|
||||
|
||||
public static boolean isAllowedNumber(char c) {
|
||||
return c >= '0' && c <= '9' || c == '.' || c == '-';
|
||||
}
|
||||
|
||||
public static boolean isNumber(char c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
public static boolean isQuotedStringStart(char c) {
|
||||
return c == SYNTAX_DOUBLE_QUOTE || c == SYNTAX_SINGLE_QUOTE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
public static final Map<Integer, Integer> PACK_FORMATS = new HashMap<>();
|
||||
static {
|
||||
PACK_FORMATS.put(1_20_00, 15);
|
||||
PACK_FORMATS.put(1_20_01, 15);
|
||||
PACK_FORMATS.put(1_20_02, 18);
|
||||
PACK_FORMATS.put(1_20_03, 22);
|
||||
PACK_FORMATS.put(1_20_04, 22);
|
||||
PACK_FORMATS.put(1_20_05, 32);
|
||||
PACK_FORMATS.put(1_20_06, 32);
|
||||
PACK_FORMATS.put(1_21_00, 34);
|
||||
PACK_FORMATS.put(1_21_01, 34);
|
||||
PACK_FORMATS.put(1_21_02, 42);
|
||||
PACK_FORMATS.put(1_21_03, 42);
|
||||
PACK_FORMATS.put(1_21_04, 46);
|
||||
PACK_FORMATS.put(1_21_05, 55);
|
||||
PACK_FORMATS.put(1_21_06, 63);
|
||||
PACK_FORMATS.put(1_99_99, 1000);
|
||||
}
|
||||
|
||||
private final int version;
|
||||
private final String versionString;
|
||||
private final int packFormat;
|
||||
|
||||
public static MinecraftVersion parse(final String version) {
|
||||
return new MinecraftVersion(version);
|
||||
}
|
||||
|
||||
public String version() {
|
||||
return versionString;
|
||||
}
|
||||
|
||||
public int packFormat() {
|
||||
return packFormat;
|
||||
}
|
||||
|
||||
public MinecraftVersion(String version) {
|
||||
this.version = VersionHelper.parseVersionToInteger(version);
|
||||
this.versionString = version;
|
||||
this.packFormat = PACK_FORMATS.get(this.version);
|
||||
}
|
||||
|
||||
public boolean isAtOrAbove(MinecraftVersion other) {
|
||||
return version >= other.version;
|
||||
}
|
||||
|
||||
public boolean isAtOrBelow(MinecraftVersion other) {
|
||||
return version <= other.version;
|
||||
}
|
||||
|
||||
public boolean isAt(MinecraftVersion other) {
|
||||
return version == other.version;
|
||||
}
|
||||
|
||||
public boolean isBelow(MinecraftVersion other) {
|
||||
return version < other.version;
|
||||
}
|
||||
|
||||
public boolean isAbove(MinecraftVersion other) {
|
||||
return version > other.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (!(object instanceof MinecraftVersion that)) return false;
|
||||
return version == that.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MinecraftVersion other) {
|
||||
return Integer.compare(this.version, other.version);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
public final class MinecraftVersions {
|
||||
private MinecraftVersions() {}
|
||||
|
||||
public static final MinecraftVersion V1_20 = new MinecraftVersion("1.20");
|
||||
public static final MinecraftVersion V1_20_1 = new MinecraftVersion("1.20.1");
|
||||
public static final MinecraftVersion V1_20_2 = new MinecraftVersion("1.20.2");
|
||||
public static final MinecraftVersion V1_20_3 = new MinecraftVersion("1.20.3");
|
||||
public static final MinecraftVersion V1_20_4 = new MinecraftVersion("1.20.4");
|
||||
public static final MinecraftVersion V1_20_5 = new MinecraftVersion("1.20.5");
|
||||
public static final MinecraftVersion V1_20_6 = new MinecraftVersion("1.20.6");
|
||||
public static final MinecraftVersion V1_21 = new MinecraftVersion("1.21");
|
||||
public static final MinecraftVersion V1_21_1 = new MinecraftVersion("1.21.1");
|
||||
public static final MinecraftVersion V1_21_2 = new MinecraftVersion("1.21.2");
|
||||
public static final MinecraftVersion V1_21_3 = new MinecraftVersion("1.21.3");
|
||||
public static final MinecraftVersion V1_21_4 = new MinecraftVersion("1.21.4");
|
||||
public static final MinecraftVersion V1_21_5 = new MinecraftVersion("1.21.5");
|
||||
public static final MinecraftVersion V1_21_6 = new MinecraftVersion("1.21.6");
|
||||
public static final MinecraftVersion FUTURE = new MinecraftVersion("1.99.99");
|
||||
}
|
||||
@@ -1,336 +0,0 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SNBTDeserializer {
|
||||
|
||||
private static final char COMPOUND_START = '{';
|
||||
private static final char COMPOUND_END = '}';
|
||||
private static final char LIST_START = '[';
|
||||
private static final char LIST_END = ']';
|
||||
private static final char STRING_DELIMITER = '"';
|
||||
private static final char KEY_VALUE_SEPARATOR = ':';
|
||||
private static final char ELEMENT_SEPARATOR = ',';
|
||||
private static final char ESCAPE_CHAR = '\\';
|
||||
|
||||
// 数字类型后缀
|
||||
private static final char BYTE_SUFFIX = 'b';
|
||||
private static final char SHORT_SUFFIX = 's';
|
||||
private static final char LONG_SUFFIX = 'l';
|
||||
private static final char FLOAT_SUFFIX = 'f';
|
||||
private static final char DOUBLE_SUFFIX = 'd';
|
||||
private static final char BOOLEAN_SUFFIX = 'B';
|
||||
|
||||
// 布尔值常量
|
||||
private static final String TRUE_LITERAL = "true";
|
||||
private static final String FALSE_LITERAL = "false";
|
||||
private static final int TRUE_LENGTH = 4;
|
||||
private static final int FALSE_LENGTH = 5;
|
||||
|
||||
// 使用 char[] 处理获得更高的性能
|
||||
private final char[] sourceContent;
|
||||
private final int length;
|
||||
private int position = 0;
|
||||
|
||||
private SNBTDeserializer(String content) {
|
||||
this.sourceContent = content.toCharArray();
|
||||
this.length = sourceContent.length;
|
||||
}
|
||||
|
||||
// 入口API
|
||||
public static Object parse(String input) throws IllegalArgumentException {
|
||||
SNBTDeserializer parser = new SNBTDeserializer(input);
|
||||
Object result = parser.parseValue();
|
||||
parser.skipWhitespace();
|
||||
|
||||
if (parser.position != parser.length) {
|
||||
throw new IllegalArgumentException("Extra content at end: " +
|
||||
new String(parser.sourceContent, parser.position,
|
||||
parser.length - parser.position));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 开始解析, 步进字符.
|
||||
private Object parseValue() {
|
||||
skipWhitespace();
|
||||
return switch (peekCurrentChar()) {
|
||||
case COMPOUND_START -> parseCompound();
|
||||
case LIST_START -> parseList();
|
||||
case STRING_DELIMITER -> parseString();
|
||||
default -> parsePrimitive();
|
||||
};
|
||||
}
|
||||
|
||||
// 解析包小肠 {}
|
||||
private Map<String, Object> parseCompound() {
|
||||
position++; // 跳过 '{'
|
||||
skipWhitespace();
|
||||
|
||||
Map<String, Object> compoundMap = new LinkedHashMap<>(16); // 避免一次扩容, 应该有一定的性能提升
|
||||
|
||||
if (position < length && sourceContent[position] != COMPOUND_END) {
|
||||
do {
|
||||
String key = parseKey();
|
||||
if (position >= length || sourceContent[position] != KEY_VALUE_SEPARATOR) {
|
||||
throw new IllegalArgumentException("Expected ':' at position " + position);
|
||||
}
|
||||
position++; // 跳过 ':'
|
||||
Object value = parseValue();
|
||||
compoundMap.put(key, value);
|
||||
skipWhitespace();
|
||||
} while (position < length && sourceContent[position] == ELEMENT_SEPARATOR && ++position > 0);
|
||||
}
|
||||
|
||||
if (position >= length || sourceContent[position] != COMPOUND_END) {
|
||||
throw new IllegalArgumentException("Expected '}' at position " + position);
|
||||
}
|
||||
position++; // 跳过 '}'
|
||||
return compoundMap;
|
||||
}
|
||||
|
||||
// 解析列表值 [1, 2, 3]
|
||||
private List<Object> parseList() {
|
||||
position++; // 跳过 '['
|
||||
skipWhitespace();
|
||||
List<Object> elementList = new ArrayList<>();
|
||||
|
||||
if (position < length && sourceContent[position] != LIST_END) {
|
||||
do {
|
||||
elementList.add(parseValue());
|
||||
skipWhitespace();
|
||||
} while (position < length && sourceContent[position] == ELEMENT_SEPARATOR && ++position > 0);
|
||||
}
|
||||
|
||||
if (position >= length || sourceContent[position] != LIST_END) {
|
||||
throw new IllegalArgumentException("Expected ']' at position " + position);
|
||||
}
|
||||
position++; // 跳过 ']'
|
||||
return elementList;
|
||||
}
|
||||
|
||||
// 解析字符串
|
||||
private String parseString() {
|
||||
position++; // 跳过开始的引号
|
||||
int start = position;
|
||||
|
||||
// 扫一次字符串, 如果没有发现转义就直接返回, 发现了就再走转义解析.
|
||||
// 这样可以避免创建一次 StringBuilder.
|
||||
while (position < length) {
|
||||
char c = sourceContent[position];
|
||||
if (c == STRING_DELIMITER) {
|
||||
String result = new String(sourceContent, start, position - start);
|
||||
position++; // 跳过结束引号
|
||||
return result; // 没有转义直接返回字符串.
|
||||
}
|
||||
// 如果发现转义字符,
|
||||
else if (c == ESCAPE_CHAR) {
|
||||
return parseStringWithEscape(start);
|
||||
}
|
||||
position++;
|
||||
}
|
||||
// 没有扫描到结束引号
|
||||
throw new IllegalArgumentException("Unterminated string at " + start);
|
||||
}
|
||||
|
||||
// 处理含转义的字符串
|
||||
private String parseStringWithEscape(int start) {
|
||||
StringBuilder sb = new StringBuilder(position - start + 16);
|
||||
sb.append(sourceContent, start, position - start);
|
||||
|
||||
while (position < length) {
|
||||
char c = sourceContent[position++];
|
||||
if (c == ESCAPE_CHAR && position < length) {
|
||||
sb.append(getEscapedChar(sourceContent[position++]));
|
||||
} else if (c == STRING_DELIMITER) { // 字符
|
||||
return sb.toString();
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
// 没有扫描到结束引号
|
||||
throw new IllegalArgumentException("Unterminated string at " + start);
|
||||
}
|
||||
|
||||
// 解析Key值
|
||||
private String parseKey() {
|
||||
skipWhitespace();
|
||||
// 如果有双引号就委托给string解析处理.
|
||||
if (position < length && sourceContent[position] == STRING_DELIMITER) {
|
||||
return parseString();
|
||||
}
|
||||
|
||||
int start = position;
|
||||
while (position < length) {
|
||||
char c = sourceContent[position];
|
||||
if (Character.isJavaIdentifierPart(c)) {
|
||||
position++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
skipWhitespace();
|
||||
return new String(sourceContent, start, position - start);
|
||||
}
|
||||
|
||||
// 解析原生值
|
||||
private Object parsePrimitive() {
|
||||
skipWhitespace();
|
||||
int tokenStart = position;
|
||||
|
||||
// 先解析获取值的长度
|
||||
while (position < length) {
|
||||
char c = sourceContent[position];
|
||||
if (c <= ' ' || c == ',' || c == ']' || c == '}') break;
|
||||
position++;
|
||||
}
|
||||
int tokenLength = position - tokenStart;
|
||||
if (tokenLength == 0) {
|
||||
throw new IllegalArgumentException("Empty value at position " + tokenStart);
|
||||
}
|
||||
|
||||
// 布尔值快速检查
|
||||
if (tokenLength == TRUE_LENGTH && matchesAt(tokenStart, TRUE_LITERAL)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
if (tokenLength == FALSE_LENGTH && matchesAt(tokenStart, FALSE_LITERAL)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
// 带后缀的值处理
|
||||
try {
|
||||
char lastChar = sourceContent[tokenStart + tokenLength - 1];
|
||||
if (tokenLength > 1 && isTypeSuffix(lastChar)) {
|
||||
return switch (lastChar) {
|
||||
case BYTE_SUFFIX -> parseByte(tokenStart, tokenLength - 1);
|
||||
case SHORT_SUFFIX -> parseShort(tokenStart, tokenLength - 1);
|
||||
case LONG_SUFFIX -> parseLong(tokenStart, tokenLength - 1);
|
||||
case FLOAT_SUFFIX -> Float.parseFloat(new String(sourceContent, tokenStart, tokenLength - 1));
|
||||
case DOUBLE_SUFFIX -> Double.parseDouble(new String(sourceContent, tokenStart, tokenLength - 1));
|
||||
case BOOLEAN_SUFFIX -> parseBoolean(new String(sourceContent, tokenStart, tokenLength - 1));
|
||||
default -> throw new IllegalArgumentException("Invalid suffixed value " + new String(sourceContent, tokenStart, tokenLength - 1));
|
||||
};
|
||||
}
|
||||
// 没有后缀就默认为 double 喵
|
||||
return Double.parseDouble(new String(sourceContent, tokenStart, tokenLength));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Invalid number value at position " + tokenStart, e);
|
||||
}
|
||||
}
|
||||
|
||||
// 工具函数: 快速检查布尔值字符串匹配, 忽略大小写.
|
||||
private boolean matchesAt(int start, String target) {
|
||||
for (int i = 0; i < target.length(); i++) {
|
||||
char c1 = sourceContent[start + i];
|
||||
char c2 = target.charAt(i);
|
||||
if (c1 != c2 && c1 != (c2 ^ 32)) return false; // 忽略大小写比较
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 工具函数: 合法后缀检查
|
||||
private boolean isTypeSuffix(char c) {
|
||||
return c == BYTE_SUFFIX || c == SHORT_SUFFIX || c == LONG_SUFFIX ||
|
||||
c == FLOAT_SUFFIX || c == DOUBLE_SUFFIX || c == BOOLEAN_SUFFIX;
|
||||
}
|
||||
|
||||
|
||||
// 手动解析值
|
||||
private byte parseByte(int start, int length) {
|
||||
int value = parseInteger(start, length);
|
||||
if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE)
|
||||
throw new IllegalArgumentException("Byte value out of range");
|
||||
return (byte) value;
|
||||
}
|
||||
|
||||
private short parseShort(int start, int length) {
|
||||
int value = parseInteger(start, length);
|
||||
if (value < Short.MIN_VALUE || value > Short.MAX_VALUE)
|
||||
throw new NumberFormatException("Short value out of range");
|
||||
return (short) value;
|
||||
}
|
||||
|
||||
private Boolean parseBoolean(String content) {
|
||||
if ("1".equals(content)) return Boolean.TRUE;
|
||||
if ("0".equals(content)) return Boolean.FALSE;
|
||||
throw new NumberFormatException("Invalid boolean value");
|
||||
}
|
||||
|
||||
private int parseInteger(int start, int length) {
|
||||
int result = 0;
|
||||
boolean negative = false;
|
||||
int i = 0;
|
||||
|
||||
if (sourceContent[start] == '-') {
|
||||
negative = true;
|
||||
i = 1;
|
||||
}
|
||||
|
||||
for (; i < length; i++) {
|
||||
char c = sourceContent[start + i];
|
||||
if (c < '0' || c > '9') throw new NumberFormatException("Invalid integer");
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
|
||||
return negative ? -result : result;
|
||||
}
|
||||
|
||||
private long parseLong(int start, int length) {
|
||||
long result = 0;
|
||||
boolean negative = false;
|
||||
int i = 0;
|
||||
|
||||
if (sourceContent[start] == '-') {
|
||||
negative = true;
|
||||
i = 1;
|
||||
}
|
||||
|
||||
for (; i < length; i++) {
|
||||
char c = sourceContent[start + i];
|
||||
if (c < '0' || c > '9') throw new NumberFormatException("Invalid long");
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
|
||||
return negative ? -result : result;
|
||||
}
|
||||
|
||||
// 转义字符处理
|
||||
private char getEscapedChar(char escapedChar) {
|
||||
return switch (escapedChar) {
|
||||
case STRING_DELIMITER -> '"';
|
||||
case ESCAPE_CHAR -> '\\';
|
||||
case COMPOUND_START -> '{';
|
||||
case COMPOUND_END -> '}';
|
||||
case LIST_START -> '[';
|
||||
case LIST_END -> ']';
|
||||
case KEY_VALUE_SEPARATOR -> ':';
|
||||
case ELEMENT_SEPARATOR -> ',';
|
||||
default -> escapedChar;
|
||||
};
|
||||
}
|
||||
|
||||
// 获取当前字符
|
||||
private char peekCurrentChar() {
|
||||
if (position >= length) throw new IllegalArgumentException("Unexpected end of input at position " + position);
|
||||
return sourceContent[position];
|
||||
}
|
||||
|
||||
|
||||
// 跳过空格
|
||||
private void skipWhitespace() {
|
||||
while (position < length) {
|
||||
char c = sourceContent[position];
|
||||
if (c > ' ') { break; } // 大于空格的字符都不是空白字符
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
|
||||
position++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class SNBTReader extends DefaultStringReader {
|
||||
private static final char COMPOUND_START = '{';
|
||||
private static final char COMPOUND_END = '}';
|
||||
private static final char LIST_START = '[';
|
||||
private static final char LIST_END = ']';
|
||||
private static final char STRING_DELIMITER = '"';
|
||||
private static final char SINGLE_QUOTES = '\'';
|
||||
private static final char DOUBLE_QUOTES = '"';
|
||||
private static final char KEY_VALUE_SEPARATOR = ':';
|
||||
private static final char ELEMENT_SEPARATOR = ',';
|
||||
|
||||
// 数字类型后缀
|
||||
private static final char BYTE_SUFFIX = 'b';
|
||||
private static final char SHORT_SUFFIX = 's';
|
||||
private static final char LONG_SUFFIX = 'l';
|
||||
private static final char FLOAT_SUFFIX = 'f';
|
||||
private static final char DOUBLE_SUFFIX = 'd';
|
||||
|
||||
public SNBTReader(String content) {
|
||||
super(content);
|
||||
}
|
||||
|
||||
public Object deserializeAsJava() {
|
||||
Object result = this.parseValue();
|
||||
this.skipWhitespace();
|
||||
if (getCursor() != getTotalLength())
|
||||
throw new IllegalArgumentException("Extra content at end: " + substring(getCursor(), getTotalLength()));
|
||||
return result;
|
||||
}
|
||||
|
||||
// 开始解析, 步进字符.
|
||||
private Object parseValue() {
|
||||
skipWhitespace();
|
||||
return switch (peek()) {
|
||||
case COMPOUND_START -> parseCompound();
|
||||
case LIST_START -> parseList();
|
||||
case DOUBLE_QUOTES -> {
|
||||
skip();
|
||||
yield readStringUntil(DOUBLE_QUOTES);
|
||||
}
|
||||
case SINGLE_QUOTES -> {
|
||||
skip();
|
||||
yield readStringUntil(SINGLE_QUOTES);
|
||||
}
|
||||
default -> parsePrimitive();
|
||||
};
|
||||
}
|
||||
|
||||
// 解析包小肠 {}
|
||||
private Map<String, Object> parseCompound() {
|
||||
skip(); // 跳过 '{'
|
||||
skipWhitespace();
|
||||
|
||||
Map<String, Object> compoundMap = new LinkedHashMap<>();
|
||||
|
||||
if (canRead() && peek() != COMPOUND_END) {
|
||||
do {
|
||||
String key = parseKey();
|
||||
if (!canRead() || peek() != KEY_VALUE_SEPARATOR) {
|
||||
throw new IllegalArgumentException("Expected ':' at position " + getCursor());
|
||||
}
|
||||
skip(); // 跳过 ':'
|
||||
Object value = parseValue();
|
||||
compoundMap.put(key, value);
|
||||
skipWhitespace();
|
||||
} while (canRead() && peek() == ELEMENT_SEPARATOR && ++super.cursor > 0 /* 跳过 ',' */);
|
||||
}
|
||||
|
||||
if (!canRead() || peek() != COMPOUND_END) {
|
||||
throw new IllegalArgumentException("Expected '}' at position " + getCursor());
|
||||
}
|
||||
skip(); // 跳过 '}'
|
||||
return compoundMap;
|
||||
}
|
||||
|
||||
// 解析列表值 [1, 2, 3]
|
||||
private List<Object> parseList() {
|
||||
skip(); // 跳过 '['
|
||||
skipWhitespace();
|
||||
List<Object> elementList = new ArrayList<>();
|
||||
|
||||
if (canRead() && peek() != LIST_END) {
|
||||
do {
|
||||
elementList.add(parseValue());
|
||||
skipWhitespace();
|
||||
} while (canRead() && peek() == ELEMENT_SEPARATOR && ++super.cursor > 0 /* 跳过 ',' */);
|
||||
}
|
||||
|
||||
if (!canRead() || peek() != LIST_END) {
|
||||
throw new IllegalArgumentException("Expected ']' at position " + getCursor());
|
||||
}
|
||||
skip(); // 跳过 ']'
|
||||
return elementList;
|
||||
}
|
||||
|
||||
// 解析Key值
|
||||
private String parseKey() {
|
||||
skipWhitespace();
|
||||
if (!canRead()) {
|
||||
throw new IllegalArgumentException("Unterminated key at " + getCursor());
|
||||
}
|
||||
|
||||
// 如果有双引号就委托给string解析处理.
|
||||
char peek = peek();
|
||||
if (peek == STRING_DELIMITER) {
|
||||
skip();
|
||||
return readStringUntil(STRING_DELIMITER);
|
||||
} else if (peek == SINGLE_QUOTES) {
|
||||
skip();
|
||||
return readStringUntil(SINGLE_QUOTES);
|
||||
}
|
||||
|
||||
int start = getCursor();
|
||||
while (canRead()) {
|
||||
char c = peek();
|
||||
if (c == ' ') break; // 忽略 key 后面的空格, { a :1} 应当解析成 {a:1}
|
||||
if (Character.isJavaIdentifierPart(c)) skip(); else break;
|
||||
}
|
||||
|
||||
String key = substring(start, getCursor());
|
||||
skipWhitespace(); // 跳过 key 后面的空格.
|
||||
return key;
|
||||
}
|
||||
|
||||
// 解析原生值
|
||||
private Object parsePrimitive() {
|
||||
// 先解析获取值的长度
|
||||
int tokenStart = getCursor();
|
||||
int lastWhitespace = 0; // 记录值末尾的空格数量,{a:炒鸡 大保健} 和 {a: 炒鸡 大保健 } 都应解析成 "炒鸡 大保健".
|
||||
boolean contentHasWhitespace = false; // 记录值中有没有空格.
|
||||
while (canRead()) {
|
||||
char c = peek();
|
||||
if (c == ',' || c == ']' || c == '}') break;
|
||||
skip();
|
||||
if (c == ' ') {
|
||||
lastWhitespace++; // 遇到空格先增加值, 代表值尾部空格数量.
|
||||
continue;
|
||||
}
|
||||
if (lastWhitespace > 0) {
|
||||
lastWhitespace = 0; // 遇到正常字符时清空记录的尾部空格数.
|
||||
contentHasWhitespace = true;
|
||||
}
|
||||
}
|
||||
int tokenLength = getCursor() - tokenStart - lastWhitespace; // 计算值长度需要再减去尾部空格.
|
||||
if (tokenLength == 0) throw new IllegalArgumentException("Empty value at position " + tokenStart);
|
||||
if (contentHasWhitespace) return substring(tokenStart, tokenStart + tokenLength); // 如果值的中间有空格, 一定是字符串, 可直接返回.
|
||||
|
||||
// 布尔值检查
|
||||
if (tokenLength == 4) {
|
||||
if (matchesAt(tokenStart, "true")) return Boolean.TRUE;
|
||||
} else if (tokenLength == 5) {
|
||||
if (matchesAt(tokenStart, "false")) return Boolean.FALSE;
|
||||
}
|
||||
if (tokenLength > 1) {
|
||||
// 至少有1个字符,给了后缀的可能性
|
||||
char lastChar = charAt(tokenStart + tokenLength - 1);
|
||||
try {
|
||||
switch (lastChar) {
|
||||
case BYTE_SUFFIX -> {
|
||||
return Byte.parseByte(substring(tokenStart, tokenStart + tokenLength - 1));
|
||||
}
|
||||
case SHORT_SUFFIX -> {
|
||||
return Short.parseShort(substring(tokenStart, tokenStart + tokenLength - 1));
|
||||
}
|
||||
case LONG_SUFFIX -> {
|
||||
return Long.parseLong(substring(tokenStart, tokenStart + tokenLength - 1));
|
||||
}
|
||||
case FLOAT_SUFFIX -> {
|
||||
return Float.parseFloat(substring(tokenStart, tokenStart + tokenLength));
|
||||
}
|
||||
case DOUBLE_SUFFIX -> {
|
||||
return Double.parseDouble(substring(tokenStart, tokenStart + tokenLength));
|
||||
}
|
||||
default -> {
|
||||
String fullString = substring(tokenStart, tokenStart + tokenLength);
|
||||
try {
|
||||
double d = Double.parseDouble(fullString);
|
||||
if (d % 1 != 0 || fullString.contains(".") || fullString.contains("e")) {
|
||||
return d;
|
||||
} else {
|
||||
return (int) d;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return fullString;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return substring(tokenStart, tokenStart + tokenLength);
|
||||
}
|
||||
} else {
|
||||
char onlyChar = charAt(tokenStart);
|
||||
if (isNumber(onlyChar)) {
|
||||
return onlyChar - '0';
|
||||
} else {
|
||||
return String.valueOf(onlyChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 工具函数: 快速检查布尔值字符串匹配, 忽略大小写.
|
||||
private boolean matchesAt(int start, String target) {
|
||||
for (int i = 0; i < target.length(); i++) {
|
||||
char c1 = charAt(start + i);
|
||||
char c2 = target.charAt(i);
|
||||
if (c1 != c2 && c1 != (c2 ^ 32)) return false; // 忽略大小写比较
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.util;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
public class SkullUtils {
|
||||
public final class SkullUtils {
|
||||
|
||||
private SkullUtils() {}
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ public interface StringReader {
|
||||
|
||||
void skip(int count);
|
||||
|
||||
char charAt(int index);
|
||||
|
||||
String substring(int start, int end);
|
||||
|
||||
void skipWhitespace();
|
||||
|
||||
void skipWhitespaceAndComment();
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class VersionHelper {
|
||||
public static final MinecraftVersion MINECRAFT_VERSION;
|
||||
private static final int version;
|
||||
private static final int majorVersion;
|
||||
private static final int minorVersion;
|
||||
@@ -36,6 +37,9 @@ public class VersionHelper {
|
||||
}
|
||||
JsonObject json = GsonHelper.parseJsonToJsonObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
|
||||
String versionString = json.getAsJsonPrimitive("id").getAsString();
|
||||
|
||||
MINECRAFT_VERSION = new MinecraftVersion(versionString);
|
||||
|
||||
String[] split = versionString.split("\\.");
|
||||
int major = Integer.parseInt(split[1]);
|
||||
int minor = split.length == 3 ? Integer.parseInt(split[2].split("-", 2)[0]) : 0;
|
||||
|
||||
Reference in New Issue
Block a user