跳至主要內容

Lua 腳本:道具與物品 API

此頁面涵蓋 FreeMinecraftModels 道具與物品腳本可用的所有 API:context.propcontext.itemcontext.eventcontext.playercontext.worldcontext.zonescontext.schedulercontext.statecontext.cooldownscontext.log。如果你剛接觸腳本,請先從 入門 開始。


context.prop

prop 表格提供道具實體的資訊以及控制其動畫的方法。為了效能,FMM 會為每個道具快取這個表格;像 current_location 這類欄位是延遲/即時取值的,因此讀取時仍會反映道具當前的狀態。

欄位

欄位類型說明
prop.model_idstring藍圖模型名稱(例如 "torch_01"
prop.current_locationlocation 表格道具的當前位置。這是即時/延遲取值的欄位,而不是一次性的快照。

位置表格擁有標準欄位:xyzworldyawpitch

範例:讀取道具資訊
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()

從世界中移除道具,並在其位置掉落放置用的紙張物品。掉落的物品可以右鍵點擊方塊以再次放置該道具。

不接受參數,也不回傳任何值。移除/掉落的工作會排入 Bukkit 主執行緒。

範例
return {
api_version = 1,

on_right_click = function(context)
-- 讓玩家可以右鍵點擊以拾起道具
context.prop:pickup()
end
}

prop:mount(player)

將玩家放上道具上第一個可用的坐騎點座位。模型必須定義了坐騎點骨骼。

參數類型說明
playerentity 表格玩家實體表格(例如來自 context.playercontext.event.player

當找到該玩家、道具具有坐騎點,且騎乘動作已排入佇列時回傳 true。當這些基本參考無效時回傳 false。回傳 true 並不證明排入佇列的動作實際執行時仍有座位可用。

範例
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)

將玩家從道具上的坐騎點座位移開。

參數類型說明
playerentity 表格玩家實體表格

當找到該玩家、道具具有騎乘管理員,且下乘檢查已排入佇列時回傳 true。當這些基本參考無效時回傳 false

範例
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()

回傳此道具的模型是否定義了坐騎點骨骼。

不接受參數。回傳 truefalse

範例
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 自訂 Boss。需要伺服器上安裝 EliteMobs。

參數類型說明
filenamestring自訂 Boss 的檔名(例如 "my_boss.yml"
xnumberX 座標
ynumberY 座標
znumberZ 座標

回傳已生成 Boss 的生物實體表格,如果未安裝 EliteMobs 或 Boss 檔案不存在則回傳 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,再次開啟時會還原。

參數類型預設值說明
playerentity 表格必填要顯示物品欄的玩家
titlestring必填物品欄標題(支援 & 顏色代碼)
rowsint3列數(1-6,其中 6 = 54 個格子 = 大型箱子)

如果道具/玩家的參考有效且開啟動作已排入佇列則回傳 true,否則回傳 false。列數會在建立物品欄之前先被夾限到 1-6 的範圍內。


prop:is_viewing_inventory(player)

回傳指定的玩家目前是否開啟著此道具的物品欄。

參數類型說明
playerentity 表格要檢查的玩家

回傳 truefalse

範例:物品欄關閉時關閉動畫
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)

從玩家的主手取走已寫成或可寫的書,並儲存到道具上。

參數類型說明
playerentity 表格持有書的玩家

如果道具/玩家的參考有效且動作已排入佇列則回傳 true。之後在主執行緒上執行的動作,只有在玩家確實持有可寫或已寫成的書、且道具上尚未存放書時才會真正放上去。


prop:read_book(player)

開啟儲存的書讓玩家閱讀。

參數類型說明
playerentity 表格要顯示書的玩家

如果道具/玩家的參考有效且閱讀動作已排入佇列則回傳 true。它並不保證確實存在已儲存的書。


prop:take_book(player)

將儲存的書歸還到玩家的物品欄,並從道具中移除。

參數類型說明
playerentity 表格接收書的玩家

如果道具/玩家的參考有效且取出動作已排入佇列則回傳 true。它並不保證確實存在已儲存的書。


prop:has_book()

回傳此道具上是否儲存了一本書。不接受參數。


prop:drop_inventory()

在道具的位置以物品實體形式掉落所有儲存的物品欄內容,然後清除儲存的資料。自動關閉任何正在檢視該物品欄的玩家視窗。

不接受參數。如果道具擁有有效的底層 armor stand 且掉落動作已排入佇列則回傳 true。它並不保證確實存在已儲存的物品。


prop:drop_book()

在道具的位置以物品實體形式掉落儲存的書,並清除儲存的書資料。

不接受參數。如果道具擁有有效的底層 armor stand 且掉落動作已排入佇列則回傳 true。它並不保證確實存在已儲存的書。


prop:set_persistent_data(key, value)

將字串值儲存到道具的 armor stand PersistentDataContainer。此資料能在伺服器重啟和區塊卸載後保留。

參數類型說明
keystring唯一鍵名(在內部儲存於 fmm_lua_<key>
valuestring要儲存的值。對數字和布林值使用 tostring()

成功時回傳 true,如果道具沒有支援的 armor stand 則回傳 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 表格僅在物品腳本中可用(道具腳本不可用)。它提供自訂物品的資訊與操作該物品的方法。此表格每次鉤子呼叫時都會重新建構。

諸如 set_amountconsumeset_usesset_nameset_lore 以及耐久度消耗輔助方法等物品寫入方法,會把它們的變更排入 Bukkit 主執行緒並回傳 nil。讀取方法回傳的是它們執行當下已裝備之相符物品的狀態。

欄位

欄位類型說明
item.idstring物品類型 ID(來自 YML 設定的 fmm_item_id

item:material()

回傳該物品的材料名稱字串(例如 "DIAMOND_SWORD""STICK")。


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

取得或設定物品的堆疊大小。set_amount(n) 會把變更排入佇列並回傳 nil

參數類型說明
nint新的堆疊數量

item:consume(n)

將「把物品的堆疊數量減去 n(預設 1)」排入佇列。如果結果數量為 0 或更少,物品會從玩家的物品欄中移除。回傳 nil

參數類型預設值說明
nint1要消耗的數量

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

取得或設定儲存在物品 PersistentDataContainer 中的自訂使用次數計數器。此計數器獨立於原版耐久度,可用於實作自訂耐久度或充能系統。set_uses(n) 會把變更排入佇列並回傳 nil

參數類型說明
nint新的使用次數

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

取得或設定物品的顯示名稱。支援使用 & 的顏色代碼。set_name(s) 會把變更排入佇列並回傳 nil

參數類型說明
sstring新的顯示名稱(例如 "&b&lFrost Sword"

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

取得或設定物品的物品說明。get_lore() 回傳字串表格(每行一個)。set_lore() 接受字串表格,會把變更排入佇列並回傳 nil

參數類型說明
tabletable字串陣列,每行物品說明一個
範例:追蹤使用次數的物品腳本
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.01.0 的分數回傳剩餘耐久度,如果該物品沒有耐久度條則回傳 nil


item:use_durability(amount, can_break)

將「把原版耐久度減少一個固定數值」排入佇列,並回傳 nil

參數類型預設值說明
amountint必填要消耗的耐久度點數
can_breakbooleanfalse若為 true,耐久度耗盡時物品會被銷毀。若為 false,耐久度會停在 1。

item:use_durability_percentage(fraction, can_break)

將「把原版耐久度減少其最大值的一個百分比」排入佇列,並回傳 nil

參數類型預設值說明
fractionnumber必填要消耗的最大耐久度的分數(例如 0.1 = 10%)
can_breakbooleanfalse若為 true,耐久度耗盡時物品會被銷毀。若為 false,耐久度會停在 1。

context.event

當前鉤子的事件資料。可用於道具和物品腳本的點擊、戰鬥、互動及一般區域鉤子中。在沒有關聯事件或玩家行為者的鉤子中回傳 nilon_spawnon_game_tickon_destroyon_equip)。

下方的鉤子參考表格會列出底層的 Bukkit 事件類型以供對照。Lua 包裝層仍然只公開此處列出的欄位與方法。

欄位與方法

欄位或方法類型說明
event.player玩家實體表格觸發事件、或跨越受監看一般區域邊界的玩家。可用於道具的 on_left_clickon_right_clickon_zone_enteron_zone_leave,以及由玩家所引發的物品鉤子。請參閱玩家實體方法以了解所有欄位和方法。
event.is_cancelledbooleancontext 建構當時的取消狀態。此欄位在呼叫 cancel()uncancel() 之後不會更新。
event.cancel()function取消事件(例如防止傷害或互動)
event.uncancel()function取消先前取消的事件
點號或冒號,兩種都可以

canceluncancel 會忽略傳給它們的任何參數,因此 context.event.cancel()context.event:cancel() 行為完全相同。FMM 隨附的預製腳本使用冒號形式;本頁使用點號形式。兩者沒有誰比較正確。

資訊

並非所有事件都可取消。如果底層的 Bukkit 事件未實作 Cancellable,或該鉤子是背後沒有 Bukkit 事件的一般區域鉤子,event.cancel()event.uncancel() 將不會存在,並且 event.is_cancelled 永遠為 false

請把 event.is_cancelled 當作初始狀態的快照。如果你的腳本自己呼叫了 event.cancel()event.uncancel(),而你之後在同一個鉤子中還需要記得這個變更,請自行保留一個本地旗標。

目前的 FMM 事件表格不會公開 Bukkit 專屬欄位,例如 targetblockprojectileitem。當你需要額外的上下文時,請使用 context.playercontext.event.playerplayer:get_target_entity(range)context.world:raycast(...),或附近實體查詢。

範例:讓道具無敵

範例
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

這是 FreeMinecraftModels/MagmaCore 的 world API。請參閱 context.world 以了解完整參考。

資訊

全域頁面上記錄的所有方法(get_block_atset_block_atspawn_particleplay_soundstrike_lightningget_timeset_timeget_nearby_entitiesget_nearby_playersspawn_entityget_highest_block_yraycastplace_temporary_blockdrop_itemspawn_firework)在 FMM 中都可用。請參閱 MagmaCore world API 以了解 world:raycast()(投射射線並偵測命中的實體/方塊)、world:place_temporary_block()(暫時性方塊替換)和 world:spawn_firework()(生成具有自訂顏色和形狀的煙火)的完整細節。EliteMobs Boss 能力以同一套 world 基礎為起點,並加上 Boss 專屬的位置表格方法,用於生成 Boss、增援、掉落方塊、暫時性方塊等等;請參閱 EliteMobs World & Environment

FMM 專屬的 world 附加方法

FreeMinecraftModels 在 context.world 上疊加了三個可選的 EliteMobs 戰利品輔助方法。它們永遠存在,但在未安裝 EliteMobs 時各自都會回傳 false 並且不做任何事:

方法說明
world:drop_elitemobs_procedural_loot(player, level, location?)為該玩家掉落一件程序化生成的 EliteMobs 物品。當程序化物品掉落被停用時回傳 false
world:drop_elitemobs_random_loot(player, level, location?)以指定等級為該玩家擲骰 EliteMobs 的戰利品表
world:drop_elitemobs_custom_loot(player, file, level, location?)為該玩家掉落指定的 EliteMobs 自訂物品檔案。當檔案無法解析時回傳 false

完整簽章請見 Lua API 參考。針對 Boss 的道具端等價方法是上文記載的 prop:spawn_elitemobs_boss(...)


玩家實體方法

玩家實體表格從 context.playercontext.event.playercontext.world:get_nearby_players() 傳回。一般的 MagmaCore on_zone_enter / on_zone_leave 鉤子會把 context.playercontext.event.player 設為進入或離開的玩家。

MagmaCore 實體表格

全域頁面上記錄的實體表格、生物實體方法、玩家專屬方法和玩家 UI 方法,就是 FMM 所使用的 MagmaCore 表格。EliteMobs Boss 能力公開的是類似但屬於 Boss 專用的實體表格,記錄於 Boss & Entities。請參閱 MagmaCore Lua 腳本引擎 以了解涵蓋實體基本欄位、生物實體欄位和方法、玩家專屬欄位和方法以及 玩家 UI 方法 的完整 FMM 參考。新的玩家方法包括 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 的 armor stand 則為 true
entity.model表格或 nil僅在 is_modeled = true 時填入(見下方)

entity.model 存在時,它會公開:

欄位 / 方法說明
model.model_id藍圖模型名稱(例如 "dragon"
model.is_dynamic若這是 DynamicEntity(附加到生物實體)則為 true
model:play_animation(name, blend, loop)播放指定名稱的動畫。在實體模型橋接層上,blendloop 預設為 false。成功時回傳 true
model:stop_animations()停止所有當前動畫
model:remove()立即移除模型化實體及其所有骨骼
on_right_click = function(context)
local player = context.event and context.event.player
if not player then return end

local target = player:get_target_entity(8)
if target and target.is_modeled then
target.model:play_animation("hurt", true, false)
end
end

EliteMobs 實體欄位

當安裝了 EliteMobs 時,FMM 會轉發到 EliteMobs 的 enricher,使相同的實體表格也公開:

欄位類型說明
entity.is_eliteboolean若實體由 EliteMobs 追蹤則為 true
entity.is_custom_bossboolean若它是自訂 Boss 設定則為 true
entity.is_significant_bossboolean對於 healthMultiplier > 1 的自訂 Boss 為 true(過濾掉雜魚命名怪物)
entity.elite表格或 nil僅在 is_elite = true 時填入。包含 levelnamehealthmax_healthhealth_multiplierdamage_multiplieris_custom_boss,加上 elite:remove()

context.zones

這是 FreeMinecraftModels/MagmaCore 的 zones API。請參閱 context.zones 以了解完整參考。EliteMobs Boss 能力使用的是另一套帶有原生 EliteMobs 區域定義的 context.zones 表格;請參閱 EliteMobs Zones & Targeting


context.scheduler

此處記錄的 scheduler API 是 FreeMinecraftModels 腳本與 EliteMobs NPC 腳本所使用的 MagmaCore 排程器。EliteMobs 風格的名稱(run_afterrun_everycancel_task)在這個共用排程器上是別名,因此兩種命名風格都可以使用。Boss 能力也透過其 Boss 專屬 context 公開相同的別名。請參閱 context.scheduler 以了解完整的 FMM 參考。


context.state

state API 由 FreeMinecraftModels 腳本、EliteMobs Boss 能力與 EliteMobs NPC 腳本共用。請參閱 context.state 以了解完整參考。


context.log

此處記錄的 logging API 是 FreeMinecraftModels/MagmaCore 的記錄器(infowarnerror)。EliteMobs NPC 腳本使用同一個記錄器;EliteMobs Boss 能力則公開 infowarndebug。請參閱 context.log 以了解完整參考。


context.cooldowns

此處記錄的 cooldown API 使用的是 FreeMinecraftModels 腳本與 EliteMobs NPC 腳本共用的 MagmaCore/FMM 參數順序:check_local(key?, duration)。EliteMobs Boss 能力使用相同的參數順序,但搭配 Boss 專屬的後端儲存。請參閱 context.cooldowns 以了解完整參考。

方法說明
local_ready(key?)檢查本地冷卻是否已就緒。
local_remaining(key?)回傳剩餘的本地冷卻 tick 數,或 0
check_local(key?, duration)以原子方式檢查並啟動本地冷卻。
set_local(duration, key?)設定本地冷卻而不進行檢查。
global_ready()檢查腳本擁有者的共用全域冷卻。
set_global(duration)設定腳本擁有者的共用全域冷卻。

一般的道具或物品動作冷卻請使用 context.cooldowns:check_local("my_key", 40)


執行階段模型

每個腳本實例一個執行階段

每個附加了腳本的道具實體都會獲得自己獨立的 Lua 執行階段實例。當道具生成時,FMM 會載入 Lua 原始碼,在一個全新的沙箱化環境中對其求值,並儲存回傳的表格。當道具被移除時,執行階段會關閉。

對於物品腳本,每個(player, itemId)對會建立一個執行階段。當玩家裝備自訂物品時,FMM 會為該玩家和物品類型建立一個腳本實例。當物品被卸下時,執行階段會關閉。

這表示:

  • 在檔案範圍宣告的本地變數對該腳本實例是私有的。
  • context.state 在實例之間完全隔離,即使它們共用相同的腳本檔案。

排程任務歸屬

所有透過 context.scheduler 建立的任務都歸屬於建立它們的執行階段。當道具被移除時:

  1. 執行階段關閉。
  2. 每個歸屬的任務 -- 一次性與重複的 -- 都會自動取消。
  3. 所有區域監視都會被清除。

Cooldown 範圍

共用的腳本引擎公開了本地冷卻輔助方法(local_readylocal_remainingcheck_localset_local)與全域冷卻輔助方法(global_readyset_global)。FMM 將那些儲存範圍劃分如下:

腳本類型Local 儲存範圍Global 儲存範圍
道具腳本每個 ScriptInstance(道具 + 腳本檔)每個 PropEntity(與繫結到該道具的每個腳本共用)
物品腳本每個 (player, itemId, scriptFile) 三元組 — 即使物品每次離開有效槽位時腳本實例都被拆除,仍能在重新裝備後持久存在每位玩家(與該玩家執行的每個 FMM 物品腳本共用)

由於物品腳本在每次裝備/卸下循環時都會被拆除並重建,物品冷卻時間會保存在以玩家 UUID 為鍵的靜態映射中,而不是放在 ScriptInstance 上。這就是為什麼當你把物品換出快捷欄再換回來後,物品冷卻時間仍然有效。

執行預算

每一次鉤子呼叫、每一個排程回呼,以及腳本檔案本身的初次求值,都在一個硬性的執行預算下執行。這個預算是在 Lua VM 內部強制執行的,因此它會在你的程式碼還在跑的時候就生效,而不是事後才看時鐘。

限制數值
目前執行緒 CPU 時間50 毫秒
執行的 Lua 指令數250,000

先觸及哪一個限制,就會以 Lua 錯誤中止該次呼叫並停用該腳本實例。訊息如下:

Lua instruction budget exceeded (250000 instruction limit)
Lua CPU-time budget exceeded (50ms current-thread CPU limit)

由於檢查是逐指令進行的,while true do end 無法凍結伺服器。

預算中的時間部分是以目前執行緒的 CPU 時間衡量,而不是實際經過時間(wall clock),因此當伺服器執行緒被排程移出時,腳本不會被計入那段時間。在無法取得目前執行緒 CPU 計時的 JVM 上,MagmaCore 會退回使用刻意較寬鬆的 250 毫秒經過時間限制(Lua elapsed-time fallback budget exceeded (250ms fallback; current-thread CPU time unavailable)),同時保留同樣的 250,000 指令上限,因此無論哪一種情況,不會終止的腳本都仍受到限制。

嵌套呼叫共用同一份預算:如果某個鉤子呼叫了一個回呼,而該回呼又呼叫了另一個,整條鏈會被當成單一份 50 毫秒 CPU/250,000 指令的額度來計算,而不是每一層各有一份。

在腳本檔案的初次求值期間還沒有實例存在,因此該定義會被拒絕且永遠不會註冊,而不是被停用。

要保持在預算內:

  • 避免在鉤子內進行無界迴圈。
  • 保持 on_game_tick 處理器輕量 -- 它們每個 tick 都會執行。
  • 使用 context.scheduler:run_repeating(...) 將工作分散到多個 tick。

完整鉤子參考

此表格列出道具與物品腳本所有可用的鉤子。

context.event 欄位描述的是底層的 Bukkit 事件家族。FMM 的 Lua 事件包裝層在適用時仍然只公開 event.playerevent.is_cancelledevent.cancel()event.uncancel()

有效的道具鉤子(7 個)

鉤子觸發時機context.event
on_spawn道具生成到世界中nil
on_game_tick每個伺服器 tick(50 毫秒)nil
on_destroy道具被移除nil
on_left_click玩家左鍵點擊道具damage 事件
on_right_click玩家右鍵點擊道具interaction 事件
on_zone_enter玩家進入受監看區域區域玩家行為者(context.player / context.event.player;不可取消)
on_zone_leave玩家離開受監看區域區域玩家行為者(context.player / context.event.player;不可取消)
保留的道具鉤子

目前的腳本驗證器會接受道具腳本中的 on_projectile_hit,但目前的執行環境尚不會把拋射物命中派送給道具腳本。若要讓拋射物行為綁定在腳本化物品上,請使用物品的 on_projectile_hit;若要在外掛端處理模型化實體的拋射物,請使用 Bukkit 的 ModeledEntityHitByProjectileEvent API。

物品鉤子(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生命週期裝備期間每個 ticknil

後續步驟

  • 範例與模式 -- 完整可運作的道具與物品腳本,含步驟解說
  • 疑難排解 -- 常見問題、除錯訣竅與 QC 檢查清單
  • 入門 -- 檔案結構、鉤子、第一個腳本步驟解說

/fmm reload 會在重建前取消腳本擁有的工作與冷卻。共用工作包括 run_afterrun_everycancel_task;世界提供 raycastplace_temporary_blockdrop_item