Lua 脚本编写:世界与环境
本页面涵盖 context.world、context.vectors、context.settings 和 context.event 上可用的每一个方法。它们让你的 Lua 能力可以与 Minecraft 世界交互——生成实体、播放特效、查询方块等等。如果你刚接触 Lua 能力,请先从 入门 开始。
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 版本为准:下文记录的每个 *_at_location 方法都会覆盖共享版本,以便 Boss 脚本保留 EliteMobs 的语义(闪电绕过保护、更丰富的粒子规格、临时方块跟踪器)。
当服务器上同时安装了 FreeMinecraftModels 时,它会在共享的 world 表上注册三个额外方法,因此 Boss 能力也会继承它们:world:drop_elitemobs_procedural_loot(player, level[, location])、world:drop_elitemobs_random_loot(player, level[, location]) 和 world:drop_elitemobs_custom_loot(player, filename, level[, location])。每个方法都接受玩家包装器、UUID 字符串或玩家名称;当 location 被省略或无效时,会回退到该玩家自身的位置;返回值为布尔值。如果缺少其中任一插件,它们会返回 false 而不是报错。
context.world
world 表提供了用于生成实体、播放特效、修改方块以及改变世界状态的方法。所有方法都使用冒号语法调用(world:method())。
world:spawn_particle_at_location(location, particleSpec)
在某个位置生成粒子。第二个参数可以是简单的粒子名称字符串,也可以是完整的粒子规格表,以便进行更高级的控制。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 生成粒子的位置 |
particleSpec | 字符串或表 | 粒子名称 或粒子规格表(见下文) |
示例
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
}
粒子规格表格式
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
particle | 字符串 | 必填 | 粒子名称 |
amount | 整数 | 1 | 粒子数量 |
x、y、z | 数字 | 0 | 各轴上的扩散/偏移 |
speed | 数字 | 0 | 粒子速度 |
red、green、blue | 整数 | 255 | 用于 DUST 和 DUST_COLOR_TRANSITION 的 RGB 颜色 |
toRed、toGreen、toBlue | 整数 | 255 | DUST_COLOR_TRANSITION 的过渡目标颜色 |
对于 DUST_COLOR_TRANSITION,你也可以使用 snake_case 形式的键:to_red、to_green、to_blue。
与 EliteScript 的 YAML 配置不同,Lua 中的粒子名称不支持旧版粒子名称转换。你必须使用当前的 Spigot API 名称(例如用 FIREWORK 而不是 FIREWORKS_SPARK,用 SMOKE 而不是 SMOKE_NORMAL,用 DUST 而不是 REDSTONE)。完整的当前名称列表及其旧版对应名称,请参见 有效粒子列表。
world:play_sound_at_location(location, sound, volume, pitch)
在某个位置播放声音。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
location | location 表 | 播放声音的位置 | |
sound | 字符串 | Minecraft 声音键(例如 "entity.blaze.shoot")或 Spigot 的 Sound 枚举名称。资源包中的键同样可用。 | |
volume | 数字 | 1.0 | 音量 |
pitch | 数字 | 1.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)
在某个位置降下闪电(既有视觉效果也会造成伤害)。
| 参数 | 类型 | 说明 |
|---|---|---|
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("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 实体。
| 参数 | 类型 | 说明 |
|---|---|---|
entityType | 字符串 | 实体类型名称(例如 "FIREBALL"、"ARROW") |
location | location 表 | 生成位置 |
options | 表(可选) | 生成选项(见下文) |
实体生成选项
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
velocity | vector 表 | nil | 初始速度 {x, y, z} |
effect | 字符串 | nil | 生成时播放的 EntityEffect |
duration | 整数 | 0 | 经过这么多游戏刻后自动移除(0 = 永不移除) |
on_land | 函数 | nil | 实体落地时的回调 |
max_ticks | 整数 | 6000 | 强制触发 on_land 回调前最多监视的游戏刻数 |
返回一个实体包装器表。非生物实体(FIREBALL、ARROW、TNT 等)返回的是
非生物引用包装器,其中 is_valid() 是一个方法。
生物实体类型(ZOMBIE、GIANT 等)返回的则是完整的
生物实体包装器,其中 is_valid 是一个布尔字段——对这类包装器调用
entity:is_valid() 会抛出 attempt to call a boolean value。
示例
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_falling_block_at_location(location, material, options)
生成一个下落的方块实体。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 生成位置 |
material | 字符串 | 材料名称(例如 "STONE"、"MAGMA_BLOCK") |
options | 表(可选) | 生成选项(见下文) |
下落方块选项
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
velocity | vector 表 | nil | 初始速度 {x, y, z} |
drop_item | 布尔值 | false | 该方块是否作为物品掉落 |
hurt_entities | 布尔值 | false | 该方块是否对它砸中的实体造成伤害 |
on_land | 函数 | nil | 方块落地时的回调 function(land_location, entity_ref) |
返回一个实体引用表。
示例
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。
| 参数 | 类型 | 说明 |
|---|---|---|
filename | 字符串 | Boss 配置文件名(例如 "my_boss.yml") |
location | location 表 | 生成位置 |
options | 表(可选) | 生成选项(见下文) |
自定义 Boss 生成选项
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
level | 整数 | Boss 等级 | 覆盖生成出来的 Boss 等级 |
silent | 布尔值 | false | 抑制生成消息 |
velocity | vector 表 | nil | 初始速度 |
add_as_reinforcement | 布尔值 | false | 注册为当前 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 生成方法。在某个位置生成自定义 Boss,等级可选。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
filename | 字符串 | Boss 配置文件名 | |
location | location 表 | Boss 位置 | 生成位置(可选,默认为 Boss 所在位置) |
level | 整数 | Boss 等级 | 覆盖生成等级(可选) |
返回一个实体包装器表,或 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, level, velocity)
生成一个由 EliteMobs 增援系统跟踪的增援怪。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
filename | 字符串 | Boss 配置文件名 | |
location | location 表 | 生成位置 | |
level | 整数 | 0 | 增援等级。设为 0 时由召唤辅助逻辑决定其默认等级行为。 |
velocity | vector 表 | 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)
生成一个烟花实体,并可完全控制其效果。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 生成位置 |
spec | 表 | 烟花规格(见下文) |
烟花规格表
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
power | 整数 | 1 | 飞行力度(高度) |
velocity | vector 表 | nil | 初始速度 |
shot_at_angle | 布尔值 | true | 烟花是否以一定角度射出(设置了 velocity 时使用) |
effects | 表的数组 | nil | 烟花效果规格的数组。如果省略,则把顶层规格当作单个效果处理。 |
烟花效果规格
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | 字符串 | "BALL_LARGE" | "BALL"、"BALL_LARGE"、"STAR"、"BURST"、"CREEPER" |
flicker | 布尔值 | true | 闪烁效果 |
trail | 布尔值 | true | 拖尾效果 |
colors | 表 | nil | 颜色名称或 {red, green, blue} 表的数组 |
fade_colors | 表 | nil | 渐隐颜色名称或 {red, green, blue} 表的数组 |
颜色名称:"WHITE"、"SILVER"、"GRAY"、"BLACK"、"RED"、"MAROON"、"YELLOW"、"OLIVE"、"LIME"、"GREEN"、"AQUA"、"TEAL"、"BLUE"、"NAVY"、"FUCHSIA"、"PURPLE"、"ORANGE"
返回一个实体引用表。你可以对它调用 :detonate() 来强制立即引爆。
示例
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" },
},
},
})
-- Detonate immediately for a visual burst
context.scheduler:run_after(1, function()
fw:detonate()
end)
end
}
world:spawn_splash_potion_at_location(location, spec)
生成一个被投掷出去的喷溅药水实体。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 生成位置 |
spec | 表 | 药水规格(见下文) |
喷溅药水规格表
| 键 | 类型 | 说明 |
|---|---|---|
velocity | vector 表 | 被投掷药水的初始速度 |
effects | 表的数组 | 药水效果规格的数组 |
药水效果规格
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | 字符串 | 必填 | 药水效果类型名称(例如 "SLOWNESS"、"POISON") |
duration | 整数 | 0 | 持续时间,单位为游戏刻 |
amplifier | 整数 | 0 | 效果等级增幅(0 = I 级) |
overwrite | 布尔值 | true | 是否覆盖同类型的已有效果 |
返回一个实体引用表,或 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)
放置一个临时方块,它会在指定时长后自动还原。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
location | location 表 | 放置位置 | |
material | 字符串 | 材料名称 | |
duration | 整数 | 0 | 方块还原前的游戏刻数(0 = 永久保留) |
requireAir | 布尔值 | false | 若为 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。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
location | location 表 | 放置位置 | |
material | 字符串 | 材料名称 | |
requireAir | 布尔值 | false | 若为 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)
以字符串形式返回某个位置方块的材料名称。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 要查询的位置 |
示例
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)
返回给定 X/Z 位置上最高的非空气方块的 Y 坐标。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 要查询的位置(只使用 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)
以数字形式返回某个位置方块的爆炸抗性。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 要查询的位置 |
示例
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。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 要查询的位置 |
示例
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)
如果该位置的方块可以穿过(实体能够从中走过),则返回 true。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 要查询的位置 |
示例
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(与 passable 类似,但基于实心判定)。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 要查询的位置 |
示例
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)
如果该位置的方块不是实心方块,并且其下方的方块是实心方块(即该位置“站在地面上”),则返回 true。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 要查询的位置 |
示例
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。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 要查询的位置 |
material | 字符串 | 要检查的 材料名称 |
示例
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)
设置世界时间。你也可以传入一个位置来指定作用于哪个世界。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表(可选) | 要影响的世界。默认为 Boss 所在的世界。 |
time | 整数 | 以游戏刻表示的世界时间(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 所在世界的天气。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
location | location 表(可选) | Boss 所在世界 | 要影响的世界 |
weather | 字符串 | "CLEAR"、"RAIN"(或 "PRECIPITATION")、"THUNDER" | |
duration | 整数 | 6000 | 天气持续时间,单位为游戏刻 |
示例
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 的爆炸恢复系统制造一次假爆炸的视觉效果(方块会被炸毁并随后恢复)。
| 参数 | 类型 | 说明 |
|---|---|---|
blockLocations | location 表的数组 | 要“炸毁”的方块位置数组 |
sourceLocation | location 表(可选) | 用于方向计算的爆炸源位置 |
示例
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)
以服务器身份执行一条控制台命令。
| 参数 | 类型 | 说明 |
|---|---|---|
command | 字符串 | 要执行的命令(不带开头的 /) |
示例
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)
运行强化闪电的视觉任务(由末影龙相关能力使用)。它会制造更具戏剧性的闪电打击,并附带额外特效。
| 参数 | 类型 | 说明 |
|---|---|---|
location | location 表 | 降下闪电的位置 |
示例
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)
生成一枚假的金粒弹射物,由弹幕系统使用。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
location | location 表 | 生成位置 | |
velocity | vector 表 | 初始速度 | |
hasGravity | 布尔值 | false | 该弹射物是否受重力影响 |
返回一个假弹射物表,包含以下方法: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)
context.world:spawn_fake_gold_nugget_at_location(
context.boss:get_location(),
{ x = dir.x, y = dir.y, z = dir.z }
)
end
}
world:run_fake_gold_nugget_damage(projectiles)
对一组假金粒弹射物执行针对附近实体的伤害处理。
| 参数 | 类型 | 说明 |
|---|---|---|
projectiles | 表 | 由 spawn_fake_gold_nugget_at_location 返回的假弹射物表的数组 |
示例
return {
api_version = 1,
on_enter_combat = function(context)
-- Spawn some projectiles and store them
context.state.active_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 }
)
table.insert(context.state.active_projectiles, nugget)
end
-- Process damage each tick for 3 seconds
local task_id
task_id = context.scheduler:run_every(1, function(tick_context)
tick_context.world:run_fake_gold_nugget_damage(tick_context.state.active_projectiles)
end)
context.scheduler:run_after(60, function(later_context)
later_context.scheduler:cancel_task(task_id)
end)
end
}
world:generate_player_loot(times)
为对该 Boss 造成过伤害的玩家生成战利品。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
times | 整数 | 1 | 战利品掷取次数 |
示例
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 的玩家掉落额外金币。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
multiplier | 数字 | 2.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
向量数学辅助工具。它们以普通函数的方式调用(点号语法),而不是方法。
| 方法 | 返回值 | 说明 |
|---|---|---|
vectors.get_vector_between_locations(loc1, loc2[, options]) | vector 表 | 从 loc1 指向 loc2 的方向 |
vectors.normalize_vector(vec) | vector 表 | 返回一个单位长度的向量 |
vectors.rotate_vector(vec, pitch, yaw) | vector 表 | 按 pitch 和 yaw 的角度旋转向量 |
所有 vector 表都包含 x、y、z 字段。
vectors.get_vector_between_locations(loc1, loc2, options)
| 参数 | 类型 | 说明 |
|---|---|---|
loc1 | location 表 | 起点 |
loc2 | location 表 | 终点 |
options | 表(可选) | 后处理选项(见下文) |
向量选项
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
normalize | 布尔值 | false | 对结果向量做归一化 |
multiplier | 数字 | 1.0 | 缩放该向量 |
offset | vector 表 | 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)
| 参数 | 类型 | 说明 |
|---|---|---|
vec | vector 表 | 输入向量 |
示例
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)
| 参数 | 类型 | 说明 |
|---|---|---|
vec | vector 表 | 输入向量 |
pitch | 数字 | 绕 X 轴旋转的角度 |
yaw | 数字 | 绕 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, 360, 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() | 布尔值 | 怪物战斗设置中是否启用了警示视觉特效 |
示例
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.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 | 带有伤害来源实体的伤害事件 | 伤害来源的实体引用包装器 |
event.projectile | 伤害来源是弹射物的伤害事件 | 弹射物的实体引用包装器 |
event.spawn_reason | on_spawn | 生成原因的枚举名称 |
event.entity | on_death、区域事件 | 相关的实体包装器 |
示例:把受到的伤害减半
示例
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()之后,它不会自动刷新。- 在计划任务的回调内部,
context.event为nil。请在事件钩子中修改事件。
