跳至主要內容

Lua 腳本:世界與環境

webapp_banner.jpg

本頁介紹 EliteMobs Boss 對 context.world 的擴充,以及 context.vectors、context.settings 和 context.event。Lua 能力可以用它們生成實體、播放效果、查詢方塊及變更世界狀態。如果你是 Lua 能力新手,請先閱讀入門指南。

EliteMobs Boss 上下文

EliteMobs 的 Boss 能力沿用 MagmaCore 的 Lua 沙箱。Boss 的 context.world 是從共用的 MagmaCore world 表衍生而來,因此像 get_block_at(...)、set_block_at(...) 與 spawn_particle(...) 這類通用的座標輔助函式仍然可用。本頁著重於 EliteMobs Boss 專屬的 context.world、context.vectors、context.settings 與 context.event 新增項目與覆寫。關於通用的 world API,請參閱 MagmaCore Lua 腳本引擎。

兩邊存在同名方法時,以 EliteMobs 版本為準。下列方法保留 EliteMobs 的行為,包括閃電生成保護繞過、較豐富的粒子規格和暫時方塊追蹤。其他共用方法仍可使用,包括 get_entity(uuid)、block_is_passable(x, y, z)、location_is_protected(location)、spawn_dust(...) 和 raycast(...)。參數及未載入區塊的處理方式見共用 API 參考;這些保證不會自動套用至 EliteMobs 的覆寫版本。

此處無法使用 FreeMinecraftModels 的戰利品方法

FreeMinecraftModels 只會在它自己的道具腳本中,將 drop_elitemobs_procedural_loot、drop_elitemobs_random_loot、drop_elitemobs_custom_loot 與 start_elitemobs_transport 加入 context.world。每個外掛都各自攜帶一份共用腳本函式庫,因此即使安裝了 FreeMinecraftModels,這些方法也不會出現在 EliteMobs 的 Boss 能力或 NPC 腳本中。Boss 能力請改用 generate_player_loot 與 drop_bonus_coins。


context.world​

world 表提供生成實體、播放效果、修改方塊及變更世界狀態的方法。它們支援冒號語法 world:method(),也支援不額外傳入 self 引數的點語法。

下列 Boss 覆寫方法透過 x、y、z、選用的 yaw/pitch 及 world 中已載入的世界名稱轉換位置表。缺少的座標為 0;省略世界時使用 Boss 目前的世界,明確指定未知世界則轉換失敗。也接受巢狀的 current_location 表。nil 或非表位置預設使用 Boss 位置。共用方法仍有各自的位置規則,並使用共用表建立時儲存的世界。

Lua 實例關閉時,世界變更及已生成實體不會自動還原。腳本管理的監看任務會停止,但獨立的實體移除計時器、爆炸再生、強化閃電及金粒投射物任務有各自的生命週期。方塊與生成覆寫方法不會自動檢查 location_is_protected,也不會自動採用共用方法的未載入區塊保護;變更世界前請自行檢查相關限制。


world:spawn_particle_at_location(location, particleSpec)​

在指定位置生成粒子。第二個引數可以是粒子名稱字串或規格表。選用的第三個整數引數提供未設定 amount 時的數量,預設為 1。查詢前會將名稱轉成大寫。無效名稱或不支援的粒子資料會產生警告,且不生成粒子。

參數類型說明
locationlocation 表要在哪裡生成粒子
particleSpecstring 或 table粒子名稱,或一個粒子規格表(見下方)
範例
return {
api_version = 1,
on_enter_combat = function(context)
-- Simple particle by name
context.world:spawn_particle_at_location(context.boss:get_location(), "FLAME")

-- Full particle spec table with red dust
context.world:spawn_particle_at_location(context.boss:get_location(), {
particle = "DUST",
amount = 10,
x = 0.5,
y = 0.5,
z = 0.5,
speed = 0.02,
red = 255,
green = 0,
blue = 0,
})
end
}

粒子規格表格式​

欄位類型預設值說明
particlestring必填粒子名稱
amountint1粒子數量
x、y、znumber0各軸上的散布/偏移量
speednumber0粒子速度
red、green、blueint255用於 DUST 與 DUST_COLOR_TRANSITION 的 RGB 顏色
toRed、toGreen、toBlueint255DUST_COLOR_TRANSITION 的漸變目標顏色
提示

DUST_COLOR_TRANSITION 也接受 to_red、to_green、to_blue,但駝峰形式的值優先。兩種粉塵粒子的大小固定為 1,RGB 分量必須介於 0..255。其他粒子不會收到額外資料,因此此方法無法支援所有需要附加資料的粒子。

注意

與 EliteScript 的 YAML 設定不同,Lua 的粒子名稱不支援舊式粒子名稱轉換。你必須使用目前的 Spigot API 名稱(例如 FIREWORK 而非 FIREWORKS_SPARK、SMOKE 而非 SMOKE_NORMAL、DUST 而非 REDSTONE)。完整的現行名稱清單及其舊式對應,請參閱有效粒子清單。


world:play_sound_at_location(location, sound, volume, pitch)​

在某個位置播放音效。

