Add Immersive Engineering materials, fix gem sockets, pick one provider per metal
Gem sockets never accepted the two Iron's Spells essences: Arsenal gates its melee gem modules on the `gem_melee` material group and Armory gates its armour ones on `gem_armor`, neither of which is the `gem` group they carried. Every gem-like material now carries both, so it fits any gem slot. Immersive Engineering adds aluminium, nickel, constantan, electrum and graphite. Its steel, lead, uranium and silver overlap mods already covered, so rather than one material accepting either mod's ingot, each metal simply names one provider - Mekanism for steel/lead/uranium, Ice and Fire for silver. That keeps one entry per metal in the crafting screen. Titanium moves to the same rule with Cosmonautics as its provider, which drops the c: tag files and the any-of pack machinery along with it. That also removes a latent crash: a tag-fed material still needed an item for its icon, and MIAPI parses icon items through the registry and throws when one is missing. The generator now clears its output directory first, so a material that moves between packs cannot leave a stale copy claiming the same id. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>modules-and-missing-materials
parent
c55caa1d1e
commit
e3accaf83f
26
README.md
26
README.md
|
|
@ -1,10 +1,10 @@
|
|||
# Create/Mekanism Modular
|
||||
|
||||
A [Truly Modular](https://modrinth.com/mod/modular-item-api) addon for Minecraft
|
||||
1.21.1 / NeoForge. It adds 72 materials drawn from Create, Mekanism, Ice and
|
||||
Fire, Iron's Spells 'n Spellbooks, Create: The Air War, Create: Cosmonautics and
|
||||
Aeronautics: Interstellar Expansion, so those mods' metals, gems, scales and
|
||||
essences can be used to build modular tools and armour.
|
||||
1.21.1 / NeoForge. It adds 77 materials drawn from Create, Mekanism, Ice and
|
||||
Fire, Immersive Engineering, Iron's Spells 'n Spellbooks, Create: The Air War,
|
||||
Create: Cosmonautics and Aeronautics: Interstellar Expansion, so those mods'
|
||||
metals, gems, scales and essences can be used to build modular tools and armour.
|
||||
|
||||
Every source mod is optional. Install any subset - the materials for mods you do
|
||||
not have are never registered.
|
||||
|
|
@ -22,11 +22,13 @@ and a material whose ingredient item is missing fails to parse. So each source
|
|||
mod's materials are a separate built-in datapack, registered in
|
||||
`CMModular.java` only when that mod is present.
|
||||
|
||||
Titanium is the exception: Air War and Cosmonautics both add a titanium ingot,
|
||||
so one material covers both and draws its ingredients from `c:ingots/titanium`
|
||||
rather than an item id. Cosmonautics already declares that tag; the tag files in
|
||||
`data/c/` fill it in for Air War, which ships no common tags, using optional
|
||||
entries so a missing mod is not an error.
|
||||
**Overlapping metals.** Several metals come from more than one mod - steel,
|
||||
lead and uranium from Mekanism and Immersive Engineering, silver from Ice and
|
||||
Fire and Immersive Engineering, titanium from both aerospace addons. Each one
|
||||
picks a single provider rather than accepting either, so the crafting screen
|
||||
shows one entry per metal instead of two identical-looking ones. Providers are
|
||||
Mekanism for steel/lead/uranium, Ice and Fire for silver, Cosmonautics for
|
||||
titanium; swapping one is a one-line change in `tools/materials.py`.
|
||||
|
||||
**Fire immunity.** Cinder essence grants immunity to fire, which is not an
|
||||
attribute the game has and not a property MIAPI offers. Instead of coupling to
|
||||
|
|
@ -115,3 +117,9 @@ Requires `pillow` and `numpy`.
|
|||
- 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.
|
||||
- Gem sockets do not check the `gem` group. Arsenal gates melee gems on
|
||||
`gem_melee` and Armory gates armour gems on `gem_armor`, so every gem-like
|
||||
material carries both and fits any gem slot.
|
||||
- Immersive Engineering contributes aluminium, nickel, constantan, electrum and
|
||||
graphite. Its steel, lead, uranium and silver are not separate materials - see
|
||||
overlapping metals above.
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import net.neoforged.fml.common.Mod;
|
|||
import net.neoforged.neoforge.event.AddPackFindersEvent;
|
||||
|
||||
/**
|
||||
* Adds the materials of Create, Mekanism, Ice and Fire, Iron's Spells and the
|
||||
* Create aerospace addons to Truly Modular.
|
||||
* Adds the materials of Create, Mekanism, Ice and Fire, Immersive Engineering,
|
||||
* Iron's Spells and the Create aerospace addons to Truly Modular.
|
||||
*
|
||||
* <p>Almost all of this mod is data. The one thing data cannot do is load
|
||||
* conditionally: MIAPI reads materials with its own loader, which honours
|
||||
|
|
@ -22,28 +22,21 @@ import net.neoforged.neoforge.event.AddPackFindersEvent;
|
|||
* file off, and a material whose ingredient item does not exist fails to parse
|
||||
* outright. So each source mod's materials live in their own built-in datapack
|
||||
* and only get registered when that mod is actually installed.
|
||||
*
|
||||
* <p>Where two mods add the same metal - steel, lead and uranium are in both
|
||||
* Mekanism and Immersive Engineering, silver in both Ice and Fire and Immersive
|
||||
* Engineering, titanium in both aerospace addons - one of them is simply picked
|
||||
* as the provider rather than the material accepting either. That keeps one
|
||||
* entry per metal in the crafting screen.
|
||||
*/
|
||||
@Mod(CMModular.MOD_ID)
|
||||
public class CMModular {
|
||||
public static final String MOD_ID = "cmmodular";
|
||||
|
||||
/**
|
||||
* A set of materials, and the mods it needs in order to load.
|
||||
*
|
||||
* @param anyOf when true one of {@code requires} is enough, rather than all
|
||||
* of them. Such a pack cannot name items directly - it has no
|
||||
* way to know which mod turned up - so it sources ingredients
|
||||
* from item tags instead.
|
||||
*/
|
||||
private record MaterialPack(String id, String name, List<String> requires, boolean anyOf) {
|
||||
MaterialPack(String id, String name, String... requires) {
|
||||
this(id, name, List.of(requires), false);
|
||||
}
|
||||
|
||||
/** A set of materials, and the mod it needs in order to load. */
|
||||
private record MaterialPack(String id, String name, String requires) {
|
||||
boolean present() {
|
||||
return anyOf
|
||||
? requires.stream().anyMatch(ModList.get()::isLoaded)
|
||||
: requires.stream().allMatch(ModList.get()::isLoaded);
|
||||
return ModList.get().isLoaded(requires);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,14 +44,12 @@ public class CMModular {
|
|||
new MaterialPack("mekanism", "Mekanism Materials", "mekanism"),
|
||||
new MaterialPack("create", "Create Materials", "create"),
|
||||
new MaterialPack("iceandfire", "Ice and Fire Materials", "iceandfire"),
|
||||
new MaterialPack("immersiveengineering", "Immersive Engineering Materials",
|
||||
"immersiveengineering"),
|
||||
new MaterialPack("irons_spellbooks", "Iron's Spells Materials", "irons_spellbooks"),
|
||||
new MaterialPack("interstellar", "Interstellar Expansion Materials", "vsie"),
|
||||
new MaterialPack("air_war", "Create: The Air War Materials", "create_the_air_wars"),
|
||||
new MaterialPack("cosmonautics", "Create: Cosmonautics Materials", "rocketnautics"),
|
||||
// Both aerospace addons add a titanium ingot. One material covers
|
||||
// them both, fed by the c:ingots/titanium tag.
|
||||
new MaterialPack("aerospace", "Aerospace Materials",
|
||||
List.of("create_the_air_wars", "rocketnautics"), true));
|
||||
new MaterialPack("cosmonautics", "Create: Cosmonautics Materials", "rocketnautics"));
|
||||
|
||||
public CMModular(IEventBus modBus) {
|
||||
FireImmunity.register(modBus);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,13 @@ versionRange = "[0,)"
|
|||
ordering = "AFTER"
|
||||
side = "BOTH"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId = "immersiveengineering"
|
||||
type = "optional"
|
||||
versionRange = "[0,)"
|
||||
ordering = "AFTER"
|
||||
side = "BOTH"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId = "vsie"
|
||||
type = "optional"
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
{
|
||||
"id": "create_the_air_wars:titaniumingot",
|
||||
"required": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
{
|
||||
"id": "create_the_air_wars:titaniumnugget",
|
||||
"required": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
{
|
||||
"id": "create_the_air_wars:titaniumsheet",
|
||||
"required": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"pack": {
|
||||
"description": "Aerospace Materials for Truly Modular",
|
||||
"pack_format": 48
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"translation": "Sulfur ",
|
||||
"groups": [
|
||||
"crystal"
|
||||
"crystal",
|
||||
"gem_melee",
|
||||
"gem_armor"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
|
|
|
|||
|
|
@ -52,16 +52,20 @@
|
|||
},
|
||||
"items": [
|
||||
{
|
||||
"tag": "c:ingots/titanium",
|
||||
"item": "rocketnautics:titanium_ingot",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"tag": "c:nuggets/titanium",
|
||||
"item": "rocketnautics:titanium_nugget",
|
||||
"value": 0.11112
|
||||
},
|
||||
{
|
||||
"tag": "c:plates/titanium",
|
||||
"item": "rocketnautics:titanium_sheet",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"item": "rocketnautics:titanium_block",
|
||||
"value": 9.0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
"translation": "Dread ",
|
||||
"groups": [
|
||||
"crystal",
|
||||
"metal"
|
||||
"metal",
|
||||
"gem_melee",
|
||||
"gem_armor"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"translation": "Pixie Dust ",
|
||||
"groups": [
|
||||
"crystal"
|
||||
"crystal",
|
||||
"gem_melee",
|
||||
"gem_armor"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
"translation": "Sapphire ",
|
||||
"groups": [
|
||||
"crystal",
|
||||
"gem"
|
||||
"gem",
|
||||
"gem_melee",
|
||||
"gem_armor"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"translation": "Aluminium ",
|
||||
"groups": [
|
||||
"metal"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
"item": "immersiveengineering:ingot_aluminum"
|
||||
},
|
||||
"hardness": 4.0,
|
||||
"density": 1.2,
|
||||
"flexibility": 3,
|
||||
"durability": 260,
|
||||
"enchantability": 17,
|
||||
"toughness": 0,
|
||||
"tier": 3,
|
||||
"mining_speed": 6,
|
||||
"mining_level": "minecraft:incorrect_for_iron_tool",
|
||||
"armor_durability": 14,
|
||||
"color": "B9C0C3",
|
||||
"color_palette": {
|
||||
"type": "grayscale_map",
|
||||
"colors": {
|
||||
"24": "3c3d3e",
|
||||
"68": "737677",
|
||||
"107": "7a7e7f",
|
||||
"150": "818587",
|
||||
"190": "93989a",
|
||||
"216": "b9c0c3",
|
||||
"255": "c5cdd0"
|
||||
},
|
||||
"filler": "interpolate"
|
||||
},
|
||||
"textures": [
|
||||
"metallic",
|
||||
"bright"
|
||||
],
|
||||
"properties": {
|
||||
"handheld": {
|
||||
"attributes": [
|
||||
{
|
||||
"attribute": "generic.attack_speed",
|
||||
"value": "0.1",
|
||||
"operation": "+",
|
||||
"slot": "mainhand"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"item": "immersiveengineering:ingot_aluminum",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:nugget_aluminum",
|
||||
"value": 0.11112
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:plate_aluminum",
|
||||
"value": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"translation": "Constantan ",
|
||||
"groups": [
|
||||
"metal"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
"item": "immersiveengineering:ingot_constantan"
|
||||
},
|
||||
"hardness": 5.6,
|
||||
"density": 4.0,
|
||||
"flexibility": 2,
|
||||
"durability": 640,
|
||||
"enchantability": 14,
|
||||
"toughness": 2,
|
||||
"tier": 4,
|
||||
"mining_speed": 7,
|
||||
"mining_level": "minecraft:incorrect_for_diamond_tool",
|
||||
"armor_durability": 24,
|
||||
"color": "FE8E70",
|
||||
"color_palette": {
|
||||
"type": "grayscale_map",
|
||||
"colors": {
|
||||
"24": "321c16",
|
||||
"68": "60352a",
|
||||
"107": "733e32",
|
||||
"150": "7f4537",
|
||||
"190": "aa5c4a",
|
||||
"216": "fe8e70",
|
||||
"255": "ff9f7e"
|
||||
},
|
||||
"filler": "interpolate"
|
||||
},
|
||||
"textures": [
|
||||
"metallic"
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
"item": "immersiveengineering:ingot_constantan",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:nugget_constantan",
|
||||
"value": 0.11112
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:plate_constantan",
|
||||
"value": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"translation": "Electrum ",
|
||||
"groups": [
|
||||
"metal"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
"item": "immersiveengineering:ingot_electrum"
|
||||
},
|
||||
"hardness": 4.4,
|
||||
"density": 3.6,
|
||||
"flexibility": 2,
|
||||
"durability": 260,
|
||||
"enchantability": 26,
|
||||
"toughness": 0,
|
||||
"tier": 3,
|
||||
"mining_speed": 9,
|
||||
"mining_level": "minecraft:incorrect_for_iron_tool",
|
||||
"armor_durability": 14,
|
||||
"color": "FFBC4C",
|
||||
"color_palette": {
|
||||
"type": "grayscale_map",
|
||||
"colors": {
|
||||
"24": "362a17",
|
||||
"68": "67512c",
|
||||
"107": "785c30",
|
||||
"150": "7d5f31",
|
||||
"190": "b0833b",
|
||||
"216": "ffbc4c",
|
||||
"255": "ffd051"
|
||||
},
|
||||
"filler": "interpolate"
|
||||
},
|
||||
"textures": [
|
||||
"metallic",
|
||||
"bright"
|
||||
],
|
||||
"properties": {
|
||||
"tool": {
|
||||
"luminious_learning": "0.5"
|
||||
}
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"item": "immersiveengineering:ingot_electrum",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:nugget_electrum",
|
||||
"value": 0.11112
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:plate_electrum",
|
||||
"value": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"translation": "Graphite ",
|
||||
"groups": [
|
||||
"metal"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
"item": "immersiveengineering:ingot_hop_graphite"
|
||||
},
|
||||
"hardness": 4.2,
|
||||
"density": 2.0,
|
||||
"flexibility": 1,
|
||||
"durability": 520,
|
||||
"enchantability": 12,
|
||||
"toughness": 2,
|
||||
"tier": 4,
|
||||
"mining_speed": 10,
|
||||
"mining_level": "minecraft:incorrect_for_diamond_tool",
|
||||
"armor_durability": 18,
|
||||
"color": "373737",
|
||||
"color_palette": {
|
||||
"type": "grayscale_map",
|
||||
"colors": {
|
||||
"24": "080808",
|
||||
"68": "101010",
|
||||
"107": "121212",
|
||||
"150": "171717",
|
||||
"190": "212121",
|
||||
"216": "373737",
|
||||
"255": "3f3f3f"
|
||||
},
|
||||
"filler": "interpolate"
|
||||
},
|
||||
"textures": [
|
||||
"rough",
|
||||
"metallic"
|
||||
],
|
||||
"properties": {
|
||||
"default": {
|
||||
"fire_proof": true
|
||||
},
|
||||
"handheld": {
|
||||
"attributes": [
|
||||
{
|
||||
"attribute": "generic.attack_speed",
|
||||
"value": "0.08",
|
||||
"operation": "+",
|
||||
"slot": "mainhand"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"item": "immersiveengineering:ingot_hop_graphite",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:plate_hop_graphite",
|
||||
"value": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"translation": "Nickel ",
|
||||
"groups": [
|
||||
"metal"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
"item": "immersiveengineering:ingot_nickel"
|
||||
},
|
||||
"hardness": 5.4,
|
||||
"density": 4.4,
|
||||
"flexibility": 1,
|
||||
"durability": 480,
|
||||
"enchantability": 10,
|
||||
"toughness": 1,
|
||||
"tier": 3,
|
||||
"mining_speed": 6,
|
||||
"mining_level": "minecraft:incorrect_for_iron_tool",
|
||||
"armor_durability": 20,
|
||||
"armor_toughness": 0.5,
|
||||
"color": "C8CEBD",
|
||||
"color_palette": {
|
||||
"type": "grayscale_map",
|
||||
"colors": {
|
||||
"24": "2b2c28",
|
||||
"68": "52544d",
|
||||
"107": "60635a",
|
||||
"150": "686c62",
|
||||
"190": "878c80",
|
||||
"216": "c8cebd",
|
||||
"255": "dfe5d2"
|
||||
},
|
||||
"filler": "interpolate"
|
||||
},
|
||||
"textures": [
|
||||
"metallic"
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
"item": "immersiveengineering:ingot_nickel",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:nugget_nickel",
|
||||
"value": 0.11112
|
||||
},
|
||||
{
|
||||
"item": "immersiveengineering:plate_nickel",
|
||||
"value": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"pack": {
|
||||
"description": "Immersive Engineering Materials for Truly Modular",
|
||||
"pack_format": 48
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"translation": "Silicon Carbide ",
|
||||
"groups": [
|
||||
"crystal"
|
||||
"crystal",
|
||||
"gem_melee",
|
||||
"gem_armor"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
"translation": "Arcane ",
|
||||
"groups": [
|
||||
"crystal",
|
||||
"gem"
|
||||
"gem",
|
||||
"gem_melee",
|
||||
"gem_armor"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
"translation": "Cinder ",
|
||||
"groups": [
|
||||
"crystal",
|
||||
"gem"
|
||||
"gem",
|
||||
"gem_melee",
|
||||
"gem_armor"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
"translation": "Fluorite ",
|
||||
"groups": [
|
||||
"crystal",
|
||||
"gem"
|
||||
"gem",
|
||||
"gem_melee",
|
||||
"gem_armor"
|
||||
],
|
||||
"icon": {
|
||||
"type": "item",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ rather than shipping a material that silently refuses to load.
|
|||
import argparse
|
||||
import json
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
|
|
@ -185,18 +186,13 @@ def build_material(spec, jars: Jars):
|
|||
return out
|
||||
|
||||
|
||||
def check_items(spec, jars: Jars, any_of_pack: bool):
|
||||
"""Item ids must exist; tags are allowed to be missing at build time."""
|
||||
def check_items(spec, jars: Jars):
|
||||
"""Every item a material names has to exist in the jar that provides it."""
|
||||
problems = []
|
||||
for entry in spec["items"]:
|
||||
if "item" not in entry:
|
||||
continue
|
||||
if any_of_pack:
|
||||
problems.append(
|
||||
f"{spec['name']}: pack '{spec['pack']}' loads when any one of its "
|
||||
f"mods is present, so it must use tags, not the item id {entry['item']}"
|
||||
)
|
||||
elif not jars.has_item(entry["item"]):
|
||||
if not jars.has_item(entry["item"]):
|
||||
problems.append(f"{spec['name']}: no such item {entry['item']}")
|
||||
if not jars.has_item(spec["icon"]):
|
||||
problems.append(f"{spec['name']}: icon item {spec['icon']} does not exist")
|
||||
|
|
@ -218,14 +214,19 @@ def main():
|
|||
|
||||
problems = []
|
||||
for spec in MATERIALS:
|
||||
pack = PACKS[spec["pack"]]
|
||||
problems += check_items(spec, jars, pack.get("any_of", False))
|
||||
problems += check_items(spec, jars)
|
||||
if problems:
|
||||
print("aborting, item ids do not check out:", file=sys.stderr)
|
||||
for p in problems:
|
||||
print(" " + p, file=sys.stderr)
|
||||
return 1
|
||||
|
||||
# Wipe first. A material that moves between packs would otherwise leave a
|
||||
# stale copy behind, and two files claiming the same material id is a silent
|
||||
# mess to debug.
|
||||
if args.out.exists():
|
||||
shutil.rmtree(args.out)
|
||||
|
||||
written = 0
|
||||
for pack_id, pack in PACKS.items():
|
||||
root = args.out / pack_id
|
||||
|
|
|
|||
|
|
@ -39,22 +39,19 @@ NUGGET = 0.11112 # 1/9, matching MIAPI's own nugget values
|
|||
BLOCK = 9.0
|
||||
|
||||
# Sub-packs. Each becomes a NeoForge built-in datapack that is only registered
|
||||
# when its `mods` are present, so a material never references a missing item.
|
||||
# `any_of` packs load when at least one listed mod is installed; those materials
|
||||
# therefore have to source their ingredients from tags, not item ids.
|
||||
# when its mod is present, so a material never references a missing item.
|
||||
# Where two mods add the same metal, one is picked as the provider and the
|
||||
# material lives in that mod's pack - see the Immersive Engineering section.
|
||||
PACKS = {
|
||||
"mekanism": {"mods": ["mekanism"], "name": "Mekanism Materials"},
|
||||
"create": {"mods": ["create"], "name": "Create Materials"},
|
||||
"iceandfire": {"mods": ["iceandfire"], "name": "Ice and Fire Materials"},
|
||||
"air_war": {"mods": ["create_the_air_wars"], "name": "Create: The Air War Materials"},
|
||||
"cosmonautics": {"mods": ["rocketnautics"], "name": "Create: Cosmonautics Materials"},
|
||||
"irons_spellbooks": {"mods": ["irons_spellbooks"], "name": "Iron's Spells Materials"},
|
||||
"interstellar": {"mods": ["vsie"], "name": "Interstellar Expansion Materials"},
|
||||
"aerospace": {
|
||||
"mods": ["create_the_air_wars", "rocketnautics"],
|
||||
"any_of": True,
|
||||
"name": "Aerospace Materials",
|
||||
},
|
||||
"mekanism": {"mod": "mekanism", "name": "Mekanism Materials"},
|
||||
"create": {"mod": "create", "name": "Create Materials"},
|
||||
"iceandfire": {"mod": "iceandfire", "name": "Ice and Fire Materials"},
|
||||
"air_war": {"mod": "create_the_air_wars", "name": "Create: The Air War Materials"},
|
||||
"cosmonautics": {"mod": "rocketnautics", "name": "Create: Cosmonautics Materials"},
|
||||
"irons_spellbooks": {"mod": "irons_spellbooks", "name": "Iron's Spells Materials"},
|
||||
"interstellar": {"mod": "vsie", "name": "Interstellar Expansion Materials"},
|
||||
"immersiveengineering": {"mod": "immersiveengineering",
|
||||
"name": "Immersive Engineering Materials"},
|
||||
}
|
||||
|
||||
# Attribute this mod registers itself, so a material can grant something the
|
||||
|
|
@ -110,6 +107,7 @@ def ingots(mod, ingot, nugget=None, block=None, extra=()):
|
|||
return out
|
||||
|
||||
|
||||
|
||||
def speed(value):
|
||||
"""Attack speed tweak on held modules: positive is faster."""
|
||||
return {"attributes": [{"attribute": "generic.attack_speed", "value": str(value),
|
||||
|
|
@ -295,10 +293,11 @@ MATERIALS = [
|
|||
# ----------------------------------------------------------------- Aerospace
|
||||
# Both Air War and Cosmonautics add titanium. This is one material fed by
|
||||
# tags so either mod (or both) supplies it; see the c: tag files.
|
||||
M("titanium", "aerospace", "metal", "Titanium", "rocketnautics:titanium_ingot",
|
||||
[{"tag": "c:ingots/titanium", "value": 1.0},
|
||||
{"tag": "c:nuggets/titanium", "value": NUGGET},
|
||||
{"tag": "c:plates/titanium", "value": 1.0}],
|
||||
M("titanium", "cosmonautics", "metal", "Titanium", "rocketnautics:titanium_ingot",
|
||||
[{"item": "rocketnautics:titanium_ingot", "value": 1.0},
|
||||
{"item": "rocketnautics:titanium_nugget", "value": NUGGET},
|
||||
{"item": "rocketnautics:titanium_sheet", "value": 1.0},
|
||||
{"item": "rocketnautics:titanium_block", "value": BLOCK}],
|
||||
tier=4, hardness=5.8, density=1.6, flexibility=3, durability=1150,
|
||||
enchantability=11, mining_speed=9, toughness=2, armor_durability=32,
|
||||
armor_toughness=1.5,
|
||||
|
|
@ -552,6 +551,60 @@ MATERIALS = [
|
|||
properties={"handheld": {"attributes": [
|
||||
attribute("irons_spellbooks:spell_power", 0.05, "mainhand", "*")]}}),
|
||||
|
||||
# ------------------------------------------------- Immersive Engineering
|
||||
# Steel, lead, uranium and silver are not here - Immersive Engineering adds
|
||||
# those too, so they live in the tag-fed shared packs above and accept
|
||||
# either mod's ingots.
|
||||
M("aluminum", "immersiveengineering", "metal", "Aluminium",
|
||||
"immersiveengineering:ingot_aluminum",
|
||||
ingots("immersiveengineering", "ingot_aluminum", "nugget_aluminum",
|
||||
extra=[{"item": "immersiveengineering:plate_aluminum", "value": 1.0}]),
|
||||
tier=3, hardness=4.0, density=1.2, flexibility=3, durability=260,
|
||||
enchantability=17, mining_speed=6, armor_durability=14,
|
||||
textures=("metallic", "bright"), properties={"handheld": speed(0.10)}),
|
||||
# Light and corrosion-proof but soft - the cheap way to a fast tool, at
|
||||
# the cost of everything else.
|
||||
|
||||
M("nickel", "immersiveengineering", "metal", "Nickel",
|
||||
"immersiveengineering:ingot_nickel",
|
||||
ingots("immersiveengineering", "ingot_nickel", "nugget_nickel",
|
||||
extra=[{"item": "immersiveengineering:plate_nickel", "value": 1.0}]),
|
||||
tier=3, hardness=5.4, density=4.4, flexibility=1, durability=480,
|
||||
enchantability=10, mining_speed=6, toughness=1, armor_durability=20,
|
||||
armor_toughness=0.5),
|
||||
# Hard, tough and stubbornly corrosion resistant; dull to enchant.
|
||||
|
||||
M("constantan", "immersiveengineering", "metal", "Constantan",
|
||||
"immersiveengineering:ingot_constantan",
|
||||
ingots("immersiveengineering", "ingot_constantan", "nugget_constantan",
|
||||
extra=[{"item": "immersiveengineering:plate_constantan", "value": 1.0}]),
|
||||
tier=4, hardness=5.6, density=4.0, flexibility=2, durability=640,
|
||||
enchantability=14, mining_speed=7, toughness=2, armor_durability=24),
|
||||
# A copper-nickel alloy prized for not changing under heat or strain,
|
||||
# so it is the steady middle option: no weakness, no standout.
|
||||
|
||||
M("electrum", "immersiveengineering", "metal", "Electrum",
|
||||
"immersiveengineering:ingot_electrum",
|
||||
ingots("immersiveengineering", "ingot_electrum", "nugget_electrum",
|
||||
extra=[{"item": "immersiveengineering:plate_electrum", "value": 1.0}]),
|
||||
tier=3, hardness=4.4, density=3.6, flexibility=2, durability=260,
|
||||
enchantability=26, mining_speed=9, armor_durability=14,
|
||||
textures=("metallic", "bright"),
|
||||
properties={"tool": {"luminious_learning": "0.5"}}),
|
||||
# Gold-silver alloy, so it inherits gold's bargain: superb to enchant,
|
||||
# falls apart quickly.
|
||||
|
||||
M("hop_graphite", "immersiveengineering", "metal", "Graphite",
|
||||
"immersiveengineering:ingot_hop_graphite",
|
||||
ingots("immersiveengineering", "ingot_hop_graphite", None,
|
||||
extra=[{"item": "immersiveengineering:plate_hop_graphite", "value": 1.0}]),
|
||||
tier=4, hardness=4.2, density=2.0, flexibility=1, durability=520,
|
||||
enchantability=12, mining_speed=10, toughness=2, armor_durability=18,
|
||||
textures=("rough", "metallic"),
|
||||
properties={"default": {"fire_proof": True}, "handheld": speed(0.08)}),
|
||||
# Graphite is a dry lubricant and shrugs off heat, hence the quick swing,
|
||||
# high mining speed and fireproofing - but it is soft, so it hits weakly.
|
||||
|
||||
# --------------------------------- Aeronautics: Interstellar Expansion (vsie)
|
||||
# Mostly a machinery mod; these are the three items that are a material
|
||||
# rather than a component. Solid E-710 is deliberately left out - it is
|
||||
|
|
@ -671,6 +724,20 @@ def _scales():
|
|||
MATERIALS.extend(_scales())
|
||||
|
||||
|
||||
# Gem sockets do not look for the "gem" group. Truly Modular: Arsenal gates its
|
||||
# melee gem modules on `gem_melee` and Armory gates its armour ones on
|
||||
# `gem_armor`, so a material tagged only "crystal"/"gem" is rejected by every
|
||||
# socket - which is exactly what happened to the two essences. Anything gem-like
|
||||
# gets both, so it fits any gem slot regardless of size or whether the item is
|
||||
# a weapon or a piece of armour.
|
||||
GEM_SOCKET_GROUPS = ("gem_melee", "gem_armor")
|
||||
|
||||
for _material in MATERIALS:
|
||||
if {"gem", "crystal"} & set(_material["groups"]):
|
||||
_material["groups"] = list(_material["groups"]) + [
|
||||
g for g in GEM_SOCKET_GROUPS if g not in _material["groups"]]
|
||||
|
||||
|
||||
# Extensions add data to a material that already exists rather than replacing it.
|
||||
# Ice and Fire's amethyst is the same stone MIAPI already ships, so it just
|
||||
# becomes another way to craft it.
|
||||
|
|
|
|||
Loading…
Reference in New Issue