diff options
Diffstat (limited to 'defaults/src/main/java/shcm/shsupercm')
3 files changed, 141 insertions, 6 deletions
diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeArmor.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeArmor.java index 9f0beed..d97bf67 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeArmor.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeArmor.java @@ -1,22 +1,27 @@ package shcm.shsupercm.fabric.citresewn.defaults.cit.types; import io.shcm.shsupercm.fabric.fletchingtable.api.Entrypoint; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.Item; import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; import shcm.shsupercm.fabric.citresewn.api.CITTypeContainer; -import shcm.shsupercm.fabric.citresewn.cit.CIT; -import shcm.shsupercm.fabric.citresewn.cit.CITCondition; -import shcm.shsupercm.fabric.citresewn.cit.CITType; +import shcm.shsupercm.fabric.citresewn.cit.*; +import shcm.shsupercm.fabric.citresewn.defaults.cit.conditions.ConditionItems; import shcm.shsupercm.fabric.citresewn.ex.CITParsingException; import shcm.shsupercm.fabric.citresewn.pack.format.PropertyGroup; import shcm.shsupercm.fabric.citresewn.pack.format.PropertyKey; +import shcm.shsupercm.fabric.citresewn.pack.format.PropertyValue; -import java.util.List; -import java.util.Set; +import java.util.*; public class TypeArmor extends CITType { @Entrypoint(CITTypeContainer.ENTRYPOINT) public static final Container CONTAINER = new Container(); + public final Map<String, Identifier> textures = new HashMap<>(); + @Override public Set<PropertyKey> typeProperties() { return Set.of(PropertyKey.of("texture")); @@ -24,7 +29,37 @@ public class TypeArmor extends CITType { @Override public void load(List<CITCondition> conditions, PropertyGroup properties, ResourceManager resourceManager) throws CITParsingException { + boolean itemsConditionPresent = false; + for (CITCondition condition : conditions) + if (condition instanceof ConditionItems conditionItems) + for (Item item : conditionItems.items) + if (item instanceof ArmorItem) + itemsConditionPresent = true; + else + throw new CITParsingException("This type only accepts armor items for the items condition", properties, -1); + + if (!itemsConditionPresent) + try { + Identifier propertiesName = new Identifier(properties.stripName()); + if (!Registry.ITEM.containsId(propertiesName)) + throw new Exception(); + Item item = Registry.ITEM.get(propertiesName); + if (!(item instanceof ArmorItem)) + throw new Exception(); + conditions.add(new ConditionItems(item)); + } catch (Exception ignored) { + throw new CITParsingException("Not targeting any item type", properties, -1); + } + for (PropertyValue propertyValue : properties.get("citresewn", "texture")) { + Identifier identifier = resolveAsset(properties.identifier, propertyValue, "textures", ".png", resourceManager); + if (identifier == null) + throw new CITParsingException("Could not resolve texture", properties, propertyValue.position()); + + textures.put(propertyValue.keyMetadata(), identifier); + } + if (textures.size() == 0) + throw new CITParsingException("Texture not specified", properties, -1); } public static class Container extends CITTypeContainer<TypeArmor> { @@ -32,14 +67,45 @@ public class TypeArmor extends CITType { super(TypeArmor.class, TypeArmor::new, "armor"); } + public Set<CIT<TypeArmor>> loaded = new HashSet<>(); + public Map<ArmorItem, Set<CIT<TypeArmor>>> loadedTyped = new IdentityHashMap<>(); + @Override public void load(List<CIT<TypeArmor>> parsedCITs) { - + loaded.addAll(parsedCITs); + for (CIT<TypeArmor> cit : parsedCITs) + for (CITCondition condition : cit.conditions) + if (condition instanceof ConditionItems items) + for (Item item : items.items) + if (item instanceof ArmorItem armorItem) + loadedTyped.computeIfAbsent(armorItem, i -> new LinkedHashSet<>()).add(cit); } @Override public void dispose() { + loaded.clear(); + loadedTyped.clear(); + } + public CIT<TypeArmor> getCIT(CITContext context) { + return ((CITCacheArmor) (Object) context.stack).citresewn$getCacheTypeArmor().get(context).get(); } + + public CIT<TypeArmor> getRealTimeCIT(CITContext context) { + if (!(context.stack.getItem() instanceof ArmorItem)) + return null; + + Set<CIT<TypeArmor>> loadedForItemType = loadedTyped.get(context.stack.getItem()); + if (loadedForItemType != null) + for (CIT<TypeArmor> cit : loadedForItemType) + if (cit.test(context)) + return cit; + + return null; + } + } + + public interface CITCacheArmor { + CITCache.Single<TypeArmor> citresewn$getCacheTypeArmor(); } } diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ArmorFeatureRendererMixin.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ArmorFeatureRendererMixin.java new file mode 100644 index 0000000..fba7159 --- /dev/null +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ArmorFeatureRendererMixin.java @@ -0,0 +1,53 @@ +package shcm.shsupercm.fabric.citresewn.defaults.mixin.types.armor; + +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import shcm.shsupercm.fabric.citresewn.cit.ActiveCITs; +import shcm.shsupercm.fabric.citresewn.cit.CIT; +import shcm.shsupercm.fabric.citresewn.cit.CITContext; +import shcm.shsupercm.fabric.citresewn.config.CITResewnConfig; +import shcm.shsupercm.fabric.citresewn.defaults.cit.types.TypeArmor; + +import java.util.Map; + +import static shcm.shsupercm.fabric.citresewn.defaults.cit.types.TypeArmor.CONTAINER; + +@Mixin(ArmorFeatureRenderer.class) +public class ArmorFeatureRendererMixin<T extends LivingEntity, M extends BipedEntityModel<T>, A extends BipedEntityModel<T>> { + private Map<String, Identifier> citresewn$cachedTextures = null; + + @Inject(method = "renderArmor", at = @At("HEAD")) + public void citresewn$renderArmor(MatrixStack matrices, VertexConsumerProvider vertexConsumers, T entity, EquipmentSlot armorSlot, int light, A model, CallbackInfo ci) { + citresewn$cachedTextures = null; + if (!CITResewnConfig.INSTANCE.enabled || !ActiveCITs.isActive()) + return; + + ItemStack equippedStack = entity.getEquippedStack(armorSlot); + + CIT<TypeArmor> cit = CONTAINER.getCIT(new CITContext(equippedStack, entity.getWorld(), entity)); + if (cit != null) + citresewn$cachedTextures = cit.type.textures; + } + + @Inject(method = "getArmorTexture", cancellable = true, at = @At("HEAD")) + private void citresewn$getArmorTexture(ArmorItem item, boolean legs, String overlay, CallbackInfoReturnable<Identifier> cir) { + if (citresewn$cachedTextures == null) + return; + + Identifier identifier = citresewn$cachedTextures.get(item.getMaterial().getName() + "_layer_" + (legs ? "2" : "1") + (overlay == null ? "" : "_" + overlay)); + if (identifier != null) + cir.setReturnValue(identifier); + } +} diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ItemStackMixin.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ItemStackMixin.java new file mode 100644 index 0000000..85b0d22 --- /dev/null +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/armor/ItemStackMixin.java @@ -0,0 +1,16 @@ +package shcm.shsupercm.fabric.citresewn.defaults.mixin.types.armor; + +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import shcm.shsupercm.fabric.citresewn.cit.CITCache; +import shcm.shsupercm.fabric.citresewn.defaults.cit.types.TypeArmor; + +@Mixin(ItemStack.class) +public class ItemStackMixin implements TypeArmor.CITCacheArmor { + private final CITCache.Single<TypeArmor> citresewn$cacheTypeArmor = new CITCache.Single<>(TypeArmor.CONTAINER::getRealTimeCIT); + + @Override + public CITCache.Single<TypeArmor> citresewn$getCacheTypeArmor() { + return this.citresewn$cacheTypeArmor; + } +} |