參數類型預設值說明
locationlocation 表要在哪裡播放音效
soundstringMinecraft 音效鍵(例如 "entity.blaze.shoot"),或 Spigot 的 Sound 列舉名稱。資源包的鍵也適用。
volumenumber1.0音量
pitchnumber1.0音高
範例
return {
api_version = 1,
on_spawn = function(context)
context.world:play_sound_at_location(
context.boss:get_location(),
"entity.wither.spawn",
1.0,
0.5
)
end
}

world:strike_lightning_at_location(location)​

生成會造成傷害的真實閃電,並啟用 EliteMobs 的閃電生成保護繞過。它不同於共用 API 中純視覺的閃電方法,也不保證繞過其他插件的所有傷害與保護規則。

參數類型說明
locationlocation 表要在哪裡降下閃電
範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("lightning", 100) then return end
context.world:strike_lightning_at_location(context.player:get_location())
context.player:send_message("&eA bolt of lightning strikes you!")
end
}

world:spawn_entity_at_location(entityType, location, options)​

直接在指定位置的世界生成原版 Minecraft 實體。未知名稱傳回 nil;已識別但不能生成的類型仍可能報錯。此方法不會自動設定投射物的發射者,也不會將實體註冊為精英增援。

參數類型說明
entityTypestring實體類型名稱(例如 "FIREBALL"、"ARROW")
locationlocation 表要在哪裡生成
optionstable(可選)生成選項(見下方)

實體生成選項​

欄位類型預設值說明
velocityvector 表nil初始速度 {x, y, z}
effectstringnil生成時要播放的 EntityEffect
durationint0正值表示經過指定 tick 數後移除;非正值不新增移除計時器
on_landfunctionnil實體著地、失效或超過 max_ticks 時呼叫 function(land_location, entity_ref);不是投射物命中事件,也不能證明實體確實落地
max_ticksint6000在強制觸發 on_land 回呼之前最多監看幾個 tick
persistentbooleanMinecraft 預設值false 會讓實體不被存入區塊存檔,因此效果進行到一半時發生關機或區塊卸載,也不會讓它殘留在世界中

傳回實體包裝表。非生物實體,如 FIREBALL、ARROW、TNT,使用 非生物參考包裝物,其中 is_valid() 是方法。 生物實體,如 ZOMBIE、GIANT,使用完整的 生物實體包裝物,其中 is_valid 是布林欄位。 對後者呼叫 entity:is_valid() 會引發 attempt to call a boolean value。

落地監看器在腳本活動期間每 tick 檢查一次,隨腳本管理的任務停止。正值 duration 的計時器獨立運作,腳本關閉後仍可能移除實體。未知的 effect 名稱會被忽略。

範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("fireball_spawn", 100) then return end
-- Spawn a fireball aimed at the player
local boss_loc = context.boss:get_location()
local dir = context.vectors.get_vector_between_locations(boss_loc, context.player:get_location())
dir = context.vectors.normalize_vector(dir)

context.world:spawn_entity_at_location("FIREBALL", boss_loc, {
velocity = { x = dir.x * 2, y = dir.y * 2, z = dir.z * 2 },
duration = 100,
})
end
}
範例
return {
api_version = 1,
on_enter_combat = function(context)
-- Spawn a primed TNT with a landing callback
context.world:spawn_entity_at_location("TNT", context.boss:get_location(), {
velocity = { x = 0, y = 1.5, z = 0 },
on_land = function(land_location, entity_ref)
context.world:spawn_particle_at_location(land_location, {
particle = "EXPLOSION_EMITTER",
amount = 1,
})
end,
})
end
}

world:spawn_display_at_location(location, options)​

生成物品展示實體或方塊展示實體:一個沒有碰撞箱、重力或 AI 的懸浮視覺物件。適用於環繞的石塊、投擲的道具,以及其他只需要被看見的效果,不必再為盔甲座設定外觀。展示實體以 location 為中心,並依其 yaw 旋轉。

選項類型預設值說明
itemstring以物品形式顯示的材質。像 "AMETHYST_BLOCK" 這類方塊物品會顯示為置中的方塊
blockstring以方塊展示形式顯示的方塊,可為材質或方塊資料,例如 "lantern[hanging=true]"
scalenumber 或 vector 表1數字會縮放所有軸;{x, y, z} 則分別縮放各軸。縮放為 1 時,方塊寬度為一格
durationint0正值表示經過指定 tick 數後移除展示實體
teleport_durationint0用戶端滑行到每個新位置所需的 tick 數,範圍 0 到 59。若你每個 tick 都傳送展示實體,請使用 1
billboardstringFIXEDFIXED、VERTICAL、HORIZONTAL 或 CENTER
glowingbooleanfalse輪廓發光
brightnessint世界光照0 到 15,覆寫展示實體所在位置的光照
bedrock_fallbackbooleantrue見下方說明

item 與 block 必須且只能提供其中一個。缺少或無法辨識的 item 或 block、兩者同時提供,或 scale 不是正數時,會傳回 nil,並記錄指出該能力名稱的警告。無法辨識的 billboard 值則維持 FIXED。

展示實體永遠不會隨區塊儲存。它們會在 duration 用完、你呼叫 remove(),或能力關閉時被移除,以先發生者為準。

