薛之猫大王
2026-02-23 af74b152737e345cc59908bbceb87ff82a2f79a5
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
local Balance = require 'config.balance'
 
local M = {}
 
local current_area   = nil
local current_radius = nil
local shrink_timer   = nil
local damage_timer   = nil
local next_shrink_timer = nil
 
-- ---------------------------------------------------------
-- 启动
-- ---------------------------------------------------------
function M.start()
    current_radius = Balance.CIRCLE_INIT_RADIUS
 
    local map_area = clicli.area.get_map_area()
    local center   = map_area:get_center_point()
 
    current_area = clicli.area.create_circle_area(center, current_radius)
    current_area:add_tag('play_zone')
 
    next_shrink_timer = clicli.timer.wait(Balance.CIRCLE_FIRST_SHRINK, function()
        M.shrink()
    end)
end
 
-- ---------------------------------------------------------
-- 缩圈
-- ---------------------------------------------------------
function M.shrink()
    if not current_area then return end
 
    local new_radius = current_radius * Balance.CIRCLE_SHRINK_RATIO
    if new_radius < Balance.CIRCLE_MIN_RADIUS then
        new_radius = Balance.CIRCLE_MIN_RADIUS
    end
 
    local delta = current_radius - new_radius
    local steps = math.max(1, math.ceil(delta / 0.5))
 
    shrink_timer = clicli.timer.count_loop(1.0, steps, function(timer, count)
        current_radius = current_radius - 0.5
        if current_radius < new_radius then
            current_radius = new_radius
        end
        current_area:set_radius(current_radius)
    end)
 
    M.start_damage()
 
    if current_radius > Balance.CIRCLE_MIN_RADIUS then
        next_shrink_timer = clicli.timer.wait(Balance.CIRCLE_INTERVAL, function()
            M.shrink()
        end)
    end
end
 
-- ---------------------------------------------------------
-- 区域外持续伤害
-- ---------------------------------------------------------
function M.start_damage()
    if damage_timer then return end
 
    damage_timer = clicli.timer.loop(2.0, function()
        if not current_area then return end
 
        local PlayerMgr = require 'core.player_manager'
        for _, pd in ipairs(PlayerMgr.get_all_player_units()) do
            if pd.alive then
                local pos = pd.unit:get_point()
                if not current_area:is_point_in_area(pos) then
                    pd.unit:add_hp(-Balance.CIRCLE_DAMAGE_PER_TICK)
                end
            end
        end
    end, '圈外伤害')
end
 
-- ---------------------------------------------------------
-- 停止
-- ---------------------------------------------------------
function M.stop()
    if shrink_timer then shrink_timer:remove(); shrink_timer = nil end
    if damage_timer then damage_timer:remove(); damage_timer = nil end
    if next_shrink_timer then next_shrink_timer:remove(); next_shrink_timer = nil end
    if current_area then current_area:remove(); current_area = nil end
end
 
return M