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