Bedrock 用戶端無法繪製展示實體。在展示實體生成時身處該世界的 Bedrock 玩家,會改為看到一個穿戴相同物品的隱形盔甲座(方塊展示實體則使用該方塊對應的物品),而展示實體本身會對他們隱藏。盔甲座會跟隨展示實體,並隨之一起移除。之後才進入該世界的 Bedrock 玩家不會看到盔甲座;沒有物品形式的方塊(例如 fire)則完全不會有盔甲座。對於 Bedrock 玩家不需要看到的效果,可用 bedrock_fallback = false 關閉此行為。

傳回的包裝物件具有 uuid 與 entity_type,以及下列方法:

方法說明
is_valid()、is_alive()展示實體是否仍然存在
get_location()目前位置
teleport_to_location(location)移動展示實體及其 Bedrock 盔甲座
remove()移除展示實體及其 Bedrock 盔甲座
set_scale(scale)與 scale 選項的值相同
set_item(material)僅限物品展示實體;否則傳回 false
set_block(block)僅限方塊展示實體;否則傳回 false
set_glowing(enabled)輪廓發光
set_brightness(level)0 到 15,或傳入 nil 以恢復使用世界光照
set_teleport_duration(ticks)與 teleport_duration 選項相同
範例
-- Three amethyst stones circle the target for three seconds.
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil or not context.cooldowns:check_local("orbit", 200) then return end
local target = context.player
local stones = {}
for i = 1, 3 do
stones[i] = context.world:spawn_display_at_location(target:get_location(), {
item = "AMETHYST_BLOCK", scale = 0.3, duration = 60, teleport_duration = 1
})
end
local elapsed = 0
local task
task = context.scheduler:run_every(1, function(context)
elapsed = elapsed + 1
if elapsed >= 60 then
context.scheduler:cancel_task(task)
return
end
local center = target:get_location()
for i = 1, 3 do
local angle = elapsed * 0.2 + i * (2 * math.pi / 3)
if stones[i] ~= nil and stones[i]:is_valid() then
stones[i]:teleport_to_location(em.create_location(
center.x + math.cos(angle) * 1.5, center.y + 1.2, center.z + math.sin(angle) * 1.5, center.world, 0, 0))
end
end
end)
end
}

world:spawn_falling_block_at_location(location, material, options)​

以方塊材質生成掉落方塊實體。提供 on_land 時,EliteMobs 會攔截其方塊變更事件、取消放置,並呼叫一次 function(land_location, entity_ref)。未提供回呼時,可能正常放置方塊。此方法沒有 duration 或 max_ticks 選項,也不會因實體失效或逾時而呼叫回呼。

參數類型說明
locationlocation 表要在哪裡生成
materialstring材質名稱(例如 "STONE"、"MAGMA_BLOCK")
optionstable(可選)生成選項(見下方)

掉落方塊選項​

欄位類型預設值說明
velocityvector 表nil初始速度 {x, y, z}
drop_itembooleanfalse該方塊是否會以物品形式掉落
hurt_entitiesbooleanfalse該方塊是否會傷害被它砸中的實體
on_landfunctionnil該方塊落地時的回呼 function(land_location, entity_ref)

傳回非生物實體參考表;位置或材質無法解析時傳回 nil。已識別的非方塊材質仍可能在建立方塊資料時失敗。

範例
return {
api_version = 1,
on_enter_combat = function(context)
-- Rain magma blocks from above
local loc = context.boss:get_location()
for i = 1, 5 do
local offset_loc = {
x = loc.x + math.random(-3, 3),
y = loc.y + 10,
z = loc.z + math.random(-3, 3),
world = loc.world
}
context.world:spawn_falling_block_at_location(offset_loc, "MAGMA_BLOCK", {
velocity = { x = 0, y = -0.5, z = 0 },
hurt_entities = true,
on_land = function(land_location, entity_ref)
context.world:spawn_particle_at_location(land_location, { particle = "LAVA", amount = 8 })
end,
})
end
end
}

world:spawn_custom_boss_at_location(filename, location, options)​

從設定檔生成一個 EliteMobs 自訂 Boss。

參數類型說明
filenamestringBoss 設定檔名(例如 "my_boss.yml")
locationlocation 表要在哪裡生成
optionstable(可選)生成選項(見下方)

自訂 Boss 生成選項​

欄位類型預設值說明
levelint自訂 Boss 自身設定或動態等級規則覆寫生成等級;省略時不會繼承施放者等級
silentbooleanfalse抑制生成訊息
velocityvector 表nil初始速度
add_as_reinforcementbooleanfalse註冊為目前 Boss 的增援

傳回一個實體包裝表;若無法建立該 Boss 則傳回 nil。

範例
return {
api_version = 1,
on_enter_combat = function(context)
local minion = context.world:spawn_custom_boss_at_location(
"skeleton_minion.yml",
context.boss:get_location(),
{ level = 10, add_as_reinforcement = true }
)
if minion ~= nil then
context.boss:send_message("&cMinions, arise!")
end
end
}

world:spawn_boss_at_location(filename, location, level)​

較簡單的 Boss 生成方法。省略位置和等級時,使用施放者的位置和等級。生成結果不會註冊為增援。要使用預設等級,請省略第三個引數;此處不接受明確傳入的 nil。

參數類型預設值說明
filenamestringBoss 設定檔名
locationlocation 表Boss 位置要在哪裡生成(可選,預設為 Boss 位置)
levelintBoss 等級覆寫生成等級(可選)

傳回一個實體包裝表,或 nil。

