コンテンツ用エンチャント
EliteMobs と FreeMinecraftModels は、共通の MagmaCore システムを通じてカスタムエンチャントを提供します。各プラグインは自身の enchantments/ フォルダーで定義と Lua の効果を管理します。Minecraft のネイティブエンチャントは引き続き minecraft: 名前空間を使います。
同梱定義の更新
カタログは不足している同梱 YAML・Lua ファイルを復元し、既存の同梱定義に不足している既定フィールドを追加します。設定済みの値と既存の Lua ソースは維持します。enchantments/ ディレクトリがすでに存在する場合も機能します。
所有元のプラグインが、廃止された形式に一致するファイルを先にアーカイブすることがあります。たとえば EliteMobs は maxLevelV2 を含むエンチャント YAML を退避してから現在の既定値を生成します。EliteMobs は古い grappling_hook.lua など、過去に同梱されたエンチャントスクリプトの未編集コピーもアーカイブし、その場所に現在の既定ファイルを書き出します。編集したスクリプトは残ります。設定アーカイブで独自設定を確認し、現在のフィールドを使って再適用してください。更新された DLC や独自の効果には、それぞれ対応する定義と Lua ソースが必要です。
アイテムからの参照
カスタム効果には小文字の名前空間付き ID と正の整数レベルを使います。以下は FMM のアイテム定義です。
enchantments:
- "minecraft:unbreaking,3"
- "elitemobs:critical_strikes,2"
たとえば、EliteMobs のエンチャントカタログ内の critical_strikes.yml は elitemobs:critical_strikes を定義します。FMM の定義は freeminecraftmodels: を使います。サブフォルダーは ID に含まれません。コンテンツのファイル名は重複させないでください。
EliteMobs のカスタムアイテム YAML は、ネイティブエンチャントには UNBREAKING,3 のような Bukkit 名を引き続き使い、カスタム効果には名前空間付き ID を要求します。FMM のネイティブエンチャント記法を別のプラグインにコピーする際は、そのプラグインのアイテム形式を確認してください。
インストール済みの提供元が ID を認識する必要があります。互換性、アイテム種別、スロット、競合、必要な機能は定義から決まります。提供元を削除しても、カスタム効果がネイティブエンチャントに変わるわけではありません。
定義形式
以下は FMM に同梱される Ignition の定義です。同じエンチャントカタログ内の ignition.lua と組み合わせます。
isEnabled: true
name: Ignition
description: Sets surviving targets on fire after a staff fireball hits.
maxLevel: 3
curse: false
validSlots: [MAINHAND]
itemTypes: [STAFF]
attackKinds: [STAFF_FIREBALL]
requires: []
conflicts: []
stacking: source_item
script: ignition.lua
parameters:
base_ticks: 20
ticks_per_level: 20
return {
api_version = 1,
on_ignition_ticks = function(context)
return math.max(0, math.min(200, context.parameters.base_ticks
+ context.parameters.ticks_per_level * context.enchantment.level))
end
}
このクエリは発火時間を FMM に返します。プロップや装備アイテムのスクリプトとしては動作しません。
| フィールド | 意味 |
|---|---|
isEnabled | 既定値は true。無効な定義はカタログに登録されません |
name | 必須のプレーンな表示名 |
description | 任意の説明。既定では空 |
maxLevel | 正の付与レベル上限。明示的に作成したアイテムは超過可能 |
curse | 呪いかどうか。既定値は false |
validSlots | 装備スロット: HEAD, CHEST, LEGS, FEET, MAINHAND, OFFHAND |
itemTypes | 対応カテゴリ: SWORD, AXE, PICKAXE, SHOVEL, HOE, BOW, CROSSBOW, TRIDENT, MACE, SPEAR, HELMET, CHESTPLATE, LEGGINGS, BOOTS, SHIELD, FISHING_ROD, SHEARS, ELYTRA, WAND, STAFF, OTHER |
attackKinds | 任意の魔法攻撃フィルター: WAND_MISSILE, STAFF_MELEE, STAFF_FIREBALL |
requires | 提供元に要求する機能 |
conflicts | 競合するほかの小文字の名前空間付きエンチャント ID |
stacking | 既定値は source_item。または sum_equipped_levels |
script | ディレクトリを含まない小文字の .lua ファイル名。必須 |
parameters | 名前付きスカラー値、またはレベル別スカラー値リスト |
set | 任意。このエンチャントをアイテムセットにします |
レベル別リストには、ちょうど maxLevel 個の値が必要です。それより高いレベルでは最後の値を使いますが、スクリプトには実際のエンチャントレベルが渡されます。パラメーターは個々の効果に属します。任意のキーを追加しても新しい仕組みは生まれません。
不明なトップレベルフィールド、重複 ID、欠落したスクリプト、未対応のフックがあると、候補カタログは拒否されます。再読み込み前にエラーで指定されたファイルを修正してください。失敗した候補で使用中のカタログを置き換えることはありません。
効果の所有元
新しい定義を所有するプラグインに同梱された効果を出発点にしてください。対応フックとその領域の操作が、実現できる動作を決めます。クエリフックは弾数、クリティカル率、脅威ボーナスなどの値を返します。アクションフックは受理済みのアイテム入力を処理し、時間を伴う効果を管理できます。
旧 FMM の context.item API と装備・解除のライフサイクルはここには適用されません。エンチャントスクリプトは独自の context.enchantment、context.parameters、取得済みの発生元情報、アクション操作を使います。古いアイテムスクリプトの名前を変えるだけでコンテキストに互換性があると考えないでください。
本と金床
カスタムエンチャントの本は、装備アイテムと同じ提供元の定義を使います。金床は元アイテム、本、ネイティブエンチャントを含む完成品全体を検証します。同じカスタムレベル同士は次のレベルに、異なるレベル同士は高い方になります。変更された各カスタムエンチャントは、その完成レベルをネイティブの修繕コストに加算します。結果のレベルは、定義の金床レベル上限、スロット、種別、機能、競合の検査を通る必要があります。
混在した本では、サーバーが受け入れるすべてのネイティブエンチャントとカスタムエンチャントを移す必要があります。ネイティブエンチャントが拒否された場合、その部分を黙って捨てるのではなくカスタム処理全体を拒否します。無効または利用できない定義もプレビューを拒否します。取り出し時に入力と提供元の状態を再検査します。表示されたプレビューは、カタログ変更後も有効な予約ではありません。
Lua クエリリファレンス
数値クエリは毎回新しいスクリプトインスタンスで実行され、結果の取得直後に閉じます。有限数を 1 つ、寄与しない場合は nil を返してください。状態や予約処理はクエリ後に残りません。失敗した定義はカタログの再読み込みが成功するまで隔離されます。呼び出し元の残り予算を使い切ること自体は隔離の理由になりません。
| コンテキスト | 内容 |
|---|---|
context.enchantment | id と実際の level |
context.parameters | そのレベルに解決された定義の値 |
context.input | 担当する仕組みが渡すスカラー情報。正確なキーは同梱効果を参照 |
context.target | 対象の Entity または Living Entity テーブル。対象なしなら nil |
context.player | クエリにプレイヤーがいる場合、その実行者 |
FMM は on_missile_count、on_missile_damage_factor、on_blast_radius_factor、on_ignition_ticks を提供します。ほかの提供元はそれぞれ独自の数値フックを公開します。定義が宣言できるのは、その提供元が受け付けるフックのみです。
Lua アクションリファレンス
アクションスクリプトは共通のスケジューラー、クールダウン、ワールド、ゾーン、プレイヤー、イベントのテーブルを使います。受理された 1 回の入力または攻撃に対して実行され、後続のコールバックでは取得済みの発生元情報を使います。チャットはチャットイベント中にメッセージを保存し、サーバースレッドで処理を振り分ける際に装備を取得します。任意の parameters.lifetime_ticks は正の整数でなければなりません。省略時の実行寿命は 1 ティックです。予約効果には、完了まで十分な寿命を設定してください。
実行は寿命の終了、実行者の死亡・切断・ワールド移動、所有ワールドのアンロード、管理対象エンティティがいるチャンクのアンロード、提供元の再読み込み・無効化で停止します。最後の入力に属する管理対象処理がなくなれば早期終了できます。parameters.stop_on_unequip: true を設定すると、取得済みのアイテムが装備されなくなった場合にも停止します。ローカルクールダウンはプレイヤーとエンチャント ID、グローバルクールダウンは提供元内のプレイヤーに属します。どちらも装備変更、実行完了、ワールド変更、正常な再読み込みを越えて維持され、切断または提供元の停止で消去されます。
| フック | 受理する入力 |
|---|---|
on_attack_entity | メインハンドのアイテムによる、成功した正のネイティブ近接ダメージ。またはプラグインが明示的に管理する攻撃 |
on_projectile_hit | 取得済みの弓の弾による、生存エンティティへの成功したダメージ。弾と対象の組み合わせごとに 1 回。またはプラグインが明示的に管理する着弾 |
on_take_damage | プレイヤーへの正のダメージ。対象となる装備スロットを検査 |
on_right_click, on_left_click | スニークしていない状態での手の操作 |
on_shift_right_click, on_shift_left_click | スニーク中の手の操作。対応する通常クリックフックを置き換える |
on_break_block | メインハンドのアイテムを使った、受理済みのプレイヤーのブロック破壊 |
on_chat | 受理済みのチャット。保存したメッセージとともにサーバースレッドで実行 |
on_sneak | スニーク開始。装備からの寄与を定義ごとに収集 |
on_projectile_launch | 消費されたエンチャント付き弾薬が弓イベントから矢として発射されるとき |
on_game_tick | この実行が有効な間のティック |
on_zone_enter, on_zone_leave | この実行が監視するゾーンをプレイヤーが出入りするとき |
これらのフックは装備・解除スクリプトの実行基盤を作りません。ティックのみを処理する定義にも、実行を開始する入力フックが必要です。ネイティブ攻撃、被ダメージ、チャット、採掘フックは受理済みの入力を観測するため、元イベントをキャンセルできません。4 種の操作フックには同期的なキャンセルフラグがあります。context.event:cancel() は対応するアイテムとブロックの操作を拒否します。予約コールバックから過去の入力をキャンセルすることはできません。
| コンテキスト | 内容 |
|---|---|
context.enchantment | id, level |
context.parameters | レベルに応じて解決された定義パラメーター |
context.player | 現在の実行者の Player Table |
context.target | 現在影響を受ける Living Entity Table、または nil |
context.source | 取得済み情報: item, slot, inventory_slot, equipment, attack_kind, providers。入力によっては ammunition, projectile, message, block, drop_items, sneaking, equipped_levels も含む |
context.item | インベントリアイテムを引き続き参照できる場合の、取得済みスロットの耐久値・消費メソッド。アイテムメソッドを参照 |
context.action | id(攻撃 UUID)、instance(実行トークン)、actor(UUID)、world(ワールド UUID)、および以下のメソッド |
context.set | アイテムセットの場合は id, name, level, pieces。それ以外は nil |
アイテムのスナップショットには material、amount、enchantments が含まれます。これはデータであり、生きたインベントリオブジェクトではありません。発生元情報の UUID は文字列です。採掘の source.block には x、y、z と小文字の material が含まれます。
| アクションメソッド | 戻り値 | 動作 |
|---|---|---|
stop() | nil | この実行を止め、管理対象の処理を片付ける |
has_previous() | bool | 同じプレイヤーの同じエンチャントに、ほかの有効な実行があるか確認 |
replace_previous() | nil | この実行を維持し、以前の実行を停止 |
damage_target(target_uuid, amount) | bool | 取得済みの発生元に帰属する正の有限ダメージを提供元に要求。拒否時は false |
own_entity(uuid) | bool | 同じワールドの有効な非プレイヤーエンティティを、終了時の削除対象として登録。スポーン後に使用 |
launch_projectile(location, direction, speed, range, ticks, impact, visual?, protected_path?=false) | bool | 管理対象のスクリプト弾を発射。速度と射程は正の有限数、ticks は 1 以上 |
attribute_projectile(uuid, callback, protect?=false) | bool | 管理対象のネイティブ弾のダメージを独自コールバックに結び付ける |
place_block(x, y, z, expected_material, block_data) | bool | 現在の素材が一致する場合のみ、プレイヤーのブロック操作検証を通して設置 |
break_block(x, y, z, expected_material, drop_material?, amount?=1) | bool | プレイヤーのブロック操作検証を通して破壊。独自のアイテムドロップを指定可能 |
break_naturally(x, y, z, expected_material) | bool | 取得済みの道具と元の破壊イベントのドロップ方針を使って破壊 |
temporary_block(x, y, z, block_data, ticks?=0) | bool | 読み込み済みブロックを一時管理し、終了時または正の ticks 後に復元。ゼロなら終了まで |
can_own_block(x, y, z) | bool | 座標が読み込み済みか、一時管理できるかを確認 |
temporary_gravity(uuid, enabled) | bool | 重力状態を一時管理し、終了時に復元 |
restore_gravity(uuid) | bool | この実行が一時管理する重力を早期復元 |
temporary_scale(uuid, scale) | bool | 生存エンティティのサイズを終了まで一時管理 |
temporary_potion(uuid, type, ticks, amplifier) | bool | 正の ticks と 0 以上の amplifier でポーション効果を一時管理 |
restore_potion(uuid, type) | bool | この実行が一時管理するポーション効果を早期復元 |
ride_rails(speed) | bool | クライアントにだけ見えるトロッコにプレイヤーを座らせ、プレイヤーのいるブロックでつながっているレールに沿って、向いている側の端へ向けて speed ブロック/ティック(0 より大きく 2 以下)で走らせる。そこにレールがない、プレイヤーがすでに乗っている、またはサーバーの NMS アダプターが利用できない場合は false |
レールの乗車は、その実行が管理する処理です。スニーク、線路の終端、テレポート、死亡、退出、そのほかプレイヤーをトロッコから 1 ブロックを超えて移動させる出来事があると、乗車が終了し、続いて実行も終了します。テレポート、死亡、退出の場合を除き、プレイヤーはトロッコが止まった場所に降ろされます。replace_previous() によるものを含め、実行を停止した場合も、プレイヤーは降ろされます。実行の lifetime_ticks は引き続き適用されるため、最も長い線路に十分な時間を設定してください。
弾の着弾コールバックは (fresh_context, target_or_nil, location)、表示コールバックは (fresh_context, location) を受け取ります。ネイティブ弾のダメージコールバックは次のティックで (fresh_context, target, native_damage) を受け取ります。通常のダメージ適用を置き換えるため、意図したダメージを明示的に適用する必要があります。通常は fresh_context.action:damage_target(target.uuid, amount) を使います。ネイティブ弾で protect=true にすると、保護対象の爆発ブロックと発火が除外されます。スクリプト弾の protected_path=true は、保護済みまたは未読み込みの位置を通る弾を消去します。
終了時の片付けは、管理対象として登録する操作に限られます。通常の world:spawn_entity、entity:set_gravity、world:set_block_at は自動でアクションの片付け対象にはなりません。一時状態メソッドは復元を管理するものであり、敵対的な効果やブロック編集が許可されているかの確認を代替しません。
アイテムセット
set セクションを追加すると、エンチャントがアイテムセットになります。すべてのパーツに同じエンチャントを付けてください。pieces に列挙した各スロットが、そのエンチャントを持つアイテムを保持している間、セットは完成しています。完成したセットは、イベントごとに 1 回だけフックを実行します。パーツが 1 つでも欠けていると、何も実行されません。
name: Crooked's Full Set
maxLevel: 1
validSlots: [HEAD, CHEST, LEGS, FEET]
itemTypes: [HELMET, CHESTPLATE, LEGGINGS, BOOTS]
script: crooked_set.lua
parameters:
lifetime_ticks: 620
stop_on_unequip: true
set:
pieces:
HEAD: Crooked's Hex-Brim
CHEST: Crooked's Warded Wrap
LEGS: Crooked's Bent Hosen
FEET: Crooked's Wayward Soles
lore:
- "&5Crooked's Full Set &7($equippedPieces/$totalPieces)"
- "$setPieces"
- "&7When damaged, has a 5% chance to grant Regeneration I."
return {
api_version = 1,
on_take_damage = function(context)
-- Runs only while all four pieces are worn, once per hit.
context.action:temporary_potion(context.player.uuid, "REGENERATION", 100, 0)
end
}
| セットのフィールド | 意味 |
|---|---|
pieces | 必須。装備スロットとパーツ名の対応。validSlots を設定する場合は、すべてのパーツのスロットを含める必要があります |
name | $setName で使われる名前。デフォルトはエンチャントの name で、& のカラーコードが使えます |
lore | セットのロア行。デフォルトは、セット名とパーツ数に続けて、パーツごとに 1 行 |
equippedPiece | 装備しているパーツの行。デフォルトは &a✔ $pieceName |
missingPiece | 欠けているパーツの行。デフォルトは &c✘ $pieceName |
セットのロアでは、次のプレースホルダーが使えます。
| プレースホルダー | 表示される内容 |
|---|---|
$setName | セット名 |
$equippedPieces | プレイヤーが装備しているパーツの数 |
$totalPieces | セットに含まれるパーツの数 |
$setPieces | スロット順にパーツごとに 1 行。equippedPiece または missingPiece の内容。プレースホルダーの前後のテキストは各行で繰り返されます |
$pieceName, $pieceSlot | equippedPiece と missingPiece の中で、パーツ名とそのスロット(Head や Main Hand など) |
$ifSetComplete | すべてのパーツを装備している間だけ、その行を表示 |
$ifSetIncomplete | パーツが欠けている間だけ、その行を表示 |
セットのアイテムでは、カスタムエンチャント一覧の 1 行の代わりに、このセクションが表示されます。EliteMobs では、ItemSettings.yml の itemLoreStructureV2 に、またはカスタムアイテム自身の lore に $itemSet を入れてください。どちらにもない場合、セットはアイテムのカスタムロアの後に続きます。$ifItemSet は、セットのアイテムにだけ構造の行を表示します。FMM のカスタムアイテムでは、$itemSet を含むロア行か、ロアの後にセットが表示されます。
このセクションには、アイテムを持っているプレイヤーが装備している内容が表示され、パーツを装備したり外したりすると再描画されます。プレイヤーのインベントリの外に保管されたアイテムは、離れたときに表示していた状態のままになります。
セットのフックは、通常のエンチャントのフックと次の点で異なります。
- 上の表にあるすべてのアクションフックは、パーツがどのスロットを使っていても、完成したセットに届きます。防具のセットが
on_attack_entityやon_break_blockに応答することもできます。 - 完成しているかどうかは、イベントが起きた時点で確認されます。弾は着弾したときに装備しているセットを確認し、弓の矢だけでなく、どの弾でも対象になります。
on_take_damageは、攻撃者がいる場合にcontext.targetへ攻撃者を設定します。context.source.itemとcontext.itemは、スロット順(HEAD、CHEST、LEGS、FEET、MAINHAND、OFFHAND)で最初のパーツです。手に持っている武器や道具は、context.source.equipment.MAINHANDから読み取ってください。context.set.levelは、パーツのうち最も低いレベルです。context.set.piecesはスロットをキーとし、各パーツのnameとinventory_slotを持ちます。stop_on_unequip: trueを設定すると、パーツが 1 つでも外れたときにセットの実行が停止します。- EliteMobs の脅威やクリティカル率、FMM のキャスト修正などの数値クエリは、セットを 1 回だけ、完成している間だけ数えます。
既存コンテンツの更新
FMM は空でない scripts: や廃止済みの名前空間なしエンチャント記述を含むカスタムアイテムをスキップします。これらのアイテム定義を名前空間付きエンチャントへ置き換えてください。プロップのスクリプトは引き続き利用できます。
EliteMobs のカスタム効果は、提供元 YAML で maxLevel と効果固有の parameters を使うようになりました。ネイティブおよびエリートレベルのエンチャント設定は別形式です。古い maxLevelV2 ファイルを提供元の定義にコピーせず、EliteMobs エンチャントリファレンスに従ってください。