Market(市场摊位)

宿主方块。GTNH 1.7.10 mod Farming for Engineers 唯一注册的方块。

基本信息

属性 值 来源
类 com.guigs44.farmingforengineers.block.BlockMarket(extends BlockContainer) block/BlockMarket.java:31
注册名 farmingforengineers:market CommonProxy.java:22
本地名 tile.farmingforengineers:market.name = Market assets/farmingforengineers/lang/en_US.lang:1
TileEntity TileMarket(空类,无槽位 / 无 NBT) block/BlockMarket.java:54
材质 Material.wood block/BlockMarket.java:37
硬度 2.0F block/BlockMarket.java:40
爆炸抗性 10.0F(setResistance,非 isExplosionResistant 覆写) block/BlockMarket.java:41
亮度 0(全仓库无 setLightLevel,grep setLightLevel 0 命中) —
最大堆叠 64(全仓库无 setMaxStackSize,沿用 Item 默认 64) —
碰撞箱 未覆写 → 整方块 0,0,0 ~ 1,1,1 —
不透明 isOpaqueCube() = false,renderAsNormalBlock() = false block/BlockMarket.java:59,64
矿物字典 未注册(OreDictionary.registerOre 全仓库 0 命中) —
掉落 无(未覆写 getItemDropped / getDrops / dropFewItems) —
渲染类型 MarketBlockRenderer.RENDER_ID = RenderingRegistry.getNextAvailableRenderId() block/BlockMarket.java:154
物品形态图标 Blocks.log.getIcon(side, 1)(桦木原木) block/BlockMarket.java:50
创造栏 FarmingForEngineers.creativeTab,tab id farmingforengineers FarmingForEngineers.java:56

metadata朝向

本方块没有真正的 subtype,metadata 直接存 ForgeDirection 的 ordinal(ForgeDirection.getOrientation(meta)),共 4 个有效值。

meta ForgeDirection 商人站位(facing.getOpposite()) 贴图旋转(blockstates/market.json)
2 NORTH 市场南侧 无(0°)
3 SOUTH 市场北侧 y: 180
4 WEST 市场东侧 y: 90
5 EAST 市场西侧 y: -90
0 / 1 / 6+ DOWN / UP / 越界 不产生合法朝向 无定义

朝向在两个时机被决定,后者覆盖前者:

时机 方法 规则
放入世界(含活塞/结构放置) onBlockAdded → findOrientation 逐个检查 4 个水平邻居:-Z 实心且 +Z 不实心 → 3;+Z 实心且 -Z 不实心 → 2;-X 实心且 +X 不实心 → 5;+X 实心且 -X 不实心 → 4;都不满足 → 保持默认 byte side = 3
玩家手动放置 onBlockPlacedBy BlockPistonBase.determineOrientation(world, x, y, z, placer) 取玩家水平朝向,写入时通知标志 2(同时通知客户端与邻居)

[!NOTE] findOrientation 的 4 个 if 是平级串联而非 else if,且只判「邻居实心 + 对面不实心」;四周全实心或全空时落入默认值 3(SOUTH)。

交互

触发 行为
右键(onBlockActivated) 服务端 player.openGui(instance, GuiHandler.MARKET, world, x, y, z),GUI ID = 1;方法恒 return true
破坏 无掉落(见上表)
活塞推动 保留 metadata(Block 默认行为),但 onBlockAdded 会在推动后重新跑 findOrientation

合成配方

ModRecipes.java:13 唯一一条配方,GameRegistry.addRecipe(有形状,非 shapeless):

PCP
W W
WWW
符号 物品 数量 / metadata
P Blocks.planks(木板) 1,任意 metadata
C Blocks.wool meta 1(橙色羊毛) 1
W Blocks.log(原木) 1,任意 metadata

摆放时生成商人

onBlockPlacedBy(block/BlockMarket.java:75)在方块放下后必定在 merchantX/Z = 方块位置 + facing.getOpposite() 处生成一个 Merchant,并按环境挑一种出生动画。

出生动画 条件(按判断顺序) 商人 Y 坐标 音效 粒子
FALLING world.canBlockSeeTheSky(x, y, z)(市场方块本身见天) merchantY + 172(从天而降) farmingforengineers:falling(ModSounds.LOC_FALLING) 无
DIGGING 上一条不成立,且 !world.isAirBlock(x, y - 1, z)(市场下方非空气) 若 !isAirBlock(merchantX, merchantY, merchantZ - 1) 则 +0.5,否则 +0.0 farmingforengineers:falling 无
MAGIC 以上都不成立 同上分支 fire.ignite(ModSounds.LOC_POOF,复用原版火把点燃音) 50 个 fireworksSpark(速度各轴 ±0.25)+ 1 个 largeexplode

生成后立即调用 merchant.setMarket(x, y, z, facing) → setToFacingAngle() → setSpawnAnimation(...) → setPosition(...) → world.spawnEntityInWorld(merchant) → merchant.onInitialSpawn(null)。客户端不执行(if (!world.isRemote)),但音效/粒子在双端都播。

渲染:两条路径

渲染器 注册 用途 模型
MarketBlockRenderer(ISimpleBlockRenderingHandler) ClientProxy.preInit → RenderingRegistry.registerBlockHandler 仅物品栏:renderInventoryBlock 用 0.7 缩放渲染,renderWorldBlock 恒 return false 内部持有一个 static new TileMarket() 并走 TESR 路径
TileEntityMarketRenderer(TileEntitySpecialRenderer) ClientProxy.preInit → ClientRegistry.bindTileEntitySpecialRenderer 世界内渲染 AdvancedModelLoader 加载 models/block/market.obj(OBJ,不是 JSON)

物品栏形态另有独立模型 models/block/market_inventory.json。

贴图绑定(blockstates/market.json)

贴图键 实际资源
particle minecraft:blocks/log_spruce(云杉原木)
texture minecraft:blocks/log_spruce(供 12 个元素中的 WallLeft / WallRight / WallFront / 立柱 / 顶棚斜面等使用)
board farmingforengineers:blocks/market_top(mod 自有)
planks minecraft:blocks/planks_spruce(云杉木板,柜台正面)
roof farmingforengineers:blocks/market_roof(mod 自有)

models/block/market.json 由 12 个 elements 立方体手工搭出(BoardMiddle / BoardTop / SupportBackLeft / RoofDiagonal(绕 x 轴 -22.5°)/ SupportBackRight / SupportFrontLeft / SupportFrontRight / Roof / WallLeft / WallRight / WallFront / BoardBottom / Cube13),最高到 y = 29(超出方块 1 格以上),设计者注明 Blay09 与 Cubik Studio。

[!NOTE] TileEntityMarketRenderer 里 metadata 初值为 0,只有 tileEntity.hasWorldObj() 时才换成 getBlockMetadata();因此物品栏渲染固定按 0°(RenderUtils.getAngle(0) → ForgeDirection.DOWN → 落进 default 分支 → -90)。

TileMarket空类

tile/TileMarket.java 全文只有 5 行——public class TileMarket extends TileEntity {}。

  • 0 个槽位(无 IInventory 实现)
  • 无自定义 NBT:未覆写 writeToNBT / readFromNBT / writeToNBTWithEntity / getUpdateItem / getUpdateTag,只继承 TileEntity 默认行为(仅 id)
  • 唯一用途是类型标记:GuiHandler 用 instanceof TileMarket 判定能否开界面,ClientProxy 用它绑定 TESR
  • 市场坐标从不写入 TileEntity——GuiHandler 直接用 openGui 传入的 x, y, z

相关条目