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
|