ironchest
[!INFO] Git Commit:
7681237| Updated: 2026-05-12
Iron Chests(@Mod 类 cpw.mods.ironchest.IronChest,modid = IronChest,name = "Iron Chests")是一个纯方块/物品型存储模组:它只注册 1 个方块(IronChest:BlockIronChest),用 11 个 metadata 变体提供 1 ~ 135 格的箱子,另有 17 个升级器物品用于把箱子就地升级。
本仓库为 GTNH(GregTech: New Horizons)fork,Minecraft 1.7.10 / Forge,cpw 原作,作者 Lishid 提供原始创意。全部内容仅 29 个 Java 文件,根包 cpw.mods.ironchest(client/ 与 plugins/nei/ 两个子包)。
[!IMPORTANT] 三个容易踩空的前提,均由源码核实:
- modid 是大写
IronChest,但资源域是小写ironchest(贴图/语言文件)。注册名写IronChest:xxx,图标与本地化键写ironchest:xxx。IronChestType有 12 个枚举常量,但只有 11 个是真实箱子。第 12 个WOOD(size = 0、clazz = null、tier = -1、textureRow = -1)是哨兵,仅代表"原版木箱子"这个升级来源,不注册任何方块、物品或 TileEntity。- 构造函数的第 6 个参数不是 metadata。它是
textureRow(贴图行号);箱子 metadata 恒等于枚举的ordinal()。
核心:IronChestType 全枚举
IronChestType 是整个 mod 的唯一数据源,构造函数 13 个参数(IronChestType.java:94):
IronChestType(int size, int rowLength, int tier, String friendlyName, String modelTexture,
int textureRow, List<String> mats, Class<? extends TileEntityIronChest> clazz,
Item itemFilter, String recipeDirect, String recipeUpgradeOneTier,
String recipeUpgradeTwoTiers, int resistance)
DIRTCHEST9000 走 12 参数重载(itemFilter 传 null),其余全部走 13 参数重载。
完整常量表
size = 容量(槽位数),rowLength = 每行格数,tier = 箱子等级,textureRow = 贴图行号(非 metadata),resistance = 抗爆标志(最后一个参数,0/1 而非抗爆数值)。
| # | metadata | 常量 | 显示名 | 容量 | 行 × 列 | tier | textureRow | resistance | 抗爆 | 材质(矿石字典) | TileEntity | modelTexture |
启用开关 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | IRON |
Iron Chest | 54 | 6 × 9 | 2 | 0 | 0 | 否 | ingotIron, ingotRefinedIron |
TileEntityIronChest |
ironchest.png |
— |
| 1 | 1 | GOLD |
Gold Chest | 81 | 9 × 9 | 4 | 1 | 0 | 否 | ingotGold |
TileEntityGoldChest |
goldchest.png |
— |
| 2 | 2 | DIAMOND |
Diamond Chest | 108 | 9 × 12 | 5 | 2 | 0 | 否 | gemDiamond |
TileEntityDiamondChest |
diamondchest.png |
— |
| 3 | 3 | COPPER |
Copper Chest | 45 | 5 × 9 | 1 | 3 | 0 | 否 | ingotCopper |
TileEntityCopperChest |
copperchest.png |
— |
| 4 | 4 | STEEL |
Steel Chest | 72 | 8 × 9 | 3 | 4 | 0 | 否 | ingotSteel |
TileEntitySteelChest |
silverchest.png |
enableSteelChests (true) |
| 5 | 5 | CRYSTAL |
Crystal Chest | 108 | 9 × 12 | 5 | 5 | 0 | 否 | blockGlass |
TileEntityCrystalChest |
crystalchest.png |
— |
| 6 | 6 | OBSIDIAN |
Obsidian Chest | 108 | 9 × 12 | 5 | 6 | 1 | 是 | obsidian→Blocks.obsidian |
TileEntityObsidianChest |
obsidianchest.png |
— |
| 7 | 7 | DIRTCHEST9000 |
Dirt Chest 9000 | 1 | 1 × 1 | -1 | 7 | 0 | 否 | dirt→Blocks.dirt |
TileEntityDirtChest |
dirtchest.png |
— |
| 8 | 8 | NETHERITE |
Netherite Chest | 135 | 9 × 15 | 6 | 2 | 1 | 是 | ingotNetherite |
TileEntityNetheriteChest |
netheritechest.png |
enableNetheriteChests (!isGTNHLoaded) |
| 9 | 9 | DARKSTEEL |
Dark Steel Chest | 135 | 9 × 15 | 6 | 2 | 0 | 否 | ingotDarkSteel |
TileEntityDarkSteelChest |
darksteelchest.png |
enableDarkSteelChests (isGTNHLoaded) |
| 10 | 10 | SILVER |
Silver Chest | 72 | 8 × 9 | 3 | 4 | 0 | 否 | ingotSilver |
TileEntitySilverChest |
silverchest.png |
enableSilverChests (false) |
| 11 | 11 | WOOD |
(不注册) | 0 | — | -1 | -1 | 0 | 否 | plankWood |
null |
"" |
— |
rowCount 由 getRowCount() = size / rowLength 推导(WOOD 会除零,因此永不被实例化)。
配方字符串(12 个字段逐条)
recipeDirect / recipeUpgradeOneTier / recipeUpgradeTwoTiers 均为 9 字符串,切成 3 行 3 列;P = 前一级箱子,m = 本级材质,G = 玻璃,C = 原版木箱,O = 黑曜石。
| 常量 | recipeDirect |
recipeUpgradeOneTier |
recipeUpgradeTwoTiers |
|---|---|---|---|
IRON |
mGmGPGmGm |
mmmmPmmmm |
— |
GOLD |
mGmGPGmGm |
mmmmPmmmm |
— |
DIAMOND |
GGGmPmGGG |
GGGGPGmmm |
— |
COPPER |
— | mmmmPmmmm |
mGmGPGmGm |
STEEL |
— | mGmGPGmGm |
mmmmPmmmm |
CRYSTAL |
mmmmPmmmm |
— | — |
OBSIDIAN |
mmmmPmmmm |
— | — |
DIRTCHEST9000 |
mmmmCmmmm |
— | — |
NETHERITE |
— | OOOmPmOOO |
OOOOPOmmm |
DARKSTEEL |
— | OOOmPmOOO |
OOOOPOmmm |
SILVER |
— | mGmGPGmGm |
mmmmPmmmm |
WOOD |
— | — | — |
[!NOTE] 配方只在未加载 GTNH 时生成:
IronChestType.registerBlocksAndRecipes末尾有if (!IronChest.isGTNHLoaded) { ... },ChestChangerType.generateRecipes()开头有if (IronChest.isGTNHLoaded) return;。GTNH(装了 DreamCraft)上本 mod 一条合成配方都不注册。
resistance 的两重用途
- 抗爆:
isExplosionResistant() = resistance >= 1→BlockIronChest.getExplosionResistance返回10000.0F。全仓库没有任何setResistance()调用。 - 配方过滤:
getRegistredChestsByTier(parent, tier, resistance)要求候选typ.resistance >= resistance。直做配方传typ.resistance - 1(放宽),升级配方传typ.resistance(收紧)。最直接的后果:下界合金箱子(resistance 1,tier 6)只能从黑曜石箱子升级,钻石/水晶箱(resistance 0)被过滤掉。
未被使用的字段
textureRow:getTextureRow()是死代码(全仓库除定义与赋值外零调用)。modelTexture/getModelTexture():只被TileEntityIronChestRenderer用来拼textures/model/<name>路径。IronChestType.VALUES:注释明确 “the array should NOT be mutated”,是高频只读缓存。
依赖与注册入口
@Mod(modid = "IronChest", name = "Iron Chests", dependencies = "required-after:Forge@[10.10,);required-after:FML@[7.2,)")
| 生命周期 | 动作 |
|---|---|
preInit |
读 9 个配置项 → new BlockIronChest() → GameRegistry.registerBlock(ironChestBlock, ItemIronChest.class, "BlockIronChest") → 初始化 PacketHandler.INSTANCE(建立 FML 通道) |
load |
对 VALUES 逐个 registerTileEntityWithAlternatives(clazz, "IronChest." + name, name) 与 bindTileEntitySpecialRenderer → OreDictionary.registerOre("chestWood", Blocks.chest) → IronChestType.registerBlocksAndRecipes → ChestChangerType.generateRecipes → registerGuiHandler → 按 OCELOTS_SITONCHESTS 注册猫 AI 事件 |
modsLoaded |
空实现 |
missingMapping |
旧存档名重映射(见下) |
preInit 里 ChestChangerType.buildItems(cfg)(注册 17 个升级器物品)与配置读取在同一个 try 块内。
旧存档名重映射
IronChest.missingMapping(FMLMissingMappingEvent):
| 条件 | 旧存档名 | 重映射到 |
|---|---|---|
STEEL.isEnabled() |
IronChest:copperSilverUpgrade(BLOCK + ITEM) |
copperSteelUpgrade |
STEEL.isEnabled() |
IronChest:silverGoldUpgrade(BLOCK + ITEM) |
steelGoldUpgrade |
DARKSTEEL.isEnabled() |
IronChest:obsidianNetheriteUpgrade |
diamondDarkSteelUpgrade |
NETHERITE.isEnabled()(else if) |
IronChest:diamondDarkSteelUpgrade |
obsidianNetheriteUpgrade |
后两条是 if / else if 串联,先判 DARKSTEEL。GTNH 上 DARKSTEEL 默认开、NETHERITE 默认关,故走第一支。
代码结构
| 文件 | 职责 |
|---|---|
IronChest.java |
@Mod 主类:配置、方块与升级器注册、TileEntity 注册、GUI handler、缺映射处理 |
IronChestType.java |
12 个常量的枚举;makeEntity / validateMeta / 配方生成 / acceptsStack / 图标注册 |
ChestChangerType.java |
17 个升级器常量:source/target/itemName/descriptiveName/3 行配方 |
BlockIronChest.java |
唯一的方块:metadata→TE、硬度、抗爆覆写、比较器、旋转、猫判定、掉落散落 |
ItemIronChest.java |
ItemBlock 形态:getMetadata 走 validateMeta、按枚举名取未本地化名、tooltip |
ItemChestChanger.java |
升级器物品:onItemUseFirst 同时处理铁箱 TE 与原版 TileEntityChest |
TileEntityIronChest.java |
物品栏 / NBT / 盖子动画 / 客户端同步 / 透明内容排序 / applyUpgradeItem |
TileEntity{Copper,Gold,Diamond,Steel,Silver,Crystal,Obsidian,Netherite,DarkSteel}Chest.java |
9 个 12~15 行的空壳,唯一实现是 super(<对应常量>) |
TileEntityDirtChest.java |
唯一有实质覆写的 TE:出厂说明书(wasPlaced)与拆除清理(removeAdornments) |
ContainerIronChest.java |
槽位布局(泥土箱子单格居中分支)、transferStackInSlot、@ChestContainer(isLargeChest = true) |
ValidatingSlot.java |
Slot.isItemValid 走 type.acceptsStack(泥土箱子只收泥土) |
PacketHandler.java |
FML 通道 IronChest,判别字 0;type(低 4 位) + facing(高 4 位) 压在一个 byte |
IronChestRenderHelper.java |
预建 11 个空 TE,让物品形态复用方块渲染器 |
OcelotsSitOnChestsHandler.java / IronChestAIOcelotSit.java |
替换豹猫 priority == 6 的 EntityAIOcelotSit |
MappableItemStackWrapper.java |
渲染用的 ItemStack 身份包装(getHasSubtypes 时改用 isItemEqual) |
CommonProxy.java / client/ClientProxy.java |
IGuiHandler 双端实现、特效渲染器绑定、客户端世界获取 |
client/GUIChest.java |
11 个 GUI 尺寸/贴图枚举 + ResourceList |
client/TileEntityIronChestRenderer.java |
ModelChest 渲染 + 水晶箱子悬浮物品 |
plugins/nei/NEIConfig.java |
IConfigureNEI:给 GUIChest 注册 DefaultBookmarkContainerHandler |
本 mod 没有的内容(grep 证据)
以下 9 个维度在 src/main/java/ 全仓库零命中,因此未建目录:
| 维度 | grep 模式 | 结果 |
|---|---|---|
| entity | registerEntity|EntityRegistry|registerModEntity|extends Entity\b|extends EntityLiving|extends EntityItem |
0 命中 |
| keybinding | KeyBinding|keyBinding|registerKeyBinding|key\.categories |
0 命中 |
| 命令 | ICommand|addChatCommand|CommandBase|registerCommand |
0 命中 |
| enchantment | Enchantment|enchantment |
0 命中 |
| potioneffect | Potion|MobEffect|applyEffect |
0 命中 |
| dimension | WorldProvider|registerDimension|DimensionManager|WorldType |
0 命中 |
| biome / structure / achievement | BiomeGen|WorldGenerator|StructureStart|StructureBoundingBox|Achievement |
0 命中 |
| multiblock | Multiblock|IMultiblock|Formation|Controller |
0 命中 |
| 能量 / 流体 | IEnergyHandler|receiveEnergy|EnergyStorage|IFluidHandler|FluidTank |
0 命中 |
另外:
- 无多方块结构:
BlockIronChest继承BlockContainer,无createTileEntity之外的成组检测。 - 无世界生成:无
WorldGen/MapGen相关类,src/main/resources下无任何世界生成配置文件。 - 无伤害/生物:mod 不注册实体,豹猫是原版
EntityOcelot。 - 无附魔 / 无 potion / 无成就。
- 无第三方 mod 整合点,唯一外部引用是 NEI(
plugins/nei/NEIConfig.java,仅注册书签 handler)与 InvTweaks(ContainerIronChest上的@ChestContainer(isLargeChest = true)与@ChestContainer.RowSizeCallback)。 - 无合成表文件:所有配方都是
ShapedOreRecipe代码注册;src/main/resources下无_recipes目录。
方块列表
宿主方块(1 个注册方块 + 11 个 metadata 变体):
- Iron Chest 方块(IronChest:BlockIronChest) - metadata 分配、硬度 3.0F、抗爆覆写、比较器、旋转、猫判定
11 个 metadata 变体:
- Iron Chest(铁箱子) - 54 格 / 6×9 / tier 2
- Copper Chest(铜箱子) - 45 格 / 5×9 / tier 1,全表最小
- Steel Chest(钢箱子) - 72 格 / 8×9 / tier 3,复用银箱子贴图
- Silver Chest(银箱子) - 72 格 / 8×9 / tier 3,默认关闭
- Gold Chest(金箱子) - 81 格 / 9×9 / tier 4,唯一正方形布局
- Diamond Chest(钻石箱子) - 108 格 / 9×12 / tier 5
- Crystal Chest(水晶箱子) - 108 格 / 9×12 / tier 5,全 mod 唯一透明
- Obsidian Chest(黑曜石箱子) - 108 格 / 9×12 / tier 5,抗爆
- Netherite Chest(下界合金箱子) - 135 格 / 9×15 / tier 6,抗爆,GTNH 上默认关闭
- Dark Steel Chest(玄钢箱子) - 135 格 / 9×15 / tier 6,GTNH 上默认开启
- Dirt Chest 9000(泥箱子 9000) - 1 格 / 只收泥土 / 出厂附说明书
物品列表
箱子物品形态:
- ItemIronChest(箱子物品形态) - damage 即 metadata,
getMetadata走validateMeta
17 个升级器物品(全部 setMaxStackSize(1),无耐久,右键已放置的方块触发):
符号:m = 目标材质,s = 来源材质,G = 玻璃,O = 黑曜石。
游戏设定列表
- 箱子类型开关(enable*Chests) - 4 个 boolean,GTNH 上
darkSteel=true/netherite=false - 升级黑名单(blocklistUpgrades) - String 列表,
SOURCE:TARGET格式,可屏蔽任意升级器与其配方 - 透明箱子渲染(transparentRender*) - boolean + double 128D,只影响水晶箱子
- 猫与箱子行为(ocelots*) - 2 个 boolean,替换豹猫坐箱 AI 与开箱门禁
[!NOTE] mod 共 9 个配置项,全在
config/ironchest.cfg的general段。blocklistUpgrades的读取与ChestChangerType.buildItems(cfg)在同一 try 块内,配置加载异常会连带导致 17 个升级器全部不注册。