import PlayerMgr from "../object/PlayerMgr"; import ActivityDefine from "./ActivityDefine"; import TeamMgr from "../core/TeamMgr"; import SKDataUtil from "../gear/SKDataUtil"; import SKLogger from "../gear/SKLogger"; import {BattleType, MsgCode, Fortifications, FortificationsOperate, ETaskKind} from "../role/EEnum"; import * as schedule from "node-schedule"; import GTimer from "../common/GTimer"; import BangMgr from "../bang/BangMgr"; import DB from "../utils/DB"; import GameUtil from "../core/GameUtil"; import NpcConfigMgr from "../core/NpcConfigMgr"; import NpcMgr from "../core/NpcMgr"; /** * 帮战 */ export default class FactionWar { static shared = new FactionWar(); // 比武状态 contest_state: any = { not_sign: 0, // 未报名 yet_sign: 1, // 已报名 } //----------------------------------------------------- 左边 ---------------------------------------------------- /** 左边基地 */ gate_xy_left: any = {x: 21, y: 10} /** 左边基地出城门传送位置 */ out_gate_xy_left: any = {x: 44, y: 47} /** 左边神龙大炮蓄力0-10ms攻击范围 MinLon:最小经度,MaxLon:最大经度,MinLat:最小纬度,MaxLat:最大纬度 */ cannon_left_0_10: any = {MinLon: 26, MaxLon: 72, MinLat: 55, MaxLat: 93} /** 左边神龙大炮蓄力10-19ms攻击范围 */ cannon_left_10_19: any = {MinLon: 22, MaxLon: 78, MinLat: 33, MaxLat: 71} /** 左边神龙大炮攻击城门范围 */ cannon_left_gate: any = {MinLon: 26, MaxLon: 45, MinLat: 16, MaxLat: 37} /** 玄冰塔、烈火塔 左边边攻击范围 */ tower_left: any = {MinLon: 25, MaxLon: 151, MinLat: 29, MaxLat: 76} //----------------------------------------------------- 右边 ---------------------------------------------------- /** 右边基地 */ gate_xy_right: any = {x: 188, y: 102} /** 右边基地出城门传送位置 */ out_gate_xy_right: any = {x: 154, y: 76} /** 右边神龙大炮蓄力0-10ms攻击范围 MinLon:最小经度,MaxLon:最大经度,MinLat:最小纬度,MaxLat:最大纬度 */ cannon_right_0_10: any = {MinLon: 46, MaxLon: 100, MinLat: 79, MaxLat: 110} /** 右边神龙大炮蓄力10-19ms攻击范围 */ cannon_right_10_19: any = {MinLon: 91, MaxLon: 179, MinLat: 62, MaxLat: 91} /** 右边神龙大炮攻击城门范围 */ cannon_right_gate: any = {MinLon: 150, MaxLon: 168, MinLat: 79, MaxLat: 97} /** 玄冰塔、烈火塔 右边攻击范围 */ tower_right: any = {MinLon: 73, MaxLon: 187, MinLat: 36, MaxLat: 100} // 定时时间(毫秒单位) state_time: any = { start_time: 20 * 60 * 1000, // 通知完20分钟后开始帮战 } // 战斗状态 FightState: any = { Wait: 1, // 等待 FightEnd: 2 // 结束战斗 } // 神龙大炮攻击半径 cannon_radius: number; // 烈火塔及玄冰塔攻击半径 tower_radius: number; // 入围帮派 cut_faction: any; name: any; // 帮战状态 activity_state: any; // 帮战开始时间 start_time: any; // 比武时间 contest_time: any[]; // 比武定时器 schedule: any; // 神龙大炮定时器 cannon_schedule: any; // 玄冰塔定时器-左 ice_l_schedule: any; // 烈火塔定时器-左 fire_l_schedule: any; // 玄冰塔定时器-右 ice_r_schedule: any; // 烈火塔定时器-右 fire_r_schedule: any; // 比武参赛队伍 contest_team: any; // 帮战参赛成员 contest_map: Map; // 烈火塔、玄冰塔,神龙大炮信息 urban_defense_map: Map; // 玄冰塔,击中目标记录<角色编号,控制时间> ice_map: Map; // 玄冰塔ms击中目标记录检查定时 ms_ice_target_schedule: any; // 烈火塔,击中目标记录<角色编号,控制时间> fire_map: Map; // 烈火塔ms击中目标记录检查定时 ms_fire_target_schedule: any; // 帮战所有参赛成员 - 角色编号 - {战斗状态 2战斗中 1未战斗,帮派编号,击杀人数 field:场数,field_win: 本人胜利场,contest: 高手胜利场, member_win:成员胜利场} contest_map_info: Map; constructor() { this.name = '帮战'; // 比武定时器 this.schedule = 0; // 神龙大炮定时器 this.cannon_schedule = 0; // 神龙大炮攻击半径 this.cannon_radius = 13.5; // 烈火塔及玄冰塔攻击半径 this.tower_radius = 12.5; // 入围帮派 this.cut_faction = {}; // 比武参赛队伍 this.contest_team = {}; // 帮战参赛成员 this.contest_map = new Map(); // 比武时间 this.contest_time = [10, 20, 30]; // 玄冰塔,击中目标记录<角色编号,控制时间> this.ice_map = new Map(); // 烈火塔,击中目标记录<角色编号,控制时间> this.fire_map = new Map(); // 烈火塔、玄冰塔信息 this.urban_defense_map = new Map(); // 帮战所有参赛成员 - 角色编号 - {战斗状态 2战斗中 1未战斗,帮派编号,击杀人数 field:场数,field_win: 本人胜利场,contest: 高手胜利场, member_win:成员胜利场} this.contest_map_info = new Map(); // 帮战开启时间 this.start_time = 0; } init() { this.activity_state = ActivityDefine.activityState.Close; this.defenceInfo(); //(周一:MON、周二:TUE、周三:WED、周四:THU、周五:FRI、周六:SAT、周天:SUN) // 周三、周四晚18:30抽取入围帮派 schedule.scheduleJob("0 30 18 ? * WED,THU", () => { this.cutFaction(); }) //周三、周四晚19:40开始进入帮战 schedule.scheduleJob("0 40 19 ? * WED,THU", () => { // 修改状态为准备报名 this.satReadyOpen(); }) //周三、周四晚20:40开结束帮战 schedule.scheduleJob("0 40 20 ? * WED,THU", () => { //结束帮战 this.close(); }) // 重启服务器读取当前入围帮战资格数据 DB.getCutFaction((code: any, info: any) => { if (MsgCode.SUCCESS == code) { for (let i = 0; i < info.length; i++) { this.cut_faction[info[i].side_id] = { gate_hp: 5000, // 城门血量 gate_max_hp: 5000, // 城门最大血量 site: info[i].site, // 占据地图位置 enemy_id: info[i].enemy_id, // 敌方帮派编号 cannon: 0, // 神龙炮开炮数 tower: 0 // 能量塔攻击数 }; this.contest_map.set(info[i].side_id.toString(), []); } this.tower_info_update(); } }); this.clear_npc(); } clear_npc(npc_id: any = 0, type: any = 0) { if (npc_id == 0) { for (let [key, value] of this.urban_defense_map) { if (key != Fortifications.cannon) { let npc: any = NpcMgr.shared.getNpcByConfigID(value.shadow); if (npc) { NpcMgr.shared.DeleteNpc(npc.onlyid); } if (type != 0){ let npc: any = NpcMgr.shared.getNpcByConfigID(key); if (npc) { NpcMgr.shared.DeleteNpc(npc.onlyid); } } } } } else { let npc: any = NpcMgr.shared.getNpcByConfigID(npc_id); if (npc) { NpcMgr.shared.DeleteNpc(npc.onlyid); } } } create_npc(npc_id: any){ let npc: any = NpcConfigMgr.shared.getConfig(npc_id); if (npc){ NpcMgr.shared.CreateNpc(npc_id, npc.auto_create.map, npc.auto_create.x, npc.auto_create.y); } } // 城防信息初始化 defenceInfo(){ /** 左边 type: 2烈火塔 3玄冰塔 state :0 蓄力,1 打断, 2 自动攻击, 3 破损 */ this.urban_defense_map.set(7207, {shadow: 47207, durable: 450, durableMax: 450, type: Fortifications.fire, site: "L", state: FortificationsOperate.INTERRUPT, bangId: 0, roleId: 0}); this.urban_defense_map.set(7208, {shadow: 47208, durable: 450, durableMax: 450, type: Fortifications.ice, site: "L", state: FortificationsOperate.INTERRUPT, bangId: 0, roleId: 0}); /** 右边 type: 2烈火塔 3玄冰塔 0 蓄力,1 打断, 2 自动攻击, 3 破损 */ this.urban_defense_map.set(7206, {shadow: 47206, time: 0, durable: 450, durableMax: 450, type: Fortifications.ice, site: "R", state: FortificationsOperate.INTERRUPT, bangId: 0, roleId: 0}); this.urban_defense_map.set(7205, {shadow: 47205, durable: 450, durableMax: 450, type: Fortifications.fire, site: "R", state: FortificationsOperate.INTERRUPT, bangId: 0, roleId: 0}); /** 神龙大炮 time 当前蓄力时间ms, state 0 蓄力 ,1 打断 2, roleId 当前蓄力者角色编号, bangId 帮派ID */ this.urban_defense_map.set(Fortifications.cannon, {time: 0, state: FortificationsOperate.INTERRUPT, roleId: 0, bangId: 0}); } // 筛选入围帮派 cutFaction() { let flag = true; let bangList: any = BangMgr.shared.getBangList(); let peak_team_all: any = []; let peak_team: any = []; // 帮派集合必须大于2 if (bangList.length > 2) { let num = 1; // let num = Math.floor(bangList.length / 2); // // 最少为两组 // if ((num % 2) != 0){ // num -= 1; // } // // 最大为3组 // if (num > 3){ // num = 3; // } // 筛选入围的帮派 for (let i = 0; i < num; i++) { let count = 0; while (flag) { if (peak_team.length < 2) { if (count >= 5) { flag = false; continue; } count++; let ran = Math.floor(Math.random() * bangList.length); peak_team.push(bangList[ran]); peak_team_all.push(bangList[ran]); } else { flag = false; } } if (peak_team.length >= 2) { // 存储当前入围帮派信息 this.cut_faction[peak_team[0].bangid] = { enemy_id: peak_team[1].bangid,// 敌方帮派编号 site: "L", // 占据地图位置 gate_hp: 5000, // 城门血量 gate_max_hp: 5000, // 城门最大血量 cannon: 0, // 神龙炮开炮数 tower: 0 // 能量塔攻击数 }; this.contest_map.set(peak_team[0].bangid.toString(), []); // 存储当前入围帮派信息 this.cut_faction[peak_team[1].bangid] = { enemy_id: peak_team[0].bangid,// 敌方帮派编号 site: "R", // 占据地图位置 gate_hp: 5000, // 城门血量 gate_max_hp: 5000, // 城门最大血量 cannon: 0, // 神龙炮开炮数 tower: 0 // 能量塔攻击数 }; this.contest_map.set(peak_team[1].bangid.toString(), []); this.tower_info_update(); DB.insertCutFaction(peak_team[0].bangid,"L", peak_team[1].bangid, "R"); } peak_team = []; flag = true; } } } /** * 开启活动进行通知 */ satReadyOpen() { let times = 3; let broad = () => { times--; let msg = `${this.name} 开启报名,请大家踊跃参加!`; PlayerMgr.shared.broadcast('s2c_notice', { strRichText: msg }); PlayerMgr.shared.broadcast('s2c_game_chat', {scale: 3, msg: msg, name: '', resid: 0, teamid: 0,}); if (times >= 0) { setTimeout(() => { broad(); }, 10 * 1000); } } broad(); // 修改状态为报名 this.activity_state = ActivityDefine.activityState.ReadyOpen; // 活动开始 启动定时检测塔击中玩家 setTimeout(() => { this.start_time = GTimer.getTime(); this.activity_state = ActivityDefine.activityState.Opening; this.ms_ice_target_schedule = setInterval(this.timing_inspect_ice, 1000, this); this.ms_fire_target_schedule = setInterval(this.timing_inspect_fire, 1000, this); // 通知前端帮战开始 this.gateHpUpdate(Object.keys(this.cut_faction)[0],0) }, this.state_time.start_time); } // 定时检测被玄冰塔击中玩家 timing_inspect_ice(this_: any){ for (let [key, value] of this_.ice_map) { value -= 1; if (value <= 0){ this_.ice_map.delete(key); let player = PlayerMgr.shared.getPlayerByRoleId(key); if (player){ // 通知前端解冻 player.isFrozen = 0; player.send('s2c_aoi_pinfo', { list: [player.toObj()] }); player.send("s2c_wars_player_state",{type: 2, ice: 0, time: GTimer.getTime()}); } }else { this_.ice_map.set(key,value); } } } // 定时检测被烈火塔击中玩家 timing_inspect_fire(this_: any){ for (let [key, value] of this_.fire_map) { value -= 1; if (value <= 0){ this_.fire_map.delete(key); }else { this_.fire_map.set(key,value); } } } /** * 请求进入帮战:玩家报名 */ playerSign(player: any) { if (player.bangid < 0) { player.send_notice("你没有帮派"); return MsgCode.FAILED; } let data: any = this.cut_faction[player.bangid]; if (data == undefined || data == null) { player.send_notice("你们帮目前没有帮战"); return MsgCode.FAILED; } if (this.activity_state != ActivityDefine.activityState.ReadyOpen){ player.send_notice("当前不在帮战报名时间"); return MsgCode.FAILED; } // 获取当前参赛成员 let map_data: any[] = this.contest_map.get(player.bangid.toString()); let team = TeamMgr.shared.getTeamInfo(player.teamid); let list: any[] = []; if (team != null) { for (let i = 0; i < team.playerlist.length; i++) { const mem = team.playerlist[i]; if (mem.bangid != player.bangid) { player.send_notice(`队伍中玩家${mem.name}不是本帮成员!`); return MsgCode.FAILED; } else { list.push(mem.roleid); } } for (let value of list) { map_data.push(value); this.contest_map_info.set(value,{state: this.FightState.Wait, bangId: player.bangid, count: 0, field: 0, field_win: 0, contest: 0, member_win: 0}); } } else { list.push(player.roleid); map_data.push(player.roleid); this.contest_map_info.set(player.roleid,{state: this.FightState.Wait, bangId: player.bangid, count: 0, field: 0, field_win: 0, contest: 0, member_win: 0}); } for (let value of list) { let p = PlayerMgr.shared.getPlayerByRoleId(value); if (p){ let d = p.toObj(); d.bangpost = p.bangpost p.send('s2c_aoi_pinfo', { list: [d] }); } } // 统计当前参战成员 this.contest_map.set(player.bangid.toString(), map_data); this.cut_faction[player.bangid] = data; this.portal(player,0); return MsgCode.SUCCESS; } /** * 请求离开帮战 * @param player * @param teamId */ leave(player: any) { // 离开帮战从数组删除当前成员信息 let map_data = this.contest_map.get(player.bangid.toString()); if (map_data != undefined){ let team = TeamMgr.shared.getTeamInfo(player.teamid); if (team != null) { for (let i = 0; i < team.playerlist.length; i++) { const mem = team.playerlist[i]; let index = map_data.indexOf(mem.roleid); if (index > -1) { map_data.splice(index, 1); } this.contest_map_info.delete(mem.roleid); } }else { let index = map_data.indexOf(player.roleid); if (index > -1) { map_data.splice(index, 1); } this.contest_map_info.delete(player.roleid); } this.contest_map.set(player.bangid.toString(), map_data); } } /** * 返回基地 * @param player */ goHome(player: any, type: number) { let data = this.check(player, 0); if (type == 1) { let contest_team: any = this.contest_team[player.bangid]; if (contest_team != undefined){ if (this.contest_state.yet_sign == contest_team.state){ // 关闭定时器 clearTimeout(this.schedule); } // 清理比武成员 delete this.contest_team[player.bangid] } } if (data != null) { this.portal(player,0) } } /** * 帮战信息统计 * @param player * @param is 0 帮战信息返回 1 帮战结束返回 */ detail_statistics(player: any, is: number = 0) { if (this.activity_state == ActivityDefine.activityState.Close) { return; } // 1.获取当前帮派信息 let data: any = this.cut_faction[player.bangid]; let enemy: any = this.cut_faction[data.enemy_id]; // 获取帮派信息 let bang: any = BangMgr.shared.getBang(player.bangid); // 参战人数 let list = this.contest_map.get(player.bangid.toString()); // 敌方帮派信息 let bang_: any = BangMgr.shared.getBang(data.enemy_id); let bang_list: any = this.contest_map.get(data.enemy_id.toString()); // 返回状态 处理 let type = 0; let impl: string = "s2c_detail_statistics"; if (is == 1){ impl = "s2c_faction_war_over"; if (data.gate_hp > enemy.gate_hp){ type = 1; player.addMoney(GameUtil.goldKind.bang_Score,100000,"帮战胜利奖励"); player.addBagItem(70004,15,true); player.addBagItem(100320,50,true); }else{ player.addMoney(GameUtil.goldKind.bang_Score,50000,"帮战失败奖励"); player.getTaskMgr().AddActive(ETaskKind.DAILY,60); player.addBagItem(100320,50,true); } }else { if (this.activity_state == ActivityDefine.activityState.Opening){ type = 1; } } // 报名中 if (this.activity_state == ActivityDefine.activityState.ReadyOpen) { player.send("s2c_detail_statistics", { factionSide: SKDataUtil.toJson({name: bang.name, num: list.length}, "{}"), factionEnemy: SKDataUtil.toJson({name: bang_.name, num: bang_list.length}, "{}"), type: type, time: this.start_time }); } // 正在进行中 else { // 己方成员胜利场数 let member = 0; // 己方高手胜利场 let contest = 0; // 己方自己杀敌 let self = 0; // 最高杀人数 let highest = "(0场)"; // 敌方成员胜利场数 let member_ = 0; // 敌方高手胜利场 let contest_ = 0; // 敌方最高杀人数 let highest_ = "(0场)"; let list: any = []; let list_enemy: any = []; for (let [key, value] of this.contest_map_info) { if (value.bangId == player.bangid) { member += value.member_win; contest += value.contest; if (key == player.roleid) { self = value.count; } list.push({key: key, count: value.count, field: value.field}); } else { member_ += value.member_win; contest_ += value.contest; list_enemy.push({key: key, count: value.count, field: value.field}); } }; // 己方最高杀人数读取 list = list.sort((a: any, b: any) => { return b.count - a.count; }); if (list.length > 0) { let s = list[0]; if (s.field > 0) { let p = PlayerMgr.shared.getPlayerByRoleId(s.key); highest = p.name + "(" + s.field + "场)"; } } // 敌方最高杀人数读取 list_enemy = list_enemy.sort((a: any, b: any) => { return b.count - a.count; }); if (list_enemy.length > 0) { let s = list_enemy[0]; if (s.field > 0) { let p = PlayerMgr.shared.getPlayerByRoleId(s.key); highest_ = p.name + "(" + s.field + "场)"; } } player.send(impl, { factionSide: SKDataUtil.toJson({ name: bang.name, num: list.length, gateHp: data.gate_hp, gateMaxHp: data.gate_max_hp, member: member, contest: contest, tower: data.tower, cannon: data.cannon, highest: highest, self: self }, "{}"), factionEnemy: SKDataUtil.toJson({ name: bang_.name, num: list.length, gateHp: enemy.gate_hp, gateMaxHp: enemy.gate_max_hp, member: member_, contest: contest_, tower: enemy.tower, cannon: enemy.cannon, highest: highest_, self: 0 }, "{}"), type: type, time: this.start_time }); } } /** * 上阵迎敌 */ toMeetThem(player: any) { let data = this.check(player,1); if (data != null) { this.portal(player,1) } } /** * 帮战点击敌方战斗 * @param player 发起者 * @param enemyRole 被受者 */ factionCombat(player: any, enemyRole: any) { let data = this.check(player, 1); if (data != null) { // 发起者 let team = TeamMgr.shared.getTeamInfo(player.teamid); if (team != null) { if (team.playerlist.length < 3) { player.send_notice("您当前队伍人数小于3人不可进行该操作"); return; } for (let i = 0; i < team.playerlist.length; i++) { const mem = team.playerlist[i]; let contest = this.contest_map_info.get(mem.roleid) contest.state = this.FightState.FightEnd; this.contest_map_info.set(mem.roleid, contest); } } else { player.send_notice("您当前未组队不可进行该操作"); return; } // 被受者 let enemy_team = TeamMgr.shared.getTeamInfo(enemyRole.teamid); if (enemy_team != null) { for (let i = 0; i < enemy_team.playerlist.length; i++) { const mem = enemy_team.playerlist[i]; let contest = this.contest_map_info.get(mem.roleid) contest.state = this.FightState.FightEnd; this.contest_map_info.set(mem.roleid, contest); } } else { this.goHome(enemyRole, 0); player.send_notice("敌方未组队不可进行该操作"); return; } this.fortifications_examine(enemyRole); // 开启战斗挑战 this.beforeFight(player, enemyRole, BattleType.FactionWarFight); } } /** * 前往比武场 */ goContest(player: any) { // 校验是否在前往比武场时间段 if (this.contest_time.indexOf(GTimer.getMinutes()) != -1) { // 校验信息 let data = this.check(player); if (data != null) { // 1.如果信息未知 查询是否有该帮派 该帮派帮主是否是当前操作者 if (player.bangpost == GameUtil.bangPost.Unknow) { let bang = BangMgr.shared.getBang(player.bangid); if (bang != null && bang != undefined) { if (bang.masterid == player.roleid) { player.bangpost = GameUtil.bangPost.BangZhu; } } } // 2.比武场必须由管理者带领前往 if (player.bangpost == GameUtil.bangPost.BangZhong || player.bangpost == GameUtil.bangPost.Unknow) { player.send_notice("比武场必须由管理者带领前往") return; } // 3.帮战比武必须3人及以上 let team = TeamMgr.shared.getTeamInfo(player.teamid); if (team == null || team.playerlist.length < 3) { player.send_notice("帮战比武必须3人及以上才可以参加哦!"); return; } // 3.1 队伍中必须都是当前帮成员 for (let i = 0; i < team.playerlist.length; i++) { const mem = team.playerlist[i]; if (mem.bangid != player.bangid) { player.send_notice(`队伍中玩家${mem.name}不是本帮成员!`); return; } } // 4.保证比武场只有当前帮一支队伍 if (this.contest_team[player.bangid] == undefined || this.contest_team[player.bangid] == null) { // 4.1 如果比武场没有当前帮派则存储数据 {当前队伍编号,比武报名状态} this.contest_team[player.bangid] = { teamId: player.teamid, state: this.contest_state.not_sign, roleId: player.roleid }; // 4.2 将当前队伍传送至比武场 player.map_transfer(3001, 167, 24) return; } else { player.send_notice(`本帮已有成员在比武场啦!`); return; } } } else { player.send_notice("不在比武时间内"); } } /** * 帮战-比武 * @param player */ contest(player: any) { // 1.检验帮派 let data = this.check(player); if (data != null) { // 2.检查比武数据是否存在当前队伍 if (this.contest_team[player.bangid] != undefined && this.contest_team[player.bangid] != null) { // 2.1 如果当前有已经报名的队伍则开打 for (let key in this.contest_team) { let data: any = this.contest_team[key]; if (data.state == this.contest_state.yet_sign) { let team: any = TeamMgr.shared.getTeamInfo(data.teamId); if (team == null || team == undefined) { // 返回基地 this.goHome(player, 1); } if (team.leader.roleid == player.roleid) { player.send_notice("你已经报名比武了,请耐心等待挑战者!") return; } // 开启比武挑战 this.beforeFight(player, PlayerMgr.shared.getPlayerByRoleId(team.leader.roleid), BattleType.FactionWarContest); // 关闭定时器 clearTimeout(this.schedule); // 比武状态改变 let side: any = this.contest_team[player.bangid]; side.state = this.contest_state.yet_sign; this.contest_team[player.bangid] = side; break; } else { // 比武状态改变 data.state = this.contest_state.yet_sign; this.contest_team[player.bangid] = data; // 生成一个定时器 2分钟后没有敌方队伍前来比赛则判断当前队伍胜利 this.schedule = setTimeout(() => { for (let key in this.contest_team) { let data: any = this.contest_team[key]; if (data.state == this.contest_state.yet_sign) { let team: any = TeamMgr.shared.getTeamInfo(data.teamId); if (team != null && team != undefined) { this.contestResult(PlayerMgr.shared.getPlayerByRoleId(team.leader.roleid), 1); } else { // 返回基地 this.goHome(PlayerMgr.shared.getPlayerByRoleId(data.roleId), 1); } break; } } }, 2 * 60 * 1000); player.send_notice("报名成功") } } } else { // 返回基地 this.goHome(player, 0); player.send_notice("参赛数据中未找到您队伍数据"); } } } /** * 比武结束处理 * @param player 当前玩家 * @param isWin 1 胜利 0 失败 */ contestResult(player: any, isWin: number) { // 1.获取当前帮派信息 let win_data: any = this.cut_faction[player.bangid] // 1.2 如果胜利 if (isWin == 1) { // 高手胜利场次记录该数据 if(player.teamid > 0){ if (player.isleader){ let data = this.contest_map_info.get(player.roleid); data.contest += 1; this.contest_map_info.set(player.roleid,data); } } // 1.2.1.敌方帮派帮派大门血量改变 this.gateHpUpdate(win_data.enemy_id,-600); } this.portal(player,0) } /** * 战斗结束处理 * @param player 当前玩家 * @param isWin 1 胜利 0 失败 */ fightResult(player: any, isWin: number, battle: any) { // 1.获取当前帮派信息 let win_data: any = this.cut_faction[player.bangid] // 1.2 取出战斗数据存 let contest = this.contest_map_info.get(player.roleid); // 1.3 如果胜利 if (isWin == 1) { // 1.3.1.敌方帮派帮派大门血量改变 this.gateHpUpdate(win_data.enemy_id,-10); if (contest != undefined){ for (let role of battle.campB.broles) { // 如果是玩家 并且死亡 if (role.living_type == 1) { // 1.3.1 杀敌数加1 contest.count += 1; } } } // 1.3.1.胜利场 contest.field_win += 1; // 如果是队长 成员胜利场加1 if(player.teamid > 0){ if (player.isleader){ contest.member_win += 1; } } } // 1.4 场次加1 contest.field += 1; // 更新战斗状态 contest.state = this.FightState.Wait; // 战斗数据存 this.contest_map_info.set(player.roleid,contest) this.portal(player,0) } /** * 校验 * @param player */ check(player: any, type: number = 0): any { if (player.bangid < 0) { player.send_notice("你没有帮派"); player.map_transfer(1011); return null; } let data: any = this.cut_faction[player.bangid]; if (data == undefined || data == null) { player.send_notice("你们帮目前没有帮战"); player.map_transfer(1011); return null; } if (type != 0){ if(player.teamid <= 0){ player.send_notice("请先进行组队"); return null; } let team = TeamMgr.shared.getTeamInfo(player.teamid); if (team == null || team.playerlist.length < 3) { player.send_notice("您当前队伍人数 < 3人,不可进行该操作"); return null; } } return data; } /** * 传送 * @param player 玩家信息 * @param type 0:基地 1:基地外围 */ portal(player: any, type: number){ let data: any = this.cut_faction[player.bangid]; if (data != undefined && data != null){ if (data.site == "L"){ if (type == 0){ player.map_transfer(3001, this.gate_xy_left.x, this.gate_xy_left.y); }else { player.map_transfer(3001, this.out_gate_xy_left.x, this.out_gate_xy_left.y); } }else { if (type == 0){ player.map_transfer(3001, this.gate_xy_right.x, this.gate_xy_right.y); }else { player.map_transfer(3001, this.out_gate_xy_right.x, this.out_gate_xy_right.y); } } }else { player.map_transfer(3001, 105, 51); } return; } /** * 烈火塔、玄冰塔操作 * @param player 玩家信息 * @param type 0:蓄力,1:打断 * @param serial 塔编号 */ tower_action(player: any, type: number, serial: number){ let data = this.check(player, 1); if (data != null) { // 获取塔状态(如果正在蓄力或者已经破损直接返回) let tower: any = this.urban_defense_map.get(serial); if (tower.state == FortificationsOperate.DAMAGED) { player.send("s2c_ask_fortifications", { type: tower.type, serial: serial, is: type, state: MsgCode.FAILED }); return; } // 1.蓄力 if (type == FortificationsOperate.STOREUP) { // 1.1 如果在蓄力状态直接返回 if (tower.state == FortificationsOperate.STOREUP) { player.send("s2c_ask_fortifications", { type: tower.type, serial: serial, is: type, state: MsgCode.FAILED }); return; } if (tower.state == FortificationsOperate.AUTOMATIC) { player.send("s2c_ask_fortifications", { type: tower.type, serial: serial, is: type, state: MsgCode.FAILED }); player.send_notice("当前塔不需要蓄力"); return; } // 1.2 关闭定时器 this.stopTowerSchedule(tower.site, tower.type); // 1.3塔操作数据 tower.time = 1; tower.state = FortificationsOperate.STOREUP; tower.roleId = player.roleid; this.urban_defense_map.set(serial, tower); if (tower.site == "L") { if (tower.type == Fortifications.ice) { // 1.4生成一个每ms定时器到20ms自动发射 this.ice_l_schedule = setInterval(this.towerScheduleMs, 20 * 1000, serial, this); } else { // 1.4生成一个每ms定时器到20ms自动发射 this.fire_l_schedule = setInterval(this.towerScheduleMs, 20 * 1000, serial, this); } } else { if (tower.type == Fortifications.ice) { // 1.4生成一个每ms定时器到20ms自动发射 this.ice_r_schedule = setInterval(this.towerScheduleMs, 20 * 1000, serial, this); } else { // 1.4生成一个每ms定时器到20ms自动发射 this.fire_r_schedule = setInterval(this.towerScheduleMs, 20 * 1000, serial, this); } } player.send("s2c_ask_fortifications", { type: tower.type, serial: Fortifications.cannon, is: type, state: MsgCode.SUCCESS }); } // 2.打断 else { // 2.1 关闭定时器 this.stopTowerSchedule(tower.site, tower.type); // 2.2恢复数据 tower.time = 0; tower.state = FortificationsOperate.INTERRUPT; } this.urban_defense_map.set(serial, tower); } } /** * 执行塔 * @param this_ */ towerScheduleMs(serial: number, this_: any) { // 1.获取塔状态 let tower: any = this_.urban_defense_map.get(serial); tower.roleId = 0; tower.time += 1; // 1.2.塔发射,减去耐久度 tower.durable -= 10; tower.state = FortificationsOperate.AUTOMATIC; // 1.3耐久度小于等于0 停止攻击 if (tower.durable <= 0) { tower.state = FortificationsOperate.DAMAGED; this_.stopTowerSchedule(tower.site, tower.type); this_.clear_npc(serial); this_.create_npc(tower.shadow); } // 1.4发射 this_.bombard_tower(serial, tower); this_.urban_defense_map.set(serial, tower); } /** * 战斗打断正在蓄力 * @param player */ fortifications_examine(player: any){ for (let [key, value] of this.urban_defense_map) { if (key >= 7205 && key <= 7208){ if (value.state == FortificationsOperate.STOREUP && value.roleId == player.roleid){ this.tower_action(player,1,key); break; } }else { if (value.state == FortificationsOperate.STOREUP && value.roleId == player.roleid){ this.cannon_action(player,1); break; } } } } /** * 关闭塔定时器 * @param site L 左 R 右 * @param type 2 烈火塔 3 玄冰塔 */ stopTowerSchedule(site: any, type: any){ if (site == "L") { if (type == Fortifications.ice) { // 左边玄冰塔定时器关闭 clearInterval(this.ice_l_schedule); } else { // 左边烈火塔定时器关闭 clearInterval(this.fire_l_schedule); } } else { if (type == Fortifications.ice) { // 右边玄冰塔定时器关闭 clearInterval(this.ice_r_schedule); } else { // 右边边烈火塔定时器关闭 clearInterval(this.fire_r_schedule); } } } /** * 塔发射攻击 * @param serial 塔的编号 * @param tower 塔的信息 */ bombard_tower(serial: number, tower: any) { let x: any = 35; let y: any = 88; let scope: any = {}; let hit_foe: any[]; if (tower.site == "L") { scope = this.tower_left; } else { scope = this.tower_right; } let list: any[] = []; let site: any[] = SKDataUtil.randomLonLat(scope.MinLon, scope.MaxLon, scope.MinLat, scope.MaxLat); if (site.length > 1) { x = site[0]; y = site[1]; } for (let key in this.cut_faction) { let data = this.cut_faction[key]; let arr: any[] = this.contest_map.get(key); if (data.site != tower.site) { // 敌方帮派成员 hit_foe = arr; } else { // 能量塔攻击数加1 data.tower += 1; } list = list.concat(arr); } // 通知所有参加帮派玩家(发射炮弹效果) PlayerMgr.shared.broadcastPart(list, "s2c_bombard_site", {x: x, y: y, serial: serial, type: tower.type, direction: ""}); // 通知所有参加帮派玩家(塔的血量) PlayerMgr.shared.broadcastPart(list, "s2c_gang_tower_info", { towerId: serial, durable: tower.durable, durableMax: tower.durableMax, bangId: tower.bangId }); // 获取附近敌方帮派成员 for (let key of hit_foe) { let player = PlayerMgr.shared.getPlayerByRoleId(Number(key)); if (player) { // 判断是否在炸点范围 在炸点范围送回基地 let is = SKDataUtil.confineTo(x, y, player.x, player.y, this.tower_radius); if (is) { // 被玄冰塔击中冰冻20秒 if (tower.type == Fortifications.ice) { let num = 20; this.ice_map.set(player.roleid, num); // 通知前端冰冻该玩家 player.send("s2c_wars_player_state", {type: 1, ice: num, time: GTimer.getTime()}); player.isFrozen = 1; player.send('s2c_aoi_pinfo', { list: [player.toObj()] }); } // 被烈火塔击中送回基地120ms内不得再进入战场 else { let num = 120; this.fire_map.set(player.roleid, num); // 返回基地 if(player.teamid > 0){ if (player.isleader){ this.goHome(player, 0); } }else { this.goHome(player, 0); } player.send_notice("你已被神烈火塔击中, 传送回基地"); } } } } } /** * 神龙大炮操作(当别人切磋该玩家打断) * @param player 玩家信息 * @param type 0:蓄力,1:打断 * @param 神龙大炮 time 当前蓄力时间ms, state 0 蓄力,1 打断, roleId 当前蓄力者角色编号, bangId 帮派ID */ cannon_action(player: any, type: number) { let data = this.check(player, 1); if (data != null) { // 1.蓄力 if (type == FortificationsOperate.STOREUP) { // 1.1获取神龙大炮状态(如果正在蓄力直接返回) let cannon: any = this.urban_defense_map.get(Fortifications.cannon); if (cannon.state == FortificationsOperate.STOREUP) { player.send("s2c_ask_fortifications", { type: Fortifications.cannon, serial: Fortifications.cannon, is: type, state: MsgCode.FAILED }); return; } else { // 1.2关闭定时器 clearInterval(this.cannon_schedule); // 1.3储存神龙跑操作数据 cannon.time = 1; cannon.state = FortificationsOperate.STOREUP; cannon.roleId = player.roleid; cannon.bangId = player.bangid; this.urban_defense_map.set(Fortifications.cannon, cannon); // 1.4生成一个每ms定时器到20ms自动发射炮弹 SKLogger.info("神龙大炮开始蓄力!") this.cannon_schedule = setInterval(this.cannonScheduleMs, 1000, this); player.send("s2c_ask_fortifications", { type: Fortifications.cannon, serial: Fortifications.cannon, is: type, state: MsgCode.SUCCESS }); } } // 2.打断 else { // 2.1关闭定时器 clearInterval(this.cannon_schedule); SKLogger.info("神龙大炮被打断蓄力!") // 2.2获取神龙大炮状态 let cannon_ms: any = this.urban_defense_map.get(Fortifications.cannon); if (cannon_ms != undefined) { this.bombard_cannon(cannon_ms.bangId, cannon_ms.time); } // 2.3数据恢复初始状态 this.urban_defense_map.set(Fortifications.cannon, { time: 0, state: FortificationsOperate.INTERRUPT, roleId: 0, bangId: 0 }); } } } /** * 执行神龙大炮 * @param this_ */ cannonScheduleMs(this_: any){ // 1.获取神龙大炮状态 let cannon_ms: any = this_.urban_defense_map.get(Fortifications.cannon); cannon_ms.time += 1; SKLogger.info("当前塔蓄力时间:"+cannon_ms.time) // 1.2神龙大炮蓄力时间大于等于20ms则发炮,数据恢复初始状态 if (cannon_ms.time >= 20) { // 1.3关闭定时器 clearInterval(this_.cannon_schedule); this_.urban_defense_map.set(Fortifications.cannon, { time: 0, state: FortificationsOperate.INTERRUPT, roleId: 0, bangId: 0 }); this_.bombard_cannon(cannon_ms.bangId, cannon_ms.time); }else { this_.urban_defense_map.set(Fortifications.cannon, cannon_ms); } } /** * 发射神龙大炮 * @param bangId 己方帮派编号 * @param time 蓄力时间 */ bombard_cannon(bangId: any, time: number) { // 1.获取当前帮派信息 let data: any = this.cut_faction[bangId] let gate: any; let x: any = 35; let y: any = 88; let direction: string = "L"; let flag: boolean = false; if (data != undefined) { if (data.site == "L") { if (time >= 20) { gate = this.cannon_right_gate; flag = true; } else if (time < 20 && time > 10) { gate = this.cannon_right_10_19; } else { gate = this.cannon_right_0_10; } let site: any[] = SKDataUtil.randomLonLat(gate.MinLon, gate.MaxLon, gate.MinLat, gate.MaxLat); if (site.length > 1) { x = site[0]; y = site[1]; } direction = "R"; } else { if (time >= 20) { gate = this.cannon_left_gate; flag = true; } else if (time < 20 && time > 10) { gate = this.cannon_left_10_19; } else { gate = this.cannon_left_0_10; } let site: any[] = SKDataUtil.randomLonLat(gate.MinLon, gate.MaxLon, gate.MinLat, gate.MaxLat); if (site.length > 1) { x = site[0]; y = site[1]; }else { x = 58; y = 98; } } // 神龙炮开炮数加1 data.cannon += 1; let side: any[] = this.contest_map.get(bangId.toString()); let enemy: any[] = this.contest_map.get(data.enemy_id.toString()); let list: any[] = side.concat(enemy); // 通知所有参加帮派玩家(发射炮弹效果) PlayerMgr.shared.broadcastPart(list,"s2c_bombard_site", {x: x, y: y, serial: Fortifications.cannon, type: Fortifications.cannon, direction: direction}) // 没有打到门子上 if (!flag){ // 获取附近的人 for (let key of list) { let player = PlayerMgr.shared.getPlayerByRoleId(Number(key)); if (player) { // 判断是否在炸点范围 在炸点范围送回基地 let is = SKDataUtil.confineTo(x, y, player.x, player.y, this.cannon_radius); if (is){ // 返回基地 if(player.teamid > 0){ if (player.isleader){ this.goHome(player, 0); } }else { this.goHome(player, 0); } player.send_notice("你已被神龙大炮击中, 传送回基地"); } } } }else { this.gateHpUpdate(data.enemy_id,-180); } } } /** * 城门血量改变 * @param bangId * @param value */ gateHpUpdate(bangId: any,value: number){ // 获取当前帮信息 let data: any = this.cut_faction[bangId]; let data_: any = this.cut_faction[data.enemy_id]; data.gate_hp += value; let l: any = {}; let r: any = {}; // 己方帮成员 let side: any[] = this.contest_map.get(bangId.toString()); // 敌方帮成员 let enemy: any[] = this.contest_map.get(data.enemy_id.toString()); let list: any[] = side.concat(enemy); if (data.site == "L"){ let bang: any = BangMgr.shared.getBang(bangId); let bang_: any = BangMgr.shared.getBang(data.enemy_id); l = {gateHp: data.gate_hp, gateMaxHp: data.gate_max_hp, name: bang.name}; r = {gateHp: data_.gate_hp, gateMaxHp: data_.gate_max_hp, name: bang_.name}; }else { let bang: any = BangMgr.shared.getBang(bangId); let bang_: any = BangMgr.shared.getBang(data.enemy_id); r = {gateHp: data.gate_hp, gateMaxHp: data.gate_max_hp, name: bang.name}; l = {gateHp: data_.gate_hp, gateMaxHp: data_.gate_max_hp, name: bang_.name}; } // 通知所有参加帮派玩家(城门血量改变) PlayerMgr.shared.broadcastPart(list,"s2c_gate_hp", {gateHpL: SKDataUtil.toJson(l,"{}"), gateHpR: SKDataUtil.toJson(r,"{}"), time: this.start_time}); // 如果帮派大门血量小于等于0 结束帮战 if (data.gate_hp <= 0) { // 5.帮战结束 this.close(); } } /** * 获取烈火塔、玄冰塔信息 * @param player 玩家信息 * @param serial 塔编号 */ tower_info(player: any, serial: number){ let data = this.check(player, 1); if (data != null) { let tower = this.urban_defense_map.get(serial); if (tower != null && tower != undefined) { let bangId: any = 0; for (let key in this.cut_faction) { let data: any = this.cut_faction[key]; if (data.site == tower.site) { bangId = key; break; } } player.send("s2c_gang_tower", { towerId: serial, // 塔编号 durable: tower.durable, // 当前耐久 durableMax: tower.durableMax, // 最大耐久 bangId: bangId // 帮派编号 }); } else { player.send_notice("获取塔信息失败!"); } } } /** * 将塔的帮派编号赋值 */ tower_info_update(){ for (let [key, value] of this.urban_defense_map) { if (key >= 7205 && key <= 7208){ let tower = this.urban_defense_map.get(key); if (tower != null && tower != undefined){ for (let k in this.cut_faction) { let data: any = this.cut_faction[k]; if (data.site == tower.site) { tower.bangId = k; this.urban_defense_map.set(key,tower); break; } } } } }; } //---------------------------------------------------------------------------------------------------------------------- // 战斗开始之前的 10秒 beforeFight(t1: any, t2: any, type: any) { let team = TeamMgr.shared.getTeamInfo(t1.teamid); let eteam = TeamMgr.shared.getTeamInfo(t2.teamid); if (team && eteam) { let selfTeam = []; for (let index = 0; index < team.playerlist.length; index++) { let member = team.playerlist[index]; let satRole: any = {}; satRole.onlyid = member.onlyid; satRole.roleid = member.roleid; satRole.resid = member.resid; satRole.level = member.level; satRole.name = member.name; selfTeam.push(satRole); } let enemyTeam = []; for (let index = 0; index < eteam.playerlist.length; index++) { let member = eteam.playerlist[index]; let satRole: any = {}; satRole.onlyid = member.onlyid; satRole.roleid = member.roleid; satRole.resid = member.resid; satRole.level = member.level; satRole.name = member.name; enemyTeam.push(satRole); } TeamMgr.shared.broadcast(t1.teamid, 's2c_match', { teamS: selfTeam, teamE: enemyTeam, }); TeamMgr.shared.broadcast(t2.teamid, 's2c_match', { teamS: enemyTeam, teamE: selfTeam, }); t1.fight_state = this.FightState.Fighting; t2.fight_state = this.FightState.Fighting; setTimeout(() => { this.startFight(t1, t2, type); }, 11 * 1000); } } /** * 进入战斗 * @param t1 * @param t2 */ startFight(t1: any, t2: any, type: any) { let team = TeamMgr.shared.getTeamInfo(t1.teamid); let eteam = TeamMgr.shared.getTeamInfo(t2.teamid); if (team && eteam) { let eonlyid = eteam.leader.onlyid; team.leader.playerBattle(eonlyid, type); } } /** * 关闭活动 */ close() { if (this.activity_state == ActivityDefine.activityState.Close) { return; } this.defenceInfo(); // 左边玄冰塔定时器关闭 clearInterval(this.ice_l_schedule); // 左边烈火塔定时器关闭 clearInterval(this.fire_l_schedule); // 右边玄冰塔定时器关闭 clearInterval(this.ice_r_schedule); // 右边边烈火塔定时器关闭 clearInterval(this.fire_r_schedule); clearInterval(this.ms_ice_target_schedule); clearInterval(this.ms_fire_target_schedule); // 通知帮战结束 let list: any[] = []; for (let [key, value] of this.contest_map) { list = list.concat(value); } for (let i = 0; i < list.length; i++) { if (list[i] != undefined){ let player = PlayerMgr.shared.getPlayerByRoleId(list[i]); if (player) { this.detail_statistics(player,1); if(player.teamid > 0){ // 清理跳转长安 if (player.isleader){ player.map_transfer(1011); } }else { // 清理跳转长安 player.map_transfer(1011); } } } } // 活动状态 this.activity_state = ActivityDefine.activityState.Close; // 帮战参赛成员 this.contest_map.clear(); this.cut_faction = {}; // 玄冰塔,击中目标记录<角色编号,控制时间> this.ice_map.clear(); // 烈火塔,击中目标记录<角色编号,控制时间> this.fire_map.clear(); // 帮战所有参赛成员 - 角色编号 - {战斗状态 2战斗中 1未战斗,帮派编号,击杀人数 field:场数,field_win: 本人胜利场,contest: 高手胜利场, member_win:成员胜利场} this.contest_map_info.clear(); this.clear_npc(0,1); for (let [key, value] of this.urban_defense_map) { if (key != Fortifications.cannon) { this.create_npc(key); } } } }