Slide Block(滑块)

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

基本信息

属性 值 来源
注册实体名 TwilightForest:tfslideblock(全小写) TwilightForestMod.java:913-920
实体 ID 常量 idVehicleSpawnSlideBlock = 20 TwilightForestMod.java:196
注册形式 EntityRegistry.registerModEntity 直调(不经 TFCreatures)→ 无刷怪蛋 TwilightForestMod.java:913
追踪距离 / 更新频率 80 / 1(每 tick 更新),sendsVelocityUpdates = true 同上 :917-919
类 twilightforest.entity.EntityTFSlideBlock(364 行) entity/EntityTFSlideBlock.java:22
父类 net.minecraft.entity.Entity(implements IEntityAdditionalSpawnData) 同上 :22
尺寸 setSize(0.98F, 0.98F),entityCollisionReduction = 1F 同上 :38、:37
所属结构 不属于任何结构;由 BlockTFSlider(滑块陷阱方块)的 updateTick 生成 block/BlockTFSlider.java:194-207

数值

属性 值 来源
预热时间 WARMUP_TIME 20 tick EntityTFSlideBlock.java:24
每 tick 加速度 方向 × 0.03999999910593033D 同上 :175-177
每 tick 阻尼 motion *= 0.9800000190734863D 同上 :180-182
撞墙后阻尼 motion *= 0.699999988079071D 同上 :224-226
方向反转时刻 WARMUP_TIME + 40 = 第 60 tick 同上 :210-218
存活上限 slideTime > 100 且 y < 1 || y > 256;或 slideTime > 600 同上 :238-239
接触伤害 DamageSource.generic 5 点 同上 :263
击退 knockBack(this, 5, kx, kz),k = (自身 - 目标) × 2.0 同上 :265-268
音效间隔 / 音量 / 音高 每 5 tick,TwilightForest:random.slider,1.0F,0.9 + rand × 0.4 同上 :185-193
getShadowSize 0.0F(无阴影) 同上 :157-160
追踪距离 / 更新频率 80 / 1 TwilightForestMod.java:917-919

maxHealth / damage / movementSpeed:本类继承的是裸 net.minecraft.entity.Entity, 不是 EntityLivingBase,没有实体属性系统,也没有生命值 —— 它是「把方块当实体推着走」 的机关。全文件无 applyEntityAttributes,所以这三项不适用而非「未设置」。

AI 行为 / 特殊机制

生成:BlockTFSlider.updateTick 在 isConnectedInRange 通过时,用滑块方块自身 与当前 meta 构造实体(BlockTFSlider.java:194-207)。构造时立刻调 determineMoveDirection() 定方向(EntityTFSlideBlock.java:59)。

方向判定(:66-137):按 myMeta & 12 分三类 —— 4(东西向)与 8(南北向)优先看上下是否一实一空,再退到 Z / X 方向, 最后朝任一开放空气方向;0(上下向)直接按 −X、+X、−Z、+Z 的顺序找。 找不到任何方向时 moveX/Y/Z 全为 0。

流程(onUpdate,:165-255):

  1. myBlock == null 或材质为空气 → 立即 setDead()(:166-167)。
  2. 第 1 tick:校验所在格仍是原方块,不符就 setDead();符合则 setBlockToAir 把原方块挖掉(:200-207)—— 视觉上是方块「活了过来」。
  3. 第 20 tick 预热结束后才开始移动(:174-179)。
  4. 第 60 tick(预热 + 40):三轴速度清零并反向 moveX/Y/Z *= -1 (:210-218)—— 撞了 2 秒就掉头再来。
  5. isCollided 或 isStopped() → 停下并 setDead();若 canPlaceEntityOnSide 且 setBlock(..., flag 3) 成功就把方块放回终点,失败则 entityDropItem(ItemStack(myBlock, 1, myBlock.damageDropped(myMeta))) 掉落物品(:223-237)。
  6. 冲出世界或超时 → 掉落物品并消失(:238-247)。

碾压:damageKnockbackEntities 对自身 boundingBox 内所有 EntityLivingBase 造成 5 点 DamageSource.generic 伤害并击退(:260-271)。在服务端每 tick 执行 (:250-252 位于 if (!worldObj.isRemote) 块内)。

完全不可推动:getCollisionBox 返回 null(:273-279)、 canBePushed() 与 isPushedByWater() 均为 false(:354-363)、 canTriggerWalking() 为 false(:146-148)—— 其它生物推不动它,也不会被它触发方块。

存活状态:canBeCollidedWith() 返回 !isDead(:153-155), canRenderOnFire() 恒 false(:288-291)。

持久化:NBT 键 TileID / Meta / Time / MoveX / MoveY / MoveZ (:293-312);writeSpawnData 把 blockId | (meta << 16) 打包成一个 int 传给客户端 (:327-352)。

相关条目