範例
return {
api_version = 1,
on_enter_combat = function(context)
context.world:spawn_boss_at_location("zombie_guard.yml", context.boss:get_location(), 5)
context.boss:send_message("&cGuards, defend me!")
end
}

world:spawn_reinforcement_at_location(filename, location, duration, velocity)​

透過 EliteMobs 增援系統靜默生成實體並記錄召喚者。若自訂 Boss 召喚者使用正規化戰鬥,增援會繼承此設定。等級由增援自身的設定與動態等級規則決定;duration 是逃離計時器,不是等級覆寫值。

參數類型預設值說明
filenamestringBoss 設定檔名
locationlocation 表要在哪裡生成
durationint0逃離前的 tick 數;0 停用此計時器
velocityvector 表nil初始速度(可選)

傳回一個實體包裝表,或 nil。

範例
return {
api_version = 1,
on_enter_combat = function(context)
context.world:spawn_reinforcement_at_location(
"necro_skeleton.yml",
context.boss:get_location(),
0,
{ x = 0, y = 0.5, z = 0 }
)
context.boss:send_message("&5Rise, my servant!")
end
}

world:spawn_fireworks_at_location(location, spec)​

生成真實煙火實體,不會自動禁止傷害。每個效果至少需要一種有效顏色;缺少顏色的效果可能在建立時失敗。

參數類型說明
locationlocation 表要在哪裡生成
spectable煙火規格(見下方)

煙火規格表​

欄位類型預設值說明
powerint1飛行力道(高度)
velocityvector 表nil初始速度
shot_at_anglebooleantrue該煙火是否以角度射出(設定 velocity 時使用)
effects表的表nil煙火效果規格的陣列。若省略,最上層的規格會被視為單一效果。

煙火效果規格​

欄位類型預設值說明
typestring"BALL_LARGE""BALL"、"BALL_LARGE"、"STAR"、"BURST"、"CREEPER"
flickerbooleantrue閃爍效果
trailbooleantrue拖尾效果
colorstable每個效果必填非空陣列,元素為顏色名稱或 {red = 255, green = 0, blue = 0} 表
fade_colorstablenil淡出顏色名稱或 {red, green, blue} 表的陣列

顏色名稱:"WHITE", "SILVER", "GRAY", "BLACK", "RED", "MAROON", "YELLOW", "OLIVE", "LIME", "GREEN", "AQUA", "TEAL", "BLUE", "NAVY", "FUCHSIA", "PURPLE", "ORANGE"

傳回非生物實體參考表,位置無法解析時傳回 nil。呼叫 :detonate() 可要求引爆。類型及顏色名稱不分大小寫;未知類型回退至 BALL_LARGE,未知顏色回退至白色。RGB 值必須介於 0..255。

範例
return {
api_version = 1,
on_spawn = function(context)
local fw = context.world:spawn_fireworks_at_location(context.boss:get_location(), {
power = 0,
effects = {
{
type = "STAR",
flicker = true,
trail = true,
colors = { "RED", "ORANGE", { red = 255, green = 200, blue = 0 } },
fade_colors = { "YELLOW" },
},
},
})

if fw == nil then return end
-- Detonate on the next tick for a visual burst
context.scheduler:run_after(1, function()
fw:detonate()
end)
end
}

world:spawn_splash_potion_at_location(location, spec)​

生成真實的投擲噴濺藥水。未知的 Bukkit 效果名稱會產生警告並被略過。此方法不會設定發射者,也不會套用直接 Boss 藥水方法使用的副本效果篩選;藥水採用正常噴濺行為。

參數類型說明
locationlocation 表要在哪裡生成
spectable藥水規格(見下方)

噴濺藥水規格表​

欄位類型說明
velocityvector 表投擲藥水的初始速度
effects表的表藥水效果規格的陣列

藥水效果規格​

欄位類型預設值說明
typestring必填藥水效果類型名稱(例如 "SLOWNESS"、"POISON")
durationint0持續時間,以 tick 計
amplifierint0效果強度(0 = 等級 I)
overwritebooleantrue取代此藥水中繼資料中先前加入的同類型效果,不控制玩家身上已有的效果

傳回一個實體參考表,或 nil。

範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("potion_throw", 200) then return end

local dir = context.vectors.get_vector_between_locations(
context.boss:get_location(),
context.player:get_location()
)
dir = context.vectors.normalize_vector(dir)

context.world:spawn_splash_potion_at_location(context.boss:get_location(), {
velocity = { x = dir.x * 1.5, y = 0.5, z = dir.z * 1.5 },
effects = {
{ type = "SLOWNESS", duration = 100, amplifier = 1 },
{ type = "WEAKNESS", duration = 60, amplifier = 0 },
},
})
end
}

world:place_temporary_block_at_location(location, material, duration, requireAir)​

放置受追蹤的方塊,持續時間為正值時會還原原本的方塊資料。只儲存方塊資料,不儲存容器內容。原本的方塊會在計時器結束、區塊或世界卸載,或插件關閉時恢復,但前提是該位置仍是這個臨時方塊,因此之後的編輯不會被覆蓋。在仍為臨時方塊的位置再次放置,會重新開始計時,並保留第一次儲存的原始方塊。帶有方塊實體的方塊(例如箱子與告示牌)、未載入的區塊,以及已被其他臨時方塊擁有者持有的方塊,都會被略過。破壞受追蹤的方塊不會掉落任何物品,並會結束追蹤且不還原。必須使用方塊材質。此 Boss 覆寫方法傳回 nil,包括 requireAir 或略過條件阻止放置時;不提供成功狀態,也不自動檢查區域保護。

