local M = {}
|
|
-- ---------------------------------------------------------
|
-- NPC行为更新(由Timer驱动,每2秒一次)
|
-- ---------------------------------------------------------
|
function M.start()
|
clicli.timer.loop(2.0, function()
|
local NpcMgr = require 'core.npc_manager'
|
local npc_list = NpcMgr.get_npc_list()
|
for _, npc in ipairs(npc_list) do
|
if npc:is_alive() then
|
M.tick(npc)
|
end
|
end
|
end, 'NPC行为更新')
|
end
|
|
function M.tick(npc)
|
if npc:storage_get('is_panicked') then
|
return
|
end
|
|
local state = npc:storage_get('ai_state') or 'idle'
|
|
if state == 'idle' then
|
if math.random(100) <= 30 then
|
M.try_interact(npc)
|
else
|
npc:storage_set('ai_state', 'moving')
|
local road = npc:storage_get('assigned_road')
|
if road then
|
npc:move_along_road(road, 1, false, true, true)
|
end
|
end
|
|
elseif state == 'moving' then
|
if not npc:is_moving() then
|
npc:storage_set('ai_state', 'idle')
|
end
|
|
elseif state == 'interacting' then
|
-- 由互动计时器回调切回idle
|
end
|
end
|
|
-- ---------------------------------------------------------
|
-- 互动点检测
|
-- ---------------------------------------------------------
|
function M.try_interact(npc)
|
local interact_configs = {
|
{ tag = 'interact_bench', anim = 'sit', time_min = 8, time_max = 15 },
|
{ tag = 'interact_board', anim = 'look', time_min = 5, time_max = 10 },
|
{ tag = 'interact_well', anim = 'wash', time_min = 5, time_max = 8 },
|
{ tag = 'interact_vendor', anim = 'trade', time_min = 6, time_max = 12 },
|
}
|
|
local pos = npc:get_point()
|
for _, cfg in ipairs(interact_configs) do
|
local areas = clicli.area.get_circle_areas_by_tag(cfg.tag)
|
for _, area in ipairs(areas) do
|
if area:is_point_in_area(pos) then
|
npc:stop()
|
npc:play_animation(cfg.anim, 1.0, 0, -1, false, true)
|
npc:storage_set('ai_state', 'interacting')
|
|
local wait = math.random(cfg.time_min, cfg.time_max)
|
clicli.timer.wait(wait, function()
|
if not npc:is_alive() then return end
|
npc:stop_cur_animation()
|
npc:storage_set('ai_state', 'idle')
|
|
local road = npc:storage_get('assigned_road')
|
if road then
|
npc:move_along_road(road, 1, false, true, true)
|
npc:storage_set('ai_state', 'moving')
|
end
|
end)
|
return true
|
end
|
end
|
end
|
|
return false
|
end
|
|
return M
|