薛之猫大王
2026-02-22 3b98d982bed635e986ab09f8185cfa9b9b2c33bb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
local CONST     = require 'config.const'
local Balance   = require 'config.balance'
 
local M = {}
 
-- ---------------------------------------------------------
-- 开始拖拽尸体
-- ---------------------------------------------------------
function M.start_drag(player_unit, corpse_unit)
    if not corpse_unit:has_tag('corpse') then return false end
    if not player_unit:is_in_radius(corpse_unit, 2.0) then return false end
    if player_unit:storage_get('is_dragging') then return false end
    if player_unit:storage_get('is_disguising') then return false end
 
    player_unit:storage_set('is_dragging', true)
    player_unit:storage_set('dragged_corpse', corpse_unit)
 
    player_unit:add_attr('移动速度', -Balance.DRAG_SPEED_PENALTY, '增益')
 
    corpse_unit:follow(player_unit, 0.5, 1.5, 3.0, 180, true)
 
    local Suspicion = require 'systems.suspicion'
    local drag_timer = clicli.timer.loop(1.0, function()
        if not player_unit:storage_get('is_dragging') then return end
        Suspicion.add(player_unit, Balance.SUS_DRAGGING)
    end, '拖拽怀疑值')
    player_unit:storage_set('drag_timer', drag_timer)
 
    return true
end
 
-- ---------------------------------------------------------
-- 释放尸体
-- ---------------------------------------------------------
function M.drop_corpse(player_unit)
    if not player_unit:storage_get('is_dragging') then return end
 
    local corpse = player_unit:storage_get('dragged_corpse')
    if corpse and corpse:is_exist() then
        corpse:stop()
    end
 
    M.cleanup_drag(player_unit)
end
 
-- ---------------------------------------------------------
-- 藏尸
-- ---------------------------------------------------------
function M.try_hide(player_unit)
    if not player_unit:storage_get('is_dragging') then return false end
 
    local pos = player_unit:get_point()
    local hide_spots = clicli.area.get_circle_areas_by_tag('hide_spot')
 
    for _, area in ipairs(hide_spots) do
        if area:is_point_in_area(pos) then
            local capacity = area:kv_load('capacity', 'integer') or 1
            local used     = area:kv_load('used', 'integer') or 0
            if used < capacity then
                local corpse = player_unit:storage_get('dragged_corpse')
                if corpse and corpse:is_exist() then
                    corpse:add_tag('hidden')
                    corpse:remove()
                end
 
                area:kv_save('used', used + 1)
                M.cleanup_drag(player_unit)
 
                local PlayerMgr = require 'core.player_manager'
                PlayerMgr.add_score(player_unit:get_owner(), Balance.SCORE_HIDE_CORPSE)
 
                return true
            end
        end
    end
 
    return false
end
 
-- ---------------------------------------------------------
-- 清理拖拽状态
-- ---------------------------------------------------------
function M.cleanup_drag(player_unit)
    player_unit:storage_set('is_dragging', false)
    player_unit:storage_set('dragged_corpse', nil)
    player_unit:add_attr('移动速度', Balance.DRAG_SPEED_PENALTY, '增益')
 
    local drag_timer = player_unit:storage_get('drag_timer')
    if drag_timer then
        drag_timer:remove()
        player_unit:storage_set('drag_timer', nil)
    end
end
 
-- ---------------------------------------------------------
-- 尸体发现检测(每2秒扫描)
-- ---------------------------------------------------------
function M.start_discovery_scan()
    clicli.timer.loop(2.0, function()
        local PlayerMgr = require 'core.player_manager'
        for _, pd in ipairs(PlayerMgr.get_all_player_units()) do
            if pd.alive then
                M.check_discovery(pd.unit)
            end
        end
    end, '尸体发现扫描')
end
 
function M.check_discovery(player_unit)
    local pos  = player_unit:get_point()
    local area = clicli.area.create_circle_area(pos, Balance.CORPSE_DISCOVER_RANGE)
    local units = area:get_all_unit_in_area()
    area:remove()
 
    for _, u in ipairs(units) do
        if u:has_tag('corpse') and not u:has_tag('hidden') and not u:has_tag('discovered') then
            u:add_tag('discovered')
            M.on_corpse_discovered(u, player_unit)
        end
    end
end
 
function M.on_corpse_discovered(corpse, discoverer)
    local Notify = require 'ui.notification'
    Notify.broadcast('发现尸体!')
 
    local NpcMgr = require 'core.npc_manager'
    NpcMgr.trigger_panic(corpse:get_point(), Balance.PANIC_RADIUS)
end
 
return M