mirror of
https://github.com/GeyserMC/Rainbow.git
synced 2025-12-19 14:59:16 +00:00
Proper attachable scripts (I think)
This commit is contained in:
@@ -1,8 +1,12 @@
|
|||||||
package org.geysermc.packgenerator.pack.attachable;
|
package org.geysermc.packgenerator.pack.attachable;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
import com.mojang.serialization.DynamicOps;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.ExtraCodecs;
|
||||||
import net.minecraft.util.StringRepresentable;
|
import net.minecraft.util.StringRepresentable;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
import org.geysermc.packgenerator.CodecUtil;
|
import org.geysermc.packgenerator.CodecUtil;
|
||||||
@@ -10,6 +14,7 @@ import org.geysermc.packgenerator.PackConstants;
|
|||||||
import org.geysermc.packgenerator.mapping.geyser.GeyserSingleDefinition;
|
import org.geysermc.packgenerator.mapping.geyser.GeyserSingleDefinition;
|
||||||
import org.geysermc.packgenerator.pack.BedrockTextures;
|
import org.geysermc.packgenerator.pack.BedrockTextures;
|
||||||
import org.geysermc.packgenerator.pack.BedrockVersion;
|
import org.geysermc.packgenerator.pack.BedrockVersion;
|
||||||
|
import org.geysermc.packgenerator.pack.geometry.BedrockGeometry;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -19,6 +24,8 @@ import java.util.EnumMap;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo info) {
|
public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo info) {
|
||||||
public static final Codec<BedrockAttachable> CODEC = RecordCodecBuilder.create(instance ->
|
public static final Codec<BedrockAttachable> CODEC = RecordCodecBuilder.create(instance ->
|
||||||
@@ -46,8 +53,8 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
|
|||||||
default -> "";
|
default -> "";
|
||||||
};
|
};
|
||||||
return builder(identifier)
|
return builder(identifier)
|
||||||
.withMaterial(DisplaySlot.DEFAULT, "armor")
|
.withMaterial(DisplaySlot.DEFAULT, VanillaMaterials.ARMOR)
|
||||||
.withMaterial(DisplaySlot.ENCHANTED, "armor_enchanted")
|
.withMaterial(DisplaySlot.ENCHANTED, VanillaMaterials.ARMOR_ENCHANTED)
|
||||||
.withTexture(DisplaySlot.DEFAULT, texture)
|
.withTexture(DisplaySlot.DEFAULT, texture)
|
||||||
.withTexture(DisplaySlot.ENCHANTED, VanillaTextures.ENCHANTED_ACTOR_GLINT)
|
.withTexture(DisplaySlot.ENCHANTED, VanillaTextures.ENCHANTED_ACTOR_GLINT)
|
||||||
.withGeometry(DisplaySlot.DEFAULT, VanillaGeometries.fromEquipmentSlot(slot))
|
.withGeometry(DisplaySlot.DEFAULT, VanillaGeometries.fromEquipmentSlot(slot))
|
||||||
@@ -56,13 +63,25 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BedrockAttachable geometry(ResourceLocation identifier, BedrockGeometry.GeometryDefinition geometry, String texture) {
|
||||||
|
// TODO animations to make it look right
|
||||||
|
return builder(identifier)
|
||||||
|
.withMaterial(DisplaySlot.DEFAULT, VanillaMaterials.ENTITY)
|
||||||
|
.withMaterial(DisplaySlot.ENCHANTED, VanillaMaterials.ENTITY_ALPHATEST_GLINT)
|
||||||
|
.withTexture(DisplaySlot.DEFAULT, texture)
|
||||||
|
.withTexture(DisplaySlot.ENCHANTED, VanillaTextures.ENCHANTED_ITEM_GLINT)
|
||||||
|
.withGeometry(DisplaySlot.DEFAULT, geometry.info().identifier())
|
||||||
|
.withRenderController(VanillaRenderControllers.ITEM_DEFAULT)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final ResourceLocation identifier;
|
private final ResourceLocation identifier;
|
||||||
private final EnumMap<DisplaySlot, String> materials = new EnumMap<>(DisplaySlot.class);
|
private final EnumMap<DisplaySlot, String> materials = new EnumMap<>(DisplaySlot.class);
|
||||||
private final EnumMap<DisplaySlot, String> textures = new EnumMap<>(DisplaySlot.class);
|
private final EnumMap<DisplaySlot, String> textures = new EnumMap<>(DisplaySlot.class);
|
||||||
private final EnumMap<DisplaySlot, String> geometries = new EnumMap<>(DisplaySlot.class);
|
private final EnumMap<DisplaySlot, String> geometries = new EnumMap<>(DisplaySlot.class);
|
||||||
private final Map<String, String> animations = new HashMap<>();
|
private final Map<String, String> animations = new HashMap<>();
|
||||||
private final Map<String, String> scripts = new HashMap<>();
|
private final Map<String, List<Script>> scripts = new HashMap<>();
|
||||||
private final List<String> renderControllers = new ArrayList<>();
|
private final List<String> renderControllers = new ArrayList<>();
|
||||||
|
|
||||||
public Builder(ResourceLocation identifier) {
|
public Builder(ResourceLocation identifier) {
|
||||||
@@ -89,11 +108,19 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder withScript(String key, String script) {
|
public Builder withScript(String key, Script script) {
|
||||||
scripts.put(key, script);
|
scripts.merge(key, List.of(script), (scripts, newScript) -> Stream.concat(scripts.stream(), newScript.stream()).toList());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder withScript(String key, String script, String condition) {
|
||||||
|
return withScript(key, new Script(script, Optional.of(condition)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withScript(String key, String script) {
|
||||||
|
return withScript(key, new Script(script, Optional.empty()));
|
||||||
|
}
|
||||||
|
|
||||||
public Builder withRenderController(String controller) {
|
public Builder withRenderController(String controller) {
|
||||||
renderControllers.add(controller);
|
renderControllers.add(controller);
|
||||||
return this;
|
return this;
|
||||||
@@ -101,7 +128,8 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
|
|||||||
|
|
||||||
public BedrockAttachable build() {
|
public BedrockAttachable build() {
|
||||||
return new BedrockAttachable(PackConstants.ENGINE_VERSION,
|
return new BedrockAttachable(PackConstants.ENGINE_VERSION,
|
||||||
new AttachableInfo(identifier, verifyDefault(materials), verifyDefault(textures), verifyDefault(geometries), Map.copyOf(animations), Map.copyOf(scripts), List.copyOf(renderControllers)));
|
new AttachableInfo(identifier, verifyDefault(materials), verifyDefault(textures), verifyDefault(geometries), Map.copyOf(animations),
|
||||||
|
new Scripts(Map.copyOf(scripts)), List.copyOf(renderControllers)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DisplayMap verifyDefault(EnumMap<DisplaySlot, String> map) {
|
private static DisplayMap verifyDefault(EnumMap<DisplaySlot, String> map) {
|
||||||
@@ -113,7 +141,7 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
|
|||||||
}
|
}
|
||||||
|
|
||||||
public record AttachableInfo(ResourceLocation identifier, DisplayMap materials, DisplayMap textures,
|
public record AttachableInfo(ResourceLocation identifier, DisplayMap materials, DisplayMap textures,
|
||||||
DisplayMap geometry, Map<String, String> animations, Map<String, String> scripts,
|
DisplayMap geometry, Map<String, String> animations, Scripts scripts,
|
||||||
List<String> renderControllers) {
|
List<String> renderControllers) {
|
||||||
private static final Codec<Map<String, String>> STRING_MAP_CODEC = Codec.unboundedMap(Codec.STRING, Codec.STRING);
|
private static final Codec<Map<String, String>> STRING_MAP_CODEC = Codec.unboundedMap(Codec.STRING, Codec.STRING);
|
||||||
public static final Codec<AttachableInfo> CODEC = RecordCodecBuilder.create(instance ->
|
public static final Codec<AttachableInfo> CODEC = RecordCodecBuilder.create(instance ->
|
||||||
@@ -123,7 +151,7 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
|
|||||||
DisplayMap.CODEC.fieldOf("textures").forGetter(AttachableInfo::textures),
|
DisplayMap.CODEC.fieldOf("textures").forGetter(AttachableInfo::textures),
|
||||||
DisplayMap.CODEC.fieldOf("geometry").forGetter(AttachableInfo::geometry),
|
DisplayMap.CODEC.fieldOf("geometry").forGetter(AttachableInfo::geometry),
|
||||||
STRING_MAP_CODEC.optionalFieldOf("animations", Map.of()).forGetter(AttachableInfo::animations),
|
STRING_MAP_CODEC.optionalFieldOf("animations", Map.of()).forGetter(AttachableInfo::animations),
|
||||||
STRING_MAP_CODEC.optionalFieldOf("scripts", Map.of()).forGetter(AttachableInfo::scripts),
|
Scripts.CODEC.optionalFieldOf("scripts", Scripts.EMPTY).forGetter(AttachableInfo::scripts),
|
||||||
Codec.STRING.listOf().optionalFieldOf("render_controllers", List.of()).forGetter(AttachableInfo::renderControllers)
|
Codec.STRING.listOf().optionalFieldOf("render_controllers", List.of()).forGetter(AttachableInfo::renderControllers)
|
||||||
).apply(instance, AttachableInfo::new)
|
).apply(instance, AttachableInfo::new)
|
||||||
);
|
);
|
||||||
@@ -151,4 +179,40 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record Scripts(Map<String, List<Script>> scripts) {
|
||||||
|
public static final Codec<Scripts> CODEC = Codec.unboundedMap(Codec.STRING, ExtraCodecs.compactListCodec(Script.CODEC)).xmap(Scripts::new, Scripts::scripts);
|
||||||
|
public static final Scripts EMPTY = new Scripts(Map.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Script(String script, Optional<String> condition) {
|
||||||
|
private static final Codec<Script> SCRIPT_WITH_CONDITION_CODEC = Codec.unboundedMap(Codec.STRING, Codec.STRING).flatXmap(
|
||||||
|
scriptMap -> {
|
||||||
|
if (scriptMap.size() != 1) {
|
||||||
|
return DataResult.error(() -> "Script with condition must have exactly one key-value pair");
|
||||||
|
}
|
||||||
|
String script = scriptMap.keySet().iterator().next();
|
||||||
|
return DataResult.success(new Script(script, Optional.of(scriptMap.get(script))));
|
||||||
|
},
|
||||||
|
script -> script.condition.map(condition -> DataResult.success(Map.of(script.script, condition)))
|
||||||
|
.orElse(DataResult.error(() -> "Script must have a condition"))
|
||||||
|
);
|
||||||
|
public static final Codec<Script> CODEC = SCRIPT_WITH_CONDITION_CODEC.mapResult(new Codec.ResultFunction<Script>() {
|
||||||
|
@Override
|
||||||
|
public <T> DataResult<Pair<Script, T>> apply(DynamicOps<T> ops, T input, DataResult<Pair<Script, T>> decoded) {
|
||||||
|
if (decoded.isError()) {
|
||||||
|
return Codec.STRING.map(script -> new Script(script, Optional.empty())).decode(ops, input);
|
||||||
|
}
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> DataResult<T> coApply(DynamicOps<T> ops, Script input, DataResult<T> encoded) {
|
||||||
|
if (encoded.isError()) {
|
||||||
|
return Codec.STRING.encodeStart(ops, input.script);
|
||||||
|
}
|
||||||
|
return encoded;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,6 @@ package org.geysermc.packgenerator.pack.attachable;
|
|||||||
public class VanillaMaterials {
|
public class VanillaMaterials {
|
||||||
public static final String ARMOR = "armor";
|
public static final String ARMOR = "armor";
|
||||||
public static final String ARMOR_ENCHANTED = "armor_enchanted";
|
public static final String ARMOR_ENCHANTED = "armor_enchanted";
|
||||||
|
public static final String ENTITY = "entity";
|
||||||
|
public static final String ENTITY_ALPHATEST_GLINT = "entity_alphatest_glint";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ package org.geysermc.packgenerator.pack.attachable;
|
|||||||
|
|
||||||
public class VanillaRenderControllers {
|
public class VanillaRenderControllers {
|
||||||
public static final String ARMOR = "controller.render.armor";
|
public static final String ARMOR = "controller.render.armor";
|
||||||
|
public static final String ITEM_DEFAULT = "controller.render.item_default";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ package org.geysermc.packgenerator.pack.attachable;
|
|||||||
|
|
||||||
public class VanillaTextures {
|
public class VanillaTextures {
|
||||||
public static final String ENCHANTED_ACTOR_GLINT = "misc/enchanted_actor_glint";
|
public static final String ENCHANTED_ACTOR_GLINT = "misc/enchanted_actor_glint";
|
||||||
|
public static final String ENCHANTED_ITEM_GLINT = "misc/enchanted_item_glint";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user