たくさんの自由帳

自作 MOD の Minecraft 26.3 移行

投稿日 : | 0 日前

文字数(だいたい) : 1763

どうもこんばんわ。

本題

Minecraft 26.3がリリースされてたので自作MODを更新しました。

minecraft_screenshot

あ、ついにGPUがオンボードからグラボに進化しました。玄人志向(名前変わった!?)のIntel Arcの安いやつ!。
4Kモニターをちょっと安く譲ってもらったのですが、4K + 60fpsがオンボードでは出せないらしく、安いやつでいいのでグラボを買う必要があった・・

まあそもそもi5 8600K(8年前くらい)なのでたいそれたものは付けません + 時期が悪い

前回

差分

移行ガイド

まいどおなじみ、ありがとう

Gradle

  • Fabric
    • 9.7.1
  • NeoForge (変わらず)
    • 9.2.1
  • Forge
    • 9.7.1

Block の playerDestroy が ServerPlayer を引数に取る

いままではPlayerだった?んでinstanceof ServerPlayerであることを確認すればよいはず。
Block#playerDestroyがServerPlayer必須になってた。が、多分その辺の処理の前にLevel#isClient()とか、Level instanceof ServerLevelとかで分岐してるはずなので、特に大変じゃないハズ

fun manaita(
    dropSize: Int,
    world: Level,
    blockPos: BlockPos,
    playerEntity: Player
) {
    if (world !is ServerLevel) return // こんな感じにすでにサーバーかどうか見ている箇所があるハズなので
    if (playerEntity !is ServerPlayer) return // これを足す

    val blockState = world.getBlockState(blockPos)
    val copyBlock = blockState.block
    val blockEntity = world.getBlockEntity(blockPos)

    repeat(dropSize) {

        // チェストの中身も増やす
        if (blockEntity is Container) {
            repeat(blockEntity.containerSize) { invIndex ->
                Block.popResource(world, blockPos, blockEntity.getItem(invIndex).copy())
            }
        }

        // ブロックを増やす
        copyBlock.playerDestroy(world, playerEntity, blockPos, blockState, blockEntity, playerEntity.mainHandItem)
    }
}

Javaなら、早期リターン効いてない?のかキャストしないとだった

public static void manaita(
        int dropSize,
        Level world,
        BlockPos blockPos,
        Player player
) {

    if (!(world instanceof ServerLevel)) {
        return;
    }

    // 足す
    if (!(player instanceof ServerPlayer)) {
        return;
    }

    BlockState blockState = world.getBlockState(blockPos);
    Block copyBlock = blockState.getBlock();
    BlockEntity blockEntity = world.getBlockEntity(blockPos);

    for (int i = 0; i < dropSize; i++) {

        // チェストの中身も増やす
        if (blockEntity instanceof Container) {
            for (int l = 0; l < ((Container) blockEntity).getContainerSize(); l++) {
                Block.popResource(world, blockPos, ((Container) blockEntity).getItem(l).copy());
            }
        }

        // ブロック複製
        // ここはキャスト
        copyBlock.playerDestroy((ServerLevel) world, (ServerPlayer) player, blockPos, blockState, blockEntity, player.getMainHandItem());

        // なんか経験値を吐き出す実装がなくなった?ので自前で用意
        int exp = blockState.getExpDrop(world, blockPos, blockEntity, player, player.getMainHandItem());
        copyBlock.popExperience((ServerLevel) world, blockPos, exp);
    }
}

なんか腕を振ってくれない

なんか昔はuseOnでSUCCESSを返すだけで、クリックしたときに腕をぶんぶん振り回してた気がするんだけど、26.3にしたらなんかクリックしても腕が動かない?。
でも見た感じFabricだけでNeoForgeとForgeだとSUCCESSだけで動いてるっぽいんだよなあ、、

override fun useOn(context: UseOnContext): InteractionResult {
    return InteractionResult.SUCCESS // これじゃだめっぽ
}

で、調べた感じ、InteractionResult.SUCCESS.heldItemTransformedTo()を使うと腕をぶんぶん振ってくれるようになった。
こんな感じ。

class ClickManaitaBaseItem(settings: Properties, private val dropSize: Int = 2) : Item(settings) {

    /**
     * ブロックを右クリックしたときに呼ばれる関数
     */
    override fun useOn(context: UseOnContext): InteractionResult {

        // 共通処理を呼び出す
        ClickManaitaItemTool.manaita(
            dropSize = dropSize,
            world = context.level,
            blockPos = context.clickedPos,
            playerEntity = context.player ?: return InteractionResult.PASS
        )

        return InteractionResult.SUCCESS.heldItemTransformedTo(context.itemInHand)
    }
}

InteractionResult、ただのenum classだと思ってたら代数的データ型的な感じに書き直されていた・・!?
Javaでもsealed classあるんだ。

Block クラスの codec() メソッドは使われなくなった

BaseEntityBlockとかにはcodec()メソッドがあったのですが、どうやら消えたらしいです。
そしてもう使われないらしいので削除するだけでいい模様。

class ResetTableBlock(settings: Properties) : BaseEntityBlock(settings) {

    // codec() メソッドを消す、もう存在しない
    override fun codec(): MapCodec<out BaseEntityBlock> {
        return CODEC
    }

    // そのほか省略...

    companion object {
        private val CODEC = simpleCodec { settings -> ResetTableBlock(settings) } // 使わないので消す
    }
}

MOD ローダー別

Fabric

build.gradleからversionとgroupが消えた、けどちゃんとgradle.propertiesの値を適用していそうだった。

- version = project.mod_version
- group = project.maven_group

おわりに

Fabricのときだけ、.ideaフォルダを消さないとエラーが消えなかった・・