參數類型預設值說明
locationlocation 表要放置在哪裡
materialstring材質名稱
durationint0正值為還原前的 tick 數;0 或負值會永久放置方塊,且不加以追蹤
requireAirbooleanfalse若為 true,只有在該方塊目前是空氣時才放置
範例
return {
api_version = 1,
on_enter_combat = function(context)
-- Create a temporary ice floor under the boss
local loc = context.boss:get_location()
for dx = -2, 2 do
for dz = -2, 2 do
context.world:place_temporary_block_at_location(
{ x = loc.x + dx, y = loc.y - 1, z = loc.z + dz, world = loc.world },
"PACKED_ICE",
100,
false
)
end
end
end
}

world:set_block_at_location(location, material, requireAir)​

透過暫時方塊管理器永久設定方塊,不設還原計時器也不加以追蹤,因此插件關閉後變更仍會保留。若該位置目前是有計時的臨時方塊,該方塊會停止被追蹤,也不會被還原。已被其他臨時方塊擁有者持有的方塊則維持不變。需要定時還原時,請使用持續時間為正值的 place_temporary_block_at_location。

參數類型預設值說明
locationlocation 表要放置在哪裡
materialstring材質名稱
requireAirbooleanfalse若為 true,只有在該方塊目前是空氣時才放置
範例
return {
api_version = 1,
on_enter_combat = function(context)
-- Place fire at the boss's location
context.world:set_block_at_location(context.boss:get_location(), "FIRE", true)
end
}

world:get_block_type_at_location(location)​

傳回指定位置的大寫材質名稱,位置無法解析時傳回 nil。與共用座標查詢不同,此覆寫方法直接存取方塊,不檢查區塊是否已載入。

參數類型說明
locationlocation 表要查詢的位置
範例
return {
api_version = 1,
on_enter_combat = function(context)
local block_type = context.world:get_block_type_at_location(context.boss:get_location())
if block_type == "WATER" then
context.boss:send_message("&bThe boss is empowered by water!")
context.boss:apply_potion_effect("SPEED", 200, 1)
end
end
}

world:get_highest_block_y_at_location(location)​

傳回 Bukkit 提供的最高方塊 Y 座標,位置無法解析時傳回 nil。不檢查區塊是否已載入,也不判斷目的地是否適合安全傳送。

參數類型說明
locationlocation 表要查詢的位置(會使用 X 與 Z)
範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("skyport", 200) then return end
local loc = context.player:get_location()
local ground_y = context.world:get_highest_block_y_at_location(loc)
-- Teleport the player to the surface
context.player:teleport_to_location({
x = loc.x, y = ground_y + 1, z = loc.z, world = loc.world
})
context.player:send_message("&eYou are teleported to the surface!")
end
}

world:get_blast_resistance_at_location(location)​

傳回指定位置材質的抗爆性,位置無法解析時傳回 0。

參數類型說明
locationlocation 表要查詢的位置
範例
return {
api_version = 1,
on_enter_combat = function(context)
local resistance = context.world:get_blast_resistance_at_location(context.boss:get_location())
context.log:info("Blast resistance at boss: " .. resistance)
end
}

world:is_air_at_location(location)​

如果該位置的方塊是空氣,則傳回 true。

參數類型說明
locationlocation 表要查詢的位置
範例
return {
api_version = 1,
on_enter_combat = function(context)
local loc = context.boss:get_location()
local above = { x = loc.x, y = loc.y + 2, z = loc.z, world = loc.world }
if context.world:is_air_at_location(above) then
-- There is space above the boss, launch upward
context.boss:set_velocity_vector({ x = 0, y = 1.5, z = 0 })
end
end
}

world:is_passable_at_location(location)​

傳回 Bukkit 的 Block.isPassable() 結果,位置無法解析時傳回 false。這只查詢單一方塊,不檢查整個實體是否有足夠空間或能否沿路徑通過。

參數類型說明
locationlocation 表要查詢的位置
範例
return {
api_version = 1,
on_enter_combat = function(context)
if context.world:is_passable_at_location(context.boss:get_location()) then
context.log:info("Boss is in a passable block")
end
end
}

world:is_passthrough_at_location(location)​

如果該位置的方塊不是固體,則傳回 true(類似於可通過,但依據的是固體檢查)。

參數類型說明
locationlocation 表要查詢的位置
範例
return {
api_version = 1,
on_enter_combat = function(context)
local loc = context.boss:get_location()
local above = { x = loc.x, y = loc.y + 1, z = loc.z, world = loc.world }
if context.world:is_passthrough_at_location(above) then
context.log:info("Boss can move upward")
end
end
}

world:is_on_floor_at_location(location)​

若該位置的方塊非固體,且 Y 座標低一格的方塊為固體,則傳回 true。不檢查實體的著地狀態、碰撞箱或頭頂空間。

