游戏模式实现
mode_manager.lua
local CONST = require 'config.const'
local Balance = require 'config.balance'
local M = {}
local current_mode = 'ffa' -- 'ffa' | 'team' | 'vip_escort'
-----------------------------------------------------------
-- 初始化
-----------------------------------------------------------
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.init_ffa()
-- 所有玩家互为敌人(不同阵营)
-- Y3中每个玩家默认自己一个阵营即可
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'
pd.unit:change_owner(CONST.TEAM_RED_PLAYER)
else
pd.team = 'blue'
pd.unit:change_owner(CONST.TEAM_BLUE_PLAYER)
end
end
-- 同队不可互相攻击(Y3阵营设置)
-- 在编辑器campinfo.json中配置阵营关系为"友好"
end
-----------------------------------------------------------
-- VIP护送模式
-----------------------------------------------------------
function M.init_vip()
local PlayerMgr = require 'core.player_manager'
local all = PlayerMgr.get_all_player_units()
-- 随机选VIP
local vip_idx = math.random(#all)
local vip_pd = all[vip_idx]
vip_pd.is_vip = true
vip_pd.team = 'escort'
-- VIP属性
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 i, pd in ipairs(all) do
if pd == vip_pd then goto continue end
if escort_count < math.floor((#all - 1) / 2) then
pd.team = 'escort'
escort_count = escort_count + 1
else
pd.team = 'assassin'
end
::continue::
end
-- 生成假VIP
M.spawn_fake_vips(vip_pd.unit:storage_get('current_model'))
-- 初始化撤退路线检查点
M.init_checkpoints()
end
function M.spawn_fake_vips(vip_model)
local fake_spawns = y3.area.get_circle_areas_by_tag('fake_vip_spawn')
for _, area in ipairs(fake_spawns) do
local pos = area:get_center_point()
local fake = y3.unit.create_unit(CONST.NPC_PLAYER, CONST.NPC_UNIT_KEYS.civilian, pos, math.random(360))
fake:replace_model(vip_model)
fake:add_tag('npc')
fake:add_tag('fake_vip')
local road = CONST.FAKE_VIP_ROADS[math.random(#CONST.FAKE_VIP_ROADS)]
fake:move_along_road(road, 1, false, true, true)
end
end
function M.init_checkpoints()
local cps = y3.area.get_circle_areas_by_tag('checkpoint')
-- 按顺序排列(编辑器中通过KV标记序号)
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 = y3.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)
-- 记录进度
-- 全局通知
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
if pd.is_vip then
return pd.respawn_left > 0
end
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
-- VIP死亡且无复活 → 刺杀队胜
local PlayerMgr = require 'core.player_manager'
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