每个职业1个主动技能。技能通过Y3物编创建技能对象,代码监听施法事件执行逻辑。
local M = {}
local profession_handlers = {}
function M.register(name, handler)
profession_handlers[name] = handler
end
function M.on_ability_cast(unit, ability)
local prof = unit:storage_get('profession')
local handler = profession_handlers[prof]
if handler then
handler(unit, ability)
end
end
return M
在 main.lua 中注册全局技能施法事件:
y3.game:subscribe_event('技能-施法开始', function(trg, data)
local unit = data.unit
if unit and unit:has_tag('player_controlled') then
ProfBase.on_ability_cast(unit, data.ability)
end
end)
-- profession/shadow_blade.lua
local CONST = require 'config.const'
local Suspicion = require 'systems.suspicion'
local Assassin = require 'systems.assassination'
local Base = require 'profession.base'
Base.register('shadow_blade', function(unit, ability)
local facing = unit:get_facing()
local pos = unit:get_point()
-- 计算冲刺终点(前方5米)
local rad = math.rad(facing)
local dx, dy = math.cos(rad) * 5, math.sin(rad) * 5
local target_point = y3.point.create(pos:get_x() + dx, pos:get_y() + dy)
-- 瞬移
unit:blink(target_point)
-- 0.8秒隐身
unit:add_state(CONST.STATE_INVISIBLE)
unit:set_transparent_when_invisible(true)
y3.timer.wait(0.8, function()
unit:remove_state(CONST.STATE_INVISIBLE)
end)
-- 检查冲刺终点是否有目标(自动刺杀)
local dash_area = y3.area.create_circle_area(target_point, 2.0)
local units = dash_area:get_all_unit_in_area()
dash_area:remove()
for _, u in ipairs(units) do
if u ~= unit and u:is_alive() then
-- 免前摇直接造成背刺伤害
unit:damage({
target = u,
damage = 105,
type = CONST.DAMAGE_TYPE_ASSASSINATE,
no_miss = true,
})
if not u:is_alive() then
Assassin.on_kill(unit, u)
end
break
end
end
Suspicion.add(unit, 15)
end)
物编配置:技能 abi_shadow_dash,冷却45秒,无目标施法
-- profession/mimic.lua
local CONST = require 'config.const'
local Suspicion = require 'systems.suspicion'
local Base = require 'profession.base'
Base.register('mimic', function(unit, ability)
unit:storage_set('mimic_active', true)
-- 找到最近NPC并复制其移动
local nearby_area = y3.area.create_circle_area(unit:get_point(), 10)
local units = nearby_area:get_all_unit_in_area()
nearby_area:remove()
local nearest_npc = nil
local min_dist = 999
for _, u in ipairs(units) do
if u:has_tag('npc') and u:is_alive() then
-- 简化距离判断
if u:is_in_radius(unit, min_dist) then
nearest_npc = u
end
end
end
if nearest_npc then
unit:follow(nearest_npc, 0.5, 2.0, 4.0, 0, false)
end
-- 10秒内怀疑值快速下降
local mimic_timer = y3.timer.loop(1.0, function(timer, count)
if count > 10 or not unit:storage_get('mimic_active') then
timer:remove()
unit:stop()
unit:storage_set('mimic_active', false)
return
end
Suspicion.add(unit, -5)
end, '完美模仿', true)
unit:storage_set('mimic_timer', mimic_timer)
end)
物编配置:技能 abi_perfect_mimic,冷却60秒
-- profession/eagle_eye.lua
local CONST = require 'config.const'
local Suspicion = require 'systems.suspicion'
local Base = require 'profession.base'
Base.register('eagle_eye', function(unit, ability)
local scan_area = y3.area.create_circle_area(unit:get_point(), 15)
local all_units = scan_area:get_all_unit_in_area()
scan_area:remove()
for _, u in ipairs(all_units) do
if u:has_tag('player_controlled') and u ~= unit and u:is_alive() then
-- 给被扫描到的玩家添加3秒标记Buff(仅对施法者可见)
u:add_buff({
key = CONST.BUFF_EAGLE_MARK,
source = unit,
time = 3.0,
})
end
end
Suspicion.add(unit, 10)
end)
物编配置:技能 abi_insight_eye,冷却50秒
Buff buff_eagle_mark:3秒持续,头顶显示特效(通过 Player.with_local 控制仅施法者可见)
-- profession/surgeon.lua
local CONST = require 'config.const'
local Suspicion = require 'systems.suspicion'
local Base = require 'profession.base'
local trap_count = {} -- player_id -> 当前场上陷阱数
Base.register('surgeon', function(unit, ability)
local pid = unit:get_owner():get_id()
trap_count[pid] = trap_count[pid] or 0
if trap_count[pid] >= 2 then return end -- 最多2个
local pos = unit:get_point()
local trap_area = y3.area.create_circle_area(pos, 1.5)
trap_area:add_tag('trap')
trap_count[pid] = trap_count[pid] + 1
Suspicion.add(unit, 5)
-- 陷阱检测循环
local trap_timer = y3.timer.loop(0.5, function(timer, count)
-- 90秒后自动消失
if count > 180 then
trap_area:remove()
timer:remove()
trap_count[pid] = trap_count[pid] - 1
return
end
local trapped_units = trap_area:get_all_unit_in_area()
for _, u in ipairs(trapped_units) do
if u:has_tag('player_controlled') and u ~= unit and u:is_alive() then
-- 定身2秒
u:add_state(CONST.STATE_IMMOBILE)
u:add_buff({ key = CONST.BUFF_TRAP_ROOT, time = 2.0 })
y3.timer.wait(2.0, function()
u:remove_state(CONST.STATE_IMMOBILE)
end)
-- 触发后陷阱消失
trap_area:remove()
timer:remove()
trap_count[pid] = trap_count[pid] - 1
return
end
end
end, '陷阱检测')
end)
物编配置:技能 abi_anesthesia_trap,冷却35秒
-- profession/phantom.lua
local CONST = require 'config.const'
local Suspicion = require 'systems.suspicion'
local Base = require 'profession.base'
Base.register('phantom', function(unit, ability)
-- 完全隐身4秒
unit:add_state(CONST.STATE_INVISIBLE)
unit:set_transparent_when_invisible(false) -- 完全不可见
unit:set_move_collision(1, false) -- 关闭碰撞
-- 移速加成
unit:add_attr('移动速度', 1.5, '增益') -- +30%约1.5
y3.timer.wait(4.0, function()
unit:remove_state(CONST.STATE_INVISIBLE)
unit:set_move_collision(1, true)
unit:add_attr('移动速度', -1.5, '增益')
end)
Suspicion.add(unit, 20)
end)
物编配置:技能 abi_ghost_walk,冷却50秒
-- profession/hound.lua
local CONST = require 'config.const'
local Suspicion = require 'systems.suspicion'
local Base = require 'profession.base'
Base.register('hound', function(unit, ability)
-- 需要目标:对unit前方最近的单位使用
local scan = y3.area.create_circle_area(unit:get_point(), 8)
local all = scan:get_all_unit_in_area()
scan:remove()
local target = nil
for _, u in ipairs(all) do
if u ~= unit and u:is_alive() then
target = u
break
end
end
if not target then return end
-- 标记20秒
target:add_buff({ key = CONST.BUFF_TRACKED, source = unit, time = 20.0 })
-- 每秒在目标位置生成脚印特效
local track_timer = y3.timer.loop(1.0, function(timer, count)
if count > 20 then timer:remove() return end
if not target:is_alive() then timer:remove() return end
local tpos = target:get_point()
-- 如果是NPC,标记提前消失
if target:has_tag('npc') then
target:remove_buffs_by_key(CONST.BUFF_TRACKED)
timer:remove()
-- 返还50%CD
local abi = unit:find_ability('英雄', CONST.ABI_BLOOD_TRACK)
if abi then
local remaining = abi:get_cd()
abi:set_cd(remaining * 0.5)
end
return
end
-- 玩家目标:生成红色脚印(通过本地特效)
y3.player.with_local(function(local_player)
if local_player == unit:get_owner() then
-- 在tpos播放脚印粒子(仅本地可见)
end
end)
end, '血迹追踪')
Suspicion.add(unit, 8)
end)
物编配置:技能 abi_blood_track,冷却40秒,对单位施法