參數類型說明
locationlocation 表要查詢的位置
範例
return {
api_version = 1,
on_enter_combat = function(context)
if context.world:is_on_floor_at_location(context.boss:get_location()) then
context.boss:send_message("&aThe boss slams the ground!")
context.world:spawn_particle_at_location(context.boss:get_location(), {
particle = "CLOUD",
amount = 30,
})
end
end
}

world:is_standing_on_material(location, material)​

如果該位置正下方的方塊符合指定的材質,則傳回 true。

參數類型說明
locationlocation 表要查詢的位置
materialstring要檢查的材質名稱
範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if context.world:is_standing_on_material(context.player:get_location(), "SOUL_SAND") then
context.player:send_message("&8The soul sand saps your strength!")
context.player:apply_potion_effect("SLOWNESS", 60, 2)
end
end
}

world:set_world_time(time) / world:set_world_time(location, time)​

設定整個世界的時間,可透過選用位置指定世界。腳本關閉時不會還原原本的時間。

參數類型說明
locationlocation 表(可選)要影響哪個世界。預設為 Boss 所在的世界。
timeint世界時間,以 tick 計(0 = 黎明、6000 = 正午、13000 = 夜晚、18000 = 午夜)
範例
return {
api_version = 1,
on_enter_combat = function(context)
-- Set to midnight when combat starts
context.world:set_world_time(18000)
context.boss:send_message("&8Darkness falls...")
end
}

world:set_world_weather(weather, duration) / world:set_world_weather(location, weather, duration)​

設定 Boss 所在世界或選用位置所在世界的天氣。名稱不分大小寫,未知名稱只產生警告。RAIN/CLEAR 設定天氣持續時間,THUNDER 設定雷暴持續時間。它影響整個世界,腳本關閉時不會還原之前的狀態。

參數類型預設值說明
locationlocation 表(可選)Boss 世界要影響哪個世界
weatherstring"CLEAR"、"RAIN"(或 "PRECIPITATION")、"THUNDER"
durationint6000天氣持續時間,以 tick 計
範例
return {
api_version = 1,
on_enter_combat = function(context)
-- Start a thunderstorm for 200 ticks
context.world:set_world_weather("THUNDER", 200)
context.boss:send_message("&eA storm gathers!")
end
}

world:generate_fake_explosion(blockLocations, sourceLocation)​

透過 EliteMobs 爆炸再生系統移除真實方塊並生成掉落方塊碎片。碎片可傷害實體,因此這不是無害的粒子效果。必須啟用 doExplosionRegen;提供來源位置時會檢查 WorldGuard 的爆炸再生旗標。空氣、火、液體和受追蹤的暫時方塊會被略過,相鄰依附方塊也可能納入。經過 1200 tick 後開始還原,每 tick 處理一個記錄的方塊。所有輸入位置應在 Boss 所在世界。操作傳回 nil,關閉腳本不會撤銷它。

參數類型說明
blockLocationslocation 表的表要「爆炸」的方塊位置陣列
sourceLocationlocation 表(可選)用於方向計算的爆炸來源
範例
return {
api_version = 1,
on_enter_combat = function(context)
local loc = context.boss:get_location()
local blocks = {}
for dx = -1, 1 do
for dz = -1, 1 do
table.insert(blocks, { x = loc.x + dx, y = loc.y, z = loc.z + dz, world = loc.world })
end
end
context.world:generate_fake_explosion(blocks, loc)
end
}

world:run_console_command(command)​

立即以伺服器身分執行主控台指令並傳回 nil,不提供指令是否成功的結果。不會自動替換玩家或 Boss 佔位符。

原版指令會回報其執行結果,而在預設的 broadcast-console-to-ops=true 下,伺服器會把每一則結果顯示給所有在線的管理員。像 data merge entity、kill 或 damage 這類經常執行的指令,會讓他們的聊天欄被洗版。請改用原生方法:視覺效果用 spawn_display_at_location,盔甲座用盔甲座方法,要移除腳本生成的實體用 entity:remove(),而要讓 Boss 造成精確傷害則用 entity:deal_custom_damage(amount)。

參數類型說明
commandstring要執行的指令(不含開頭的 /)
範例
return {
api_version = 1,
on_enter_combat = function(context)
context.world:run_console_command("say The boss has entered phase 2!")
end
}

world:run_empowered_lightning_task_at_location(location)​

在儲存的位置啟動獨立 Bukkit 任務。先發出 SOUL_FIRE_FLAME,持續 60 次迭代,接著生成帶生成保護繞過的真實閃電,並向下發射爆炸強度為 5 的火球,標記為 ender_dragon_empowered_lightning.yml。這是會造成傷害的攻擊。關閉或暫停 Lua 腳本不會取消任務,此方法也不會讀取預警效果設定。

參數類型說明
locationlocation 表要在哪裡降下閃電
範例
return {
api_version = 1,
on_enter_combat = function(context)
context.world:run_empowered_lightning_task_at_location(context.boss:get_location())
context.boss:send_message("&eFeel the power of the storm!")
end
}

world:spawn_fake_gold_nugget_at_location(location, velocity, hasGravity)​

透過封包為附近玩家顯示金粒,玩家和漏斗無法拾取。僅建立它不會使其移動或造成傷害。應將它放入一批投射物,傳給 run_fake_gold_nugget_damage 一次,或明確移除。

參數類型預設值說明
locationlocation 表生成位置
velocityvector 表初始速度
hasGravitybooleanfalse該投射物是否受重力影響

