Tower Ghast(高塔幽灵)

事实基准:/Users/evlos/a/mirror/twilightforest(minecraftVersion = 1.7.10)逐行读源码。

基本信息

属性 值 来源
注册实体名 TwilightForest:Tower Ghast TwilightForestMod.java:636
英文显示名 Carminite Ghastguard(entity.TwilightForest.Tower Ghast.name) assets/twilightforest/lang/en_US.lang:602
实体 ID 常量 idMobTowerGhast = 215 TwilightForestMod.java:1117(声明在 :153)
蛋色 主 0xbcbcbc / 副 0xb77878 TwilightForestMod.java:638-639
注册形式 TFCreatures.registerTFCreature → 追踪 80 / 更新 3 entity/TFCreatures.java:23
类 twilightforest.entity.EntityTFTowerGhast(494 行) entity/EntityTFTowerGhast.java:18
父类 net.minecraft.entity.monster.EntityGhast 同上 :18
体型 setSize(4.0F, 6.0F) 同上 :42
所属结构 黑暗高塔(TFFeature.darkTower,特性 ID 14)屋顶房间 1,权重 10、1~4 只 TFFeature.java:179

🚨 本条目不属于冰霜高塔,见 Tower Golem 同款说明。 类名 Tower 指「塔内通用小怪」;本类挂在黑暗高塔刷怪表的屋顶房间里 (TFFeature.java:178 的注释写作 // roof ghasts,:179 是该行生效的代码, 第一个参数 1 即房间号)。 本类不在任何群系刷怪表中。

数值

属性 值 来源
maxHealth 30.0 EntityTFTowerGhast.java:63
movementSpeed 源码中未设置(本类与 EntityTFTowerGhast.java 全文检索 movementSpeed 无命中),沿用 EntityGhast 链上的父类默认 —
attackDamage 源码中未设置(同上检索方式),沿用 EntityGhast 链上的父类默认 —
仇恨半径 aggroRange 64.0F 同上 :44
凝视半径 stareRange 32.0F 同上 :45
游荡幅度 wanderFactor 16.0F 同上 :47
垂直转身速度 getVerticalFaceSpeed 500(源码注释:原版算法算出来有问题,故意调高到让转向被忽略) 同上 :282-284
声音音量 getSoundVolume 0.5F 同上 :69-71
说话间隔 getTalkInterval 160 tick 同上 :76-78
单区块上限 getMaxSpawnedInChunk 8 同上 :83-85
火焰弹发射间隔 attackCounter 到 20 发射,随后置 -40 同上 :245-248
蓄力音效触发点 attackCounter == 10 时播音效 1007 同上 :239-241
发射后解除攻击概率 1/6 同上 :308-310
DataWatcher 索引 AGGRO_STATUS = 16(0 平静 / 1 仇恨 / 2 蓄力) 同上 :20、:269-274
experienceValue 源码中未设置(全文检索无命中),沿用 EntityGhast 链上的父类默认 —

AI 行为 / 特殊机制

完全覆写 updateEntityActionState()(:140-275)——本类不靠 vanilla EntityAITarget/EntityAIFlyingMoveToTarget,而是自己手写整套飞行 AI。

塔内束缚(checkForTowerHome,:421-448):每 tick 检查最近特性, 若不是 TFFeature.darkTower 则 detachHome() 并 entityAge += 5(快速老化直至死亡); 在塔内则把家设到塔中心 y + 128、半径 64(:442)。 isWithinHomeDistance 覆写为圆柱判定:y > 64 && y < 210 且水平距离平方 < 64² (:453-468,源码注释说明「塔太大,简单半径不管用」)。

索敌与仇恨:无目标时用 findPlayerInRange() 找 aggroRange 内最近的可攻击玩家, 但还必须满足「距离 < stareRange」或 shouldAttackPlayer() 为真才锁定(:319-329)。 shouldAttackPlayer 的实现只有两个条件:worldObj.canBlockSeeTheSky + canEntityBeSeen(:355-361)—— ⚠️ 方法上方的 javadoc 写的是「玩家上方方块不是高塔木时才攻击」, 代码里没有任何高塔木检查,以代码为准。 锁定后 checkToIncreaseAggro 每次调用 aggroCounter++,累计到 ≥ 20 才 isAggressive = true(:336-349);过程中首次会播 mob.ghast.moan(:339)。 脱离仇恨范围则 isAggressive = false 且清空目标(:250-253)。

被动挨打会还手:attackEntityFrom 在受伤成功且伤害来源是生物时, 直接把该生物设为目标并置 isAggressive = true(:386-398)。

火焰弹:用原版 EntityLargeFireball(不是暮色森林自有投射物,:298), 从体心 + 视线方向 0.5 格处生成,播音效 1008(:296、:300-305)。 发射后有 1/6 概率主动解除攻击(:308-310)。

幽灵陷阱:TileEntityTFGhastTrapActive:177-179 检测到本类时调用 setInTrap(), 把 inTrapCounter 置 10(:470-472);期间 updateEntityActionState 直接 return, 不索敌不攻击(:151-155)。陷阱每 tick 另有 1/10 概率对被困幽灵造成 10 点 DamageSource.generic 伤害(TileEntityTFGhastTrapActive.java:172-174)。

老化与粒子:onLivingUpdate 在亮度 > 0.5 时 entityAge += 2(:117-121), 并有 50% 概率生成 1 个 reddust 粒子(:123-132)。

刷新条件放宽:isValidLightLevel() 恒 true(:414-416), getCanSpawnHere 只检查无碰撞、不在液体中、难度非和平(:403-409)—— 即塔内屋顶不受光照限制。

死代码:

  • :52-55 注释掉的 getMaxHealth() { return 30; } 覆写(生效值来自 :63);
  • :90-104 整段按 aggroStatus 切换贴图的 switch 被注释(1.6 时代遗留写法);
  • :40 的 // this.texture = ...towerghast.png;
  • :209-210、:434、:444-445、:459-462 的调试 println 全部被注释。

相关条目