Luaスクリプティング:ゾーンとターゲティング
EliteMobsのLua機能は、空間領域の定義とターゲット解決のために2つの補完的なアプローチを提供します:
- ネイティブゾーン (
context.zones) -- シンプルで直接的。ゾーン定義を通常のLuaテーブルとして構築し、エンティティや位置を問い合わせます。単純な「このエリアに何かいるか?」チェックに最適です。 - スクリプトユーティリティ (
context.script) -- より豊富なターゲティング、watch/contains/entitiesメソッドを持つゾーンハンドル、パーティクル生成、ダメージ、プッシュアクション。EliteScriptゾーンやEliteScriptターゲットと同じフィールド名を使用し、馴染みやすくしています。
両方のアプローチはネイティブLua APIです。パワーの複雑さに合ったものを選択してください。
ネイティブゾーン:context.zones
ネイティブゾーンでは、ゾーンを通常のLuaテーブルとして定義し、直接問い合わせることができます。ハンドルなし、余分な抽象化なし -- 形状を記述するテーブルとそれを問い合わせるメソッド呼び出しだけです。
メソッド
| メソッド | 備考 |
|---|---|
zones:get_entities_in_zone(zoneDef, options) | ゾーン内のエンティティラッパーの配列を返す |
zones:get_locations_in_zone(zoneDef, options) | ゾーン内の位置テーブルの配列を返す |
zones:zone_contains(zoneDef, location[, "full"|"border"]) | 位置がゾーン内にある場合にtrueを返す |
zones:watch_zone(zoneDef, callbacks, options) | ティックごとに発火する永続的なゾーンウォッチャーを登録する |
ゾーン定義フィールド
| フィールド | 型 | 備考 |
|---|---|---|
kind | string | "sphere", "dome", "cylinder", "cuboid", "cone", "static_ray", "rotating_ray", "translating_ray" |
radius | number | ゾーン半径(sphere、dome、cylinder、cone) |
height | number | シリンダーの高さ |
origin | location | 中心位置(省略時はボスの位置がデフォルト) |
destination | location | レイとコーンの終点 |
x, y, z | number | 直方体の半分の範囲 |
length | number | コーンとレイの長さ |
thickness / point_radius | number | レイの太さ |
border_radius | number | ボーダー幅(デフォルト1) |
x_border, y_border, z_border | number | 直方体のボーダー幅(デフォルト1) |
animation_duration | int | アニメーションレイのアニメーション長(ティック単位) |
pitch_pre_rotation, yaw_pre_rotation | number | 事前回転角度(回転レイ) |
pitch_rotation, yaw_rotation | number | ティックごとの回転角度(回転レイ) |
origin_end, destination_end | location | 移動レイの終了位置 |
ignores_solid_blocks | boolean | レイが固体ブロックを通過するかどうか(デフォルトtrue) |
クエリオプション
| キー | 備考 |
|---|---|
filter | "player" / "players", "elite" / "elites", "mob" / "mobs", "living"(デフォルト) |
mode | "full"(デフォルト)または"border" |
coverage | 0.0から1.0 -- サンプリングする位置の割合(デフォルト1.0) |
ウォッチコールバック
| キー | 備考 |
|---|---|
on_enter | function(entity) -- エンティティがゾーンに入った時に呼び出される |
on_leave | function(entity) -- エンティティがゾーンから出た時に呼び出される |
例:基本的な球体クエリ
例
return {
api_version = 1,
on_spawn = function(context)
-- Store a zone definition for reuse
context.state.danger_zone = {
kind = "sphere",
origin = context.boss:get_location(),
radius = 10
}
end,
on_boss_damaged_by_player = function(context)
-- Update the origin to the boss's current position
context.state.danger_zone.origin = context.boss:get_location()
local players = context.zones:get_entities_in_zone(
context.state.danger_zone,
{ filter = "players" }
)
for _, player in ipairs(players) do
player:send_message("&cYou are in the danger zone!")
end
end
}
例:入退場によるゾーン監視
例
return {
api_version = 1,
on_spawn = function(context)
context.zones:watch_zone(
{
kind = "sphere",
origin = context.boss:get_location(),
radius = 8
},
{
on_enter = function(entity)
entity:apply_potion_effect("SLOWNESS", 40, 1)
entity:send_message("&7You feel sluggish near the boss...")
end,
on_leave = function(entity)
entity:send_message("&aYou escape the slowing aura.")
end
},
{ filter = "players", mode = "full" }
)
end
}
ウォッチャーに関する注意:
- ウォッチャーコールバックは
context.event経由ではなく、単一のエンティティラッパーを直接受け取る - ウォッチャーはボスが削除されると自動的にクリーンアップされる
- 各ウォッチャーは毎ティック実行されるため、コールバックロジックは軽量に保つこと
- ボスエンティティ自体はゾーンクエリから除外される
スクリプトユーティリティ:context.script
スクリプトユーティリティは、ターゲット解決、ゾーンハンドル、相対ベクトル、パーティクル生成、戦闘アクションを提供します。EliteScriptゾーンやEliteScriptターゲットと同じフィールド名を使用し、馴染みやすくしています -- enum名("NEARBY_PLAYERS"、"SPHERE"、"ZONE_FULL"など)は同一であり、すでにEliteScriptに慣れている作者がその知識を直接転用できるようになっています。
context.scriptはネイティブLua APIです。YAMLやEliteScriptランタイムへのブリッジではありません。同じ命名規則を再利用しているだけなので、2番目のenum名セットを学ぶ必要はありません。
メソッド
| メソッド | 備考 |
|---|---|
script:target(spec) | ターゲット仕様テーブルからターゲットハンドルを作成する |
script:zone(spec) | ゾーン仕様テーブルからゾーンハンドルを作成する |
script:relative_vector(spec[, actionLocation][, zoneHandle]) | 相対ベクトルハンドルを作成する |
script:damage(targetHandle, amount[, multiplier]) | 解決されたターゲットにダメージを与える |
script:push(targetHandle, vectorOrHandle[, additive]) | 解決されたターゲットを押す |
script:set_facing(targetHandle, vectorOrHandle) | ターゲットの向きを設定する |
script:spawn_particles(targetHandle, particleSpec) | 解決されたターゲット位置にパーティクルを生成する |
ターゲットハンドルメソッド
| メソッド | 備考 |
|---|---|
handle:entities() | エンティティラッパーの配列を返す |
handle:locations() | 位置テーブルの配列を返す |
handle:first_entity() | 最初のエンティティまたはnilを返す |
handle:first_location() | 最初の位置またはnilを返す |
ターゲット仕様キー
| キー | 備考 |
|---|---|
targetType | "SELF", "DIRECT_TARGET", "NEARBY_PLAYERS", "NEARBY_MOBS", "NEARBY_ELITES", "ZONE_FULL", "ZONE_BORDER", "ALL_PLAYERS", "WORLD_PLAYERS", "SELF_SPAWN", "LOCATION" |
range | 近接型ターゲットの範囲 |
coverage | ゾーンターゲットの場合0.0から1.0 |
offset | "x,y,z"文字列または{ x = n, y = n, z = n }テーブル |
track | 移動するターゲットを再解決するかどうか |
例:ターゲットの作成と使用
例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.cooldowns:check_local("roar", 200) then return end
-- Find all players within 20 blocks
local nearby = context.script:target({
targetType = "NEARBY_PLAYERS",
range = 20
})
for _, player in ipairs(nearby:entities()) do
player:send_message("&eThe boss roars in fury!")
end
-- Single-entity access
local closest = nearby:first_entity()
if closest then
closest:show_title("&cRUN!", "&7The boss is targeting you")
end
end
}
ゾーンハンドルメソッド
| メソッド | 備考 |
|---|---|
handle:full_target([coverage]) | ゾーンボリューム全体のターゲットハンドルを返す |
handle:border_target([coverage]) | ゾーンボーダーのターゲットハンドルを返す |
handle:full_locations([coverage]) | ゾーンボリューム全体の位置を返す |
handle:border_locations([coverage]) | ゾーンボーダーの位置を返す |
handle:full_entities() | ゾーンボリューム全体のエンティティを返す |
handle:border_entities() | ゾーンボーダーのエンティティを返す |
handle:contains(location[, "full"|"border"]) | 位置がゾーン内にある場合にtrueを返す |
handle:watch(callbacks[, mode]) | 入退場イベントのためにゾーンを監視し、タスクIDを返す |
ゾーン仕様キー
| キー | 備考 |
|---|---|
shape | "SPHERE", "DOME", "CYLINDER", "CUBOID", "CONE", "STATIC_RAY", "ROTATING_RAY", "TRANSLATING_RAY" |
radius | ゾーン半径 |
height | シリンダーの高さ |
x, y, z | 直方体の半分の範囲 |
borderRadius | ボーダー幅 |
pointRadius | レイの太さ |
animationDuration | アニメーションレイのアニメーション長(ティック単位) |
Target | 中心ターゲット仕様(テーブル) -- 同じターゲット仕様フォーマットを使用 |
Target2 | レイとコーンの第2ポイント |
filter | エンティティフィルター |
ignoresSolidBlocks | boolean |
pitchPreRotation, yawPreRotation | 事前回転角度 |
pitchRotation, yawRotation | ティックごとの回転角度 |
例:ダメージとパーティクル付きゾーン
例
return {
api_version = 1,
on_enter_combat = function(context)
-- Create a sphere zone centered on the boss
local zone = context.script:zone({
shape = "SPHERE",
radius = 6,
Target = { targetType = "SELF" }
})
-- Spawn warning particles on the zone border
context.script:spawn_particles(
zone:border_target(0.3),
{ particle = "FLAME", amount = 1, speed = 0.02 }
)
-- Damage all players inside the zone
local targets = zone:full_target()
context.script:damage(targets, 5.0)
-- Repeat every 20 ticks
context.scheduler:run_every(20, function(ctx)
local z = ctx.script:zone({
shape = "SPHERE",
radius = 6,
Target = { targetType = "SELF" }
})
ctx.script:spawn_particles(
z:border_target(0.3),
{ particle = "FLAME", amount = 1, speed = 0.02 }
)
ctx.script:damage(z:full_target(), 5.0)
end)
end
}
相対ベクトル仕様キー
| キー | 備考 |
|---|---|
SourceTarget | ソースターゲット仕様(テーブル) |
DestinationTarget | デスティネーションターゲット仕様(テーブル) |
normalize | boolean -- 結果のベクトルを正規化するかどうか |
multiplier | 正規化後に適用されるスケール係数 |
offset | "x,y,z"文字列または{ x = n, y = n, z = n }テーブル |
相対ベクトルハンドルメソッド
| メソッド | 備考 |
|---|---|
handle:resolve() | 計算されたベクトルテーブルを返す |
例:相対ベクトルでターゲットを押す
例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.cooldowns:check_local("knockback", 100) then return end
-- Build a vector from the boss toward the attacker
local vec = context.script:relative_vector({
SourceTarget = { targetType = "SELF" },
DestinationTarget = { targetType = "DIRECT_TARGET" },
normalize = true,
multiplier = 2.5
})
-- Push the attacker away
local target = context.script:target({
targetType = "DIRECT_TARGET"
})
context.script:push(target, vec)
end
}
パーティクル仕様フォーマット
パーティクル仕様は文字列、単一のテーブル、またはテーブルの配列で指定できます:
| キー | 備考 |
|---|---|
particle | パーティクル名(例:"FLAME"、"DUST"、"SMOKE") |
amount | パーティクルの数 |
x, y, z | オフセット/拡散値 |
speed | パーティクル速度 |
red, green, blue | DUST / DUST_COLOR_TRANSITIONの色(0-255) |
toRed, toGreen, toBlue | DUST_COLOR_TRANSITIONのトランジション先の色 |
パーティクル名の完全なリストはEnumリファレンスを参照してください。
重要な注意事項
- スクリプトユーティリティのハンドルは、作成されたイベントコンテキストに紐づけられています。後のフック呼び出しで使用するために
context.stateに保存しないでください。 - ゾーンの
watch()はcontext.scheduler:cancel_task()でキャンセルできるタスクIDを返します。 - カバレッジ値は位置ベースの解決にのみ適用され、エンティティクエリには適用されません。
- すべての文字列値はEliteScript YAMLと同じUPPER_SNAKE_CASEのenum名を使用します(例:
"SELF"、"NEARBY_PLAYERS"、"SPHERE")。
emヘルパー名前空間
em名前空間はすべてのLuaパワーファイルでグローバルに利用可能です。位置、ベクトル、ゾーン定義の便利なコンストラクタを提供します。
位置とベクトルのコンストラクタ
| 関数 | 備考 |
|---|---|
em.create_location(x, y, z[, world][, yaw][, pitch]) | add(dx, dy, dz)メソッドを持つ位置テーブルを返す |
em.create_vector(x, y, z) | ベクトルテーブルを返す |
ゾーンビルダーヘルパー
em.zoneサブテーブルは、context.zonesと互換性のあるゾーン定義テーブルを返すビルダー関数を提供します。各ビルダーはチェーン可能なミューテーターメソッドを持つテーブルを返します。
| 関数 | パラメータ | ミューテーター |
|---|---|---|
em.zone.create_sphere_zone(radius) | radius | :set_center(location) |
em.zone.create_dome_zone(radius) | radius | :set_center(location) |
em.zone.create_cylinder_zone(radius, height) | radius, height | :set_center(location) |
em.zone.create_cuboid_zone(x, y, z) | x, y, z(半分の範囲) | :set_center(location) |
em.zone.create_cone_zone(length, radius) | length, radius | :set_origin(location), :set_destination(location) |
em.zone.create_static_ray_zone(length, thickness) | length, thickness | :set_origin(location), :set_destination(location) |
em.zone.create_rotating_ray_zone(length, point_radius, animation_duration) | length, point_radius, animation_duration | :set_origin(location), :set_destination(location) |
em.zone.create_translating_ray_zone(length, point_radius, animation_duration) | length, point_radius, animation_duration | :set_origin(location), :set_destination(location) |
例
例
return {
api_version = 1,
on_spawn = function(context)
-- Create a location offset from the boss
local boss_loc = context.boss:get_location()
local above = em.create_location(boss_loc.x, boss_loc.y + 5, boss_loc.z)
-- Create a sphere zone using the builder
local zone = em.zone.create_sphere_zone(10):set_center(boss_loc)
-- Use with native zone queries
local players = context.zones:get_entities_in_zone(zone, { filter = "players" })
for _, p in ipairs(players) do
p:send_message("&cYou are within the boss's aura!")
end
-- Create a directional vector
local push_vec = em.create_vector(0, 1.5, 0)
context.boss:set_velocity_vector(push_vec)
end
}
em名前空間はインスタンスごとではありません -- すべてのLuaパワーインスタンスが同じemヘルパー関数を共有します。関数は純粋なコンストラクタであり、状態を保持しません。
ネイティブゾーン vs. スクリプトユーティリティ
両方のシステムは同じ基盤となるゾーンジオメトリで動作します。それぞれの使い分けは以下の通りです:
| ユースケース | 推奨アプローチ |
|---|---|
| 単純な「このエリアに何かいるか?」チェック | ネイティブゾーン(context.zones) |
| 形状を使った素早いエンティティクエリ | ネイティブゾーン |
カバレッジ付きのNEARBY_PLAYERS、ZONE_FULL | スクリプトユーティリティ(context.script) |
| アニメーションゾーン(回転/移動レイ) | どちらでも -- ネイティブゾーンもこれらの形状をサポート |
watch/contains/entitiesメソッド付きゾーンハンドル | スクリプトユーティリティ |
| ゾーン位置でのパーティクル生成 | スクリプトユーティリティ(spawn_particles) |
| ターゲティングに連動したダメージとプッシュアクション | スクリプトユーティリティ(damage、push) |
| 方向性エフェクト用の相対ベクトル | スクリプトユーティリティ(relative_vector) |
| Lua制御フローと豊富なターゲティングの組み合わせ | スクリプトユーティリティ |
実際には、多くのパワーは両方を使用します。ネイティブゾーンはクールダウンガード内の最初の「プレイヤーが近くにいるか?」チェックに最適で、スクリプトユーティリティはその後の複雑な攻撃ロジックを処理します。
次のステップ
- 例とパターン -- 学習・応用できる完全な動作パワー
- APIリファレンス --
context.*メソッドの完全なリファレンス - Enumリファレンス -- Particle、Sound、Material、その他の文字列定数の有効な値
