edit | blame | history | raw

职业技能实现

每个职业1个主动技能。技能通过Y3物编创建技能对象,代码监听施法事件执行逻辑。

技能注册框架 (profession/base.lua)

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)

1. 影刃 — 暗影突进

-- 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秒,无目标施法


2. 千面 — 完美模仿

-- 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秒


3. 鹰眼 — 洞察之眼

-- 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 控制仅施法者可见)


4. 医师 — 麻醉陷阱

-- 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秒


5. 幽灵 — 幽灵漫步

-- 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秒


6. 猎犬 — 血迹追踪

-- 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秒,对单位施法