Minecraft: Pi Edition: Reborn(以後、MCPI++と略す)のSDKでゴールデンシャベルというアイテムを追加してみた。

追加するまでに行ったことをメモとして残しておく。

当記事を試すには、Minecraft: Pi Edition: RebornのSDKを使ってみる2の記事に記載したCMakeが使用できる状況にしておく必要がある。


今回の開発はhttps://github.com/Bigjango13/MCPI-Mods/blob/master/mcpi-competition/week-1/jetpack.cppを少しずつ改変しながら進めた。




ディレクトリ構造は下記の通り

goldenshovel
├── CMakeLists.txt
├── img
│         ├── goldenshovel.png
│         └── items.png
├── lang
│         └── en_US.lang
├── readme.txt
└── src
        └── goldenshovel.cpp

はじめに画像ファイルを作成する。



MCreatorで作成したが、Raspberry Piでは動作しなかった(ARM64未対応)ので、Windows機で作成した。

MCreatorの操作は今回は触れないことにする。

MCreator - The Best Minecraft Mod Maker Ever


アイテム用の画像は16×16のPNG形式の画像とする。




~/.minecraft-pi/overrides/images/gui/items.pngのファイルを開発環境(今回であれば/path/to/dir/goldenshovel/img/items.png)にコピーして、



作成したアイテムの画像をitems.pngの空いている箇所に挿入して保存する。

追加した場所はコード作成の際に使用するのでメモしておく。

今回は左から7番目上から7番目の場所にアイテムのアイコンを挿入した。




続いて、goldenshovel/src/goldenshovel.cppを作成する。

作成したコードは下記の通り

#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/misc/misc.h>

// 下記の2行についてはArmorの時に触れることにする
typedef unsigned char *(*ToolItem_t)(unsigned char *ToolItem, int id);
static ToolItem_t ToolItem = (ToolItem_t) 0x99488; // ←値はminecraft.hから得た

// Custom golden shovel item
unsigned char *gs;
unsigned char *make_golden_shovel(){
    // golden shovel
    unsigned char *item = (unsigned char *) ::operator new(0x34); // Tool_SIZE
    ALLOC_CHECK(item);
    (*ToolItem)(item, 148); // ←148の意味はわからない
    
    // Set VTable
    unsigned char *vtable = *(unsigned char **) item;

    // Get Functions
    Item_setIcon_t Item_setIcon = *(Item_setIcon_t *) (vtable + Item_setIcon_vtable_offset);
    Item_setDescriptionId_t Item_setDescriptionId = *(Item_setDescriptionId_t *) (vtable + Item_setDescriptionId_vtable_offset);

    // Setup
    (*Item_setIcon)(item, 6, 6);
    (*Item_setDescriptionId)(item, "golden shovel");

    return item;
}

static void Item_initGSItems_injection(__attribute__((unused)) unsigned char *null) {
    gs = make_golden_shovel();
}

// Add golden shovel to creative inventory
static void Inventory_setupDefault_FillingContainer_addGSItem_call_injection(unsigned char *filling_container) {
    ItemInstance *gs_instance = new ItemInstance;
    ALLOC_CHECK(gs_instance);
    gs_instance->count = 255;
    gs_instance->auxiliary = 0; // ?
    // 404以外のIDを指定すると意図しないアイテムになる 全部の番号を試したわけではない 使える番号を把握したい
    gs_instance->id = 404;  
    (*FillingContainer_addItem)(filling_container, gs_instance);
}

__attribute__((constructor)) static void init() {
    // 下記二行の実行でアイテムとして追加される 下記の関数はmisc.hにある    
misc_run_on_creative_inventory_setup(Inventory_setupDefault_FillingContainer_addGSItem_call_injection);
    misc_run_on_items_setup(Item_initGSItems_injection);
}

コードはまだ理解できていないので、詳細説明は端折る。


(*Item_setIcon)(item, 6, 6);

の箇所は先程作成したitems.pngからアイコンを指定するコードになる。

先程残したメモではゴールデンシャベルのアイコンは左から7番目、上から7番目であったが、両方の数字から-1した値を第二引数と第三引数で指定する。




続いて、ゲーム中のアイテム名の表記周りの対応を行う。

~/.minecraft-pi/overrides/lang/en_US.langのファイルを開発環境(今回であれば/path/to/dir/goldenshovel/img/items.png)にコピーして、ファイルの末尾にitem.goldenshovel.name=Golden Shovelを追加する。




最後にCMakeLists.txtを作成する。

CMakeLists.txtの記述は下記の通り。

cmake_minimum_required(VERSION 3.16.0)

if(NOT MODS_BEING_BUILD STREQUAL "all")
    set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
    set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
endif()

# Start Project
project(goldenshovel)

# Include SDK
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake")

# Build the goldenshovel
add_library(goldenshovel SHARED src/goldenshovel.cpp)
target_link_libraries(goldenshovel mods-headers reborn-patch symbols misc mods-headers media-layer-core)

# Install custom goldenshovel textures
install(FILES img/items.png DESTINATION "$ENV{HOME}/.minecraft-pi/overrides/images/gui/")
install(FILES lang/en_US.lang DESTINATION "$ENV{HOME}/.minecraft-pi/overrides/lang/")



実行してゴールデンシャベルが読み込まれるかを確認する。

# goldenshovelディレクトリまで移動していることとする
$ cmake -S . -B build
$ cmake --build build
$ mv build/libgoldenshovel.so ~/.minecraft-pi/mods
$ mcpi


アイテム一覧の画面の末尾にゴールデンシャベルが追加されていれば終了。


今回のコードは下記のページで確認できるようにした。

https://github.com/inunosinsi/mcpi_shared_lib/tree/master/goldenshovel