local CONST = require 'config.const'
local Balance = require 'config.balance'
local M = {}
local spawn_points = {} -- { area, current_item, respawn_timer }
-----------------------------------------------------------
-- 初始化
-----------------------------------------------------------
function M.init()
local areas = y3.area.get_circle_areas_by_tag('item_spawn')
for _, area in ipairs(areas) do
local sp = {
area = area,
current_item = nil,
respawn_timer = nil,
}
M.spawn_item(sp)
table.insert(spawn_points, sp)
end
-- 监听物品拾取事件
y3.game:subscribe_event('单位-获得物品', function(trg, data)
local unit = data.unit
local item = data.item
if unit and unit:has_tag('player_controlled') then
local Suspicion = require 'systems.suspicion'
Suspicion.add(unit, 3) -- 拾取物品+3怀疑值
end
end)
end
-----------------------------------------------------------
-- 在刷新点生成物品
-----------------------------------------------------------
function M.spawn_item(sp)
local item_key = M.roll_item()
local pos = sp.area:get_center_point()
-- 在地面创建物品实体
local item = y3.item.create_item(item_key, pos)
sp.current_item = item
end
-----------------------------------------------------------
-- 物品权重随机
-----------------------------------------------------------
local ITEM_POOL = {
{ key = CONST.ITEM_POISON, weight = 15 },
{ key = CONST.ITEM_KNIFE, weight = 10 },
{ key = CONST.ITEM_ARMOR, weight = 15 },
{ key = CONST.ITEM_SMOKE, weight = 15 },
{ key = CONST.ITEM_MASK, weight = 8 },
{ key = CONST.ITEM_TRACKER, weight = 15 },
{ key = CONST.ITEM_SILENCER, weight = 10 },
{ key = CONST.ITEM_JAMMER, weight = 12 },
}
function M.roll_item()
local total = 0
for _, e in ipairs(ITEM_POOL) do total = total + e.weight end
local r = math.random(total)
local acc = 0
for _, e in ipairs(ITEM_POOL) do
acc = acc + e.weight
if r <= acc then return e.key end
end
return ITEM_POOL[1].key
end
-----------------------------------------------------------
-- 刷新点重生(物品被拾取后调用)
-----------------------------------------------------------
function M.on_item_picked(sp)
sp.current_item = nil
local delay = Balance.ITEM_RESPAWN_TIME
-- 最后2分钟刷新加速
local GameMgr = require 'core.game_manager'
if GameMgr.get_state() == 'overtime' then
delay = delay * 0.5
end
sp.respawn_timer = y3.timer.wait(delay, function()
M.spawn_item(sp)
end)
end
return M
每个物品在物编中配置为"主动使用"物品,绑定一个技能。使用后由对应技能的施法事件触发。
-- 监听物品技能施法
-- 对前方3米目标造成持续伤害
local function use_poison(unit, ability)
local facing = unit:get_facing()
local pos = unit:get_point()
local rad = math.rad(facing)
local target_pos = y3.point.create(
pos:get_x() + math.cos(rad) * 3,
pos:get_y() + math.sin(rad) * 3
)
local area = y3.area.create_circle_area(target_pos, 1.5)
local units = area:get_all_unit_in_area()
area:remove()
for _, u in ipairs(units) do
if u ~= unit and u:is_alive() then
u:add_buff({
key = CONST.BUFF_POISON,
source = unit,
time = 3.0,
pulse = 1.0, -- 每秒心跳
})
break
end
end
Suspicion.add(unit, 15)
end
Buff buff_poison:持续3秒,心跳1秒,每次心跳造成约17伤害(总计50),附带减速20%。
local function use_knife(unit, ability)
local target_point = ability:get_target(1) -- 获取施法目标点
-- 创建投射物
y3.projectile.create({
key = CONST.PROJ_KNIFE,
source = unit,
start = unit:get_point(),
target = target_point,
speed = 15,
max_range = 15,
on_hit = function(proj, hit_unit)
unit:damage({
target = hit_unit,
damage = 40,
type = CONST.DAMAGE_TYPE_ASSASSINATE,
no_miss = true,
})
end,
})
Suspicion.add(unit, 25)
end
local function use_armor(unit, ability)
unit:add_buff({
key = CONST.BUFF_SHIELD,
time = 30.0,
})
end
local function use_smoke(unit, ability)
local pos = unit:get_point()
-- 粒子特效
y3.particle.create_at_point(CONST.SFX_SMOKE, pos, 5.0)
-- 创建烟雾区域
local smoke_area = y3.area.create_circle_area(pos, 8)
smoke_area:add_tag('smoke_zone')
-- 5秒后消失
y3.timer.wait(5.0, function()
smoke_area:remove()
end)
Suspicion.add(unit, 20)
end
local function use_mask(unit, ability)
local model = require('core.player_manager').get_random_npc_model()
unit:replace_model(model)
unit:storage_set('current_model', model)
Suspicion.set(unit, 0)
end
local function use_tracker(unit, ability)
local area = y3.area.create_circle_area(unit:get_point(), 8)
local units = area:get_all_unit_in_area()
area:remove()
for _, u in ipairs(units) do
if u:has_tag('player_controlled') and u ~= unit and u:is_alive() then
u:add_buff({
key = CONST.BUFF_FOOTPRINT,
source = unit,
time = 5.0,
pulse = 0.5,
})
end
end
Suspicion.add(unit, 10)
end
local function use_silencer(unit, ability)
unit:add_buff({
key = CONST.BUFF_SILENCER,
time = 30.0,
})
end
local function use_jammer(unit, ability)
local target_point = ability:get_target(1)
local area = y3.area.create_circle_area(target_point, 10)
local npcs = area:get_all_unit_in_area()
area:remove()
for _, npc in ipairs(npcs) do
if npc:has_tag('npc') and npc:is_alive() then
local random_point = y3.area.create_circle_area(target_point, 10):random_point()
npc:move_to_pos(random_point)
end
end
Suspicion.add(unit, 8)
end