local CONST = require 'config.const'
local Balance = require 'config.balance'
local M = {}
local current_mode = 'ffa'
-- ---------------------------------------------------------
-- 初始化
-- ---------------------------------------------------------
function M.init()
current_mode = CONST.GAME_MODE
if current_mode == 'ffa' then
M.init_ffa()
elseif current_mode == 'team' then
M.init_team()
elseif current_mode == 'vip_escort' then
M.init_vip()
end
end
function M.get_mode()
return current_mode
end
-- ---------------------------------------------------------
-- 独狼模式:所有玩家互为敌人
-- ---------------------------------------------------------
function M.init_ffa()
end
-- ---------------------------------------------------------
-- 组队模式:分两队
-- ---------------------------------------------------------
function M.init_team()
local PlayerMgr = require 'core.player_manager'
local all = PlayerMgr.get_all_player_units()
local half = math.ceil(#all / 2)
for i, pd in ipairs(all) do
if i <= half then
pd.team = 'red'
else
pd.team = 'blue'
end
end
end
-- ---------------------------------------------------------
-- VIP护送模式
-- ---------------------------------------------------------
function M.init_vip()
local PlayerMgr = require 'core.player_manager'
local all = PlayerMgr.get_all_player_units()
if #all == 0 then return end
local vip_idx = math.random(#all)
local vip_pd = all[vip_idx]
vip_pd.is_vip = true
vip_pd.team = 'escort'
vip_pd.unit:set_attr('最大生命', 200, '基础')
vip_pd.unit:set_hp(200)
vip_pd.unit:add_attr('移动速度', -0.3, '增益')
vip_pd.unit:add_tag('vip')
local escort_count = 0
for _, pd in ipairs(all) do
if pd ~= vip_pd then
if escort_count < math.floor((#all - 1) / 2) then
pd.team = 'escort'
escort_count = escort_count + 1
else
pd.team = 'assassin'
end
end
end
M.spawn_fake_vips(vip_pd.unit:storage_get('current_model'))
M.init_checkpoints()
end
function M.spawn_fake_vips(vip_model)
if not vip_model then return end
local fake_spawns = clicli.area.get_circle_areas_by_tag('fake_vip_spawn')
for _, area in ipairs(fake_spawns) do
local pos = area:get_center_point()
local fake = clicli.unit.create_unit(
CONST.NPC_PLAYER,
CONST.NPC_UNIT_KEYS.civilian,
pos,
math.random(0, 360)
)
fake:replace_model(vip_model)
fake:add_tag('npc')
fake:add_tag('fake_vip')
if #CONST.FAKE_VIP_ROADS > 0 then
local road = CONST.FAKE_VIP_ROADS[math.random(#CONST.FAKE_VIP_ROADS)]
fake:move_along_road(road, 1, false, true, true)
end
end
end
function M.init_checkpoints()
local cps = clicli.area.get_circle_areas_by_tag('checkpoint')
table.sort(cps, function(a, b)
return (a:kv_load('order', 'integer') or 0) < (b:kv_load('order', 'integer') or 0)
end)
for i, cp in ipairs(cps) do
cp:event('区域-进入', function(trg, data)
local enter_unit = data.unit
if enter_unit and enter_unit:has_tag('vip') then
M.on_vip_checkpoint(i)
end
end)
end
local exits = clicli.area.get_circle_areas_by_tag('exit_point')
for _, ex in ipairs(exits) do
ex:event('区域-进入', function(trg, data)
local enter_unit = data.unit
if enter_unit and enter_unit:has_tag('vip') then
M.on_vip_escaped()
end
end)
end
end
function M.on_vip_checkpoint(index)
local Notify = require 'ui.notification'
Notify.broadcast('VIP到达检查点 ' .. tostring(index))
end
function M.on_vip_escaped()
local GameMgr = require 'core.game_manager'
GameMgr.switch_state('ended')
end
-- ---------------------------------------------------------
-- 复活判断
-- ---------------------------------------------------------
function M.can_respawn(pd)
if current_mode == 'ffa' then
return Balance.FFA_CAN_RESPAWN and pd.respawn_left > 0
elseif current_mode == 'team' then
return pd.respawn_left > 0
elseif current_mode == 'vip_escort' then
return pd.respawn_left > 0
end
return false
end
-- ---------------------------------------------------------
-- 胜负检查
-- ---------------------------------------------------------
function M.check_victory()
local PlayerMgr = require 'core.player_manager'
local GameMgr = require 'core.game_manager'
if current_mode == 'ffa' then
if PlayerMgr.get_alive_count() <= 1 then
GameMgr.switch_state('ended')
end
elseif current_mode == 'team' then
local red_alive = PlayerMgr.get_alive_count_by_team('red')
local blue_alive = PlayerMgr.get_alive_count_by_team('blue')
if red_alive == 0 or blue_alive == 0 then
GameMgr.switch_state('ended')
end
elseif current_mode == 'vip_escort' then
for _, pd in ipairs(PlayerMgr.get_all_player_units()) do
if pd.is_vip and not pd.alive and pd.respawn_left <= 0 then
GameMgr.switch_state('ended')
return
end
end
end
end
return M