等离子球
基本信息
| 属性 | 值 |
|---|---|
| 实现类 | com.gtnewhorizons.gravisuiteneo.common.EntityPlasmaBallMKII |
| 父类 | gravisuite.EntityPlasmaBall(父模组 GraviSuite) |
| 实体 ID | 由父模组的 registerEntity 分配,见下方「实体注册」 |
基础伤害 PLASMA_DAMAGE |
100.0F(EntityPlasmaBallMKII.java:34) |
| 产出者 | 等离子炮 |
⚠️ 本条目只覆盖本 mod 覆写与新增的部分。追踪、碰撞、渲染的主体逻辑在父类 gravisuite.EntityPlasmaBall 中,父模组不在本 wiki 收录范围。
实体注册
本仓库没有任何 EntityRegistry.registerModEntity / registerGlobalEntityID 调用。注册是通过 Mixin 借用父模组的注册流程完成的:
@ModifyConstant(constant = @Constant(classValue = EntityPlasmaBall.class),
method = "preInit", remap = false) // MixinGraviSuite_General.java:102
private Class<?> gravisuiteneo$getEntityPlasmaBallClass(Class<?> original) {
return EntityPlasmaBallMKII.class;
}
父模组 GraviSuite.preInit 调用 registerEntity(EntityPlasmaBall.class, ...) 时,这个 @ModifyConstant 把常量替换成本类,于是实体 ID 由父模组的 registerEntity 分配,注册名也是父模组那一套(该方法的 slice 见 MixinGraviSuite_General.java:88-97)。
运行时生成方式有两种,都是直接 new + spawnEntityInWorld:
| 调用点 | 场景 |
|---|---|
items/ItemPlasmaLauncher.java:94、:98 |
等离子炮 开火 |
mixins/MixinItemRelocator.java:53 |
父模组传送器产生的等离子球(构造器带 TeleportPoint) |
因此本实体沿用父模组的实体 ID 与刷怪/追踪配置,不占用本 mod 自己的 ID 段。
三个构造路径
| 构造器 | 用途 | 关键设置 |
|---|---|---|
(World, EntityPlasmaBall, float) |
爆炸阶段(:39-50) |
entityType = 3;maxRange = 512.0;speedPerTick = 1.0;motion 三轴清零;位置复制自原球;finalTicksForDestruction = ticksExisted + 10 |
(World, EntityLivingBase, float, byte) |
发射阶段(:55-64) |
dataWatcher[29] = charge;maxRange = 512.0;speedPerTick = 1.33;entityType == 2 时再 changeEntitySpeed(3.0F) |
(World, EntityLivingBase, TeleportPoint, byte) |
传送点变体(:83-85) |
直接透传给父类 |
(World) |
反射/反序列化用(:87-89) |
直接透传给父类 |
changeEntitySpeed(3.0F)(:66-81)把 motion 向量归一化后再乘 3.0,并把父类的 speedPerTick 也乘 3.0 —— 即炮弹的初速是基础值的 3 × 1.33。
⚠️ changeEntitySpeed 未做 magnitude == 0 判零(:68-70),在 motion 为零向量时会除零得到 NaN。
生命周期
onUpdate(:99-105)在服务端额外加一条销毁条件:
if (!worldObj.isRemote && finalTicksForDestruction > -1
&& ticksExisted >= finalTicksForDestruction) setDead();
finalTicksForDestruction 初值 -1(:37),只有「爆炸阶段」构造器会设为 ticksExisted + 10(:42)——即爆炸视觉球存活 10 tick 后自毁。发射阶段的球不受此限制,由父类按 maxRange = 512 控制。
伤害与范围
onImpact(:129-)仅在 actionType == 2(炮弹)时进入伤害逻辑(:135);爆炸球(actionType == 3)直接 return(:130-132)。
命中半径
getImpactRadius(charge) = 6.0 * charge // :123-126
tImpactRadius = clamp_double(getImpactRadius(charge), 1.0, 15.0) // :139
- 公式基准:效率 100% 时半径 6(源码注释:“Nominal radius for 100% plasma is 6; That’s a 12x12x12 cube”,
:124) - 实际钳制到 [1.0, 15.0](
:139)。源码:137的注释写「Cap the radius at 10, that’s 30x30x30」,但代码写的是 15.0 而非 10.0 —— 注释与实现不一致 - 伤害系数
charge来自炮的Math.min(100.0F, efficiency / 100),故半径最大为6 × 100 = 600,被钳到 15
范围选取
getEntitiesWithinAABB(EntityLivingBase.class, ...)(:144-152 命中实体 / :154-162 命中方块)取以命中点为中心、半边长 tImpactRadius 的立方 AABB —— 因此是立方体而非球体:半径 15 实际覆盖 30×30×30(与 :137 注释一致)。
伤害结算
tFinalDamage = this.charge * PLASMA_DAMAGE; // :165,即 charge × 100.0
| charge | 单体伤害 | AABB 半径 |
|---|---|---|
| 1(效率 100%) | 100 | 6 |
| 2 | 200 | 12 |
| 10(效率 1000%,但炮侧封顶 100) | 1000 | 15(钳制) |
| 100(炮侧上限) | 10000 | 15(钳制) |
伤害源为 DamageSources.causePlayerPlazmaDamage(ownerEntity)(:178),属主取自 getOwnerEntity()(:142)。
地形破坏
tTerrainDamage = this.charge >= 2(:140)。为真时 worldObj.createExplosion(null, blockX, blockY, blockZ, this.charge, true)(:168)——强度就是 charge,且点燃方块(最后一个参数 true)。
⚠️ 即 charge < 2(即等离子效率 < 200%)时不破坏地形,charge >= 2 时按 charge 强度炸方块。
成就触发
onImpact 里两个分支直接触发成就(需 ownerEntity 非 null):
| 条件 | 成就 | 源码 |
|---|---|---|
累计伤害 tDamageDealt > 9000 |
OVER9000(gravisuite.itsover9000) |
:181-183 |
致死实体数 tEntitiesHitDeadly > 100 |
ULTRAKILL(gravisuite.ultrakill) |
:184-186 |
两者都是 成就树 上以 PLASMAGUN 为前置的 special 成就。注意判定用严格大于(>),恰好 9000 或恰好 100 不触发。
NBT
| 键 | 类型 | 源码 |
|---|---|---|
charge |
float | writeToNBT :110,readFromNBT :116 |
另有 dataWatcher 索引 29 存 charge(entityInit :92-96,getCharge :120),setObjectWatched(29) 开启同步。
声音
命中时在服务端播放 gravisuiteneo:plasmaImpact,音量 1.25F,音高 1.0F(:190-196)。开火声音 plasmaFired 挂在炮上,见 等离子炮。
渲染
渲染由 mixins/MixinRenderPlasmaBall 注入父类渲染器,仅客户端加载(GraviSuiteNeoMixins.java:51)。