xy-server/game/activity/FactionWar.ts

1531 lines
59 KiB
TypeScript
Raw Permalink Normal View History

2025-04-23 09:34:08 +08:00
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<String, any>;
// 烈火塔、玄冰塔,神龙大炮信息
urban_defense_map: Map<number, any>;
// 玄冰塔,击中目标记录<角色编号,控制时间>
ice_map: Map<number, number>;
// 玄冰塔ms击中目标记录检查定时
ms_ice_target_schedule: any;
// 烈火塔,击中目标记录<角色编号,控制时间>
fire_map: Map<number, number>;
// 烈火塔ms击中目标记录检查定时
ms_fire_target_schedule: any;
// 帮战所有参赛成员 - 角色编号 - {战斗状态 2战斗中 1未战斗,帮派编号,击杀人数 field场数,field_win: 本人胜利场,contest: 高手胜利场, member_win成员胜利场}
contest_map_info: Map<number, any>;
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<String, any[]>();
// 比武时间
this.contest_time = [10, 20, 30];
// 玄冰塔,击中目标记录<角色编号,控制时间>
this.ice_map = new Map<number, number>();
// 烈火塔,击中目标记录<角色编号,控制时间>
this.fire_map = new Map<number, number>();
// 烈火塔、玄冰塔信息
this.urban_defense_map = new Map<number, any>();
// 帮战所有参赛成员 - 角色编号 - {战斗状态 2战斗中 1未战斗,帮派编号,击杀人数 field场数,field_win: 本人胜利场,contest: 高手胜利场, member_win成员胜利场}
this.contest_map_info = new Map<number, any>();
// 帮战开启时间
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 01
* @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 01
* @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);
}
}
}
}