環境
- Minecraft 1.12.2
- forgeBin-1.12.2-14.23.5.2768.jar
背景
アイテムをデスポーンさせないための処理は EntityItem.setNoDespawn
に書かれている。
バニラでは唯一ウィザーのドロップアイテムにだけ適用されていて、それはこんな風に書かれている。
protected void dropFewItems(boolean p_dropFewItems_1_, int p_dropFewItems_2_) {
EntityItem entityitem = this.dropItem(Items.NETHER_STAR, 1);
if(entityitem != null) {
entityitem.setNoDespawn();
}
}
Wikiにもネザースターはデスポーンしないとある。
このネザースターはデスポーンしたり爆発によって消滅したりはしない。
英語版にも
The wither drops the nether star upon death which, until picked up, cannot despawn or be destroyed by explosions.
とある。
疑問
ところで、そのsetNoDespawnの中身に疑問がある。
public void setNoDespawn() {
this.age = -6000;
}
ageはアイテムエンティティが生成されてからの経過tick数で、0から始まり毎tickインクリメントされる。ただし-32768である場合はインクリメントされない(ドラクエか)。 EntityItem.setAgeToCreativeDespawnTime
を呼び出すと4800(4分)にセットされる。つまりクリエイティブ状態だと投げたアイテムが1分で消える。
また、別にlifespanという変数が存在し、これは6000で初期化される。ageがlifespan以上になるとデスポーンが発生する。
ageを-32768にすると不老になるわけだが、なぜかsetNoDespawnでは-6000にしている。これでは12000カウント(10分)経過したらデスポーンするように見える。
実験結果
ウィザーを倒してみた。ところ、確かにネザースターよりも先に壊れたネザーラックが消え、その後5分くらいしてネザースターも消えた。
結論
setNoDespawnを呼び出すと、現在の年齢が-5分になり、結果的にデスポーンまでの待機時間が10分になる。lifespanに非常に大きな数を入れでもしない限りデスポーンはする。ウィザーを倒してもネザースターが消える(Forge14.23.5.2768現在)。
この現象はたまに知られている。
- https://github.com/MinecraftForge/MinecraftForge/issues/5628
- https://github.com/ModCoderPack/MCPBot-Issues/issues/607
これを呼び出しているMODがあった。
しかし、実際には働かないためなのかは知らないが、別の場所では触れている間だけ常に年齢を4分で固定するという戦法を取っていた。