製作理由
複雑な機能を持つアドオンのゲーム内説明書を全playerに与える処理を作りたかったので。
記入済みの本をScriptAPI上で作成する方法がわからなかった(たぶん現状ではできない)ので、loot_tableを使ってloot commandで渡すことにしました。
副次的に、loot_tableを編集するだけで「ゲームに初めて参加したプレイヤーに特定のアイテムを与える」などの処理が可能となり、意外と扱いやすそうだったので公開することに。
機能
アプデ後初回ログインボーナス機能もとい、readme本を各プレイヤーに一回だけ配るためのScriptAPI
応用することで、もちろん本当にボーナスアイテムを与えることだって可能。
inventoryの空き具合を確認して処理を行わないことで次回スポーン時まで持越しにしたり、プレイヤー座標に直接アイテムをスポーンさせることで受け取り失敗を回避することもできる。
仕様・コード
最終ログインVersionをDPを使ってplayerに記録することで、ボーナスを受け取り済みかどうかチェックしている
//main.js
import { Player, world } from"@minecraft/server";
import { isOldVer } from"./checkVer.js"
const addonVer ="0.0.0";
const lastLoginVerDPID = "lastLoginVer";
world.afterEvents.playerSpawn.subscribe(ev=>{
if(isLastLoginVerOutdated(ev.player)){
ev.player.setDynamicProperty(lastLoginVerDPID,addonVer);
giveReadme(ev.player);
}
});
/**
* 紛失時用救済コマンド
*/
world.afterEvents.chatSend.subscribe(ev=>{
if(ev.message=="!getReadme"){
giveReadme(ev.sender);
}
});
/**
* ルートテーブルを使って記述済みのreadome本を与える
* @param {Player} player
*/
function giveReadme(player){
player.runCommand(`loot give @s loot "items/test_readme"`);
};
function isLastLoginVerOutdated(player){
try{
const lastLoginVer = player.getDynamicProperty(lastLoginVerDPID);
if(isOldVer(lastLoginVer,addonVer)){
return true;
}
}catch{
return true;
}
return false;
};
//checkVer.js
/**
* versionAが大きい=1 versionBが大きい=-1 等しいなら0を返す
* @param {*} versionA
* @param {*} versionB
* @returns
*/
export function compareVersions(versionA, versionB) {
// バージョンを配列に分割し、数値に変換
const partsA = versionA.split(".").map(Number);
const partsB = versionB.split(".").map(Number);
// MAJOR, MINOR, PATCH を比較
for (let i = 0; i < 3; i++) {
if (partsA[i] > partsB[i]) return 1;
if (partsA[i] < partsB[i]) return -1;
}
return 0;
};
export function isOldVer(target, base){
if(compareVersions(base,target)>0){
return true;
}
return false;
};
コメント