傳回假投射物表;位置或向量無法解析時傳回 nil。方法包括 get_location()、set_gravity(bool)、remove()、is_removed()。

範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("nugget", 60) then return end

local dir = context.vectors.get_vector_between_locations(
context.boss:get_location(),
context.player:get_location()
)
dir = context.vectors.normalize_vector(dir)

local nugget = context.world:spawn_fake_gold_nugget_at_location(
context.boss:get_location(),
{ x = dir.x, y = dir.y, z = dir.z }
)
if nugget ~= nil then
context.world:run_fake_gold_nugget_damage({ nugget })
end
end
}

world:run_fake_gold_nugget_damage(projectiles)​

啟動獨立 Bukkit 任務,每 tick 移動並檢查整批投射物。每批只呼叫一次,每次呼叫都會建立新任務。它在新位置查詢半尺寸為 0.5 的方框內的生物,略過發起攻擊的 Boss 及正在格擋的玩家,並透過 Boss 傷害規則提交 1 點自訂傷害。即使傷害被拒絕,碰撞仍可能移除投射物。觸地或任務達到 100 tick 也會移除它。這是取樣碰撞檢查,不是連續射線檢測;關閉或暫停 Lua 實例不會取消任務。

參數類型說明
projectilestable來自 spawn_fake_gold_nugget_at_location 的假投射物表陣列
範例
return {
api_version = 1,
on_enter_combat = function(context)
-- Keep this batch separate from later combat entries.
local projectiles = {}
local loc = context.boss:get_location()
for i = 1, 5 do
local angle = (i / 5) * math.pi * 2
local nugget = context.world:spawn_fake_gold_nugget_at_location(
loc,
{ x = math.cos(angle) * 0.5, y = 0.3, z = math.sin(angle) * 0.5 }
)
if nugget ~= nil then table.insert(projectiles, nugget) end
end

-- Start the batch once; the helper runs its own per-tick task.
context.world:run_fake_gold_nugget_damage(projectiles)
-- Remove any surviving projectiles after 3 seconds.
context.scheduler:run_after(60, function()
for _, projectile in ipairs(projectiles) do
projectile:remove()
end
end)
end
}

world:generate_player_loot(times)​

執行正常的玩家戰利品產生流程 times 次;非正值不執行。需要啟用 eliteLoot、未觸發防濫用狀態、已載入玩家資料,並記錄了至少最大生命值 10% 的傷害。副本獎勵鎖定中的玩家會被略過。每次可能發放金幣;啟用隨機戰利品時,也會依正常設定和隊伍規則產生隨機或特殊戰利品及卷軸。它不會重新執行所有自訂掉落,也不保證每次必出一件物品。重複呼叫會增加獎勵嘗試次數,沒有每個 Boss 只能執行一次的保護。

參數類型預設值說明
timesint1戰利品擲骰次數
範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
local pct = context.boss:get_health() / context.boss:get_maximum_health()
if pct < 0.5 and not context.boss:has_tag("bonus_loot") then
context.boss:add_tag("bonus_loot")
context.world:generate_player_loot(2)
context.boss:send_message("&6Bonus loot drops!")
end
end
}

world:drop_bonus_coins(multiplier)​

為記錄傷害嚴格超過 Boss 最大生命值 10% 的合格玩家掉落額外金幣。略過 NPC 及沒有已載入資料的玩家。獎勵依 Boss 獎勵等級及 multiplier 縮放。

參數類型預設值說明
multipliernumber2.0金幣數量倍率
範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
local pct = context.boss:get_health() / context.boss:get_maximum_health()
if pct < 0.25 and not context.boss:has_tag("bonus_coins") then
context.boss:add_tag("bonus_coins")
context.world:drop_bonus_coins(3.0)
context.boss:send_message("&6Gold spills everywhere!")
end
end
}

context.vectors​

向量數學輔助函式接受範例中的點語法,也支援冒號語法。輸入可用命名欄位 x、y、z、數字索引 1..3 或巢狀的 direction 表。缺少的分量為 0。結果是新表,不會修改輸入。

方法傳回值說明
vectors.get_vector_between_locations(loc1, loc2[, options])vector 表位移 loc2 - loc1,預設不正規化
vectors.normalize_vector(vec)vector 表非零輸入得到單位向量;零向量仍為零
vectors.rotate_vector(vec, pitch, yaw)vector 表先繞世界 X 軸,再繞世界 Y 軸旋轉,單位為度

所有 vector 表都有 x、y、z 欄位。

vectors.get_vector_between_locations(loc1, loc2, options)​

參數類型說明
loc1location 表起點
loc2location 表終點
optionstable(可選)後處理選項(見下方)

向量選項​

欄位類型預設值說明
normalizebooleanfalse將結果向量正規化
multipliernumber1.0縮放該向量
offsetvector 表nil加上一個偏移向量

選項依序執行:正規化非零位移、乘上倍率,再加世界軸偏移。位置無法解析或位於不同世界時,套用任何選項前就傳回零向量。有效但重合的位置仍可加上偏移。

範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("dash", 100) then return end
-- Compute a normalized direction from boss to player, scaled to speed 2
local dir = context.vectors.get_vector_between_locations(
context.boss:get_location(),
context.player:get_location(),
{ normalize = true, multiplier = 2.0 }
)
-- Launch the boss toward the player
context.boss:set_velocity_vector(dir)
end
}

