跳到主要内容

Lua 脚本:道具与物品 API

本页涵盖了 FreeMinecraftModels 道具和物品脚本可用的所有 API:context.propcontext.itemcontext.eventcontext.playercontext.worldcontext.zonescontext.schedulercontext.statecontext.log。如果您是脚本新手,请先从入门指南开始。


context.prop

道具表提供关于道具实体的信息以及控制其动画的方法。它在每次钩子调用时重新构建。

字段

字段类型说明
prop.model_idstring蓝图模型名称(例如 "torch_01"
prop.current_locationlocation 表构建上下文时道具的位置

location 表具有标准字段: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()

从世界中移除道具并在其位置掉落一个放置用的纸质物品。掉落的物品可以右键点击方块来重新放置道具。

不接受任何参数。

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

返回此道具的模型是否定义了骑乘点骨骼。

不接受任何参数。返回 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 中,再次打开时恢复。

参数类型默认值说明
player实体表必填要显示物品栏的玩家
titlestring必填物品栏标题(支持 & 颜色代码)
rowsint3行数(1-6,其中 6 = 54 格 = 大箱子)

如果物品栏已打开则返回 true,否则返回 false


prop:is_viewing_inventory(player)

返回给定玩家当前是否打开了此道具的物品栏。

参数类型说明
player实体表要检查的玩家

返回 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)

从玩家的主手取走已书写或可书写的书并存储在道具上。

参数类型说明
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.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() 返回字符串表(每行一个)。set_lore() 接受字符串表。

参数类型说明
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)

减少物品的原版耐久度一个固定数量。

参数类型默认值说明
amountint必填要消耗的耐久点数
can_breakbooleanfalse如果为 true,耐久耗尽时物品会被销毁。如果为 false,耐久会停在 1。

item:use_durability_percentage(fraction, can_break)

按最大值的百分比减少物品的原版耐久度。

参数类型默认值说明
fractionnumber必填要消耗的最大耐久度的分数(例如 0.1 = 10%)
can_breakbooleanfalse如果为 true,耐久耗尽时物品会被销毁。如果为 false,耐久会停在 1。

context.event

当前钩子的事件数据。在道具和物品脚本的点击、战斗和交互钩子中可用。在没有关联事件的钩子中返回 nilon_spawnon_game_tickon_destroyon_zone_enteron_zone_leaveon_equip)。

字段和方法

字段或方法类型说明
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 Boss 相同的 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 表用于生成 Boss、增援等 -- 参见 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() -- 详情请参见玩家特定方法


context.zones

zones API 在所有 Nightbreak 插件中共享。完整参考请参见 context.zones


context.scheduler

scheduler API 在所有 Nightbreak 插件中共享。完整参考请参见 context.scheduler


context.state

state API 在所有 Nightbreak 插件中共享。完整参考请参见 context.state


context.log

日志 API 在所有 Nightbreak 插件中共享。完整参考请参见 context.log


运行时模型

每个脚本实例一个运行时

每个附带脚本的道具实体都会获得自己独立的 Lua 运行时实例。当道具生成时,FMM 加载 Lua 源码,在新的沙盒环境中执行,并存储返回的表。当道具被移除时,运行时关闭。

对于物品脚本,每个(玩家,itemId)对创建一个运行时。当玩家装备自定义物品时,FMM 为该玩家和物品类型创建脚本实例。当物品被卸下时,运行时关闭。

这意味着:

  • 在文件作用域声明的局部变量对该脚本实例是私有的。
  • context.state 在实例间完全隔离,即使它们共享同一脚本文件。

调度任务所有权

通过 context.scheduler 创建的所有任务归创建它们的运行时所有。当道具被移除时:

  1. 运行时关闭。
  2. 所有拥有的任务 -- 一次性和重复性的 -- 都自动取消。
  3. 所有区域监视被清除。

执行预算

每次钩子调用和每次回调调用都会计时。如果单次调用超过 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玩家左键点击道具伤害事件
on_right_click玩家右键点击道具交互事件
on_projectile_hit投射物命中道具投射物命中事件
on_zone_enter玩家进入被监视的区域nil
on_zone_leave玩家离开被监视的区域nil

物品钩子(22)

钩子类别触发时机context.event
on_attack_entity战斗玩家攻击实体伤害事件
on_kill_entity战斗玩家击杀实体死亡事件
on_take_damage战斗玩家受到伤害伤害事件
on_shield_block战斗玩家用盾牌格挡伤害事件
on_shoot_bow战斗玩家射箭射箭事件
on_projectile_hit战斗玩家的投射物命中投射物命中事件
on_projectile_launch战斗玩家发射投射物发射事件
on_right_click交互玩家右键点击交互事件
on_left_click交互玩家左键点击交互事件
on_shift_right_click交互玩家 Shift+右键点击交互事件
on_shift_left_click交互玩家 Shift+左键点击交互事件
on_interact_entity交互玩家右键点击实体实体交互事件
on_equip装备物品进入活动栏位nil
on_unequip装备物品离开活动栏位nil
on_swap_hands装备主/副手交换交换事件
on_drop装备玩家丢弃物品丢弃事件
on_break_block实用玩家破坏方块方块破坏事件
on_consume实用玩家消耗物品消耗事件
on_item_damage实用物品受到耐久损耗物品损耗事件
on_fish实用玩家使用钓鱼竿钓鱼事件
on_death实用装备时玩家死亡死亡事件
on_game_tick生命周期装备期间每个刻nil

后续步骤