メインコンテンツまでスキップ

Luaスクリプティング: プロップ&アイテムAPI

このページでは、FreeMinecraftModelsのプロップおよびアイテムスクリプトで利用可能なすべてのAPIについて説明します:context.propcontext.itemcontext.eventcontext.playercontext.worldcontext.zonescontext.schedulercontext.state、およびcontext.log。スクリプティングが初めての場合は、まずはじめにを参照してください。


context.prop

propテーブルは、プロップエンティティの情報とそのアニメーションを制御するメソッドを提供します。これはフック呼び出しごとに新しく再構築されます。

フィールド

フィールド備考
prop.model_idstring設計図モデル名(例:"torch_01"
prop.current_locationlocation テーブルコンテキストが構築された時点でのプロップの位置

locationテーブルには標準フィールドがあります:xyzworldyawpitch

例:propの情報を読み取る
return {
api_version = 1,

on_spawn = function(context)
context.log:info("Prop spawned: " .. (context.prop.model_id or "unknown"))
local loc = context.prop.current_location
if loc then
context.log:info("Location: " .. loc.x .. ", " .. loc.y .. ", " .. loc.z)
end
end
}

prop:play_animation(name, blend, loop)

プロップモデルで名前付きアニメーションを再生します。

パラメータデフォルト備考
namestring必須モデルファイルで定義されたアニメーション名
blendbooleantrue現在のアニメーションとブレンドするかどうか
loopbooleantrueアニメーションがループするかどうか

アニメーションが見つかって開始された場合はtrue、それ以外はfalseを返します。

return {
api_version = 1,

on_right_click = function(context)
local success = context.prop:play_animation("open", true, false)
if not success then
context.log:warn("Animation 'open' not found on this model!")
end
end
}

prop:stop_animation()

プロップで現在再生中のすべてのアニメーションを停止します。

パラメータなし。

return {
api_version = 1,

on_right_click = function(context)
context.prop:stop_animation()
end
}

prop:hurt_visual()

プロップに実際のダメージを与えずに、視覚的なダメージアニメーション(赤いティントフラッシュ)を再生します。

パラメータなし。

return {
api_version = 1,

on_left_click = function(context)
-- 殴られた時に赤くフラッシュするが、実際にはダメージを受けない
if context.event then
context.event.cancel()
end
context.prop:hurt_visual()
end
}

prop:pickup()

プロップをワールドから削除し、その場所に配置用の紙アイテムをドロップします。ドロップされたアイテムはブロックを右クリックすることでプロップを再配置できます。

パラメータなし。

return {
api_version = 1,

on_right_click = function(context)
-- プレイヤーが右クリックでプロップを拾えるようにする
context.prop:pickup()
end
}

prop:mount(player)

プロップ上の最初の利用可能なマウントポイントシートにプレイヤーを乗せます。モデルにはマウントポイントボーンが定義されている必要があります。

パラメータ備考
playerエンティティテーブルプレイヤーのエンティティテーブル(例:context.event.playerから)
return {
api_version = 1,

on_right_click = function(context)
local player = context.event and context.event.player
if player then
context.prop:mount(player)
end
end
}

prop:dismount(player)

プロップ上のマウントポイントシートからプレイヤーを降ろします。

パラメータ備考
playerエンティティテーブルプレイヤーのエンティティテーブル
return {
api_version = 1,

on_right_click = function(context)
local player = context.event and context.event.player
if player then
-- マウント/ディスマウントをトグル
local passengers = context.prop:get_passengers()
for i = 1, #passengers do
if passengers[i].uuid == player.uuid then
context.prop:dismount(player)
return
end
end
context.prop:mount(player)
end
end
}

prop:get_passengers()

プロップ上の現在の乗員すべてに対するエンティティテーブルのLua配列を返します。

パラメータなし。

return {
api_version = 1,

on_game_tick = function(context)
local passengers = context.prop:get_passengers()
if #passengers > 0 then
context.log:info("Prop has " .. #passengers .. " passenger(s)")
end
end
}

prop:has_mount_points()

このプロップがモデルにマウントポイントボーンを定義しているかどうかを返します。

パラメータなし。trueまたはfalseを返します。

return {
api_version = 1,

on_right_click = function(context)
local player = context.event and context.event.player
if player and context.prop:has_mount_points() then
context.prop:mount(player)
end
end
}

prop:spawn_elitemobs_boss(filename, x, y, z)

指定された位置にEliteMobsカスタムボスをスポーンします。サーバーにEliteMobsがインストールされている必要があります。

パラメータ備考
filenamestringカスタムボスのファイル名(例:"my_boss.yml"
xnumberX座標
ynumberY座標
znumberZ座標

スポーンされたボスのリビングエンティティテーブルを返します。EliteMobsがインストールされていないか、ボスファイルが存在しない場合はnilを返します。

return {
api_version = 1,

on_right_click = function(context)
local loc = context.prop.current_location
if loc then
local boss = context.prop:spawn_elitemobs_boss("dungeon_guardian.yml", loc.x, loc.y + 1, loc.z)
if boss then
context.log:info("Spawned boss: " .. (boss.name or "unknown"))
else
context.log:warn("Could not spawn boss -- is EliteMobs installed?")
end
end
end
}

prop:open_inventory(player, title, rows)

プレイヤーに対して永続化されるチェストインベントリGUIを開きます。コンテンツはインベントリが閉じられた際にプロップのPersistentDataContainerに保存され、再度開かれたときに復元されます。

パラメータデフォルト備考
playerエンティティテーブル必須インベントリを表示するプレイヤー
titlestring必須インベントリのタイトル(&カラーコードに対応)
rowsint3行数(1-6、6は54スロット=ダブルチェスト)

インベントリが開かれた場合はtrue、それ以外はfalseを返します。


prop:is_viewing_inventory(player)

指定されたプレイヤーが現在このプロップのインベントリを開いているかどうかを返します。

パラメータ備考
playerエンティティテーブルチェックするプレイヤー

trueまたはfalseを返します。

例:インベントリが閉じられた時のクローズアニメーション
context.state["task_" .. player.uuid] = context.scheduler:run_repeating(5, 5, function(tick_context)
if not tick_context.prop:is_viewing_inventory(player) then
tick_context.prop:play_animation("close", true, false)
tick_context.scheduler:cancel(tick_context.state["task_" .. player.uuid])
end
end)

prop:place_book(player)

プレイヤーのメインハンドから記入済みまたは書き込み可能な本を取り出して、プロップに保管します。

パラメータ備考
playerエンティティテーブル本を持っているプレイヤー

成功した場合はtrueを返します。


prop:read_book(player)

プレイヤーが読むために保管された本を開きます。

パラメータ備考
playerエンティティテーブル本を表示するプレイヤー

本が開かれた場合はtrueを返します。


prop:take_book(player)

保管された本をプレイヤーのインベントリに返し、プロップから削除します。

パラメータ備考
playerエンティティテーブル本を渡すプレイヤー

成功した場合はtrueを返します。


prop:has_book()

このプロップに本が保管されているかどうかを返します。パラメータなし。


prop:drop_inventory()

保管されたインベントリの内容をすべてプロップの位置にアイテムエンティティとしてドロップし、保管されたデータをクリアします。現在表示中のプレイヤーに対しては自動的にインベントリを閉じます。

パラメータなし。成功した場合はtrueを返します。


prop:drop_book()

保管された本をプロップの位置にアイテムエンティティとしてドロップし、保管された本のデータをクリアします。

パラメータなし。成功した場合はtrueを返します。


prop:set_persistent_data(key, value)

プロップのアーマースタンドのPersistentDataContainerに文字列値を保存します。このデータはサーバー再起動とチャンクアンロードを通じて存続します。

パラメータ備考
keystring一意のキー名(内部的にfmm_lua_<key>の下に保存されます)
valuestring保存する値。数値とブール値にはtostring()を使用してください。

成功した場合はtrue、プロップに裏付けのアーマースタンドがない場合はfalseを返します。


prop:get_persistent_data(key)

set_persistent_dataで以前に保存された文字列値を取得します。キーが設定されていない場合はnilを返します。

パラメータ備考
keystringset_persistent_dataで使用されたキー名
例:永続的なトグル状態
return {
api_version = 1,

on_spawn = function(context)
local saved = context.prop:get_persistent_data("active")
context.state.active = saved == "true"
end,

on_right_click = function(context)
context.state.active = not context.state.active
context.prop:set_persistent_data("active", tostring(context.state.active))
end
}

context.item

itemテーブルはアイテムスクリプトのみで利用可能です(プロップスクリプトでは利用できません)。カスタムアイテムの情報とそれを操作するメソッドを提供します。このテーブルはフック呼び出しごとに新しく再構築されます。

フィールド

フィールド備考
item.idstringアイテムタイプID(YML設定からのfmm_item_id

item:material()

アイテムのマテリアル名を文字列として返します(例:"DIAMOND_SWORD""STICK")。


item:get_amount() / item:set_amount(n)

アイテムのスタックサイズを取得または設定します。

パラメータ備考
nint新しいスタック量

item:consume(n)

アイテムのスタック量をn(デフォルト1)だけ減らします。結果の量が0以下になった場合、アイテムはプレイヤーのインベントリから削除されます。

パラメータデフォルト備考
nint1消費する量

item:get_uses() / item:set_uses(n)

アイテムのPersistentDataContainerに保存されたカスタム使用カウンターを取得または設定します。これはバニラ耐久度から独立しており、カスタムの耐久度やチャージシステムを実装するために使用できます。

パラメータ備考
nint新しい使用回数

item:get_name() / item:set_name(s)

アイテムの表示名を取得または設定します。&によるカラーコードに対応しています。

パラメータ備考
sstring新しい表示名(例:"&b&lFrost Sword"

item:get_lore() / item:set_lore(table)

アイテムのロアを取得または設定します。get_lore()は文字列のテーブル(1行につき1つ)を返します。set_lore()は文字列のテーブルを受け取ります。

パラメータ備考
tabletable文字列の配列、1ロア行につき1つ
例:使用回数を追跡するアイテムスクリプト
return {
api_version = 1,

on_right_click = function(context)
local uses = context.item:get_uses()
if uses <= 0 then
context.player:send_message("&cThis item is out of charges!")
return
end
context.item:set_uses(uses - 1)
context.player:send_message("&aUsed! Charges remaining: " .. (uses - 1))
end
}

item:get_durability()

アイテムのバニラ耐久度を表すcurrentmaxフィールドを持つテーブルを返します。アイテムに耐久度バーがない場合はnilを返します。

local dur = context.item:get_durability()
if dur then
context.player:send_message("Durability: " .. dur.current .. "/" .. dur.max)
end

item:get_durability_percentage()

残りの耐久度を0.0から1.0の比率として返します。アイテムに耐久度バーがない場合はnilを返します。


item:use_durability(amount, can_break)

アイテムのバニラ耐久度を一定量だけ減らします。

パラメータデフォルト備考
amountint必須消費する耐久度ポイント数
can_breakbooleanfalsetrueの場合、耐久度が尽きるとアイテムは破壊されます。falseの場合、耐久度は1で止まります。

item:use_durability_percentage(fraction, can_break)

アイテムのバニラ耐久度を最大値の割合で減らします。

パラメータデフォルト備考
fractionnumber必須消費する最大耐久度の割合(例:0.1は10%)
can_breakbooleanfalsetrueの場合、耐久度が尽きるとアイテムは破壊されます。falseの場合、耐久度は1で止まります。

context.event

現在のフックのイベントデータ。プロップとアイテムスクリプト両方のクリック、戦闘、インタラクションフックで利用可能です。関連するイベントがないフック(on_spawnon_game_tickon_destroyon_zone_enteron_zone_leaveon_equip)ではnilを返します。

フィールドとメソッド

フィールドまたはメソッド備考
event.playerプレイヤーエンティティテーブルイベントをトリガーしたプレイヤー。on_left_clickon_right_clickon_projectile_hit(射手がプレイヤーだった場合)で利用可能。すべてのフィールドとメソッドについてはプレイヤーエンティティメソッドを参照してください。
event.is_cancelledbooleanイベントが現在キャンセルされているかどうか
event.cancel()functionイベントをキャンセルします(例:ダメージやインタラクションを防ぐ)
event.uncancel()function以前にキャンセルされたイベントをアンキャンセルします
備考

すべてのイベントがキャンセル可能ではありません。基底のBukkitイベントがCancellableを実装していない場合、event.cancel()event.uncancel()は存在せず、event.is_cancelledは常にfalseになります。

例:プロップを無敵にする

return {
api_version = 1,

on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}

例:キャンセル状態のチェック

return {
api_version = 1,

on_left_click = function(context)
if context.event and not context.event.is_cancelled then
context.event.cancel()
context.log:info("Damage cancelled!")
end
end
}
注意

スケジュール済みコールバック(scheduler:run_laterscheduler:run_repeating)内では、context.eventは常にnilです。イベントの変更はイベントフック自体の間にしか行えません。


context.world

world APIはすべてのNightbreakプラグインで共有されています。完全なリファレンスについてはcontext.worldを参照してください。

備考

FMMのプロップはEliteMobsボスと同じMagmaCore worldテーブルを使用します。グローバルページに記載されているすべてのメソッド(get_block_atset_block_atspawn_particleplay_soundstrike_lightningget_timeset_timeget_nearby_entitiesget_nearby_playersspawn_entityget_highest_block_yraycastspawn_firework)がFMMで利用できます。world:raycast()(光線を投射してヒットしたエンティティ/ブロックを検出)およびworld:spawn_firework()(カスタム色と形状で花火ロケットをスポーン)の完全な詳細については、MagmaCore world APIを参照してください。EliteMobsはボス、増援などをスポーンするための追加メソッドでworldテーブルを拡張します -- EliteMobs World & Environmentを参照してください。


プレイヤーエンティティメソッド

プレイヤーエンティティテーブルは、context.event.playercontext.world:get_nearby_players()、ゾーンコールバックから返されます。

共有API

エンティティテーブル、リビングエンティティメソッド、プレイヤー固有メソッド、プレイヤーUIメソッドはすべてのNightbreakプラグインで共有されています。エンティティ基本フィールド、リビングエンティティのフィールドとメソッド、プレイヤー固有のフィールドとメソッド、プレイヤーUIメソッドを網羅した完全リファレンスは、MagmaCore Luaスクリプティングエンジンを参照してください。新しいプレイヤーメソッドにはplayer:get_target_entity()(レイキャストターゲティング)、player:get_eye_location()player:get_look_direction()player:send_block_change()(プレイヤーごとのフェイクブロック)、player:reset_block()が含まれます -- 詳細はプレイヤー固有メソッドを参照してください。

FMM固有のエンティティフィールド

FMMスクリプト内で構築されたすべてのエンティティテーブルは、FMMのLuaEntityEnricherを介してこれらの追加フィールドが自動的に付与されます:

フィールド備考
entity.is_modeledbooleanこのBukkitエンティティがModeledEntityの基底のエンティティである場合はtrue
entity.is_propbooleanこのエンティティがPropEntityを支えるアーマースタンドである場合はtrue
entity.modelテーブルまたはnilis_modeled = trueの場合のみ設定される(下記参照)

entity.modelが存在する場合、以下が公開されます:

フィールド / メソッド備考
model.model_id設計図モデル名(例:"dragon"
model.is_dynamicDynamicEntityの場合はtrue(リビングエンティティに付属)
model:play_animation(name, blend, loop)名前付きアニメーションを再生します。成功時にtrueを返します
model:stop_animations()すべての現在のアニメーションを停止します
model:remove()モデル化されたエンティティとそのすべてのボーンを即座に削除します
on_attack_entity = function(context)
local target = context.event.target
if target and target.is_modeled then
target.model:play_animation("hurt", true, false)
end
end

EliteMobsエンティティフィールド

EliteMobsがインストールされている場合、FMMはEliteMobsのエンリッチャーに転送するため、同じエンティティテーブルが以下も公開します:

フィールド備考
entity.is_elitebooleanエンティティがEliteMobsによって追跡されている場合はtrue
entity.is_custom_bossbooleanカスタムボス設定の場合はtrue
entity.is_significant_bossbooleanhealthMultiplier > 1を持つカスタムボスの場合はtrue(雑魚の名前付きMobをフィルタアウト)
entity.eliteテーブルまたはnilis_elite = trueの場合のみ設定される。levelnamehealthmax_healthhealth_multiplierdamage_multiplieris_custom_boss、およびelite:remove()を含む

context.zones

zones APIはすべてのNightbreakプラグインで共有されています。完全なリファレンスについてはcontext.zonesを参照してください。


context.scheduler

scheduler APIはすべてのNightbreakプラグインで共有されています。完全なリファレンスについてはcontext.schedulerを参照してください。


context.state

state APIはすべてのNightbreakプラグインで共有されています。完全なリファレンスについてはcontext.stateを参照してください。


context.log

logging APIはすべてのNightbreakプラグインで共有されています。完全なリファレンスについてはcontext.logを参照してください。


ランタイムモデル

スクリプトインスタンスごとに1つのランタイム

スクリプトがアタッチされているすべてのプロップエンティティは、独自の独立したLuaランタイムインスタンスを取得します。プロップがスポーンすると、FMMはLuaソースをロードし、新鮮なサンドボックス化された環境で評価し、返されたテーブルを保存します。プロップが削除されると、ランタイムがシャットダウンされます。

アイテムスクリプトの場合、(プレイヤー、アイテムID)ペアごとに1つのランタイムが作成されます。プレイヤーがカスタムアイテムを装備すると、FMMはそのプレイヤーとアイテムタイプ用のスクリプトインスタンスを作成します。アイテムが装備解除されると、ランタイムはシャットダウンされます。

これは以下を意味します:

  • ファイルスコープで宣言されたローカル変数は、そのスクリプトインスタンスにプライベートです。
  • context.stateは、同じスクリプトファイルを共有していても、インスタンス間で完全に分離されています。

スケジュールされたタスクの所有権

context.schedulerを介して作成されたすべてのタスクは、それを作成したランタイムによって所有されます。プロップが削除されると:

  1. ランタイムがシャットダウンします。
  2. 所有されているすべてのタスク(ワンショットと繰り返しの両方)が自動的にキャンセルされます。
  3. すべてのゾーンウォッチがクリアされます。

クールダウンのスコーピング

共有スクリプティングエンジンはcontext.cooldowns:set_local:check_local:set_global:check_globalを公開しています(MagmaCoreクールダウンリファレンス参照)。FMMはこれらのストアを以下のようにスコープします:

スクリプト型ローカルストアスコープグローバルストアスコープ
プロップスクリプトScriptInstanceごと(プロップ + スクリプトファイル)PropEntityごと(そのプロップにバインドされたすべてのスクリプト間で共有)
アイテムスクリプト(player, itemId, scriptFile)トリプルごと — アイテムがアクティブスロットから外れるたびにスクリプトインスタンスが破棄されても、再装備を通じて永続化されるプレイヤーごと(そのプレイヤーが実行するすべてのFMMアイテムスクリプト間で共有)

アイテムスクリプトは装備/装備解除サイクルごとに破棄され再構築されるため、アイテムクールダウンはScriptInstanceに存続するのではなく、プレイヤーUUIDをキーとする静的マップに保持されます。これが、アイテムをホットバーから出し入れしてもアイテムクールダウンが引き続き適用される理由です。

実行予算

すべてのフック呼び出しとすべてのコールバック呼び出しが計測されます。1回の呼び出しが50ミリ秒を超える場合、スクリプトはコンソール警告と共に無効化されます:

[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.

予算内に収めるには:

  • フック内の無限ループを避けます。
  • on_game_tickハンドラを軽量に保ちます -- それらは毎ティックごとに実行されます。
  • ティックをまたいで作業を分散するにはcontext.scheduler:run_repeating(...)を使用します。

完全なフックリファレンス

このテーブルは、プロップとアイテムスクリプト両方で利用可能なすべてのフックをリストしています。

プロップフック(8個)

フック発火するときcontext.event
on_spawnプロップがワールドにスポーンするnil
on_game_tick毎サーバーティック(50ms)nil
on_destroyプロップが削除されるnil
on_left_clickプレイヤーがプロップを左クリックdamageイベント
on_right_clickプレイヤーがプロップを右クリックinteractionイベント
on_projectile_hit飛び道具がプロップに命中projectile hitイベント
on_zone_enterプレイヤーが監視中のゾーンに入るnil
on_zone_leaveプレイヤーが監視中のゾーンから出るnil

アイテムフック(22個)

フックカテゴリ発火するときcontext.event
on_attack_entity戦闘プレイヤーがエンティティを攻撃damageイベント
on_kill_entity戦闘プレイヤーがエンティティを倒すdeathイベント
on_take_damage戦闘プレイヤーがダメージを受けるdamageイベント
on_shield_block戦闘プレイヤーが盾でブロックdamageイベント
on_shoot_bow戦闘プレイヤーが弓を射るbow shootイベント
on_projectile_hit戦闘プレイヤーの飛び道具が命中projectile hitイベント
on_projectile_launch戦闘プレイヤーが飛び道具を発射launchイベント
on_right_clickインタラクションプレイヤーが右クリックinteractイベント
on_left_clickインタラクションプレイヤーが左クリックinteractイベント
on_shift_right_clickインタラクションプレイヤーがshift+右クリックinteractイベント
on_shift_left_clickインタラクションプレイヤーがshift+左クリックinteractイベント
on_interact_entityインタラクションプレイヤーがエンティティを右クリックentity interactイベント
on_equip装備アイテムがアクティブスロットに入るnil
on_unequip装備アイテムがアクティブスロットから外れるnil
on_swap_hands装備メイン/オフハンドをスワップswapイベント
on_drop装備プレイヤーがアイテムを落とすdropイベント
on_break_blockユーティリティプレイヤーがブロックを壊すblock breakイベント
on_consumeユーティリティプレイヤーがアイテムを消費consumeイベント
on_item_damageユーティリティアイテムが耐久度ダメージを受けるitem damageイベント
on_fishユーティリティプレイヤーが釣り竿を使用fishイベント
on_deathユーティリティ装備中にプレイヤーが死亡deathイベント
on_game_tickライフサイクル装備中の毎ティックnil

次のステップ