vectors.normalize_vector(vec)​

參數類型說明
vecvector 表輸入向量
範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
local raw = context.vectors.get_vector_between_locations(
context.boss:get_location(),
context.player:get_location()
)
local unit = context.vectors.normalize_vector(raw)
context.log:info("Direction: " .. unit.x .. ", " .. unit.y .. ", " .. unit.z)
end
}

vectors.rotate_vector(vec, pitch, yaw)​

參數類型說明
vecvector 表輸入向量
pitchnumber繞 X 軸旋轉的度數
yawnumber繞 Y 軸旋轉的度數
範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("spread_shot", 100) then return end
local forward = context.vectors.normalize_vector(
context.vectors.get_vector_between_locations(
context.boss:get_location(),
context.player:get_location()
)
)
-- Fire three fireballs in a spread pattern
for _, yaw_offset in ipairs({ -30, 0, 30 }) do
local dir = context.vectors.rotate_vector(forward, 0, yaw_offset)
context.boss:summon_projectile(
"FIREBALL",
context.boss:get_eye_location(),
{
x = context.boss:get_location().x + dir.x * 10,
y = context.boss:get_location().y + dir.y * 10,
z = context.boss:get_location().z + dir.z * 10,
world = context.boss:get_location().world
},
1.0
)
end
end
}
提示

你可以在迴圈中旋轉一個基準向量,藉此建立出一組散開的方向:

local base = context.vectors.normalize_vector(
context.vectors.get_vector_between_locations(boss_loc, target_loc)
)
for angle = 0, 330, 30 do
local dir = context.vectors.rotate_vector(base, 0, angle)
-- Use dir for spawning projectiles in a ring
end

context.settings​

以唯讀方式存取能力設定。此方法在呼叫時讀取目前設定,不會自動禁止粒子或其他效果。腳本必須依傳回值決定是否顯示預警。

方法傳回值說明
settings:warning_visual_effects_enabled()boolean怪物戰鬥設定中是否啟用了警告視覺效果
範例
return {
api_version = 1,
on_enter_combat = function(context)
if context.settings:warning_visual_effects_enabled() then
context.world:spawn_particle_at_location(context.boss:get_location(), {
particle = "DUST",
amount = 20,
red = 255, green = 0, blue = 0,
})
end
end
}

context.event​

目前掛鉤的事件資料。可用欄位取決於底層事件,使用選用欄位前請先檢查。數值傷害設定方法必須使用點語法,例如 event.set_damage_amount(value);transfer_damage 同時支援點與冒號語法。Boss 事件表不提供共用表中的 cancel、uncancel 或 is_cancelled。

欄位或方法可用時機說明
event.damage_amount傷害掛鉤延遲建立的事件表首次解析時的傷害快照
event.get_damage_amount()傷害掛鉤讀取修改後的目前傷害量
event.damage_cause傷害掛鉤Bukkit DamageCause 列舉名稱(例如 "ENTITY_ATTACK")
event.cancel_event()可取消的事件取消該事件
event.set_damage_amount(value)以 EliteDamageEvent 為基礎的掛鉤直接設定傷害值
event.multiply_damage_amount(multiplier)以 EliteDamageEvent 為基礎的掛鉤將目前的傷害乘上倍率
event.damager帶有加害實體的傷害事件原始 Bukkit 加害者包裝物;投射物命中時是投射物本身,不是發射者
event.projectile加害者為投射物的傷害事件投射物的實體參考包裝物
event.spawn_reasonon_spawn生成原因的列舉名稱
event.entity玩家對 Boss 的傷害、on_death、區域事件受傷 Boss、死亡實體或穿越區域的實體;增援受傷時為該增援
event.is_damage_transfer玩家對 Boss 的傷害,包括增援轉發這次傷害是否由轉移建立
event:transfer_damage(target, amount)玩家對 Boss 的傷害,包括增援轉發向另一個合格精英實體提交獨立傷害;請見傷害轉移規則

範例:把承受的傷害減半​

範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.event ~= nil then
local dmg = context.event.damage_amount
context.log:info("Boss took " .. dmg .. " damage, halving it")
context.event.multiply_damage_amount(0.5)
end
end
}

範例:取消來自投射物的傷害​

範例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.event ~= nil and context.event.damage_cause == "PROJECTILE" then
context.event.cancel_event()
if context.player ~= nil then
context.player:send_message("&cThe boss deflects your projectile!")
end
end
end
}

範例:讀取傷害原因​

範例
return {
api_version = 1,
on_player_damaged_by_boss = function(context)
if context.event ~= nil then
context.log:info("Damage cause: " .. (context.event.damage_cause or "unknown"))
end
end
}
備註
  • damage_amount 是一份快照。在呼叫 set_damage_amount() 或 multiply_damage_amount() 之後,它不會自動更新。
  • 排程回呼收到的新上下文中 event = nil。即使保留了原掛鉤上下文,也不能在事件結束後有效修改它;請在掛鉤執行期間修改事件。
  • 傷害設定方法修改的是待處理事件,不是已損失的生命值。後續監聽器仍可修改或取消傷害。成功轉移會提交額外的一次傷害,不會自動減少或取消原傷害。

後續步驟​