diff --git a/README.md b/README.md index d807ac0..b7232db 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Create/Mekanism Modular A [Truly Modular](https://modrinth.com/mod/modular-item-api) addon for Minecraft -1.21.1 / NeoForge. It adds 126 materials drawn from 22 mods - Create, Mekanism, Ice +1.21.1 / NeoForge. It adds 127 materials drawn from 22 mods - Create, Mekanism, Ice and Fire, Immersive Engineering, Ender IO, Applied Energistics, Occultism, Ars Nouveau, Iron's Spells, Pastel, Crystal Chronicles, NauTec, Superb Warfare, Industrial Foregoing, RFTools, Create Deco, Steampunk Dimension and the Create @@ -58,6 +58,10 @@ watches for it. Neither side knows about the other. **Breathing in a vacuum.** The same trick, for the space set - see below. +**Breathing underwater.** And again, for sea serpent fang: `WaterBreathing.java` +answers the same `LivingBreatheEvent`, but only when the bearer's eyes are in +water, so a fang is a fang rather than half a spacesuit. + ## Modules Three of the packs hold modules rather than materials. They are hand-written @@ -213,6 +217,23 @@ folders, so the hand-written packs survive it. emissive, so it still reads as fire in game. - Dragon scales are one material per colour (12 dragon, 7 sea serpent, 3 death worm chitin). Colours within an element share stats and differ only in palette. +- Bones are the other half of that. Dragon bone already built grips, handles + and hafts - `bone` is on every tool and bow whitelist - and now carries + `gem_armor` as a hidden group as well, so a piece can be set into an armour + socket instead of only shaped into the armour. Sea serpent fang is new and + does both: Ice and Fire has no sea serpent bone, and the fang is what a + serpent leaves behind besides its scales. It grants water breathing, which is + what Ice and Fire's own Tide Guardian armour does, from slot `any` - so one + fang socketed, worn or held is enough, and a second neither adds nor dilutes. +- Scales are in the `scute` group, and no module in Truly Modular accepts that + group - not Armory's armour, not Arsenal's or Archery's parts, and MIAPI's own + turtle and armadillo scutes are stuck the same way. So each scale material + carries `bone` as a hidden group: matched when a module decides what it will + accept, ignored when the workbench decides what heading to file the material + under, which is how Armory hands its own gem slots vanilla materials. Bone is + on every armour whitelist except the scuba set - that one takes + fabric/metal/glass, being a sealed suit rather than a plated one - so a scale + builds every other piece of armour, and tool and bow parts besides. - Interstellar Expansion is mostly machinery. Only three of its items are a material rather than a component; solid E-710 is left out because it is rocket fuel. diff --git a/gradle.properties b/gradle.properties index 12c446b..e8081b0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ neo_version=21.1.248 mod_id=cmmodular mod_name=Create/Mekanism Modular -mod_version=1.2.0 +mod_version=1.3.0 mod_group_id=eu.abdelbaki.cmmodular mod_authors=themiro mod_description=Materials from Create, Mekanism, Ice and Fire, Iron's Spells and the Create aerospace addons, for Truly Modular - plus a khopesh blade and a sealed space suit. diff --git a/src/main/java/eu/abdelbaki/cmmodular/CMModular.java b/src/main/java/eu/abdelbaki/cmmodular/CMModular.java index 4691cbe..ea29e0d 100644 --- a/src/main/java/eu/abdelbaki/cmmodular/CMModular.java +++ b/src/main/java/eu/abdelbaki/cmmodular/CMModular.java @@ -73,6 +73,7 @@ public class CMModular { public CMModular(IEventBus modBus) { FireImmunity.register(modBus); VacuumSeal.register(modBus); + WaterBreathing.register(modBus); modBus.addListener(this::addMaterialPacks); } diff --git a/src/main/java/eu/abdelbaki/cmmodular/WaterBreathing.java b/src/main/java/eu/abdelbaki/cmmodular/WaterBreathing.java new file mode 100644 index 0000000..c1b59ae --- /dev/null +++ b/src/main/java/eu/abdelbaki/cmmodular/WaterBreathing.java @@ -0,0 +1,62 @@ +package eu.abdelbaki.cmmodular; + +import net.minecraft.core.registries.Registries; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; +import net.minecraft.world.entity.ai.attributes.RangedAttribute; +import net.neoforged.bus.api.EventPriority; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.entity.EntityAttributeModificationEvent; +import net.neoforged.neoforge.event.entity.living.LivingBreatheEvent; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; + +/** + * Sea serpent fang lets its bearer breathe underwater, which is what Ice and + * Fire's own Tide Guardian armour does and the only reason to hunt the thing. + * + *

There is no attribute for it and MIAPI has no property for it either - the + * closest data can get is a fake Respiration enchantment, which only postpones + * drowning. So this follows the pattern {@link FireImmunity} and + * {@link VacuumSeal} already set: an attribute of this mod's own that the + * material grants like any other, and a listener here that watches for it. + * + *

It answers the same event {@link VacuumSeal} does but only underwater, so + * a fang is a fang and not half a spacesuit. + */ +public final class WaterBreathing { + private static final DeferredRegister ATTRIBUTES = + DeferredRegister.create(Registries.ATTRIBUTE, CMModular.MOD_ID); + + /** At or above 1 the bearer never drowns; the fang grants a whole one. */ + public static final DeferredHolder WATER_BREATHING = + ATTRIBUTES.register("water_breathing", id -> new RangedAttribute( + "attribute.cmmodular.water_breathing", 0.0D, 0.0D, 1.0D).setSyncable(true)); + + private WaterBreathing() { + } + + static void register(IEventBus modBus) { + ATTRIBUTES.register(modBus); + modBus.addListener(WaterBreathing::attachToEntities); + // Last, so it answers after whatever said there was no air. + NeoForge.EVENT_BUS.addListener(EventPriority.LOWEST, WaterBreathing::onBreathe); + } + + /** Attributes only exist on an entity if they were added to its type. */ + private static void attachToEntities(EntityAttributeModificationEvent event) { + event.getTypes().forEach(type -> event.add(type, WATER_BREATHING)); + } + + private static void onBreathe(LivingBreatheEvent event) { + if (event.canBreathe() || !event.getEntity().isEyeInFluid(FluidTags.WATER)) { + return; + } + AttributeInstance instance = event.getEntity().getAttribute(WATER_BREATHING); + if (instance != null && instance.getValue() >= 1.0D) { + event.setCanBreathe(true); + } + } +} diff --git a/src/main/resources/assets/cmmodular/lang/en_us.json b/src/main/resources/assets/cmmodular/lang/en_us.json index 6f136e7..3e1a17d 100644 --- a/src/main/resources/assets/cmmodular/lang/en_us.json +++ b/src/main/resources/assets/cmmodular/lang/en_us.json @@ -1,6 +1,7 @@ { "attribute.cmmodular.fire_immunity": "Fire Immunity", "attribute.cmmodular.vacuum_seal": "Vacuum Seal", + "attribute.cmmodular.water_breathing": "Water Breathing", "miapi.module.cmmodular.blade.khopesh.name": "Khopesh Blade", "miapi.module.cmmodular.pommel.gem_socket.name": "Socketed Pommel", diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/bone/dragonbone.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/bone/dragonbone.json index a2aeae3..042da0f 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/bone/dragonbone.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/bone/dragonbone.json @@ -3,6 +3,9 @@ "groups": [ "bone" ], + "hidden_groups": [ + "gem_armor" + ], "icon": { "type": "item", "item": "iceandfire:dragonbone" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/bone/sea_serpent_fang.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/bone/sea_serpent_fang.json new file mode 100644 index 0000000..0359563 --- /dev/null +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/bone/sea_serpent_fang.json @@ -0,0 +1,64 @@ +{ + "translation": "Sea Serpent Fang ", + "groups": [ + "bone" + ], + "hidden_groups": [ + "gem_armor" + ], + "icon": { + "type": "item", + "item": "iceandfire:sea_serpent_fang" + }, + "hardness": 6.0, + "density": 3.0, + "flexibility": 4, + "durability": 760, + "enchantability": 16, + "toughness": 2, + "tier": 4, + "mining_speed": 7, + "mining_level": "minecraft:incorrect_for_diamond_tool", + "armor_durability": 26, + "color": "C8C8C9", + "color_palette": { + "type": "grayscale_map", + "colors": { + "24": "12131d", + "68": "222538", + "107": "525f68", + "150": "525f68", + "190": "8c8c8c", + "216": "c8c8c9", + "255": "e2fffa" + }, + "filler": "interpolate" + }, + "textures": [ + "rough", + "shiny" + ], + "properties": { + "default": { + "attributes": [ + { + "attribute": "cmmodular:water_breathing", + "value": "1", + "operation": "+", + "slot": "any" + } + ] + }, + "boot": { + "fake_enchants": { + "minecraft:depth_strider": 1 + } + } + }, + "items": [ + { + "item": "iceandfire:sea_serpent_fang", + "value": 1.0 + } + ] +} diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_red.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_red.json index 7c32a8a..13226d9 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_red.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_red.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:deathworm_chitin_red" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_white.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_white.json index c0e8ab1..4f894b6 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_white.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_white.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:deathworm_chitin_white" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_yellow.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_yellow.json index 377ca09..0221325 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_yellow.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/deathworm_chitin_yellow.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:deathworm_chitin_yellow" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_amethyst.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_amethyst.json index a833291..6b3da22 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_amethyst.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_amethyst.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_amethyst" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_black.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_black.json index c845e0a..7552590 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_black.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_black.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_black" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_blue.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_blue.json index 5aed92d..cf00d4f 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_blue.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_blue.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_blue" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_bronze.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_bronze.json index c853bea..86946b9 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_bronze.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_bronze.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_bronze" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_copper.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_copper.json index 1217a89..2b6feb0 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_copper.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_copper.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_copper" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_electric.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_electric.json index 1573902..931d4d4 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_electric.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_electric.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_electric" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_gray.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_gray.json index e9e970e..524792c 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_gray.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_gray.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_gray" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_green.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_green.json index bd88933..9ae7fc5 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_green.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_green.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_green" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_red.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_red.json index b2d1f3a..d31315a 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_red.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_red.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_red" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_sapphire.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_sapphire.json index ac64583..c8d8069 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_sapphire.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_sapphire.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_sapphire" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_silver.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_silver.json index 67e9305..a6929a4 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_silver.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_silver.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_silver" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_white.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_white.json index 4259544..7a6b25a 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_white.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/dragonscales_white.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:dragonscales_white" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_blue.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_blue.json index 504476b..e42b91d 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_blue.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_blue.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:sea_serpent_scales_blue" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_bronze.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_bronze.json index 2d8a3c6..bdba393 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_bronze.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_bronze.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:sea_serpent_scales_bronze" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_deepblue.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_deepblue.json index 0540c00..25f81c1 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_deepblue.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_deepblue.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:sea_serpent_scales_deepblue" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_green.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_green.json index 46d2a5c..c7b02ca 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_green.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_green.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:sea_serpent_scales_green" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_purple.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_purple.json index 6a7e5c0..c219c4b 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_purple.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_purple.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:sea_serpent_scales_purple" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_red.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_red.json index 3284898..423f998 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_red.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_red.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:sea_serpent_scales_red" diff --git a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_teal.json b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_teal.json index 47f250c..124927b 100644 --- a/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_teal.json +++ b/src/main/resources/packs/iceandfire/data/cmmodular/miapi/materials/scute/sea_serpent_scales_teal.json @@ -3,6 +3,9 @@ "groups": [ "scute" ], + "hidden_groups": [ + "bone" + ], "icon": { "type": "item", "item": "iceandfire:sea_serpent_scales_teal" diff --git a/tools/generate_materials.py b/tools/generate_materials.py index 211badc..390b39c 100644 --- a/tools/generate_materials.py +++ b/tools/generate_materials.py @@ -183,6 +183,10 @@ def build_material(spec, jars: Jars): out = { "translation": spec["translation"] + " ", # trailing space: "Steel Sword" "groups": spec["groups"], + # Counts for what a module will accept, but is not a heading the + # workbench files the material under. See SCALE_CRAFTING_GROUP. + **({"hidden_groups": spec["hidden_groups"]} + if spec.get("hidden_groups") else {}), "icon": {"type": "item", "item": spec["icon"]}, } out.update(spec["stats"]) diff --git a/tools/materials.py b/tools/materials.py index 5c40a64..dd0a414 100644 --- a/tools/materials.py +++ b/tools/materials.py @@ -80,9 +80,10 @@ PACKS = { "armory": {"mod": "tm_armory", "name": "Armory Modules"}, } -# Attribute this mod registers itself, so a material can grant something the -# game has no attribute for. See FireImmunity.java. +# Attributes this mod registers itself, so a material can grant something the +# game has no attribute for. See FireImmunity.java and WaterBreathing.java. FIRE_IMMUNITY = "cmmodular:fire_immunity" +WATER_BREATHING = "cmmodular:water_breathing" def attribute(attr, value, slot, operation="+"): @@ -91,7 +92,7 @@ def attribute(attr, value, slot, operation="+"): def M(name, pack, group, translation, palette_from, items, tier, hardness, density, flexibility, durability, enchantability, mining_speed, *, groups=None, - toughness=0, armor_durability=None, armor_toughness=None, + hidden_groups=None, toughness=0, armor_durability=None, armor_toughness=None, knockback_resistance=None, textures=("metallic",), properties=None, icon=None, mining_level=None): """One material. `palette_from` is the item whose texture seeds the palette.""" @@ -104,6 +105,7 @@ def M(name, pack, group, translation, palette_from, items, tier, hardness, densi "icon": icon or palette_from, "items": items, "groups": list(groups) if groups else [group], + "hidden_groups": list(hidden_groups) if hidden_groups else [], "textures": list(textures), "properties": properties or {}, "stats": { @@ -418,10 +420,36 @@ MATERIALS = [ {"item": "iceandfire:dragon_bone_block", "value": 4.0}], tier=4, hardness=6.2, density=4.4, flexibility=3, durability=700, enchantability=12, mining_speed=7, toughness=2, armor_durability=24, - groups=("bone",), textures=("rough",), + groups=("bone",), hidden_groups=("gem_armor",), textures=("rough",), properties={"head": {"fracturing": "10"}}), # Vanilla bone with the numbers pushed to diamond tier; keeps the - # fracturing quirk MIAPI gives bone. + # fracturing quirk MIAPI gives bone. The `bone` group already builds + # grips, handles and hafts wherever Arsenal and Archery take bone; + # `gem_armor` on top of it lets a piece sit in an armour socket too, so a + # dragon's bones can be set into a suit rather than only shaped into one. + + M("sea_serpent_fang", "iceandfire", "bone", "Sea Serpent Fang", + "iceandfire:sea_serpent_fang", + [{"item": "iceandfire:sea_serpent_fang", "value": 1.0}], + tier=4, hardness=6.0, density=3.0, flexibility=4, durability=760, + enchantability=16, mining_speed=7, toughness=2, armor_durability=26, + groups=("bone",), hidden_groups=("gem_armor",), textures=("rough", "shiny"), + properties={ + "default": { + "attributes": [ + # Ice and Fire's own sea serpent armour grants water + # breathing, and that is the whole reason to hunt one. Slot + # `any`, capped at 1 and read as "at or above 1" by the + # handler, so one fang anywhere - socketed, worn or held - is + # enough and a second neither adds nor dilutes, exactly as + # cinder essence does for fire. + attribute(WATER_BREATHING, 1, "any"), + ], + }, + "boot": {"fake_enchants": {"minecraft:depth_strider": 1}}, + }), + # Lighter and springier than dragon bone and quicker to enchant, but + # softer: a serpent's tooth, not a wyrm's femur. M("witherbone", "iceandfire", "bone", "Witherbone", "iceandfire:witherbone", [{"item": "iceandfire:witherbone", "value": 1.0}, @@ -1042,6 +1070,25 @@ DRAGON_SCALE_PROPERTIES = { SEA_SERPENT_COLORS = ["blue", "bronze", "deepblue", "green", "purple", "red", "teal"] DEATHWORM_COLORS = {"red": "Red", "white": "White", "yellow": "Tan"} +# No module anywhere accepts the "scute" group. Armory's armour whitelists +# wood/fabric/metal/flint/bone/stone/crystal/glass, Arsenal's and Archery's +# parts much the same, and none of the four lists "scute" - so a scale material +# was a material you could look at and never build with, the same trap the +# gem groups below were in. MIAPI's own turtle and armadillo scutes are stuck +# there too, so this is not something the scales were doing wrong. +# +# Bone is the group they join: it is on every armour whitelist except the scuba +# set (fabric/metal/glass - a sealed suit, not a plated one), it is what a hard +# organic plate is nearest to, and it carries them into tool and bow parts as +# well, which suits stats that were always meant to be usable and unremarkable +# in hand rather than unusable. +# +# It goes in `hidden_groups` rather than `groups`: MIAPI matches a module's +# whitelist against both, but only `groups` decides where the material is filed +# in the workbench, so a dragonscale still lists as a scale rather than as a +# bone. Armory itself does this to hand its gem slots vanilla materials. +SCALE_CRAFTING_GROUP = ("bone",) + def _scales(): out = [] @@ -1057,7 +1104,8 @@ def _scales(): enchantability=15, mining_speed=7, toughness=4, armor_durability=44, armor_toughness=3.5, mining_level=MINING_LEVEL[4], - groups=("scute",), textures=("rough", "shiny"), + groups=("scute",), hidden_groups=SCALE_CRAFTING_GROUP, + textures=("rough", "shiny"), properties=DRAGON_SCALE_PROPERTIES[element])) # Armour-first, like Tinkers' ancient hide: high toughness and # armour durability, unremarkable as a cutting edge. @@ -1071,7 +1119,8 @@ def _scales(): tier=4, hardness=5.4, density=2.4, flexibility=5, durability=950, enchantability=16, mining_speed=6, toughness=3, armor_durability=32, armor_toughness=2.5, - groups=("scute",), textures=("rough", "shiny"), + groups=("scute",), hidden_groups=SCALE_CRAFTING_GROUP, + textures=("rough", "shiny"), properties={"armor": {"fake_enchants": {"minecraft:respiration": 1}}, "boot": {"fake_enchants": {"minecraft:depth_strider": 1}}})) for color, label in DEATHWORM_COLORS.items(): @@ -1082,7 +1131,8 @@ def _scales(): tier=4, hardness=5.6, density=2.2, flexibility=4, durability=880, enchantability=13, mining_speed=6, toughness=3, armor_durability=30, armor_toughness=2.0, - groups=("scute",), textures=("rough",), + groups=("scute",), hidden_groups=SCALE_CRAFTING_GROUP, + textures=("rough",), properties={"default": {"fire_proof": True}})) # Desert worms, so heat immunity comes with the shell. return out