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