初めに
どうも餅わらびすとです。この記事では究極の機能、ScriptAPI(gametestとも言う)のサンプルコード集を置いていきます。
良いなと思ったものがあればたまに更新するかも?
よく使うであろうコードを選んだので役に立てれば嬉しいです。
「まずScriptAPIについて知らない」、という方はこちらの、「【統合版アドオン】part-1│究極の機能、ScriptAPIを徹底解説!」で基本的な使い方を解説しているので、見ていない方は見てください。ここでは、リンクの記事の内容を理解していることを前提にしているので、記事を見た後に来るのを推奨します。
モジュールから全ての要素をインポート
@minecraft/serverにある、クラスや変数などの要素がmcに入ります。これによりいちいち必要な要素をインポートする手間がなくなるでしょう。(今回のコード集ではこれを使います)
import * as mc from "@minecraft/server";
import * as ui from "@minecraft/server-ui";
使用例: 棒を使ったら使用者にメッセージを送信する
import * as mc from "@minecraft/server";
mc.world.afterEvents.itemUse.subscribe(ev => {
if (ev.itemStack.typeId === "minecraft:stick") ev.source.sendMessage("棒を使った!");
});
全プレイヤーの取得
for () {}の、{}の中ではgetPlayers()で取得した配列の要素1つ1つにplayerという名前を付けて処理を出来ます。
playerという部分の命名に制限はありません。
for (const player of mc.world.getPlayers()) {
//処理
}
使用例: 20ティック(1秒)毎に全プレイヤーへメッセージを送る
mc.system.runInterval(() => {
for (const player of mc.world.getPlayers()) {
player.sendMessage("あなたは全プレイヤーの内の1人です");
}
}, 20);
全エンティティの取得
同じく、for () {}の、{}の中ではgetEntities()で取得した配列の要素1つ1つにentityという名前を付けて処理を出来ます。
entityという部分の命名に制限はありません。
また、mc.world.getDimension(“overworld”)の部分はディメンションオーバーワールドを取得しているということなのでこの部分を事前に所得していたディメンションに置き換えても問題ありません。
for (const entity of mc.world.getDimension("overworld").getEntities()) {
//処理
}
使用例: 20ティック(1秒)毎にプレイヤーを除外した全エンティティを消す
mc.system.runInterval(() => {
for (const entity of mc.world.getDimension("overworld").getEntities({ excludeTypes: ["minecraft:player"] })) {
entity.remove();
}
}, 20);
スコアボードオブジェクトの追加や取得
取得したスコアボードは操作出来ます。
mc.world.scoreboard.getObjective(/* 取得したいオブジェクトの名前 */);
mc.world.scoreboard.addObjective(/* 追加したいオブジェクトの名前 */);
使用例: チャットによりスコアを操作
mc.world.afterEvents.chatSend.subscribe(ev => {
//testスコアボードを取得してundefinedだったらtestスコアボードを追加。結果をscoreへ代入
const score = mc.world.scoreboard.getObjective("test") ?? mc.world.scoreboard.addObjective("test");
//チャットへ.addと送信されたら送信者のtestスコアを1追加
if (ev.message === ".add") score.addScore(ev.sender, 1);
//チャットへ.getと送信されたら送信者のtestスコアを送信
if (ev.message === ".get") ev.sender.sendMessage(String(score.getScore(ev.sender)));
});
DynamicProperyへオブジェクトを保存
現状DPには文字列,数値,真偽値,Vetor3の4つしか入れられなく、Vector3以外のオブジェクトは入れられないため、オブジェクトをJSON化(文字列化)してセットする必要があります。そのため、取得する際もJSON化されたオブジェクトをオブジェクトに戻す必要があります。
オブジェクトを直接入れているわけではないのでItemStackを保存、のようなことは出来ません。
//セットするとき
mc.world.setDynamicProperty("DPのID", JSON.stringify(/* 保存したいオブジェクト */));
//取得するとき
JSON.parse(mc.world.getDynamicProperty("DPのID"));
使用例: プレイヤー参加時にDPjoinedPlayersに参加したプレイヤーの名前を追加された配列をセットする
mc.world.afterEvents.playerJoin.subscribe(ev => {
//DP、joinedPlayersを取得
let joinedPlayers = mc.world.getDynamicProperty("joinedPlayers");
//変数joinedPlayersがundefinedだったら変数joinedPlayersへ[](JSONで表す空の配列)をセット
joinedPlayers ??= "[]";
//オブジェクトへ変換され、配列となった変数joinedPlayersへ参加したプレイヤーの名前を追加された配列を定数newJoinedPlayersへ代入
const newJoinedPlayers = JSON.parse(joinedPlayers).concat(ev.playerName);
//JSON化された定数newJoinedPlayersをDP、joinedPlayersへセット
mc.world.setDynamicProperty("joinedPlayers", JSON.stringify(newJoinedPlayers));
});
コンポーネントの取得
取得したコンポーネントはその要素をいじくれたりします。コンポーネントを追加ことは出来ません。
entity.getComponent("コンポーネント名");
使用例: 常にインベントリ番号0の位置へ棒をセットする
mc.system.runInterval(() => {
for (const player of mc.world.getPlayers()) {
const stick = new mc.ItemStack("minecraft:stick", 1);
player.getComponent("minecraft:inventory").container.setItem(0, stick);
}
});
ウォッチドックによるクラッシュのキャンセル
一定の大きさの負荷が掛かるとscriptapi側がワールドを閉じてしまうので、それをキャンセルします。
mc.system.beforeEvents.watchdogTerminate.subscribe(ev => {
ev.cancel = true;
});
スクリーンの操作
onScreenDisplayの中に操作出来る要素があります。
player.onScreenDisplay;
使用例: エフェクトが追加されたらタイトルを表示
mc.world.afterEvents.effectAdd.subscribe(ev => {
const { entity, effect } = ev;
entity.onScreenDisplay.setTitle(effect.displayName, {
fadeInDuration: 0,
stayDuration: 60,
fadeOutDuration: 20,
subtitle: "エフェクトが追加されました"
});
});
ブロックステートがセットされたブロックの設置
ブロックステートは調べれば出てきます。設置音はしません。
Vector3は、x,y,zという三つのプロパティを持ったオブジェクトです。
const permutation = mc.BlockPermutation.resolve("ブロック名", ブロックステート);
dimension.setBlockPermutation(Vector3, permutation);
使用例: アイテムを使用したらブロックステートを設定されたブロックを設置する
mc.world.afterEvents.itemUse.subscribe(ev => {
const { source, itemStack } = ev;
const { dimension } = source;
if (itemStack.nameTag === "肥料") {
const permutation = mc.BlockPermutation.resolve("minecraft:tallgrass", { tall_grass_type: "fern" });
dimension.setBlockPermutation(source.location, permutation);
}
});
処理されたItemStackをセット
ItemStackは処理後にインベントリにセットしてあげないと名前を変えたりしても変化しないのでこのようにセットする必要があります。
//ItemStackへの処理
player.getComponent("equippable").setEquipment("Mainhand", 処理されたItemStack);
使用例: アイテムを使用したらアイテムの説明欄に説明をセットする
mc.world.afterEvents.itemUse.subscribe(ev => {
const { source, itemStack } = ev;
if (itemStack.typeId === "minecraft:dragon_breath") {
itemStack.setLore(["試してみたが飲めたものじゃない。"]);
source.getComponent("equippable").setEquipment("Mainhand", itemStack);
}
});
全ItemTypeの取得
ItemTypeはItemStackの生成なんかに使えるものです。ブロックもアイテムに入ります。ワールドにあるものを取得するのでアドオンでの追加アイテムなども取得できます。
mc.ItemTypes.getAll();
使用例: チャットをしたらIDにgoldと入ったアイテムをスポーンさせる
mc.world.afterEvents.chatSend.subscribe(ev => {
if (ev.message === "getGoldItems") {
for (const itemType of mc.ItemTypes.getAll().filter(it => it.id.includes("gold"))) {
const item = new mc.ItemStack(itemType, 1);
ev.sender.dimension.spawnItem(item, ev.sender.location);
}
}
});
最後に
ここまで読んでくださりありがとうございました!役に立ったと思ってもらえたら嬉しいです。
なにか質問があるときはこちらのディスコードサーバーから受け付けています。どんな人も大歓迎!一応ここでも受け付けますが内容が複雑になると判断した質問はサーバーでしか受け付けません。
まだScriptAPIについて知らないことも少なくないので、間違っているところがあれば教えてほしいです。
それでは良いアドオンライフを!
コメント
ありがとうございます!
役に立ちました!
よかったです!
励みになります
スクリプトを実行してみたのですが ran with error: syntax error expecting ‘,’ at main.js 18とエラーがでます。ちなみに構文は以下の通りです。
import { world, system } from “@minecraft/server”;
system.afterEvents.entitySpawn.subscribe(ev => {
const zombie = world.getDimension(“overworld”);
if (typeId === “minecraft:zombie”) {
system.runInterval(() => {
//(Command)
zombie.runCommandAsync(“execute as @e[type=minecraft:zombie] at @s positioned ~-4~~-4 run gametest create test -48 48 -48”);
zombie.runCommandAsync(“execute as @e[type=minecraft:zombie] at @s positioned ~-4~~1 run gametest create test -48 48 48”);
zombie.runCommandAsync(“execute as @e[type=minecraft:zombie] at @s positioned ~1~~1 run gametest create test 48 48 48”);
zombie.runCommandAsync(“execute as @e[type=minecraft:zombie] at @s positioned ~2~~-7 run gametest create test 48 48 -48”);
zombie.runCommandAsync(“execute as @e[type=minecraft:zombie] at @s positioned ~3~~-3 run gametest create test 48 48 -48”);
zombie.runCommandAsync(“execute as @e[type=minecraft:zombie] at @s positioned ~~~-8 run gametest create test 48 48 -48”);
}
}
});
間違えているところをご指摘いただけると幸いです。よろしくお願いします。
runIntervalの括弧が閉じられてない…?
こちらの記事での質問にて、解決しているようです
https://minecraft-mcworld.com/86403/