Lua 脚本:Boss 与实体
本页涵盖 EliteMobs Lua 能力中关于 Boss 和实体包装器的一切:context.boss、context.player、context.players、context.entities,以及它们返回的实体包装表。如果你是 Lua 能力的新手,请先从入门指南开始。
实体包装器
通过 context.boss、context.player、context.players:nearby_players() 等查询结果或事件字段访问实体时,你得到的是包装表,而不是原始 Bukkit 对象。字段保存创建时的快照,方法则在调用时访问服务器。
本页介绍 EliteMobs 原生 Boss 能力包装器。context.world:get_entity(uuid) 等共享 MagmaCore 方法可能返回另一种包装器,其字段延迟读取实时值,方法签名也可能不同,详见共享 API 参考。原生方法支持冒号调用,也支持无需显式传入 self 的点号调用。给包装器字段赋值只会修改 Lua 表;要修改实体,请使用方法。
记住两条规则:
- 像
health、current_location和maximum_health这样的字段是快照。它们反映包装器创建那一刻的状态,不会自动更新。 - 像
get_location()、get_health()和is_alive()这样的方法在每次调用时都会执行一次实时检查。
通用实体字段
每个生命实体包装器都包含以下字段。
| 字段 | 类型 | 备注 |
|---|---|---|
entity.name | string | 显示名称 |
entity.uuid | string | UUID 文本 |
entity.entity_type | string | Bukkit EntityType 名称(例如 "ZOMBIE"、"PLAYER") |
entity.is_player | boolean | 玩家时为 true |
entity.is_elite | boolean | 若 EliteMobs 将其作为精英进行追踪则为 true |
entity.is_mount | boolean | 若此包装器代表一个 Boss 坐骑则为 true |
entity.is_monster | boolean | 怪物类型实体时为 true |
entity.health | number | 当前生命值(快照) |
entity.maximum_health | number | 最大生命值(快照) |
entity.current_location | location 表 | 包装器创建时的位置 |
entity.is_valid | boolean | 包装器创建时的 Bukkit 有效性快照,不只是存在性检查 |
is_valid 是字段而不是方法在生命实体包装器上(包括 context.player 和 context.boss),is_valid 是包装器构建时捕获的一个普通布尔值。调用 entity:is_valid() 会抛出 attempt to call a boolean value 并使该能力被禁用。
- 使用点号读取快照:
entity.is_valid。 - 若需要实时检查,请改为调用
entity:is_alive()—— 它每次都会重新向服务器查询。
在由 summon_projectile、spawn_falling_block_at_location 等函数返回的更轻量的非生命实体引用包装器上,is_valid() 确实是一个真正的方法。那些包装器正是你最有可能跨 tick 保存的对象,实时检查在那里才有意义。
若要读取精英专属数据(如 Boss 等级),请使用下方 context.boss 章节中描述的 context.boss 字段和方法。若要从脚本中让一个精英消失,请调用 entity:remove_elite() 方法。
示例
return {
api_version = 1,
on_enter_combat = function(context)
context.log:info("Boss level: " .. context.boss.level)
end
}
示例
return {
api_version = 1,
on_enter_combat = function(context)
local target = context.players:current_target()
if target ~= nil then
context.log:info("Target: " .. target.name .. " HP: " .. target.health)
end
end
}
通用实体方法
以下方法实时访问服务器。移动、生命值、装备和效果操作属于生命实体包装器;聊天、快捷栏、标题、Boss 血条和玩家命令需要玩家包装器。context.boss:send_message(...) 是向附近玩家广播的独立 Boss 方法。除非明确说明返回值,修改方法返回 nil,不是操作成功标志。
AI、感知、无敌和缩放的修改归做出修改的能力所有。每项修改都会记录它所替换的值:正数持续时间会在指定 tick 后恢复该值,关闭脚本时也会恢复所有仍然生效的修改。多个能力修改同一属性时,结束其中一项修改会恢复剩余修改中最新的那一项;没有剩余修改时则恢复原始值。如果在此期间有其他插件或命令修改了该属性,则保留它们设置的值。暂停脚本不会撤销这些修改。标签持续时间、延迟推力和玩家 Boss 血条使用独立的游戏时钟任务,脚本关闭后仍会继续运行。其他实体修改不会被撤销。
entity:is_alive()
如果实体仍然有效且未死亡,则返回 true。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if context.player:is_alive() then
context.player:send_message("&aYou're still standing!")
end
end
}
entity:get_location()
以 location 表的形式返回当前的实时位置。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
local loc = context.player:get_location()
context.world:play_sound_at_location(loc, "entity.experience_orb.pickup")
end
}
entity:get_eye_location()
以 location 表的形式返回视线高度的位置。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
local eye = context.player:get_eye_location()
context.world:spawn_particle_at_location(eye, "FLAME")
end
}
entity:get_health() / entity:get_maximum_health()
返回实时的当前生命值或最大生命值。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
local pct = context.player:get_health() / context.player:get_maximum_health()
if pct < 0.25 then
context.player:send_message("&cYou're running low!")
end
end
}
entity:get_velocity()
以 vector 表的形式返回实体当前的速度。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
local vel = context.player:get_velocity()
context.log:info("Player speed Y: " .. vel.y)
end
}
entity:send_message(text)
向玩家发送聊天消息,支持 EliteMobs 颜色格式。
| 参数 | 类型 | 备注 |
|---|---|---|
text | string | 带颜色代码的消息 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
context.player:send_message("&6[Boss] &fPrepare yourself!")
end
}
entity:show_action_bar(message)
通过 EliteMobs 的 Lua 快捷栏消息源向玩家发送消息。它参与快捷栏合成,不会为此脚本独占显示区域。
| 参数 | 类型 | 备注 |
|---|---|---|
message | string | 带颜色代码的快捷栏文本 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
context.player:show_action_bar("&c&lDANGER ZONE")
end
}
entity:show_title(title[, subtitle][, fadeIn][, stay][, fadeOut])
向玩家发送标题和可选副标题,支持 EliteMobs 颜色格式。时间参数是整数 tick 数。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
title | string | 标题文本 | |
subtitle | string | "" | 副标题文本 |
fadeIn | number | 10 | 淡入 tick 数 |
stay | number | 40 | 停留 tick 数 |
fadeOut | number | 10 | 淡出 tick 数 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
local nearby = context.players:nearby_players(20)
for _, p in ipairs(nearby) do
p:show_title("&4PHASE 2", "&7The boss is enraged!", 10, 40, 10)
end
end
}
entity:show_boss_bar(title[, color][, style][, duration])
通过 Boss 血条顺序管理器为玩家创建新的血条。颜色和样式名不区分大小写,未知值分别使用 WHITE 和 SOLID。正数持续时间会安排独立的移除计时器,非正数不添加计时器。此方法不返回供以后移除的句柄或键,请使用正数持续时间。此签名与共享 MagmaCore 的键控血条 API 不同。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
title | string | 血条标题文本 | |
color | string | "WHITE" | BarColor 值 |
style | string | "SOLID" | BarStyle 值 |
duration | number | 40 | 持续时间(以 tick 为单位) |
示例
return {
api_version = 1,
on_enter_combat = function(context)
local nearby = context.players:nearby_players(20)
for _, p in ipairs(nearby) do
p:show_boss_bar("&cIncoming Attack!", "RED", "SOLID", 100)
end
end
}
entity:teleport_to_location(location)
请求 Bukkit 传送并返回 nil,不报告传送是否成功。原生位置转换接受 x、y、z、可选的 yaw/pitch、已加载的 world 名称或嵌套的 current_location 表。缺失坐标取 0;省略世界时使用施法 Boss 的世界,不一定是目标实体的世界。显式指定未知世界会转换失败。nil 或非表值使用 Boss 位置。这里不添加安全目的地或区域保护检查。
| 参数 | 类型 | 备注 |
|---|---|---|
location | location 表 | 目的地 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("teleport_pull", 200) then return end
context.player:teleport_to_location(context.boss:get_location())
context.player:send_message("&cThe boss pulls you in!")
end
}
entity:set_velocity_vector(vector)
立即设置实体的速度。
| 参数 | 类型 | 备注 |
|---|---|---|
vector | vector 表 | { x, y, z } 或 { x = 0, y = 1, z = 0 } |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("launch", 100) then return end
context.player:set_velocity_vector({ x = 0, y = 1.5, z = 0 })
context.player:send_message("&cYou are launched into the air!")
end
}
entity:apply_push_vector(vector[, additive][, delay])
保存传入的速度向量,在延迟后应用,默认延迟 1 tick。独立计时器会检查实体是否仍有效。additive = true 时加到执行时的速度上,否则替换该速度。暂停或关闭脚本不会取消推力。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
vector | vector 表 | 方向和强度 | |
additive | boolean | false | 叠加到现有速度上,而非替换 |
delay | number | 1 | 施加前的延迟(以 tick 为单位) |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("push_up", 100) then return end
context.player:apply_push_vector({ x = 0, y = 2.0, z = 0 })
context.player:send_message("&cUpward blast!")
end
}
entity:face_direction_or_location(directionOrLocation)
将实体以新的旋转角度传送到当前位置,从而改变朝向。含字符串 world 或嵌套 current_location 的表被视为目的地,必须与实体在同一世界。只有 x/y/z 的表被视为方向向量。零向量不执行操作。
| 参数 | 类型 | 备注 |
|---|---|---|
directionOrLocation | vector 表或 location 表 | 要朝向的目标 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
context.player:face_direction_or_location(context.boss:get_location())
context.player:send_message("&cThe boss forces you to look at it!")
end
}
entity:set_fire_ticks(ticks)
设置 Bukkit 燃烧 tick 数。调用时重新按实例效果规则检查目标。玩家必须在线、存活且与效果来源处于同一世界;实例中的玩家还必须属于有效比赛及其参与者列表。其他生命实体必须有效。此操作不保证火焰造成伤害。
| 参数 | 类型 | 备注 |
|---|---|---|
ticks | number | 着火持续时间(以 tick 为单位,20 tick = 1 秒) |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("ignite", 100) then return end
context.player:set_fire_ticks(60)
context.player:send_message("&cYou catch fire!")
end
}
entity:add_visual_freeze_ticks([ticks])
增加 Bukkit 的实际冻结 tick 数,遵守与 set_fire_ticks 相同的实例效果规则。它不只是数据包层面的画面覆盖,也不会直接冻结 AI 或移动;正常的 Minecraft 冻结行为可能生效。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
ticks | number | 1 | 冻结 tick 数量 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("freeze", 200) then return end
context.player:add_visual_freeze_ticks(100)
context.player:send_message("&bYou feel a chilling frost!")
end
}
entity:apply_potion_effect(effect, duration[, amplifier])
通过与 set_fire_ticks 相同的实例效果检查后,施加 Bukkit 药水效果。名称不区分大小写,未知名称会警告且不执行操作。替换已有状态遵循 Bukkit 的效果规则,不会强制覆盖所有现有效果。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
effect | string | PotionEffectType 名称 | |
duration | number | 持续时间(以 tick 为单位) | |
amplifier | number | 0 | 效果等级(0 = 等级 I) |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("slow", 200) then return end
context.player:apply_potion_effect("SLOWNESS", 60, 1)
context.player:send_message("&7You feel sluggish...")
end
}
remove_potion_effect(effect) 不适用于 EliteMobs 原生 Boss 能力实体包装器,但共享 MagmaCore 包装器提供此方法。施加效果时请设置合适的持续时间。再次施加持续时间为 0 的效果并不能可靠地移除现有效果。
entity:deal_damage(amount) / entity:deal_custom_damage(amount) / entity:deal_damage_from_boss(amount)
向 Bukkit 提交伤害。三种方法都返回 nil;请求量不能证明实际损失的生命值。战斗规则及后续监听器可能修改或取消攻击。
| 方法 | 备注 |
|---|---|
deal_damage(amount) | 不指定攻击者,调用 Bukkit 伤害方法 |
deal_custom_damage(amount) | 以施法 Boss 调用 BossCustomAttackDamage,拒绝自身、无敌或死亡目标,以及非 Survival/Adventure 玩家;提交自定义攻击后清除原生伤害冷却 |
deal_damage_from_boss(amount) | 以施法 Boss 为攻击者调用 Bukkit 伤害方法,可能进入正常 EliteMobs 战斗处理 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
local nearby = context.players:nearby_players(10)
for _, p in ipairs(nearby) do
p:deal_custom_damage(10)
p:send_message("&cThe boss unleashes a shockwave!")
end
end
}
entity:restore_health(amount)
对追踪中的精英调用 EliteMobs 治疗并触发可取消的 EliteMobHealEvent。其他生命实体直接回复到最大生命属性的基础值,这可能不同于 get_maximum_health() 返回的实际最大值。请传入非负数量;此方法不是会自动限制输入的伤害 API。
| 参数 | 类型 | 备注 |
|---|---|---|
amount | number | 回复量 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
-- Heal the player slightly when they hit the boss
context.player:restore_health(5)
context.player:send_message("&aYou drain life from the boss!")
end
}
entity:set_invulnerable(enabled[, duration])
设置实体的无敌状态,并记录它所替换的值。正数持续时间会在指定 tick 后恢复该值;否则修改会一直持续到该能力关闭,关闭时同样会恢复。同一能力再次调用时,会替换该能力之前的修改。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
enabled | boolean | true 表示启用无敌 | |
duration | number | 0 | 在这些 tick 后恢复被替换的值;0 表示修改保持到能力关闭为止 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("shield", 200) then return end
context.player:set_invulnerable(true, 40)
context.player:send_message("&6A brief shield protects you!")
end
}
entity:set_ai_enabled(enabled[, duration])
设置实体的 AI,并记录它所替换的值。正数持续时间会在指定 tick 后恢复该值;否则修改会一直持续到该能力关闭,关闭时同样会恢复。当该能力持有 AI 修改时调用 set_ai_enabled(true),会结束该修改并恢复被替换的值,而不是再应用一项新修改。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
enabled | boolean | true 表示启用 AI | |
duration | number | 0 | 在这些 tick 后恢复被替换的值;0 表示修改保持到能力关闭为止 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
-- Disable boss AI for 3 seconds at combat start
context.boss:set_ai_enabled(false, 60)
context.boss:send_message("&7The boss is stunned!")
end
}
entity:add_tag(tag[, duration]) / entity:remove_tag(tag) / entity:has_tag(tag)
管理追踪中精英及已加载 EliteMobs 玩家背包数据的玩家标签。它们不是 Bukkit 计分板标签,不适用于普通未追踪生物。标签区分大小写。到期计时器独立运行,旧计时器可能移除后来重新添加的同名标签。
| 方法 | 参数 | 备注 |
|---|---|---|
add_tag(tag[, duration]) | string,可选 number | 添加标签,可选择在若干 tick 后自动移除 |
remove_tag(tag) | string | 移除该标签 |
has_tag(tag) | string | 如果存在该标签则返回 true |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.player:has_tag("marked") then
context.player:add_tag("marked", 200)
context.player:send_message("&cYou have been marked!")
end
end
}
entity:run_command(command)
立即以玩家身份及其权限运行命令,返回 nil。这是玩家专用方法,不展开占位符。命令不要带开头的 /。
| 参数 | 类型 | 备注 |
|---|---|---|
command | string | 不带开头 / 的命令文本 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("curse_cmd", 200) then return end
context.player:run_command("say I have been cursed!")
end
}
entity:set_scale(scale[, duration])
在可用时设置实体缩放属性的基础值,并记录它所替换的值。正数持续时间会在指定 tick 后恢复该值;否则修改会一直持续到该能力关闭,关闭时同样会恢复。属性修饰符仍可能使实际大小有所不同。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
scale | number | 缩放倍数 | |
duration | number | 0 | 在这些 tick 后恢复被替换的缩放值;0 表示修改保持到能力关闭为止 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
-- Boss grows to double size for 5 seconds
context.boss:set_scale(2.0, 100)
context.boss:send_message("&4The boss grows in size!")
end
}
entity:set_gravity(enabled)
设置实体重力,不自动恢复。下面的恢复回调属于 Lua 实例,脚本关闭后可能不会执行。
| 参数 | 类型 | 备注 |
|---|---|---|
enabled | boolean | true 表示正常重力 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("levitate", 200) then return end
-- Change the boss's gravity; the callback runs only while this script stays active.
context.boss:set_gravity(false)
context.scheduler:run_after(60, function(tick_context)
if tick_context.boss.exists then
tick_context.boss:set_gravity(true)
end
end)
end
}
entity:play_sound_at_entity(sound[, volume][, pitch])
在实体所在位置播放一个声音。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
sound | string | Minecraft 声音键,例如 "entity.ender_dragon.growl",或 Spigot Sound 枚举名。也支持资源包声音键 | |
volume | number | 1.0 | 音量 |
pitch | number | 1.0 | 音调 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
context.player:play_sound_at_entity("entity.ender_dragon.growl", 1.0, 0.5)
end
}
entity:play_sound_at_self(sound[, volume][, pitch])
play_sound_at_entity 的别名。在实体所在位置播放一个声音。
entity:spawn_particle_at_self(particleOrSpec[, count])
在实体当前位置生成粒子,使用与原生世界方法相同的粒子规格。表中的 amount 优先于备用的 count。名称转为大写,不支持的数据依赖型粒子会警告而不生成。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
particleOrSpec | string 或 table | 粒子名称或粒子规格表 | |
count | number | 1 | 粒子数量 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
context.player:spawn_particle_at_self("HEART", 5)
end
}
entity:spawn_particles_at_location(location, particle[, count])
在指定位置生成粒子。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
location | location 表 | 目标位置 | |
particle | string | 粒子类型名称 | |
count | number | 1 | 粒子数量 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
local loc = context.player:get_location()
context.player:spawn_particles_at_location(loc, "FLAME", 10)
end
}
entity:play_model_animation(name)
仅当 EliteMobs 将实体追踪为具有自定义模型的自定义 Boss 时请求动画。返回 nil,不等待完成,也不报告动画名是否存在。普通带模型实体不满足此原生方法的条件。
| 参数 | 类型 | 备注 |
|---|---|---|
name | string | 动画名称 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
context.boss:play_model_animation("attack_swing")
end
}
载具与乘客方法
生命实体包装器也提供 Bukkit 载具与乘客方法。包装器参数通过 Bukkit UUID 解析,不接受单独的 UUID 字符串。骑乘会拒绝缺失、相同或无效实体,临时绕过 EliteMobs 的坐骑漏洞防护,并返回 Bukkit 是否接受操作。这些方法不会注册脚本运输路线,也不安排脚本关闭时的清理。
| 方法 | 返回值 | 备注 |
|---|---|---|
entity:is_inside_vehicle() | boolean | 如果该实体正骑乘在另一个实体上则为 True。 |
entity:has_vehicle() | boolean | 如果该实体当前拥有载具则为 True。 |
entity:get_vehicle() | 实体包装器或 nil | 返回当前载具的包装器。 |
entity:set_vehicle(vehicle) | boolean | 让该实体骑乘 vehicle。 |
entity:leave_vehicle() | boolean | 让该实体离开其当前载具。 |
entity:has_passengers() | boolean | 如果该实体拥有乘客则为 True。 |
entity:get_passenger_count() | number | 乘客数量。 |
entity:get_passengers() | table | 乘客包装器的数组。 |
entity:add_passenger(passenger) | boolean | 为该实体添加一个乘客。 |
entity:remove_passenger(passenger) | boolean | 从该实体移除一个乘客。 |
entity:eject_passengers() | boolean | 弹出所有乘客。 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if context.player:has_vehicle() then
context.player:leave_vehicle()
end
end
}
entity:push_relative_to(source[, strength][, xOffset][, yOffset][, zOffset])
将从源位置指向实体的位移归一化,乘以 strength,加上世界轴偏移,立即用结果替换速度。位置重合时仍使用偏移。包装器提供的是保存的 current_location,需要实时位置时请传入 source:get_location()。此方法不检查世界是否一致,只应使用同一世界的位置。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
source | location 表或包装器 | 推力的起点 | |
strength | number | 1.0 | 推力强度倍率 |
xOffset | number | 0 | 额外的 X 偏移 |
yOffset | number | 0 | 额外的 Y 偏移 |
zOffset | number | 0 | 额外的 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("knockback", 60) then return end
context.player:push_relative_to(context.boss:get_location(), 2.0, 0, 0.5, 0)
context.player:send_message("&cThe boss knocks you back!")
end
}
entity:set_custom_name(name) / entity:reset_custom_name()
使用颜色格式设置 Bukkit 自定义名称。重置时,追踪中的精英使用配置名称;未追踪实体使用其当前 getName(),因此不会恢复预先保存的原名。这不会修改玩家账号名或包装器的快照字段。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("mark", 200) then return end
context.boss:set_custom_name("&c&lEnraged Boss")
context.boss:send_message("&cThe boss is enraged!")
-- Reset after 5 seconds
context.scheduler:run_after(100, function(tick_context)
if tick_context.boss:is_alive() then
tick_context.boss:reset_custom_name()
end
end)
end
}
entity:place_temporary_block(material[, duration][, requireAir])
在实体当前位置放置临时方块,返回 nil,包括 requireAir 阻止放置的情况。持续时间为正数时,在计时器结束、区块或世界卸载,或插件关闭时,会恢复保存的方块数据(不恢复容器内容),但前提是该位置仍是这个临时方块。在同一临时方块上再次放置会重新开始计时。带有方块实体的方块(例如箱子)以及被其他临时方块所有者占用的方块会被跳过。破坏该方块不会掉落任何东西。非正数持续时间会永久放置方块且不进行追踪。请使用方块材质并自行检查保护规则。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
material | string | 方块材质名称 | |
duration | number | 0 | 正数表示恢复前的 tick 数;非正数会永久放置方块 |
requireAir | boolean | false | 仅当该方块当前为空气时才放置 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
if not context.cooldowns:check_local("ice_trap", 200) then return end
context.player:place_temporary_block("ICE", 60, true)
context.player:send_message("&bIce forms at your feet!")
end
}
entity:get_height()
以方块为单位返回实体的高度。
entity:is_on_ground()
返回 Bukkit 当前的 isOnGround() 标志,不重新查询方块或头部空间。
entity.is_valid
在生命实体包装器上,这是布尔字段,不是方法。它记录包装器创建时的 Bukkit 有效性,不只是实体是否存在。请用点号读取 entity.is_valid,用冒号调用会报错。
由于它只是一份快照,会随时间过期,因此不能替代实时检查。当你需要当前状态时请使用 entity:is_alive();对于你跨 tick 保存下来的非生命实体引用包装器,则使用 is_valid()(方法)。
entity:is_frozen()
如果实体(作为自定义 Boss 进行追踪时)设置了冻结标志,则返回 true。
entity:set_awareness_enabled(aware[, duration])
设置怪物的感知状态,并记录它所替换的值。仅影响 Mob 类型实体。正数持续时间会在指定 tick 后恢复该值;否则修改会一直持续到该能力关闭,关闭时同样会恢复。当该能力持有感知修改时以 true 调用,会结束该修改,而不是再应用一项新修改。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
aware | boolean | true 表示启用感知 | |
duration | number | 0 | 在这些 tick 后恢复被替换的值;0 表示修改保持到能力关闭为止 |
entity:is_healing() / entity:set_healing(enabled)
读取或设置追踪中精英的治疗状态标志,不直接回复生命值,也不启动治疗计时器。set_healing(true) 会在精英尚未处于治疗状态时将其标记为治疗中;set_healing(false) 只清除由该能力设置的治疗状态。能力关闭时,会清除它仍持有的所有治疗标志。未追踪实体的读取结果为 false,写入不产生变化。
entity:overlaps_box_at_location(center[, halfX][, halfY][, halfZ])
检查实体碰撞箱是否与数值定义的轴对齐盒子重叠,不比较世界。请传入与实体同世界的中心。无法解析中心时返回 false。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
center | location 表 | 测试盒子的中心 | |
halfX | number | 0.5 | X 轴上的半宽 |
halfY | number | 与 halfX 相同 | Y 轴上的半高 |
halfZ | number | 与 halfX 相同 | Z 轴上的半宽 |
entity:remove_elite()
将精英实体从 EliteMobs 的追踪中移除。如果该实体是精英,这会通过 EliteMobs 正确地让其消失。
entity:remove()
移除由脚本生成的普通生物实体,例如盔甲架。成功移除时返回 true。玩家和精英会被拒绝并返回 false;让精英消失请使用 remove_elite()。
entity:set_invisible(enabled) 和 entity:set_silent(enabled)
set_invisible 会隐藏实体的身体;穿戴和手持的物品仍然可见。set_silent 会让实体自身的声音静音。
entity:set_marker(enabled)
仅适用于盔甲架。这四个方法只存在于盔甲架包装对象上,其他所有实体都没有。
| 方法 | 效果 |
|---|---|
set_marker(enabled) | 标记盔甲架没有碰撞箱,无法被击中或碰撞 |
set_small(enabled) | 半尺寸的盔甲架 |
set_base_plate(enabled) | 显示或隐藏石头底座 |
set_arms(enabled) | 显示或隐藏手臂 |
如果只需要纯视觉的悬浮物品或方块,建议使用 world:spawn_display_at_location,它不需要上述任何方法。
entity:set_custom_name_visible(visible)
设置实体的自定义名称是始终可见,还是仅在被注视时可见。
| 参数 | 类型 | 备注 |
|---|---|---|
visible | boolean | true 表示始终可见 |
entity:set_equipment(slot, material[, options])
用新建的材质物品替换所选槽位。槽位、材质和附魔名称不区分大小写。未知槽位或材质不执行操作;未知附魔被跳过,已识别附魔使用不受常规限制的等级。此方法不加载自定义物品文件,也不保留原物品的元数据,返回 nil。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
slot | string | 装备槽位:"HEAD"、"CHEST"、"LEGS"、"FEET"、"HAND"、"OFF_HAND" | |
material | string | 材质名称(例如 "DIAMOND_SWORD"、"IRON_HELMET") | |
options | table | {} | 可选设置(见下文) |
options 表:
| 键 | 类型 | 默认值 | 备注 |
|---|---|---|---|
enchantments | 表的数组 | nil | 每个条目:{ type = "SHARPNESS", level = 2 } |
unbreakable | boolean | false | 该物品是否不可破坏 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
-- Give the boss a glowing diamond sword
context.boss:set_equipment("HAND", "DIAMOND_SWORD", {
unbreakable = true,
enchantments = {
{ type = "SHARPNESS", level = 5 }
}
})
end
}
entity:damage_equipment(slot, amount)
损伤 HAND、OFF_HAND、HEAD、CHEST、LEGS 或 FEET 槽位的物品,返回实际应用的耐久损伤。每次请求 1 到 64 点。缺失、没有耐久值或不可破坏的物品返回 0。
玩家操作触发 PlayerItemDamageEvent,遵守取消及修改后的数量。监听器可以把数量提高到原始请求上限 64 以上,但最终仍受剩余耐久限制。达到最大损伤时会移除整个物品堆叠,并触发玩家的 PlayerItemBreakEvent。支持自定义最大损伤元数据,不自行计算耐久附魔减免。无效槽位或超出 1..64 的请求会引发 Lua 参数错误。
entity:is_ai_enabled()
实体当前启用 AI 时返回 true。追踪中的精英读取 EliteMobs 的逻辑 AI 状态,包括原生行为的控制权,而不只依赖底层 Bukkit AI 标志。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.boss:is_ai_enabled() then
context.log:info("Boss AI is active")
else
context.log:info("Boss AI is disabled (stunned?)")
end
end
}
非生命实体引用包装器
当生成的实体不是 LivingEntity 时——例如下落的方块、投射物或火球——你会得到一个更轻量的引用包装器。它们由诸如 context.world:spawn_falling_block_at_location() 或 context.boss:summon_projectile() 之类的方法返回。
快照字段: name、uuid、entity_type、is_player(固定为 false)、is_elite(固定为 false)、is_mount(通常为 false;boss:get_mount() 将其设为 true)、current_location
方法:
| 方法 | 备注 |
|---|---|
is_valid() | 实时有效性检查。与生命实体包装器不同,这里它确实是一个方法 |
get_location() | 当前实时位置 |
get_velocity() | 当前速度向量 |
is_on_ground() | 是否在地面上 |
teleport_to_location(location) | 传送该实体 |
set_velocity_vector(vector) | 设置速度 |
set_direction_vector(vector) | 设置方向(仅限 Fireball) |
set_yield(value) | 设置爆炸威力(仅限 Fireball) |
set_gravity(enabled) | 切换重力 |
detonate() | 请求引爆烟花实体,对其他类型不生效 |
remove() | 将该实体从世界中移除 |
unregister([reason]) | 对追踪器识别的实体执行 EliteMobs 移除流程,未追踪实体不变 |
这些包装器也提供全部载具与乘客方法,包括 is_inside_vehicle()、get_vehicle()、set_vehicle(v)、add_passenger(p) 和 eject_passengers() 等,因此可以让 Boss 乘坐非生物实体。
unregister 接受不区分大小写的移除原因,默认为 OTHER,不是布尔成功查询。包装器方法保留底层实体引用,使用保存的引用前请调用 is_valid()。Lua 实例安排的延迟移除会在实例关闭时被取消;若清理必须在脚本结束后继续,请使用合适的原生持续时间或所有者追踪。
示例
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", 100) then return end
local fb = context.boss:summon_projectile("FIREBALL",
context.boss:get_eye_location(),
context.player:get_location(),
1.5
)
if fb == nil then return end
-- fb is a non-living reference wrapper; remove it after 5 seconds if still alive
context.scheduler:run_after(100, function()
if fb:is_valid() then
fb:remove()
end
end)
end
}
context.player
当事件的直接目标或行为者能解析为玩家时可用,包括 on_boss_damaged_by_player 和 on_player_damaged_by_boss,优先使用直接目标。玩家包装器提供通用生命实体方法,但要求追踪中精英或自定义 Boss 的方法对普通玩家不生效。以下额外内容仅供玩家使用。
在没有关联玩家的钩子中,context.player 为 nil,例如 on_spawn、计划回调和计时器钩子。使用前请始终进行 nil 保护检查。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
context.player:send_message("&cHello!")
end
}
仅玩家可用的字段
| 字段 | 类型 | 备注 |
|---|---|---|
game_mode | string | 创建时的游戏模式快照,使用大写名称,例如 "SURVIVAL" |
仅玩家可用的方法
| 方法 | 备注 |
|---|---|
send_message(message) | 带 EliteMobs 颜色格式化的聊天消息 |
show_action_bar(message) | 快捷栏文本 |
show_title(title[, subtitle][, fadeIn][, stay][, fadeOut]) | 标题屏幕覆盖层 |
show_boss_bar(title[, color][, style][, duration]) | 临时 Boss 血条 |
run_command(command) | 以玩家身份运行命令(不带开头的 /) |
示例
return {
api_version = 1,
on_player_damaged_by_boss = function(context)
if context.player == nil then return end
local hp_pct = context.player:get_health() / context.player:get_maximum_health()
if hp_pct < 0.3 then
context.player:show_title("&4LOW HEALTH", "&7Find cover!", 5, 30, 10)
context.player:show_boss_bar("&cBoss Enrage Incoming", "RED", "SEGMENTED_6", 80)
end
end
}
context.boss
拥有此 Lua 能力的精英怪包装器。底层实体不存在时,不会提供完整的生命实体字段和方法。
底层实体存在时,Boss 包装器继承通用生命实体操作,但不包含玩家专用的界面和命令操作。本节方法是 Boss 专属方法,或通过 EliteEntity 层执行不同行为的方法。
Boss 字段
| 字段 | 类型 | 备注 |
|---|---|---|
boss.name | string | 显示名称 |
boss.uuid | string | Boss 精英的 UUID |
boss.entity_type | string | Bukkit EntityType 名称 |
boss.is_monster | boolean | 如果底层实体是 Monster 则为 true |
boss.level | number | 精英等级 |
boss.health | number | 当前生命值(快照) |
boss.maximum_health | number | 最大生命值(快照) |
boss.damager_count | number | 伤害施加者的数量(快照) |
boss.is_in_combat | boolean | 战斗状态快照 |
boss.exists | boolean | 该精英是否存在的快照 |
boss.current_location | location 表 | 包装器创建时的位置(快照) |
示例
return {
api_version = 1,
on_spawn = function(context)
context.log:info(context.boss.name .. " level " .. context.boss.level)
end
}
Boss 方法
巡逻移动方法
配置了巡逻的首领会提供 patrol_pause()、patrol_resume()、walk_to(x, y, z)、hold(x, y, z) 和 teleport(x, y, z)。坐标是相对于生成位置的偏移,每个方法都返回请求是否被接受。walk_to 到达后恢复路线;hold 等待 patrol_resume();长距离使用自动求解器。
boss:is_alive()
如果 Boss 实体有效、未死亡且该精英仍然存在,则返回 true。对于实时检查,请使用此方法而非 exists 字段。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.boss:is_alive() then return end
context.boss:send_message("&cI still live!")
end
}
boss:get_location()
以 location 表的形式返回 Boss 当前的实时位置。
示例
return {
api_version = 1,
on_enter_combat = function(context)
local loc = context.boss:get_location()
context.world:spawn_particle_at_location(loc, "FLAME")
end
}
boss:get_eye_location()
返回 Boss 视线高度的位置。
示例
return {
api_version = 1,
on_enter_combat = function(context)
local eye = context.boss:get_eye_location()
context.world:spawn_particle_at_location(eye, "SMOKE")
end
}
boss:set_ai_enabled(enabled[, duration])
设置 Boss 的 AI,遵循与 entity:set_ai_enabled 相同的修改归属规则:正数持续时间会恢复被替换的值,关闭能力时会恢复所有仍然生效的修改。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
enabled | boolean | true 表示启用 AI | |
duration | number | 0 | 在这些 tick 后恢复被替换的值;0 表示修改保持到能力关闭为止 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.cooldowns:check_local("stun", 200) then return end
context.boss:set_ai_enabled(false, 60)
context.boss:send_message("&7The boss is stunned for 3 seconds!")
end
}
boss:teleport_to_location(location)
请求传送 Boss,但不修改配置中的生成位置或巡逻路线。返回 nil,不是传送成功标志。
| 参数 | 类型 | 备注 |
|---|---|---|
location | location 表 | 目的地 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.cooldowns:check_local("retreat", 300) then return end
local spawn = context.entities:get_boss_spawn_location()
context.boss:teleport_to_location(spawn)
context.boss:send_message("&7The boss retreats to its lair!")
end
}
boss:set_velocity_vector(vector)
立即设置 Boss 的速度。
| 参数 | 类型 | 备注 |
|---|---|---|
vector | vector 表 | { x, y, z } 或 { x = 0, y = 1, z = 0 } |
示例
return {
api_version = 1,
on_enter_combat = function(context)
-- Boss leaps into the air at combat start
context.boss:set_velocity_vector({ x = 0, y = 2.0, z = 0 })
context.boss:send_message("&cThe boss leaps!")
end
}
boss:restore_health(amount)
用非负数量治疗 Boss,上限为 EliteMobs 最大生命值与最大生命属性基础值中的较小者。会触发可取消的 EliteMobHealEvent,返回 nil。
| 参数 | 类型 | 备注 |
|---|---|---|
amount | number | 回复量 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.cooldowns:check_local("heal", 200) then return end
context.boss:restore_health(20)
context.boss:send_message("&aThe boss regenerates!")
context.boss:spawn_particle_at_self("HEART")
end
}
boss:play_sound_at_self(sound[, volume][, pitch])
在 Boss 所在位置播放一个声音。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
sound | string | Minecraft 声音键,例如 "entity.wither.spawn",或 Spigot Sound 枚举名。也支持资源包声音键 | |
volume | number | 1.0 | 音量 |
pitch | number | 1.0 | 音调 |
示例
return {
api_version = 1,
on_spawn = function(context)
context.boss:play_sound_at_self("entity.wither.spawn", 1.0, 0.8)
end
}
boss:spawn_particle_at_self(particleOrSpec[, count])
在 Boss 所在位置生成粒子。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
particleOrSpec | string 或 table | 粒子名称或粒子规格表 | |
count | number | 1 | 粒子数量 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
context.boss:spawn_particle_at_self("SMOKE", 20)
context.boss:send_message("&8Smoke billows from the boss!")
end
}
boss:play_model_animation(name)
如果可用,则在 Boss 上播放一个自定义模型动画。
| 参数 | 类型 | 备注 |
|---|---|---|
name | string | 动画名称 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
context.boss:play_model_animation("slam")
end
}
boss:has_mount() / boss:get_mount()
检查或返回此 Boss 当前所骑乘的实体。如果 Boss 没有坐骑,boss:get_mount() 返回 nil。当返回一个坐骑时,其包装器的 is_mount = true。
示例
return {
api_version = 1,
on_enter_combat = function(context)
local mount = context.boss:get_mount()
if mount ~= nil then
context.log:info("Boss is mounted on " .. mount.entity_type)
end
end
}
boss:set_mount(entity) / boss:clear_mount() / boss:dismount()
让 Boss 骑乘或下乘。boss:set_mount(entity) 让 Boss 骑乘所提供的实体包装器,如果 Bukkit 接受了该乘客变更则返回 true。boss:clear_mount() 和 boss:dismount() 都会让 Boss 离开其当前载具。
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if not context.cooldowns:check_local("mount_check", 100) then return end
if context.boss:has_mount() then
context.boss:dismount()
end
end
}
boss:face_direction_or_location(vectorOrLocation)
使 Boss 朝向某个方向或位置。
| 参数 | 类型 | 备注 |
|---|---|---|
vectorOrLocation | vector 表或 location 表 | 要朝向的方向 |
示例
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then return end
context.boss:face_direction_or_location(context.player:get_location())
end
}
boss:navigate_to_location(location[, speed][, forceTeleport][, timeout])
使用寻路让 Boss 走向指定位置。仅适用于自定义 Boss。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
location | location 表 | 目的地 | |
speed | number | 1.0 | 移动速度倍率 |
forceTeleport | boolean | false | 若经过 timeout 仍未抵达,将 Boss 传送至目的地 |
timeout | number | 0 | 放弃导航前等待的 tick 数。0 使用内置默认值 100 tick(5秒) |
当 Boss 距离目的地不足一个方块、不再存在或离开目的地所在世界时,导航也会停止。开始新的导航会取消该 Boss 原先正在进行的导航。它使用独立 Bukkit 任务,暂停或关闭 Lua 实例不会取消。目的地在调用时保存,返回 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("charge", 200) then return end
context.boss:navigate_to_location(context.player:get_location(), 1.5)
context.boss:send_message("&cThe boss charges at you!")
end
}
boss:add_tag(tag[, duration]) / boss:remove_tag(tag) / boss:has_tag(tag)
管理 Boss 上的标签。
示例
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("phase2") then
context.boss:add_tag("phase2")
context.boss:send_message("&4Entering Phase 2!")
end
end
}
boss:send_message(message[, range])
向 Boss 同世界球形三维范围内的所有玩家发送带格式的聊天消息,不按游戏模式、视线、战斗参与或实例成员身份筛选。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
message | string | 带颜色代码的消息文本 | |
range | number | 20 | 半径(以方块为单位) |
示例
return {
api_version = 1,
on_enter_combat = function(context)
context.boss:send_message("&4You dare challenge me?!")
end
}
boss:summon_projectile(entityType, origin, destination[, speed][, options])
创建实体并返回原生包装器;位置无法解析或实体类型未知时返回 nil。已识别但不能生成的类型仍可能失败。普通 Bukkit 投射物从 Boss 发射,除非设置 spawn_at_origin = true;提供的起点仍用于计算朝向目的地的方向。此方法不检查两个位置的世界是否一致,请确保它们在同一世界。非投射物在提供的起点生成,并使用对应的生命或非生命包装器。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
entityType | string | 实体类型(例如 "FIREBALL"、"ARROW") | |
origin | location 表 | 发射位置 | |
destination | location 表 | 目标位置 | |
speed | number | 1.0 | 投射物速度 |
options | table | {} | 见下方选项 |
options 表:
| 键 | 类型 | 备注 |
|---|---|---|
duration | number | 正数安排独立计时器,在这些 tick 后移除;非正数不添加计时器 |
max_ticks | number | 落地监测上限,默认为 6000 |
custom_damage | number | 投射物战斗处理使用的自定义伤害元数据,不保证生命损失量 |
detonation_power | string | 爆炸投射物元数据使用的能力文件名,不是数值爆炸强度 |
yield | number | 爆炸威力(Fireball) |
persistent | boolean | 提供时设置 Bukkit 持久性,不覆盖持续时间、碰撞或所有者移除 |
effect | string | 生成时播放的 EntityEffect 名称 |
incendiary | boolean | 爆炸是否为燃烧性 |
gravity | boolean | 投射物是否有重力 |
glowing | boolean | 发光效果 |
invulnerable | boolean | 投射物是否无敌 |
track | boolean | 默认为 true:向 EliteMobs 注册投射物,不会使其追踪目标。 |
spawn_at_origin | boolean | 默认为 false:普通投射物从 Boss 处发射。设为 true 才会在指定起点生成。 |
direction_only | boolean | 对显式起点生成的火球,设置方向后不额外设置速度 |
on_land | function | 接地、失效或超过 max_ticks 时的回调 (landing_location, spawned_entity),不只在撞击时触发 |
direction_only 影响在指定起点显式生成的火球,跳过设置方向后的额外速度赋值。目的地仍决定方向。Bukkit 投射物以 Boss 为射手。track = true 会向 EliteMobs 注册投射物,并将其纳入 Boss 增援的生命周期;此追踪不适用于非投射物类型。track = false 不参与所有者清理,需要另行安排移除。
on_land 监测属于 Lua 实例,在实例关闭时停止。它在接地、失效或计数器超限时调用一次 (landing_location, spawned_entity),监测本身不会移除实体。正数 duration 计时器独立运行,脚本关闭后仍继续。因此,回调发生并不证明投射物命中了目标。
示例
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", 100) then return end
context.boss:summon_projectile(
"FIREBALL",
context.boss:get_eye_location(),
context.player:get_location(),
1.5,
{
custom_damage = 10,
on_land = function(loc, entity)
context.world:spawn_particle_at_location(loc, "EXPLOSION")
end
}
)
end
}
boss:summon_reinforcement(filename[, zoneOrLocation][, duration])
从自定义 Boss 文件静默召唤增援,记录召唤者,并在自定义 Boss 召唤者使用标准化战斗时继承该模式。增援等级由其自身配置和动态等级规则决定。区域会随机选择采样位置,若没有位置则使用中心;解析失败时回退到 Boss 位置。返回存活增援的生命实体包装器,未生成存活增援时返回 nil。
| 参数 | 类型 | 备注 |
|---|---|---|
filename | string | Boss 配置文件名 |
zoneOrLocation | location 表或 zone | 可选的生成位置或区域定义。默认为 Boss 的位置。 |
duration | number | 可选的正数逃离时间,以 tick 为单位。默认 0 不添加此方法的计时器;不是等级覆盖值 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
context.boss:summon_reinforcement("my_minion.yml", context.boss:get_location(), 0)
context.boss:send_message("&cMinions, come to my aid!")
end
}
boss:despawn()
通过 EliteMobs 以原因 OTHER 移除 Boss。boss:remove() 是使用相同生命周期的别名。此操作不是伤害命中,也不是正常死亡奖励请求。
示例
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.1 then
context.boss:send_message("&7The boss vanishes into thin air!")
context.boss:despawn()
end
end
}
boss:get_nearby_players(range)
返回 Boss 同世界球形三维范围内的玩家包装器数组,不按游戏模式、视线或实例参与筛选,也不按距离排序。
| 参数 | 类型 | 备注 |
|---|---|---|
range | number | 半径(以方块为单位) |
示例
return {
api_version = 1,
on_enter_combat = function(context)
local players = context.boss:get_nearby_players(30)
for _, p in ipairs(players) do
p:show_action_bar("&cThe boss sees you!")
end
end
}
boss:get_damager_count()
返回 Boss 已记录攻击者映射的当前大小。与 damager_count 字段不同,这是实时读取,但不代表附近或当前在线的战斗参与者人数。
boss:get_nearby_elites(radius)
返回 Boss 同世界内最多 32 个存活且受追踪的精英,排除 Boss 自身。半径必须有限、大于 0 且不超过 64 个方块。结果为生命实体包装器,按距离排序,同距离以精英 UUID 决定顺序。此查询本身并不证明某个效果可以作用于所有结果。
boss:get_target_player()
以玩家包装器的形式返回 Boss 当前的怪物目标,如果目标不是玩家或未设定,则返回 nil。
区域与粒子方法
这些方法将区域与粒子效果结合在一起。它们需要一个 zone 表作为输入。
boss:get_nearby_players_in_zone(zone)
返回 Boss 世界内满足原生区域形状的玩家包装器,不按游戏模式或实例参与筛选。每次重新查询,不是持续监测器。
| 参数 | 类型 | 备注 |
|---|---|---|
zone | zone 表 | 一个区域形状定义 |
boss:spawn_particles_in_zone(zone, particle[, amount][, x][, y][, z][, speed][, coverage])
用粒子填充区域内部。参数必须按位置传入,此方法不接受规格表。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
zone | zone 表 | 使用原生 kind 格式的区域形状;参阅区域与目标选择 | |
particle | string | 粒子类型名称 | |
amount | number | 1 | 每个采样位置的粒子数量 |
x, y, z | number | 0 | 扩散量;amount 为 0 时表示方向 |
speed | number | 0 | 粒子速度 |
coverage | number | 1.0 | 每个位置独立的采样概率,限制在 0.01 到 1.0;非空位置集合至少贡献一个位置 |
boss:spawn_particles_in_zone_border(zone, particle[, amount][, x][, y][, z][, speed][, coverage])
与上一个方法相同,但采样区域边界而非内部位置。
boss:get_particles_from_self_toward_zone(zone, particle[, speed])
返回位于区域采样位置、方向远离 Boss 的粒子规格表数组。它不会在 Boss 位置生成粒子,也不会创建从那里出发的移动动画。请将结果传给 boss:spawn_particles_with_vector(...)。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
zone | zone 表 | 目标区域 | |
particle | string | 粒子类型名称 | |
speed | number | 0.1 | 粒子移动速度 |
每个条目的格式为 { location = ..., particle = ..., amount = 0, x/y/z = <unit direction>, speed = ... }。每个区域位置有 20% 的采样概率,非空集合至少选择一个位置;随后跳过与 Boss 重合的位置。实际方向行为取决于粒子类型。
boss:get_particles_toward_self(zone, particle, speed)
返回从区域朝向 Boss 的粒子规格数组,不会直接生成粒子。请把结果传给 boss:spawn_particles_with_vector(...)。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
zone | zone 表 | 源区域 | |
particle | string | 粒子类型名称 | |
speed | number | 请显式传入 0.1 等数值;省略时会尝试将粒子名称作为数字读取,导致调用失败。 |
boss:spawn_particles_with_vector(particles)
生成一个方向性粒子的数组,每个粒子都有自己的位置和速度向量。
| 参数 | 类型 | 备注 |
|---|---|---|
particles | 表的数组 | 每个条目定义一个带有位置和方向的粒子 |
末影龙方法
这些方法仅在 Boss 实体为末影龙时适用。
boss:get_ender_dragon_phase()
以字符串形式返回当前的 EnderDragon.Phase 名称,如果 Boss 不是末影龙则返回 nil。
boss:set_ender_dragon_phase(phase)
设置末影龙的阶段。
| 参数 | 类型 | 备注 |
|---|---|---|
phase | string | EnderDragon.Phase 名称(例如 "CIRCLING"、"CHARGE_PLAYER") |
特殊能力支持方法
这些方法支持从 Lua 脚本调用 EliteMobs 内置的能力机制。
boss:start_tracking_fireball_system(speed?)
为 Monster 类型 Boss 上的该能力启动一个控制器。在怪物有目标时,控制器会在首次运行(下一个 tick)时以及之后每 8 秒,向每个轴向 20 格范围内的 Survival/Adventure 玩家发射追踪火球。没有目标的运行会停止控制器,首次运行也不例外;再次调用可重启。运行中重复调用不会替换速度。控制器归属于该能力的脚本:暂停脚本会暂停它,关闭脚本会停止它。调用启动控制器时,速度必须是有限正数,否则调用会抛出错误。
火球爆炸威力为 3 且可点火。每个火球的追踪任务独立于脚本。它在约 3 分钟后或上下文无效时停止,但停止任务本身不移除火球。对受追踪火球的未取消攻击会让其在玩家与施法者之间切换追逐目标。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
speed | number | 0.5 | 火球速度;必须是有限正数 |
boss:handle_spirit_walk_damage(cause)
将伤害原因传给 Spirit Walk 方法。火焰、燃烧 tick、中毒、凋零、荆棘及横扫攻击不推进计数器。溺水或窒息立即触发逃离;其他受理原因每第九次命中触发。它查找附近有效目的地,并在临时无敌状态下播放移动过程。不会取消传入的伤害事件,也不保证移动到攻击者背后。
| 参数 | 类型 | 备注 |
|---|---|---|
cause | string | Bukkit DamageCause 名称(例如 "ENTITY_ATTACK"、"PROJECTILE") |
boss:shield_wall_is_active()
返回护盾控制器的激活标志,不保证某个方向仍有正数护盾值。
boss:initialize_shield_wall(openingDirection?)
如果护盾墙尚未激活,则初始化方向护盾值和显示。每个受保护方向的初始生命值等于 Boss 等级。参数选择未保护的开口方向,不是充能次数。返回 nil,不会自动注册伤害事件处理器。
| 参数 | 类型 | 默认值 | 备注 |
|---|---|---|---|
openingDirection | number | 1 | 1 = 北,2 = 东,3 = 南,4 = 西;其他整数使四面都受保护 |
boss:shield_wall_absorb_damage(player, damage)
根据攻击者相对 Boss 的位置确定方向,从该方向护盾值减去指定伤害。减法前的值为正时返回 true,即使本次伤害超过剩余值。玩家或状态缺失、位于其他世界、该方向已耗尽或为开口时返回 false。不会取消伤害事件。 返回 true 时,你的伤害钩子必须调用 context.event.cancel_event() 才能阻止命中。请传入非负伤害量。
| 参数 | 类型 | 备注 |
|---|---|---|
player | 玩家包装器 | 进行攻击的玩家 |
damage | number | 要吸收的伤害量 |
boss:deactivate_shield_wall()
停止护盾墙独立的显示任务,移除状态和护盾盔甲架。仅关闭 Lua 实例不会调用此方法;机制结束时请显式停用。
boss:start_zombie_necronomicon(target, chant)
用生命实体目标和滚动咒文启动 Necronomicon 控制器。第二个参数是显示文本,不是 Boss 文件名。它以施法者等级,每 60 tick 召唤一个固定文件的增援,80% 概率使用 necronomicon_zombie.yml,20% 使用 necronomicon_skeleton.yml。仅当受追踪增援不超过 9 个且没有活动控制器时接受新启动。运行中的控制器补充至 11 个,满员时启用 AI,数量下降后恢复施法。
施法会禁用 Boss AI 并更改显示名称,警告显示遵守警告效果设置。目标必须保持有效、同世界且位于 30 方块内。上下文无效或所有者移除会停止控制器、恢复显示并清除其增援。这些是独立 Bukkit 任务,仅关闭 Lua 不会停止。方法返回 nil。
| 参数 | 类型 | 备注 |
|---|---|---|
target | 实体包装器 | 死灵之书的目标实体 |
chant | string | 滚动显示文本;空白文本使用 Boss 名称,较短文本会补齐 |
context.players
围绕 Boss 的玩家查询辅助方法。使用它们来查找玩家,而无需从事件中获取特定的玩家。
这些查询不按游戏模式、视线、存活状态、战斗参与或实例成员身份筛选,也不按距离排序。current_target() 优先使用事件行为者,可能不同于优先使用直接目标的 context.player。新建的调度上下文没有事件行为者,因此回退到当前 Mob 目标。
| 方法 | 返回值 | 备注 |
|---|---|---|
players:current_target() | 玩家包装器或 nil | 事件玩家,或当 Boss 怪物目标是玩家时返回该目标 |
players:nearby_players(radius) | 玩家包装器的数组 | Boss 半径内的所有玩家 |
players:all_players_in_world() | 玩家包装器的数组 | Boss 所在世界中的所有玩家 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
local nearby = context.players:nearby_players(20)
for _, player in ipairs(nearby) do
player:send_message("&cThe boss is enraged!")
player:apply_potion_effect("GLOWING", 60, 0)
end
end
}
示例
return {
api_version = 1,
on_spawn = function(context)
-- Warn everyone in the world
local everyone = context.players:all_players_in_world()
for _, p in ipairs(everyone) do
p:show_title("&4WARNING", "&7A world boss has spawned!", 10, 60, 20)
end
end
}
context.entities
围绕 Boss 的通用实体查询辅助方法。
| 方法 | 返回值 | 备注 |
|---|---|---|
entities:get_nearby_entities(radius[, filter]) | 实体包装器的数组 | Boss 周围的附近实体 |
entities:get_entities_in_box(center, halfX, halfY, halfZ[, filter]) | 实体包装器的数组 | 中心所在世界中,脚部位置位于包含边界的盒子内的生命实体;不是碰撞箱重叠检测 |
entities:get_all_entities([filter]) | 实体包装器的数组 | Boss 世界中所有匹配的实体 |
entities:get_direct_target_entity() | 实体包装器或 nil | 当前事件的直接目标 |
entities:get_boss_spawn_location() | location 表 | Boss 最初的生成位置 |
有效的过滤器: living(默认)、player / players、elite / elites、mob / mobs、all / entities
all / entities 仅在 get_nearby_entities 中生效。它包含掉落物和投射物等非生命实体,以轻量的引用包装器返回;生命实体仍使用完整的生命实体包装器。此过滤器使用每轴取指定半径的轴对齐盒子搜索,生命实体过滤器使用球形距离。在其他查询中,all / entities 回退为 living。所有结果都排除 Boss 自身。
过滤器不区分大小写,未知值也回退为 living。mob 指任何非玩家生命实体,不只是敌对怪物。这些查询没有自动的实例参与者筛选、结果数上限或距离排序。广泛的生命实体查询会扫描世界中已加载的生命实体,请限制半径并避免不必要的重复扫描。get_direct_target_entity() 使用事件直接目标,可能为 nil,不会回退到怪物当前战斗目标。
示例
return {
api_version = 1,
on_enter_combat = function(context)
-- Damage all nearby elites
local elites = context.entities:get_nearby_entities(10, "elites")
for _, elite in ipairs(elites) do
elite:deal_damage(5)
end
end
}
示例
return {
api_version = 1,
on_enter_combat = function(context)
-- Find players in a box area
local center = context.boss:get_location()
local players = context.entities:get_entities_in_box(center, 10, 5, 10, "players")
for _, p in ipairs(players) do
p:send_message("&eYou are in the danger zone!")
end
end
}
